From a5edf813795cef287465601641b9cb34c7c33120 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 14 Jan 2011 18:48:07 +0100 Subject: [PATCH] correctly handle return annotations in 'override' and formatter (PY-2690) --- .../override/PyOverrideImplementUtil.java | 4 ++++ .../jetbrains/python/formatter/PyBlock.java | 21 ++++++++++++++++--- .../python/psi/impl/PyFunctionBuilder.java | 12 ++++++++++- python/testData/override/returnAnnotation.py | 6 ++++++ .../override/returnAnnotation_after.py | 8 +++++++ .../com/jetbrains/python/PyOverrideTest.java | 5 ++++- 6 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 python/testData/override/returnAnnotation.py create mode 100644 python/testData/override/returnAnnotation_after.py diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 0fec303396e4..d995c60bd3d3 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -149,6 +149,10 @@ public class PyOverrideImplementUtil { if (decorators != null && decorators.findDecorator(PyNames.CLASSMETHOD) != null) { pyFunctionBuilder.decorate(PyNames.CLASSMETHOD); } + PyAnnotation anno = baseFunction.getAnnotation(); + if (anno != null) { + pyFunctionBuilder.annotation(anno.getText()); + } final PyParameter[] baseParams = baseFunction.getParameterList().getParameters(); for (PyParameter parameter : baseParams) { pyFunctionBuilder.parameter(parameter.getText()); diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java index fff4437b966d..75438a9c9108 100644 --- a/python/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/src/com/jetbrains/python/formatter/PyBlock.java @@ -277,6 +277,18 @@ public class PyBlock implements ASTBlock { return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, false, 1); } + if (parentType == PyElementTypes.ANNOTATION) { + if (type1 == PyTokenTypes.GT) { + return createSpaces(1); + } + if (type1 == PyTokenTypes.MINUS && type2 == PyTokenTypes.GT) { + return createSpaces(0); + } + } + if (type2 == PyElementTypes.ANNOTATION) { + return createSpaces(1); + } + if (type1 == PyTokenTypes.COLON) { if (type2 == PyElementTypes.STATEMENT_LIST) { return Spacing.createSpacing(1, Integer.MAX_VALUE, 0, true, 0); @@ -338,7 +350,7 @@ public class PyBlock implements ASTBlock { if (parentType == PyElementTypes.NAMED_PARAMETER || parentType == PyElementTypes.STAR_ARGUMENT_EXPRESSION || parentType == PyElementTypes.STAR_EXPRESSION) { - return Spacing.createSpacing(0, 0, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + return createSpaces(0); } return getSpacingForOption(mySettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS); } @@ -392,8 +404,11 @@ public class PyBlock implements ASTBlock { } private Spacing getSpacingForOption(boolean isOptionSet) { - int spaces = isOptionSet ? 1 : 0; - return Spacing.createSpacing(spaces, spaces, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + return createSpaces(isOptionSet ? 1 : 0); + } + + private Spacing createSpaces(int count) { + return Spacing.createSpacing(count, count, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } private static boolean isStatementOrDeclaration(final IElementType type) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java index a4625ec39fab..890e58dd2587 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java @@ -22,6 +22,7 @@ public class PyFunctionBuilder { private final List myParameters = new ArrayList(); private final List myStatements = new ArrayList(); private final List myDecorators = new ArrayList(); + private String myAnnotation = null; public PyFunctionBuilder(String name) { myName = name; @@ -38,6 +39,11 @@ public class PyFunctionBuilder { return this; } + public PyFunctionBuilder annotation(String text) { + myAnnotation = text; + return this; + } + public PyFunctionBuilder statement(String text) { myStatements.add(text); return this; @@ -65,7 +71,11 @@ public class PyFunctionBuilder { builder.append("def "); builder.append(myName).append("("); builder.append(StringUtil.join(myParameters, ", ")); - builder.append("):"); + builder.append(")"); + if (myAnnotation != null) { + builder.append(myAnnotation); + } + builder.append(":"); List statements = myStatements.isEmpty() ? Collections.singletonList("pass") : myStatements; final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getInstance(project).getCurrentSettings(); int indentSize = codeStyleSettings.getIndentOptions(PythonFileType.INSTANCE).INDENT_SIZE; diff --git a/python/testData/override/returnAnnotation.py b/python/testData/override/returnAnnotation.py new file mode 100644 index 000000000000..bae69e02e630 --- /dev/null +++ b/python/testData/override/returnAnnotation.py @@ -0,0 +1,6 @@ +class A(): + def some_method(self) -> "return value": + pass + +class B(A): + pass \ No newline at end of file diff --git a/python/testData/override/returnAnnotation_after.py b/python/testData/override/returnAnnotation_after.py new file mode 100644 index 000000000000..091cad05b2d6 --- /dev/null +++ b/python/testData/override/returnAnnotation_after.py @@ -0,0 +1,8 @@ +class A(): + def some_method(self) -> "return value": + pass + +class B(A): + def some_method(self) -> "return value": + super().some_method() + diff --git a/python/testSrc/com/jetbrains/python/PyOverrideTest.java b/python/testSrc/com/jetbrains/python/PyOverrideTest.java index d489452d84a2..23573d5175ea 100644 --- a/python/testSrc/com/jetbrains/python/PyOverrideTest.java +++ b/python/testSrc/com/jetbrains/python/PyOverrideTest.java @@ -78,8 +78,11 @@ public class PyOverrideTest extends PyLightFixtureTestCase { doTest3k(); } - public void testTypeAnnotations() { // PY-2547 doTest3k(); } + + public void testReturnAnnotation() { // PY-2690 + doTest3k(); + } }