protected Collection<String> generateSuggestedNames(PyExpression expression) { Collection<String> candidates = new LinkedHashSet<String>() { @Override public boolean add(String s) { if (PyNames.isReserved(s)) { return false; } return super.add(s); } }; String text = expression.getText(); final Pair<PsiElement, TextRange> selection = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE); if (selection != null) { text = selection.getSecond().substring(text); } if (expression instanceof PyCallExpression) { final PyExpression callee = ((PyCallExpression) expression).getCallee(); if (callee != null) { text = callee.getText(); } } if (text != null) { candidates.addAll(NameSuggesterUtil.generateNames(text)); } final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getContainingFile()); PyType type = context.getType(expression); if (type != null && type != PyNoneType.INSTANCE) { String typeName = type.getName(); if (typeName != null) { if (type.isBuiltin()) { typeName = typeName.substring(0, 1); } candidates.addAll(NameSuggesterUtil.generateNamesByType(typeName)); } } final PyKeywordArgument kwArg = PsiTreeUtil.getParentOfType(expression, PyKeywordArgument.class); if (kwArg != null && kwArg.getValueExpression() == expression) { candidates.add(kwArg.getKeyword()); } final PyArgumentList argList = PsiTreeUtil.getParentOfType(expression, PyArgumentList.class); if (argList != null) { final CallArgumentsMapping result = argList.analyzeCall(PyResolveContext.noImplicits()); if (result.getMarkedCallee() != null) { final PyNamedParameter namedParameter = result.getPlainMappedParams().get(expression); if (namedParameter != null) { candidates.add(namedParameter.getName()); } } } return candidates; }
private static Pair<String, String> getTypeAndDescription( @Nullable final String docString, @NotNull final PyNamedParameter followed) { StructuredDocString structuredDocString = DocStringUtil.parse(docString); String type = null; String desc = null; if (structuredDocString != null) { final String name = followed.getName(); type = structuredDocString.getParamType(name); desc = structuredDocString.getParamDescription(name); } return Pair.create(type, desc); }
private static void highlightMissingArguments( PyArgumentList node, ProblemsHolder holder, CallArgumentsMapping result) { ASTNode our_node = node.getNode(); if (our_node != null) { ASTNode close_paren = our_node.findChildByType(PyTokenTypes.RPAR); if (close_paren != null) { for (PyNamedParameter param : result.getUnmappedParams()) { holder.registerProblem( close_paren.getPsi(), PyBundle.message("INSP.parameter.$0.unfilled", param.getName())); } } } }
@Override public void visitPyDecoratorList(final PyDecoratorList node) { PyDecorator[] decorators = node.getDecorators(); for (PyDecorator deco : decorators) { if (deco.hasArgumentList()) continue; final PyCallExpression.PyMarkedCallee markedCallee = deco.resolveCallee(resolveWithoutImplicits()); if (markedCallee != null && !markedCallee.isImplicitlyResolved()) { final Callable callable = markedCallee.getCallable(); int firstParamOffset = markedCallee.getImplicitOffset(); final List<PyParameter> params = PyUtil.getParameters(callable, myTypeEvalContext); final PyNamedParameter allegedFirstParam = params.size() < firstParamOffset ? null : params.get(firstParamOffset - 1).getAsNamed(); if (allegedFirstParam == null || allegedFirstParam.isKeywordContainer()) { // no parameters left to pass function implicitly, or wrong param type registerProblem( deco, PyBundle.message( "INSP.func.$0.lacks.first.arg", callable.getName())); // TODO: better names for anon lambdas } else { // possible unfilled params for (int i = firstParamOffset; i < params.size(); i += 1) { final PyParameter parameter = params.get(i); if (parameter instanceof PySingleStarParameter) continue; final PyNamedParameter par = parameter.getAsNamed(); // param tuples, non-starred or non-default won't do if (par == null || (!par.isKeywordContainer() && !par.isPositionalContainer() && !par.hasDefaultValue())) { String parameterName = par != null ? par.getName() : "(...)"; registerProblem( deco, PyBundle.message("INSP.parameter.$0.unfilled", parameterName)); } } } } // else: this case is handled by arglist visitor } }