From dade15b0315dcf25a82ab6d50d44a2a8c8b24fa5 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Mon, 7 Sep 2015 14:02:58 +0300 Subject: [PATCH] Cleanup in SpecifyTypeIn*Intentions and PyDocstringInspection Like SpecifyTypeInDocstringIntention SpecifyTypeInPy3AnnotationIntention operates only on named function parameters. --- .../SpecifyTypeInDocstringIntention.java | 14 +++--- .../SpecifyTypeInPy3AnnotationsIntention.java | 50 +++++++++---------- .../documentation/PyDocstringGenerator.java | 15 +++--- .../inspections/PyDocstringInspection.java | 37 +++++++------- 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java index bc645609897e..ea70948b9a0c 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java @@ -53,12 +53,12 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { } public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - PsiElement elementAt = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset()); - PyExpression problemElement = getProblemElement(elementAt); - PsiReference reference = problemElement == null ? null : problemElement.getReference(); + final PsiElement elementAt = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset()); + final PyExpression problemElement = getProblemElement(elementAt); + final PsiReference reference = problemElement == null ? null : problemElement.getReference(); final PsiElement resolved = reference != null ? reference.resolve() : null; - PyNamedParameter parameter = getParameter(problemElement, resolved); + final PyNamedParameter parameter = getParameter(problemElement, resolved); final PyCallable callable; if (parameter != null) { @@ -72,7 +72,7 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { } } - private static void generateDocstring(@Nullable PyNamedParameter param, PyFunction pyFunction) { + private static void generateDocstring(@Nullable PyNamedParameter param, @NotNull PyFunction pyFunction) { if (!DocStringUtil.ensureNotPlainDocstringFormat(pyFunction)) { return; } @@ -101,8 +101,8 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { } @Override - protected boolean isParamTypeDefined(@NotNull final PyParameter parameter) { - PyFunction pyFunction = PsiTreeUtil.getParentOfType(parameter, PyFunction.class); + protected boolean isParamTypeDefined(@NotNull PyParameter parameter) { + final PyFunction pyFunction = PsiTreeUtil.getParentOfType(parameter, PyFunction.class); if (pyFunction != null) { final StructuredDocString structuredDocString = pyFunction.getStructuredDocString(); if (structuredDocString == null) { diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java index a1e22b488264..c6f13a67839f 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java @@ -39,8 +39,6 @@ import org.jetbrains.annotations.NotNull; */ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { private String myText = PyBundle.message("INTN.specify.type.in.annotation"); - public SpecifyTypeInPy3AnnotationsIntention() { - } @NotNull public String getText() { @@ -59,12 +57,12 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { } public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - PsiElement elementAt = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset()); - PyExpression problemElement = getProblemElement(elementAt); - PsiReference reference = problemElement == null? null : problemElement.getReference(); + final PsiElement elementAt = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset()); + final PyExpression problemElement = getProblemElement(elementAt); + final PsiReference reference = problemElement == null ? null : problemElement.getReference(); - final PsiElement resolved = reference != null? reference.resolve() : null; - PyParameter parameter = getParameter(problemElement, resolved); + final PsiElement resolved = reference != null ? reference.resolve() : null; + final PyNamedParameter parameter = getParameter(problemElement, resolved); if (parameter != null) { annotateParameter(project, editor, parameter); @@ -74,42 +72,43 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { } } - private static void annotateParameter(Project project, Editor editor, PyParameter parameter) { - PyExpression defaultParamValue = parameter instanceof PyNamedParameter? parameter.getDefaultValue() : null; + private static void annotateParameter(Project project, Editor editor, @NotNull PyNamedParameter parameter) { + final PyExpression defaultParamValue = parameter.getDefaultValue(); final String name = StringUtil.notNullize(parameter.getName()); - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - String defaultParamText = defaultParamValue == null? null: defaultParamValue.getText(); - final PyNamedParameter namedParameter = elementGenerator.createParameter(name, defaultParamText, PyNames.OBJECT, LanguageLevel.forElement(parameter)); + final String defaultParamText = defaultParamValue == null ? null : defaultParamValue.getText(); + final PyNamedParameter namedParameter = elementGenerator.createParameter(name, defaultParamText, PyNames.OBJECT, + LanguageLevel.forElement(parameter)); assert namedParameter != null; - parameter = (PyParameter)parameter.replace(namedParameter); + parameter = (PyNamedParameter)parameter.replace(namedParameter); parameter = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(parameter); editor.getCaretModel().moveToOffset(parameter.getTextOffset()); - PyAnnotation annotation = parameter instanceof PyNamedParameter? ((PyNamedParameter)parameter).getAnnotation() : null; + final PyAnnotation annotation = parameter.getAnnotation(); if (annotation != null) { - PyExpression annotationValue = annotation.getValue(); + final PyExpression annotationValue = annotation.getValue(); final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(parameter); - int replacementStart = annotation.getStartOffsetInParent() + annotationValue.getStartOffsetInParent(); + assert annotationValue != null : "Generated parameter must have annotation"; + final int replacementStart = annotation.getStartOffsetInParent() + annotationValue.getStartOffsetInParent(); builder.replaceRange(TextRange.create(replacementStart, replacementStart + annotationValue.getTextLength()), PyNames.OBJECT); - Template template = ((TemplateBuilderImpl)builder).buildInlineTemplate(); + final Template template = ((TemplateBuilderImpl)builder).buildInlineTemplate(); TemplateManager.getInstance(project).startTemplate(editor, template); } } private void annotateReturnType(Project project, PsiElement resolved) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); PyCallable callable = getCallable(resolved); if (callable instanceof PyFunction) { final String functionSignature = "def " + callable.getName() + callable.getParameterList().getText(); String functionText = functionSignature + - " -> object:"; + " -> object:"; final PyStatementList statementList = ((PyFunction)callable).getStatementList(); - assert statementList != null; for (PyStatement st : statementList.getStatements()) { functionText = functionText + "\n\t" + st.getText(); } @@ -121,17 +120,18 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { final PyAnnotation annotation = ((PyFunction)callable).getAnnotation(); assert annotation != null; final PyExpression annotationValue = annotation.getValue(); + assert annotationValue != null : "Generated function must have annotation"; final int offset = annotationValue.getTextOffset(); final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(annotationValue); builder.replaceRange(TextRange.create(0, PyNames.OBJECT.length()), PyNames.OBJECT); - Template template = ((TemplateBuilderImpl)builder).buildInlineTemplate(); - OpenFileDescriptor descriptor = new OpenFileDescriptor( + final Template template = ((TemplateBuilderImpl)builder).buildInlineTemplate(); + final OpenFileDescriptor descriptor = new OpenFileDescriptor( project, callable.getContainingFile().getVirtualFile(), offset ); - Editor targetEditor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + final Editor targetEditor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); if (targetEditor != null) { targetEditor.getCaretModel().moveToOffset(offset); TemplateManager.getInstance(project).startTemplate(targetEditor, template); @@ -144,7 +144,7 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { return isDefinedInAnnotation(parameter); } - private boolean isDefinedInAnnotation(PyParameter parameter) { + private static boolean isDefinedInAnnotation(PyParameter parameter) { if (LanguageLevel.forElement(parameter).isOlderThan(LanguageLevel.PYTHON30)) { return false; } @@ -159,6 +159,6 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { @Override protected void updateText(boolean isReturn) { - myText = isReturn? PyBundle.message("INTN.specify.return.type.in.annotation") : PyBundle.message("INTN.specify.type.in.annotation"); + myText = isReturn ? PyBundle.message("INTN.specify.return.type.in.annotation") : PyBundle.message("INTN.specify.type.in.annotation"); } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java index 365c4044b1eb..d78bda5a7e36 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java @@ -123,18 +123,13 @@ public class PyDocstringGenerator { return withParam(getPreferredParameterName(param)); } - @NotNull - public PyDocstringGenerator withoutParam(@NotNull String name) { - return withParamTypedByName(name, null); - } - @NotNull public PyDocstringGenerator withParamTypedByName(@NotNull String name, @Nullable String type) { myAddedParams.add(new DocstringParam(name, type, false)); return this; } - - @NotNull + + @NotNull public PyDocstringGenerator withParamTypedByName(@NotNull PyNamedParameter name, @Nullable String type) { return withParamTypedByName(getPreferredParameterName(name), type); } @@ -145,6 +140,12 @@ public class PyDocstringGenerator { return this; } + @NotNull + public PyDocstringGenerator withoutParam(@NotNull String name) { + myRemovedParams.add(new DocstringParam(name, null, false)); + return this; + } + @NotNull public PyDocstringGenerator withQuotes(@NotNull String quotes) { myQuotes = quotes; diff --git a/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java b/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java index bff48f346748..bef55660f381 100644 --- a/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java @@ -70,12 +70,12 @@ public class PyDocstringInspection extends PyInspection { } @Override - public void visitPyFile(PyFile node) { + public void visitPyFile(@NotNull PyFile node) { checkDocString(node); } @Override - public void visitPyFunction(PyFunction node) { + public void visitPyFunction(@NotNull PyFunction node) { if (PythonUnitTestUtil.isUnitTestCaseFunction(node)) return; final PyClass containingClass = node.getContainingClass(); if (containingClass != null && PythonUnitTestUtil.isUnitTestCaseClass(containingClass)) return; @@ -84,7 +84,7 @@ public class PyDocstringInspection extends PyInspection { } @Override - public void visitPyClass(PyClass node) { + public void visitPyClass(@NotNull PyClass node) { if (PythonUnitTestUtil.isUnitTestCaseClass(node)) return; final String name = node.getName(); if (name == null || name.startsWith("_")) { @@ -98,7 +98,7 @@ public class PyDocstringInspection extends PyInspection { checkDocString(node); } - private void checkDocString(PyDocStringOwner node) { + private void checkDocString(@NotNull PyDocStringOwner node) { final PyStringLiteralExpression docStringExpression = node.getDocStringExpression(); if (docStringExpression == null) { PsiElement marker = null; @@ -111,8 +111,8 @@ public class PyDocstringInspection extends PyInspection { if (n != null) marker = n.getPsi(); } else if (node instanceof PyFile) { - TextRange tr = new TextRange(0, 0); - ProblemsHolder holder = getHolder(); + final TextRange tr = new TextRange(0, 0); + final ProblemsHolder holder = getHolder(); if (holder != null) { holder.registerProblem(node, tr, PyBundle.message("INSP.no.docstring")); } @@ -127,29 +127,29 @@ public class PyDocstringInspection extends PyInspection { } } else { - boolean registered = checkParameters(node, docStringExpression); + final boolean registered = checkParameters(node, docStringExpression); if (!registered && StringUtil.isEmptyOrSpaces(docStringExpression.getStringValue())) { registerProblem(docStringExpression, PyBundle.message("INSP.empty.docstring")); } } } - private boolean checkParameters(PyDocStringOwner pyDocStringOwner, PyStringLiteralExpression node) { + private boolean checkParameters(@NotNull PyDocStringOwner pyDocStringOwner, @NotNull PyStringLiteralExpression node) { final String text = node.getText(); if (text == null) { return false; } - StructuredDocString docString = DocStringUtil.parse(text, node); + final StructuredDocString docString = DocStringUtil.parse(text, node); if (docString instanceof PlainDocString) { return false; } if (pyDocStringOwner instanceof PyFunction) { - PyParameter[] realParams = ((PyFunction)pyDocStringOwner).getParameterList().getParameters(); + final PyParameter[] realParams = ((PyFunction)pyDocStringOwner).getParameterList().getParameters(); - List missingParams = getMissingParams(docString, realParams); + final List missingParams = getMissingParams(docString, realParams); boolean registered = false; if (!missingParams.isEmpty()) { for (PyNamedParameter param : missingParams) { @@ -157,10 +157,10 @@ public class PyDocstringInspection extends PyInspection { } registered = true; } - List unexpectedParams = getUnexpectedParams(docString, realParams); + final List unexpectedParams = getUnexpectedParams(docString, realParams); if (!unexpectedParams.isEmpty()) { for (Substring param : unexpectedParams) { - ProblemsHolder holder = getHolder(); + final ProblemsHolder holder = getHolder(); if (holder != null) { holder.registerProblem(node, param.getTextRange(), @@ -175,8 +175,9 @@ public class PyDocstringInspection extends PyInspection { return false; } - private static List getUnexpectedParams(StructuredDocString docString, PyParameter[] realParams) { - Map unexpected = Maps.newHashMap(); + @NotNull + private static List getUnexpectedParams(@NotNull StructuredDocString docString, @NotNull PyParameter[] realParams) { + final Map unexpected = Maps.newHashMap(); for (Substring s : docString.getParameterSubstrings()) { unexpected.put(s.toString(), s); @@ -190,14 +191,14 @@ public class PyDocstringInspection extends PyInspection { return Lists.newArrayList(unexpected.values()); } - private static List getMissingParams(StructuredDocString docString, PyParameter[] realParams) { - List missing = new ArrayList(); + @NotNull + private static List getMissingParams(@NotNull StructuredDocString docString, @NotNull PyParameter[] realParams) { + final List missing = new ArrayList(); final List docStringParameters = docString.getParameters(); for (PyParameter p : realParams) { if (p.isSelf() || !(p instanceof PyNamedParameter)) { continue; } - //noinspection ConstantConditions if (!docStringParameters.contains(p.getName())) { missing.add((PyNamedParameter)p); }