void () { if (myParametersPrepared) { return; } final Set<Pair<String, Boolean>> withoutType = new HashSet<>(); final Map<Pair<String, Boolean>, String> paramTypes = Maps.newHashMap(); for (DocstringParam param : myAddedParams) { if (param.getType() == null) { withoutType.add(Pair.create(param.getName(), param.isReturnValue())); } else { // leave only the last type for parameter paramTypes.put(Pair.create(param.getName(), param.isReturnValue()), param.getType()); } } // Sanitize parameters PySignature signature = null; if (myDocStringOwner instanceof PyFunction && myUseTypesFromDebuggerSignature) { signature = PySignatureCacheManager.getInstance(myDocStringOwner.getProject()).findSignature((PyFunction)myDocStringOwner); } final DocStringFormat format = myDocStringFormat; final ArrayList<DocstringParam> filtered = new ArrayList<>(); final Set<Pair<String, Boolean>> processed = new HashSet<>(); for (DocstringParam param : myAddedParams) { final Pair<String, Boolean> paramCoordinates = Pair.create(param.getName(), param.isReturnValue()); if (processed.contains(paramCoordinates)) { continue; } if (param.getType() == null) { String type = paramTypes.get(paramCoordinates); if (type == null && PyCodeInsightSettings.getInstance().INSERT_TYPE_DOCSTUB) { if (signature != null) { type = StringUtil.notNullize(param.isReturnValue() ? signature.getReturnTypeQualifiedName() : signature.getArgTypeQualifiedName(param.getName())); } else { type = ""; } } if (type != null) { // Google and Numpy docstring formats combine type and description in single declaration, thus // if both declaration with type and without it are requested, we should filter out duplicates if (format != DocStringFormat.GOOGLE && format != DocStringFormat.NUMPY) { // In reST and Epydoc for each parameter add two tags, e.g. in reST (Sphinx) // :param foo: // :type foo: filtered.add(param); } filtered.add(new DocstringParam(param.getName(), type, param.isReturnValue())); } else { // no type was given and it's not required by settings filtered.add(param); } } else if (!withoutType.contains(paramCoordinates)) { filtered.add(param); } processed.add(paramCoordinates); } myAddedParams.clear(); myAddedParams.addAll(filtered); myParametersPrepared = true; }