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 void highlightStarArgumentTypeMismatch( PyArgumentList node, ProblemsHolder holder, TypeEvalContext context) { for (PyExpression arg : node.getArguments()) { if (arg instanceof PyStarArgument) { PyExpression content = PyUtil.peelArgument(PsiTreeUtil.findChildOfType(arg, PyExpression.class)); if (content != null) { PyType inside_type = context.getType(content); if (inside_type != null && !PyTypeChecker.isUnknown(inside_type)) { if (((PyStarArgument) arg).isKeyword()) { if (!PyABCUtil.isSubtype(inside_type, PyNames.MAPPING)) { holder.registerProblem( arg, PyBundle.message("INSP.expected.dict.got.$0", inside_type.getName())); } } else { // * arg if (!PyABCUtil.isSubtype(inside_type, PyNames.ITERABLE)) { holder.registerProblem( arg, PyBundle.message("INSP.expected.iter.got.$0", inside_type.getName())); } } } } } } }
public static void inspectPyArgumentList( PyArgumentList node, ProblemsHolder holder, final TypeEvalContext context, int implicitOffset) { if (node.getParent() instanceof PyClass) return; // class Foo(object) is also an arg list CallArgumentsMapping result = node.analyzeCall( PyResolveContext.noImplicits().withTypeEvalContext(context), implicitOffset); final PyCallExpression.PyMarkedCallee callee = result.getMarkedCallee(); if (callee != null) { final Callable callable = callee.getCallable(); // Decorate functions may have different parameter lists. We don't match arguments with // parameters of decorators yet if (callable instanceof PyFunction && PyUtil.hasCustomDecorators((PyFunction) callable)) { return; } } highlightIncorrectArguments(holder, result, context); highlightMissingArguments(node, holder, result); highlightStarArgumentTypeMismatch(node, holder, context); }
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())); } } } }