From 4d1ca37c016787729849277d6801da09e16ce344 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 20 Jan 2014 17:26:17 +0100 Subject: [PATCH 01/25] Merge PyKeywords with PyNames --- .../src/com/jetbrains/python/PyNames.java | 153 +++++++++++------- .../python/codeInsight/PyKeywords.java | 64 -------- .../PyUnindentingInsertHandler.java | 15 +- .../PyKeywordCompletionContributor.java | 53 +++--- .../PyCallingNonCallableInspection.java | 7 +- .../PyMissingConstructorInspection.java | 2 +- .../src/com/jetbrains/python/psi/PyUtil.java | 4 +- .../psi/impl/PyCallExpressionHelper.java | 2 +- 8 files changed, 138 insertions(+), 162 deletions(-) delete mode 100644 python/src/com/jetbrains/python/codeInsight/PyKeywords.java diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index 81c05df64174..ba5c5b10b2c9 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -45,7 +45,7 @@ public class PyNames { public static final String NEW = "__new__"; public static final String GETATTR = "__getattr__"; public static final String GETATTRIBUTE = "__getattribute__"; - public static final String CLASS = "__class__"; + public static final String __CLASS__ = "__class__"; public static final String DUNDER_METACLASS = "__metaclass__"; public static final String METACLASS = "metaclass"; public static final String TYPE = "type"; @@ -136,7 +136,7 @@ public class PyNames { public static final String COLLECTIONS_NAMEDTUPLE = COLLECTIONS + "." + NAMEDTUPLE; public static final String FORMAT = "format"; - + public static final String ABSTRACTMETHOD = "abc.abstractmethod"; public static final String ABSTRACTPROPERTY = "abc.abstractproperty"; @@ -156,7 +156,7 @@ public class PyNames { public static final String TEST_CASE = "TestCase"; - public static final String PYCACHE = "__pycache__"; + public static final String PYCACHE = "__pycache__"; public static final String NOT_IMPLEMENTED_ERROR = "NotImplementedError"; @@ -166,7 +166,7 @@ public class PyNames { * Contains all known predefined names of "__foo__" form. */ public static ImmutableSet UnderscoredAttributes = ImmutableSet.of( - "__all__", + "__all__", "__author__", "__bases__", "__defaults__", @@ -227,38 +227,38 @@ public class PyNames { .put("__abs__", _only_self_descr) .put("__add__", _self_other_descr) .put("__and__", _self_other_descr) - //_BuiltinMethods.put("__all__", _only_self_descr); - //_BuiltinMethods.put("__author__", _only_self_descr); - //_BuiltinMethods.put("__bases__", _only_self_descr); + //_BuiltinMethods.put("__all__", _only_self_descr); + //_BuiltinMethods.put("__author__", _only_self_descr); + //_BuiltinMethods.put("__bases__", _only_self_descr); .put("__call__", new BuiltinDescription("(self, *args, **kwargs)")) - //_BuiltinMethods.put("__class__", _only_self_descr); + //_BuiltinMethods.put("__class__", _only_self_descr); .put("__cmp__", _self_other_descr) .put("__coerce__", _self_other_descr) .put("__complex__", _only_self_descr) .put("__contains__", _self_item_descr) - //_BuiltinMethods.put("__debug__", _only_self_descr); + //_BuiltinMethods.put("__debug__", _only_self_descr); .put("__del__", _only_self_descr) .put("__delete__", new BuiltinDescription("(self, instance)")) .put("__delattr__", _self_item_descr) .put("__delitem__", _self_key_descr) .put("__delslice__", new BuiltinDescription("(self, i, j)")) - //_BuiltinMethods.put("__dict__", _only_self_descr); + //_BuiltinMethods.put("__dict__", _only_self_descr); .put("__divmod__", _self_other_descr) - //_BuiltinMethods.put("__doc__", _only_self_descr); - //_BuiltinMethods.put("__docformat__", _only_self_descr); + //_BuiltinMethods.put("__doc__", _only_self_descr); + //_BuiltinMethods.put("__docformat__", _only_self_descr); .put("__enter__", _only_self_descr) .put("__exit__", new BuiltinDescription("(self, exc_type, exc_val, exc_tb)")) .put("__eq__", _self_other_descr) - //_BuiltinMethods.put("__file__", _only_self_descr); + //_BuiltinMethods.put("__file__", _only_self_descr); .put("__float__", _only_self_descr) .put("__floordiv__", _self_other_descr) - //_BuiltinMethods.put("__future__", _only_self_descr); + //_BuiltinMethods.put("__future__", _only_self_descr); .put("__ge__", _self_other_descr) .put("__get__", new BuiltinDescription("(self, instance, owner)")) .put("__getattr__", _self_item_descr) .put("__getattribute__", _self_item_descr) .put("__getitem__", _self_item_descr) - //_BuiltinMethods.put("__getslice__", new BuiltinDescription("(self, i, j)")); + //_BuiltinMethods.put("__getslice__", new BuiltinDescription("(self, i, j)")); .put("__gt__", _self_other_descr) .put("__hash__", _only_self_descr) .put("__hex__", _only_self_descr) @@ -266,7 +266,7 @@ public class PyNames { .put("__iand__", _self_other_descr) .put("__idiv__", _self_other_descr) .put("__ifloordiv__", _self_other_descr) - //_BuiltinMethods.put("__import__", _only_self_descr); + //_BuiltinMethods.put("__import__", _only_self_descr); .put("__ilshift__", _self_other_descr) .put("__imod__", _self_other_descr) .put("__imul__", _self_other_descr) @@ -286,18 +286,18 @@ public class PyNames { .put("__long__", _only_self_descr) .put("__lshift__", _self_other_descr) .put("__lt__", _self_other_descr) - //_BuiltinMethods.put("__members__", _only_self_descr); - //_BuiltinMethods.put("__metaclass__", _only_self_descr); + //_BuiltinMethods.put("__members__", _only_self_descr); + //_BuiltinMethods.put("__metaclass__", _only_self_descr); .put("__mod__", _self_other_descr) - //_BuiltinMethods.put("__mro__", _only_self_descr); + //_BuiltinMethods.put("__mro__", _only_self_descr); .put("__mul__", _self_other_descr) - //_BuiltinMethods.put("__name__", _only_self_descr); + //_BuiltinMethods.put("__name__", _only_self_descr); .put("__ne__", _self_other_descr) .put("__neg__", _only_self_descr) .put(NEW, new BuiltinDescription("(cls, *args, **kwargs)")) .put("__oct__", _only_self_descr) .put("__or__", _self_other_descr) - //_BuiltinMethods.put("__path__", _only_self_descr); + //_BuiltinMethods.put("__path__", _only_self_descr); .put("__pos__", _only_self_descr) .put("__pow__", new BuiltinDescription("(self, power, modulo=None)")) .put("__radd__", _self_other_descr) @@ -322,13 +322,13 @@ public class PyNames { .put("__setattr__", new BuiltinDescription("(self, key, value)")) .put("__setitem__", new BuiltinDescription("(self, key, value)")) .put("__setslice__", new BuiltinDescription("(self, i, j, sequence)")) - //_BuiltinMethods.put("__self__", _only_self_descr); - //_BuiltinMethods.put("__slots__", _only_self_descr); + //_BuiltinMethods.put("__self__", _only_self_descr); + //_BuiltinMethods.put("__slots__", _only_self_descr); .put("__str__", _only_self_descr) .put("__sub__", _self_other_descr) .put("__truediv__", _self_other_descr) .put("__unicode__", _only_self_descr) - //_BuiltinMethods.put("__version__", _only_self_descr); + //_BuiltinMethods.put("__version__", _only_self_descr); .put("__xor__", _self_other_descr) .build(); @@ -355,53 +355,89 @@ public class PyNames { public static final String CANONICAL_CLS = "cls"; public static final String BASESTRING = "basestring"; + /* + Python keywords + */ + + public static final String CLASS = "class"; + public static final String DEF = "def"; + public static final String IF = "if"; + public static final String ELSE = "else"; + public static final String ELIF = "elif"; + public static final String TRY = "try"; + public static final String EXCEPT = "except"; + public static final String FINALLY = "finally"; + public static final String WHILE = "while"; + public static final String FOR = "for"; + public static final String WITH = "with"; + public static final String AS = "as"; + public static final String ASSERT = "assert"; + public static final String DEL = "del"; + public static final String EXEC = "exec"; + public static final String FROM = "from"; + public static final String IMPORT = "import"; + public static final String RAISE = "raise"; + public static final String PRINT = "print"; + public static final String BREAK = "break"; + public static final String CONTINUE = "continue"; + public static final String GLOBAL = "global"; + public static final String RETURN = "return"; + public static final String YIELD = "yield"; + public static final String NONLOCAL = "nonlocal"; + public static final String AND = "and"; + public static final String OR = "or"; + public static final String IS = "is"; + public static final String IN = "in"; + public static final String NOT = "not"; + public static final String LAMBDA = "lambda"; + /** * Contains keywords as of CPython 2.5. */ public static ImmutableSet Keywords = ImmutableSet.of( - "and", - "del", - "from", - "not", - "while", - "as", - "elif", - "global", - "or", - "with", - "assert", - "else", - "if", - "pass", - "yield", - "break", - "except", - "import", - "print", - "class", - "exec", - "in", - "raise", - "continue", - "finally", - "is", - "return", - "def", - "for", - "lambda", - "try" + AND, + DEL, + FROM, + NOT, + WHILE, + AS, + ELIF, + GLOBAL, + OR, + WITH, + ASSERT, + ELSE, + IF, + PASS, + YIELD, + BREAK, + EXCEPT, + IMPORT, + PRINT, + __CLASS__, + EXEC, + IN, + RAISE, + CONTINUE, + FINALLY, + IS, + RETURN, + DEF, + FOR, + LAMBDA, + TRY ); public static Set BuiltinInterfaces = ImmutableSet.of( - CALLABLE, HASHABLE, ITERABLE, ITERATOR, SIZED, CONTAINER, SEQUENCE, MAPPING, ABC_COMPLEX, ABC_REAL, ABC_RATIONAL, ABC_INTEGRAL, - ABC_NUMBER + CALLABLE, HASHABLE, ITERABLE, ITERATOR, SIZED, CONTAINER, SEQUENCE, MAPPING, ABC_COMPLEX, ABC_REAL, ABC_RATIONAL, ABC_INTEGRAL, + ABC_NUMBER ); /** * TODO: dependency on language level. + * * @param name what to check * @return true iff the name is either a keyword or a reserved name, like None. - * */ public static boolean isReserved(@NonNls String name) { return Keywords.contains(name) || NONE.equals(name) || "as".equals(name) || "with".equals(name); @@ -412,6 +448,7 @@ public class PyNames { /** * TODO: dependency on language level. + * * @param name what to check * @return true iff name is not reserved and is a well-formed identifier. */ diff --git a/python/src/com/jetbrains/python/codeInsight/PyKeywords.java b/python/src/com/jetbrains/python/codeInsight/PyKeywords.java deleted file mode 100644 index 458715fbf6c4..000000000000 --- a/python/src/com/jetbrains/python/codeInsight/PyKeywords.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jetbrains.python.codeInsight; - -/** - * @author traff - */ -public class PyKeywords { - public static final String DEF = "def"; - public static final String CLASS = "class"; - - public static final String IF = "if"; - public static final String ELSE = "else"; - public static final String ELIF = "elif"; - - public static final String TRY = "try"; - public static final String EXCEPT = "except"; - public static final String FINALLY = "finally"; - - public static final String WHILE = "while"; - - public static final String FOR = "for"; - public static final String WITH = "with"; - public static final String AS = "as"; - - public static final String ASSERT = "assert"; - public static final String DEL = "del"; - public static final String EXEC = "exec"; - public static final String FROM = "from"; - public static final String IMPORT = "import"; - public static final String RAISE = "raise"; - public static final String PRINT = "print"; - public static final String BREAK = "break"; - public static final String CONTINUE = "continue"; - public static final String GLOBAL = "global"; - public static final String RETURN = "return"; - public static final String YIELD = "yield"; - public static final String NONLOCAL = "nonlocal"; - - public static final String AND = "and"; - public static final String OR = "or"; - public static final String IS = "is"; - public static final String IN = "in"; - public static final String NOT = "not"; - - public static final String LAMBDA = "lambda"; - - public static final String TRUE = "True"; - public static final String FALSE = "False"; - public static final String NONE = "None"; -} diff --git a/python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java b/python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java index c6a69d72e275..d932d71f9629 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java +++ b/python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java @@ -25,6 +25,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.python.PyNames; import com.jetbrains.python.codeInsight.completion.PythonLookupElement; import com.jetbrains.python.psi.PyStatementWithElse; import com.jetbrains.python.psi.PyTryExceptStatement; @@ -67,28 +68,28 @@ public class PyUnindentingInsertHandler implements InsertHandler parentClass = null; - int last_offset = nonspace_offset + PyKeywords.FINALLY.length(); // the longest of all + int last_offset = nonspace_offset + PyNames.FINALLY.length(); // the longest of all if (last_offset > offset) last_offset = offset; int local_length = last_offset - nonspace_offset + 1; if (local_length > 0) { String piece = text.subSequence(nonspace_offset, last_offset + 1).toString(); - final int else_len = PyKeywords.ELSE.length(); + final int else_len = PyNames.ELSE.length(); if (local_length >= else_len) { - if ((piece.startsWith(PyKeywords.ELSE) || piece.startsWith(PyKeywords.ELIF)) && + if ((piece.startsWith(PyNames.ELSE) || piece.startsWith(PyNames.ELIF)) && (else_len == piece.length() || piece.charAt(else_len) < 'a' || piece.charAt(else_len) > 'z')) { parentClass = PyStatementWithElse.class; } } - final int except_len = PyKeywords.EXCEPT.length(); + final int except_len = PyNames.EXCEPT.length(); if (local_length >= except_len) { - if (piece.startsWith(PyKeywords.EXCEPT) && + if (piece.startsWith(PyNames.EXCEPT) && (except_len == piece.length() || piece.charAt(except_len) < 'a' || piece.charAt(except_len) > 'z')) { parentClass = PyTryExceptStatement.class; } } - final int finally_len = PyKeywords.FINALLY.length(); + final int finally_len = PyNames.FINALLY.length(); if (local_length >= finally_len) { - if (piece.startsWith(PyKeywords.FINALLY) && + if (piece.startsWith(PyNames.FINALLY) && (finally_len == piece.length() || piece.charAt(finally_len) < 'a' || piece.charAt(finally_len) > 'z')) { parentClass = PyTryExceptStatement.class; } diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java index 6d7202457e83..f8698d06fbdb 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java @@ -33,7 +33,6 @@ import com.intellij.util.ProcessingContext; import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.PythonLanguage; -import com.jetbrains.python.codeInsight.PyKeywords; import com.jetbrains.python.codeInsight.PyUnindentingInsertHandler; import com.jetbrains.python.documentation.doctest.PyDocstringFile; import com.jetbrains.python.psi.*; @@ -287,9 +286,9 @@ public class PyKeywordCompletionContributor extends CompletionContributor { psiElement() .inside(PyConditionalStatementPart.class) .andOr( - psiElement().afterLeaf(psiElement().withText(PyKeywords.IF)), - psiElement().afterLeaf(psiElement().withText(PyKeywords.ELIF)), - psiElement().afterLeaf(psiElement().withText(PyKeywords.WHILE)) + psiElement().afterLeaf(psiElement().withText(PyNames.IF)), + psiElement().afterLeaf(psiElement().withText(PyNames.ELIF)), + psiElement().afterLeaf(psiElement().withText(PyNames.WHILE)) ); private static final PsiElementPattern.Capture IN_IMPORT_STMT = @@ -379,8 +378,8 @@ public class PyKeywordCompletionContributor extends CompletionContributor { protected void addCompletions( @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result ) { - putKeywords(result, TailType.NONE, PyKeywords.DEF, PyKeywords.CLASS, PyKeywords.FOR, PyKeywords.IF, PyKeywords.WHILE, PyKeywords.WITH); - putKeywords(result, TailType.CASE_COLON, PyKeywords.TRY); + putKeywords(result, TailType.NONE, PyNames.DEF, PyNames.CLASS, PyNames.FOR, PyNames.IF, PyNames.WHILE, PyNames.WITH); + putKeywords(result, TailType.CASE_COLON, PyNames.TRY); } } ); @@ -403,13 +402,13 @@ public class PyKeywordCompletionContributor extends CompletionContributor { protected void addCompletions( @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result ) { - putKeywords(result, TailType.SPACE, PyKeywords.ASSERT, PyKeywords.DEL, PyKeywords.EXEC, PyKeywords.FROM, PyKeywords.IMPORT, PyKeywords.RAISE); + putKeywords(result, TailType.SPACE, PyNames.ASSERT, PyNames.DEL, PyNames.EXEC, PyNames.FROM, PyNames.IMPORT, PyNames.RAISE); putKeywords(result, TailType.NONE, PyNames.PASS); } } ); - extend(CompletionType.BASIC, inStatement.andNot(PY3K), new PyKeywordCompletionProvider(TailType.SPACE, PyKeywords.PRINT)); + extend(CompletionType.BASIC, inStatement.andNot(PY3K), new PyKeywordCompletionProvider(TailType.SPACE, PyNames.PRINT)); } private void addBreak() { @@ -422,7 +421,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andNot(IN_ARG_LIST) .and(IN_LOOP) , - new PyKeywordCompletionProvider(TailType.NONE, PyKeywords.BREAK) + new PyKeywordCompletionProvider(TailType.NONE, PyNames.BREAK) ); } @@ -437,7 +436,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andNot(IN_FINALLY_NO_LOOP) .and(IN_LOOP) , - new PyKeywordCompletionProvider(TailType.NONE, PyKeywords.CONTINUE) + new PyKeywordCompletionProvider(TailType.NONE, PyNames.CONTINUE) ); } @@ -449,7 +448,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .and(IN_BEGIN_STMT) .andNot(AFTER_QUALIFIER) , - new PyKeywordCompletionProvider(PyKeywords.GLOBAL, PyKeywords.RETURN, PyKeywords.YIELD) + new PyKeywordCompletionProvider(PyNames.GLOBAL, PyNames.RETURN, PyNames.YIELD) ); extend( @@ -460,7 +459,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .and(PY3K) .andNot(AFTER_QUALIFIER) , - new PyKeywordCompletionProvider(PyKeywords.NONLOCAL) + new PyKeywordCompletionProvider(PyNames.NONLOCAL) ); } @@ -472,7 +471,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andOr(IN_IF_BODY, AFTER_IF) .andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL) , - new PyKeywordCompletionProvider(TailType.NONE, PyUnindentingInsertHandler.INSTANCE, PyKeywords.ELIF)); + new PyKeywordCompletionProvider(TailType.NONE, PyUnindentingInsertHandler.INSTANCE, PyNames.ELIF)); } private void addWithinTry() { @@ -488,8 +487,8 @@ public class PyKeywordCompletionContributor extends CompletionContributor { protected void addCompletions( @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result ) { - putKeyword(PyKeywords.EXCEPT, PyUnindentingInsertHandler.INSTANCE, TailType.NONE, result); - putKeyword(PyKeywords.FINALLY, PyUnindentingInsertHandler.INSTANCE, TailType.CASE_COLON, result); + putKeyword(PyNames.EXCEPT, PyUnindentingInsertHandler.INSTANCE, TailType.NONE, result); + putKeyword(PyNames.FINALLY, PyUnindentingInsertHandler.INSTANCE, TailType.CASE_COLON, result); } } ); @@ -503,7 +502,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andOr(IN_COND_STMT, IN_EXCEPT_BODY, AFTER_COND_STMT_NO_ELSE, AFTER_LOOP_NO_ELSE, AFTER_EXCEPT) .andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL) , - new PyKeywordCompletionProvider(TailType.CASE_COLON, PyUnindentingInsertHandler.INSTANCE, PyKeywords.ELSE)); + new PyKeywordCompletionProvider(TailType.CASE_COLON, PyUnindentingInsertHandler.INSTANCE, PyNames.ELSE)); } private void addInfixOperators() { @@ -517,7 +516,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andNot(AFTER_QUALIFIER). andNot(IN_STRING_LITERAL).and(IN_BEGIN_STMT) , - new PyKeywordCompletionProvider(PyKeywords.AND, PyKeywords.OR, PyKeywords.IS, PyKeywords.IN) + new PyKeywordCompletionProvider(PyNames.AND, PyNames.OR, PyNames.IS, PyNames.IN) ); } @@ -531,7 +530,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andNot(IN_FUNCTION_HEADER) .andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL) , - new PyKeywordCompletionProvider(PyKeywords.NOT, PyKeywords.LAMBDA) + new PyKeywordCompletionProvider(PyNames.NOT, PyNames.LAMBDA) ); } @@ -546,7 +545,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andNot(AFTER_QUALIFIER) .andNot(IN_FUNCTION_HEADER) , - new PyKeywordCompletionProvider(TailType.NONE, PyKeywords.TRUE, PyKeywords.FALSE, PyKeywords.NONE) + new PyKeywordCompletionProvider(TailType.NONE, PyNames.TRUE, PyNames.FALSE, PyNames.NONE) ); } @@ -557,7 +556,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .andOr(IN_IMPORT_AFTER_REF, IN_WITH_AFTER_REF, IN_EXCEPT_AFTER_REF) .andNot(AFTER_QUALIFIER) , - new PyKeywordCompletionProvider(PyKeywords.AS) + new PyKeywordCompletionProvider(PyNames.AS) ); } @@ -568,7 +567,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .and(IN_FROM_IMPORT_AFTER_REF) .andNot(AFTER_QUALIFIER) , - new PyKeywordCompletionProvider(PyKeywords.IMPORT) + new PyKeywordCompletionProvider(PyNames.IMPORT) ); } @@ -604,9 +603,9 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .withLanguage(PythonLanguage.getInstance()) .afterLeafSkipping(psiElement().whitespace(), psiElement().inside(psiElement(PyConditionalExpression.class)) - .and(psiElement().afterLeaf(PyKeywords.IF))) + .and(psiElement().afterLeaf(PyNames.IF))) , - new PyKeywordCompletionProvider(TailType.SPACE, PyKeywords.ELSE)); + new PyKeywordCompletionProvider(TailType.SPACE, PyNames.ELSE)); } private void addRaiseFrom() { @@ -615,7 +614,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .withLanguage(PythonLanguage.getInstance()) .and(PY3K) .afterLeaf(psiElement().inside(PyRaiseStatement.class)), - new PyKeywordCompletionProvider(PyKeywords.FROM)); + new PyKeywordCompletionProvider(PyNames.FROM)); } private void addYieldFrom() { @@ -624,7 +623,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .withLanguage(PythonLanguage.getInstance()) .and(PY3K) .afterLeaf(psiElement().withElementType(PyTokenTypes.YIELD_KEYWORD)), - new PyKeywordCompletionProvider(PyKeywords.FROM)); + new PyKeywordCompletionProvider(PyNames.FROM)); } public PyKeywordCompletionContributor() { @@ -655,14 +654,14 @@ public class PyKeywordCompletionContributor extends CompletionContributor { .withLanguage(PythonLanguage.getInstance()) .inside(psiElement(PySequenceExpression.class)) .andNot(psiElement().afterLeaf(or(psiElement(PyTokenTypes.LBRACE), psiElement(PyTokenTypes.LBRACKET), psiElement(PyTokenTypes.LPAR)))), - new PyKeywordCompletionProvider(PyKeywords.FOR)); + new PyKeywordCompletionProvider(PyNames.FOR)); } private void addInToFor() { extend(CompletionType.BASIC, psiElement() .withLanguage(PythonLanguage.getInstance()) - .and(psiElement()).afterLeaf(psiElement().afterLeaf(PyKeywords.FOR)), + .and(psiElement()).afterLeaf(psiElement().afterLeaf(PyNames.FOR)), new PyKeywordCompletionProvider("in")); } diff --git a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java index 47f55a483292..4af6767fbcb2 100644 --- a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java @@ -20,7 +20,10 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.PsiElementVisitor; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.*; -import com.jetbrains.python.psi.types.*; +import com.jetbrains.python.psi.types.PyClassType; +import com.jetbrains.python.psi.types.PyType; +import com.jetbrains.python.psi.types.PyTypeChecker; +import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -89,7 +92,7 @@ public class PyCallingNonCallableInspection extends PyInspection { @Nullable private static Boolean isCallable(@NotNull PyExpression element, @NotNull TypeEvalContext context) { - if (element instanceof PyQualifiedExpression && PyNames.CLASS.equals(element.getName())) { + if (element instanceof PyQualifiedExpression && PyNames.__CLASS__.equals(element.getName())) { return true; } return PyTypeChecker.isCallable(context.getType(element)); diff --git a/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java b/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java index 0a4c3625ff57..90871800c2bc 100644 --- a/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java @@ -139,7 +139,7 @@ public class PyMissingConstructorInspection extends PyInspection { if (args.length > 0) { String firstArg = args[0].getText(); final String qualifiedName = cl.getQualifiedName(); - if (firstArg.equals(cl.getName()) || firstArg.equals(CANONICAL_SELF+"."+ CLASS) || + if (firstArg.equals(cl.getName()) || firstArg.equals(CANONICAL_SELF+"."+ __CLASS__) || (qualifiedName != null && qualifiedName.endsWith(firstArg))) return true; for (PyClass s : cl.getAncestorClasses(myTypeEvalContext)) { diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 0cd299422694..2fce2d0d3110 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -415,7 +415,7 @@ public class PyUtil { PyExpression qualifier = ref.getQualifier(); if (qualifier != null) { String attr_name = ref.getReferencedName(); - if (PyNames.CLASS.equals(attr_name)) { + if (PyNames.__CLASS__.equals(attr_name)) { PyType qualifierType = context.getType(qualifier); if (qualifierType instanceof PyClassType) { return new PyClassTypeImpl(((PyClassType)qualifierType).getPyClass(), true); // always as class, never instance @@ -1114,7 +1114,7 @@ public class PyUtil { PyExpression[] args = node.getArguments(); if (args.length > 0) { String firstArg = args[0].getText(); - if (firstArg.equals(klass.getName()) || firstArg.equals(PyNames.CANONICAL_SELF + "." + PyNames.CLASS)) { + if (firstArg.equals(klass.getName()) || firstArg.equals(PyNames.CANONICAL_SELF + "." + PyNames.__CLASS__)) { return true; } for (PyClass s : klass.getAncestorClasses()) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java index 506fdb0071ce..bd33be42b4af 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java @@ -490,7 +490,7 @@ public class PyCallExpressionHelper { if (first_arg instanceof PyReferenceExpression) { final PyReferenceExpression firstArgRef = (PyReferenceExpression)first_arg; final PyExpression qualifier = firstArgRef.getQualifier(); - if (qualifier != null && PyNames.CLASS.equals(firstArgRef.getReferencedName())) { + if (qualifier != null && PyNames.__CLASS__.equals(firstArgRef.getReferencedName())) { final PsiReference qRef = qualifier.getReference(); final PsiElement element = qRef == null ? null : qRef.resolve(); if (element instanceof PyParameter) { From 609c0db87b6a49564139d4dadbd1ea1314a10770 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 20 Jan 2014 17:27:17 +0100 Subject: [PATCH 02/25] Keywords already contains 'as' and 'with' --- python/psi-api/src/com/jetbrains/python/PyNames.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index ba5c5b10b2c9..109f70c09c89 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -440,7 +440,7 @@ public class PyNames { * @return true iff the name is either a keyword or a reserved name, like None. */ public static boolean isReserved(@NonNls String name) { - return Keywords.contains(name) || NONE.equals(name) || "as".equals(name) || "with".equals(name); + return Keywords.contains(name) || NONE.equals(name); } // NOTE: includes unicode only good for py3k From 2e110fdd2ce9e71b6e069f1812928e361772460a Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 21 Jan 2014 00:45:02 +0400 Subject: [PATCH 03/25] PY-6955 Unused import not greyed out if also failing (test refactored) --- .../python/fixtures/PyInspectionTestCase.java | 16 ++++++++++- .../PyUnresolvedReferencesInspectionTest.java | 27 +++++++------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java index 96fca13931a9..4769b09c808e 100644 --- a/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java +++ b/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java @@ -24,11 +24,25 @@ public abstract class PyInspectionTestCase extends PyTestCase { * Launches test. To be called by test author */ protected void doTest() { - myFixture.configureByFile("inspections/" + getInspectionClass().getSimpleName() + "/" + getTestName(true) + ".py"); + myFixture.configureByFile(getTestDirectory(true) + ".py"); + configureInspection(); + } + + protected void doMultiFileTest(@NotNull String filename) { + myFixture.copyDirectoryToProject(getTestDirectory(false), ""); + myFixture.configureFromTempProjectFile(filename); + configureInspection(); + } + + private void configureInspection() { myFixture.enableInspections(getInspectionClass()); myFixture.checkHighlighting(isWarning(), isInfo(), isWeakWarning()); } + private String getTestDirectory(boolean lowercaseFirstLetter) { + return "inspections/" + getInspectionClass().getSimpleName() + "/" + getTestName(lowercaseFirstLetter); + } + protected boolean isWeakWarning() { return true; diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java index 53bcbc34d60e..7ef9511b0ea2 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java @@ -15,15 +15,14 @@ */ package com.jetbrains.python.inspections; -import com.jetbrains.python.fixtures.PyTestCase; +import com.jetbrains.python.fixtures.PyInspectionTestCase; import com.jetbrains.python.psi.LanguageLevel; import org.jetbrains.annotations.NotNull; /** * @author yole */ -public class PyUnresolvedReferencesInspectionTest extends PyTestCase { - private static final String TEST_DIRECTORY = "inspections/PyUnresolvedReferencesInspection/"; +public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { public void testSelfReference() { doTest(); @@ -77,11 +76,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase { public void testTypeAssertions() { doTest(); } - + public void testUnresolvedImportedModule() { // PY-2075 doTest(); } - + public void testSuperType() { // PY-2320 doTest(); } @@ -89,7 +88,7 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase { public void testImportFunction() { // PY-1896 doTest(); } - + public void testSuperclassAsLocal() { // PY-5427 doTest(); } @@ -336,17 +335,9 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase { doTest(); } - private void doTest() { - myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py"); - myFixture.enableInspections(PyUnresolvedReferencesInspection.class); - myFixture.checkHighlighting(true, false, false); - } - - private void doMultiFileTest(@NotNull String filename) { - final String testName = getTestName(false); - myFixture.copyDirectoryToProject(TEST_DIRECTORY + testName, ""); - myFixture.configureFromTempProjectFile(filename); - myFixture.enableInspections(PyUnresolvedReferencesInspection.class); - myFixture.checkHighlighting(true, false, false); + @NotNull + @Override + protected Class getInspectionClass() { + return PyUnresolvedReferencesInspection.class; } } From d2af13aa3a28fc041e8636a02ffa0ac74f38f74d Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 21 Jan 2014 02:13:02 +0400 Subject: [PATCH 04/25] PY-6955 Unused import not greyed out if also failing --- .../PyUnresolvedReferencesInspection.java | 4 +++ .../FromPackageImportBuiltin/a.py | 2 ++ .../UnusedUnresolvedNameImported/a.py | 1 + .../UnusedUnresolvedNameImported/my_module.py | 2 ++ .../a.py | 2 ++ .../my_module.py | 2 ++ .../a.py | 4 +++ .../my_package/__init__.py | 1 + .../my_package/my_module.py | 2 ++ .../importFunction.py | 2 ++ .../unresolvedImport.py | 2 ++ .../unusedUnresolvedModuleImported.py | 1 + .../unusedUnresolvedPackageImported.py | 1 + .../python/fixtures/PyInspectionTestCase.java | 3 +++ .../PyUnresolvedReferencesInspectionTest.java | 25 +++++++++++++++++++ 15 files changed, 54 insertions(+) create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/a.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/my_module.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/a.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/my_module.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/a.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/__init__.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/my_module.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedModuleImported.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedPackageImported.py diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 998530a016b3..7b71bdb7cfde 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -984,6 +984,10 @@ public class PyUnresolvedReferencesInspection extends PyInspection { final PyImportElement importElement = (PyImportElement)unusedImport; final PsiElement element = importElement.resolve(); if (element == null) { + if (importElement.getImportedQName() != null) { + //Mark import as unused even if it can't be resolved + result.add(importElement.getParent()); + } continue; } if (dunderAll != null && dunderAll.contains(importElement.getVisibleName())) { diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/FromPackageImportBuiltin/a.py b/python/testData/inspections/PyUnresolvedReferencesInspection/FromPackageImportBuiltin/a.py index a66445c7362c..8880a48e3db9 100644 --- a/python/testData/inspections/PyUnresolvedReferencesInspection/FromPackageImportBuiltin/a.py +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/FromPackageImportBuiltin/a.py @@ -1 +1,3 @@ from importSource import len + +len() diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/a.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/a.py new file mode 100644 index 000000000000..b0ad821f96b9 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/a.py @@ -0,0 +1 @@ +from my_module import eggs diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/my_module.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/my_module.py new file mode 100644 index 000000000000..51d8eaddb572 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImported/my_module.py @@ -0,0 +1,2 @@ +def my_func(): + pass \ No newline at end of file diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/a.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/a.py new file mode 100644 index 000000000000..5e1c928b579d --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/a.py @@ -0,0 +1,2 @@ +from my_module import eggs +from my_module import eggs diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/my_module.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/my_module.py new file mode 100644 index 000000000000..51d8eaddb572 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UnusedUnresolvedNameImportedSeveralTimes/my_module.py @@ -0,0 +1,2 @@ +def my_func(): + pass \ No newline at end of file diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/a.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/a.py new file mode 100644 index 000000000000..767f9bf68131 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/a.py @@ -0,0 +1,4 @@ +from my_package.my_module import eggs +from my_package.my_module import eggs + +eggs() diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/__init__.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/__init__.py new file mode 100644 index 000000000000..a5f9f02f5908 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/__init__.py @@ -0,0 +1 @@ +__author__ = 'Ilya.Kazakevich' diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/my_module.py b/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/my_module.py new file mode 100644 index 000000000000..51d8eaddb572 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/UsedUnresolvedNameImportedSeveralTimes/my_package/my_module.py @@ -0,0 +1,2 @@ +def my_func(): + pass \ No newline at end of file diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/importFunction.py b/python/testData/inspections/PyUnresolvedReferencesInspection/importFunction.py index 2bfbaa3d0ee9..75ddd5c94722 100644 --- a/python/testData/inspections/PyUnresolvedReferencesInspection/importFunction.py +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/importFunction.py @@ -1 +1,3 @@ import collections.OrderedDict + +collections.OrderedDict() diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedImport.py b/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedImport.py index e96da63adfe4..91aae4269564 100644 --- a/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedImport.py +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedImport.py @@ -1 +1,3 @@ import wurm + +wurm() diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedModuleImported.py b/python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedModuleImported.py new file mode 100644 index 000000000000..3351b1dbceeb --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedModuleImported.py @@ -0,0 +1 @@ +import spam diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedPackageImported.py b/python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedPackageImported.py new file mode 100644 index 000000000000..ba929a6c244b --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/unusedUnresolvedPackageImported.py @@ -0,0 +1 @@ +import spam.eggs \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java index 4769b09c808e..717a579ce97b 100644 --- a/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java +++ b/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java @@ -28,6 +28,9 @@ public abstract class PyInspectionTestCase extends PyTestCase { configureInspection(); } + protected void doMultiFileTest() { + doMultiFileTest("a.py"); + } protected void doMultiFileTest(@NotNull String filename) { myFixture.copyDirectoryToProject(getTestDirectory(false), ""); myFixture.configureFromTempProjectFile(filename); diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java index 7ef9511b0ea2..546795e4fe8f 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java @@ -335,6 +335,31 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { doTest(); } + // PY-6955 + public void testUnusedUnresolvedModuleImported() { + doTest(); + } + + // PY-6955 + public void testUnusedUnresolvedNameImported() { + doMultiFileTest(); + } + + // PY-6955 + public void testUnusedUnresolvedNameImportedSeveralTimes() { + doMultiFileTest(); + } + + // PY-6955 + public void testUsedUnresolvedNameImportedSeveralTimes() { + doMultiFileTest(); + } + + // PY-6955 + public void testUnusedUnresolvedPackageImported() { + doTest(); + } + @NotNull @Override protected Class getInspectionClass() { From f293c4ae0b209805dcd28ad26a35892b55df571e Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 21 Jan 2014 03:34:53 +0400 Subject: [PATCH 05/25] IDEA-119619 Settings / Language Injections: project level XML tag injection loses Sub-Tags value on IDE restart --- .../java/JavaLanguageInjectionSupport.java | 5 +---- .../config/ui/AbstractInjectionPanel.java | 19 +++++++------------ .../inject/config/XmlAttributeInjection.java | 8 -------- .../inject/config/ui/TagPanel.java | 1 - .../inject/config/ui/XmlAttributePanel.java | 3 --- .../xml/XmlLanguageInjectionSupport.java | 5 +++-- 6 files changed, 11 insertions(+), 30 deletions(-) diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java index d70ee60161bb..14c7535f8044 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java @@ -174,10 +174,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } public BaseInjection createInjection(final Element element) { - if (element.getName().equals(MethodParameterInjection.class.getSimpleName())) { - return new MethodParameterInjection(); - } - else return new BaseInjection(JAVA_SUPPORT_ID); + return new BaseInjection(JAVA_SUPPORT_ID); } private static boolean doInjectInJava(final Project project, diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java index b82d26a72d82..9b6fc83533fa 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java @@ -15,8 +15,6 @@ */ package org.intellij.plugins.intelliLang.inject.config.ui; -import com.intellij.openapi.editor.event.DocumentAdapter; -import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.project.Project; import com.intellij.util.ui.UIUtil; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; @@ -73,7 +71,6 @@ public abstract class AbstractInjectionPanel implements final InjectionPanel p = getField(panel); p.init(copy); } - reset(); } public final boolean isModified() { @@ -95,18 +92,22 @@ public abstract class AbstractInjectionPanel implements // auto-generated name should go last apply(myOrigInjection); - myOrigInjection.generatePlaces(); - myEditCopy.copyFrom(myOrigInjection); + if (!myOtherPanels.isEmpty()) { + myOrigInjection.generatePlaces(); + myEditCopy.copyFrom(myOrigInjection); + } } protected abstract void apply(T other); @SuppressWarnings({"unchecked"}) public final void reset() { + if (!myOtherPanels.isEmpty()) { + myEditCopy.copyFrom(myOrigInjection); + } for (Field panel : myOtherPanels) { getField(panel).reset(); } - myEditCopy.copyFrom(myOrigInjection); UIUtil.invokeAndWaitIfNeeded(new Runnable() { public void run() { resetImpl(); @@ -139,10 +140,4 @@ public abstract class AbstractInjectionPanel implements updater.run(); } } - - protected class TreeUpdateListener extends DocumentAdapter { - public void documentChanged(DocumentEvent e) { - updateTree(); - } - } } diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java index 312d444822be..32a2239dd3a1 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java @@ -102,14 +102,6 @@ public class XmlAttributeInjection extends AbstractTagInjection { return this; } - protected void readExternalImpl(Element e) { - super.readExternalImpl(e); - } - - protected void writeExternalImpl(Element e) { - super.writeExternalImpl(e); - } - @SuppressWarnings({"RedundantIfStatement"}) public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java index c49145c65c9c..2b224a1be58d 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java @@ -49,7 +49,6 @@ public class TagPanel extends AbstractInjectionPanel { $$$setupUI$$$(); myNamespace.setModel(createNamespaceUriModel(myProject)); - myLocalName.getDocument().addDocumentListener(new TreeUpdateListener()); } public static ComboBoxModel createNamespaceUriModel(Project project) { diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java index d1f7571eb4a5..79f451dd31f9 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java @@ -48,9 +48,6 @@ public class XmlAttributePanel extends AbstractInjectionPanel Date: Tue, 21 Jan 2014 04:18:46 +0400 Subject: [PATCH 06/25] PY-6955 Unused import not greyed out if also failing --- python/testData/optimizeImports/insertBlankLines.after.py | 1 + python/testData/optimizeImports/insertBlankLines.py | 1 + python/testData/optimizeImports/order.after.py | 1 + python/testData/optimizeImports/order.py | 1 + python/testData/optimizeImports/unresolved.after.py | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/python/testData/optimizeImports/insertBlankLines.after.py b/python/testData/optimizeImports/insertBlankLines.after.py index e3719e04dcc0..62bebf5883ee 100644 --- a/python/testData/optimizeImports/insertBlankLines.after.py +++ b/python/testData/optimizeImports/insertBlankLines.after.py @@ -8,3 +8,4 @@ from bar import * sys.path datetime.datetime +foo.bar() \ No newline at end of file diff --git a/python/testData/optimizeImports/insertBlankLines.py b/python/testData/optimizeImports/insertBlankLines.py index 9e77f444d6eb..fcf075fcbb21 100644 --- a/python/testData/optimizeImports/insertBlankLines.py +++ b/python/testData/optimizeImports/insertBlankLines.py @@ -7,3 +7,4 @@ from bar import * sys.path datetime.datetime +foo.bar() \ No newline at end of file diff --git a/python/testData/optimizeImports/order.after.py b/python/testData/optimizeImports/order.after.py index e3719e04dcc0..62bebf5883ee 100644 --- a/python/testData/optimizeImports/order.after.py +++ b/python/testData/optimizeImports/order.after.py @@ -8,3 +8,4 @@ from bar import * sys.path datetime.datetime +foo.bar() \ No newline at end of file diff --git a/python/testData/optimizeImports/order.py b/python/testData/optimizeImports/order.py index ad3147aef522..eaa3e27e71bd 100644 --- a/python/testData/optimizeImports/order.py +++ b/python/testData/optimizeImports/order.py @@ -6,3 +6,4 @@ import datetime sys.path datetime.datetime +foo.bar() \ No newline at end of file diff --git a/python/testData/optimizeImports/unresolved.after.py b/python/testData/optimizeImports/unresolved.after.py index b014e1fe1183..8b137891791f 100644 --- a/python/testData/optimizeImports/unresolved.after.py +++ b/python/testData/optimizeImports/unresolved.after.py @@ -1 +1 @@ -import xyzzy_shazam + From 22d73991e70a32155f992d3718177a9c1818469e Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Tue, 21 Jan 2014 10:26:46 +0400 Subject: [PATCH 07/25] IDEA-95410 Arrangement: Preserve fold regions on arrangement --- .../JavaRearrangerFoldingTest.groovy | 198 +++++++++++++----- .../actions/ReformatCodeAction.java | 2 +- .../arrangement/engine/ArrangementEngine.java | 19 +- .../RestoreFoldArrangementCallback.java | 46 ++-- 4 files changed, 195 insertions(+), 70 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy index 9166eaf5d4ae..dfee35bb83c6 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy @@ -15,6 +15,9 @@ */ package com.intellij.psi.codeStyle.arrangement +import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.PRIVATE +import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.PUBLIC + /** * @author Denis Zhdanov * @since 11/20/12 3:34 PM @@ -24,51 +27,152 @@ class JavaRearrangerFoldingTest extends AbstractJavaRearrangerTest { void "test dummy"() { } - // This should be uncommented as soon as cdr pushed fixes for range markers processing. -// void "test that doc comment folding is preserved"() { -// commonSettings.BLANK_LINES_AROUND_METHOD = 1 -// doTest( -// initial: '''\ -//import java.util.List; -//import java.util.Set; -// -///** -// * Class comment -// */ -//class Test { -// -// /** -// * Another method comment -// */ -// public void test(Set s) {} -//}''', -// -// rules: [rule(PUBLIC), rule(PRIVATE)], -// -// expected: '''\ -//import java.util.List; -//import java.util.Set; -// -///** -// * Class comment -// */ -//class Test { -// -// /** -// * Method comment -// */ -// private void test(List l) {} -//}''' -// ) -// } + void "test that doc comment folding is preserved"() { + commonSettings.BLANK_LINES_AROUND_METHOD = 1 + doTest( + initial: '''\ +import java.util.List; +import java.util.Set; + +/** +* Class comment +*/ +class Test { + + /** + * Another method comment + */ + public void test(Set s) {} +}''', + + rules: [rule(PUBLIC), rule(PRIVATE)], + + expected: '''\ +import java.util.List; +import java.util.Set; + +/** +* Class comment +*/ +class Test { + + /** + * Method comment + */ + private void test(List l) {} +}''' + ) + } + + void "test that doc comment and method folding is preserved"() { + commonSettings.BLANK_LINES_AROUND_METHOD = 1 + doTest( + initial: '''\ +import java.util.List; +import java.util.Set; + +class MyTest { + /** + * comment 1 + * + * @param s + */ + private void test(String s) { + } + + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + } +}''', + + rules: [rule(PUBLIC), rule(PRIVATE)], + + expected: '''\ +import java.util.List; +import java.util.Set; + +class MyTest { + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + } + + /** + * comment 1 + * + * @param s + */ + private void test(String s) { + } +}''' + ) + } + + void "test that single doc comment folding is preserved"() { + commonSettings.BLANK_LINES_AROUND_METHOD = 1 + doTest( + initial: '''\ +package a.b; + +class MyTest { + /** + * private comment + * + * @param s + */ + private void test(String s) { + } + + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + System.out.println(1); + } +}''', + + rules: [rule(PUBLIC), rule(PRIVATE)], + + expected: '''\ +package a.b; + +class MyTest { + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + System.out.println(1); + } + + /** + * private comment + * + * @param s + */ + private void test(String s) { + } +}''' + ) + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java index 0dc880d92a53..215e9a56ec40 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java @@ -194,7 +194,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - engine.arrange(finalFile, Collections.singleton(rangeToUse)); + engine.arrange(editor, finalFile, Collections.singleton(rangeToUse)); } }, getTemplatePresentation().getText(), null); } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java index 53907d7c4d02..4f54fa7b56aa 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java @@ -53,12 +53,25 @@ import java.util.*; */ public class ArrangementEngine { + /** + * Arranges given PSI root contents that belong to the given ranges. + * Note: After arrangement editor foldings we'll be preserved. + * + * @param editor + * @param file target PSI root + * @param ranges target ranges to use within the given root + */ public void arrange(@NotNull final Editor editor, @NotNull PsiFile file, Collection ranges) { - arrange(file, ranges, null); - // This should be uncommented as soon as cdr pushed fixes for range markers processing. - //arrange(file, ranges, new RestoreFoldArrangementCallback(editor)); + arrange(file, ranges, new RestoreFoldArrangementCallback(editor)); } + /** + * Arranges given PSI root contents that belong to the given ranges. + * Note: Editor foldings are not expected to be preserved. + * + * @param file target PSI root + * @param ranges target ranges to use within the given root + */ public void arrange(@NotNull PsiFile file, @NotNull Collection ranges) { arrange(file, ranges, null); } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java index 8f93afe4cc50..b23b79c8c88b 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java @@ -18,16 +18,10 @@ package com.intellij.psi.codeStyle.arrangement.engine; import com.intellij.codeInsight.folding.CodeFoldingManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; -import com.intellij.openapi.fileEditor.impl.text.CodeFoldingState; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.Comparator; +import java.util.ArrayList; import java.util.List; /** @@ -37,34 +31,48 @@ import java.util.List; public class RestoreFoldArrangementCallback implements ArrangementCallback { @NotNull private final Editor myEditor; - @Nullable private final CodeFoldingState myCodeFoldingState; public RestoreFoldArrangementCallback(@NotNull Editor editor) { myEditor = editor; - - Project project = editor.getProject(); - if (project == null) { - myCodeFoldingState = null; - } - else { - final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(editor.getProject()); - myCodeFoldingState = foldingManager.saveFoldingState(editor); - } } @Override public void afterArrangement(@NotNull final List moveInfos) { // Restore state for the PSI elements not affected by arrangement. Project project = myEditor.getProject(); - if (myCodeFoldingState != null && project != null) { + if (project != null) { + final FoldRegion[] regions = myEditor.getFoldingModel().getAllFoldRegions(); + final List foldRegionsInfo = new ArrayList(); + for (FoldRegion region : regions) { + final FoldRegionInfo info = new FoldRegionInfo(region.getStartOffset(), region.getEndOffset(), region.isExpanded()); + foldRegionsInfo.add(info); + } + final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(project); foldingManager.updateFoldRegions(myEditor); myEditor.getFoldingModel().runBatchFoldingOperation(new Runnable() { @Override public void run() { - foldingManager.restoreFoldingState(myEditor, myCodeFoldingState); + for (FoldRegionInfo info : foldRegionsInfo) { + final FoldRegion foldRegion = foldingManager.findFoldRegion(myEditor, info.myStart, info.myEnd); + if (foldRegion != null) { + foldRegion.setExpanded(info.myIsExpanded); + } + } } }); } } + + private static class FoldRegionInfo { + private int myStart; + private int myEnd; + private boolean myIsExpanded; + + private FoldRegionInfo(int start, int end, boolean expanded) { + myStart = start; + myEnd = end; + myIsExpanded = expanded; + } + } } From 3ab8bc7a66fdde859513fb919470c5b4f3ee76bb Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Tue, 21 Jan 2014 12:21:49 +0400 Subject: [PATCH 08/25] Code Style: Lazy arrangement settings save --- .../codeStyle/arrangement/JavaRearranger.java | 64 ++++--- .../arrangement/ArrangementUtil.java | 20 ++- .../DefaultArrangementSettingsSerializer.java | 167 ++++++++++-------- .../psi/codeStyle/arrangement/Rearranger.java | 11 ++ .../ArrangementSettingsSerializationTest.java | 110 +++++++++++- .../xml/arrangement/XmlRearranger.java | 12 +- 6 files changed, 268 insertions(+), 116 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java index cc35e7d75e70..7e3f95a692a2 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java @@ -101,6 +101,38 @@ public class JavaRearranger implements Rearranger, GROUPING_RULES.put(DEPENDENT_METHODS, ContainerUtilRt.newArrayList(BREADTH_FIRST, DEPTH_FIRST)); } + private static final StdArrangementSettings DEFAULT_SETTINGS; + + static { + List groupingRules = ContainerUtilRt.newArrayList(new ArrangementGroupingRule(GETTERS_AND_SETTERS)); + List matchRules = ContainerUtilRt.newArrayList(); + ArrangementSettingsToken[] visibility = {PUBLIC, PROTECTED, PACKAGE_PRIVATE, PRIVATE}; + for (ArrangementSettingsToken modifier : visibility) { + and(matchRules, FIELD, STATIC, FINAL, modifier); + } + for (ArrangementSettingsToken modifier : visibility) { + and(matchRules, FIELD, STATIC, modifier); + } + for (ArrangementSettingsToken modifier : visibility) { + and(matchRules, FIELD, FINAL, modifier); + } + for (ArrangementSettingsToken modifier : visibility) { + and(matchRules, FIELD, modifier); + } + and(matchRules, FIELD); + and(matchRules, CONSTRUCTOR); + and(matchRules, METHOD, STATIC); + and(matchRules, METHOD); + and(matchRules, ENUM); + and(matchRules, INTERFACE); + and(matchRules, CLASS, STATIC); + and(matchRules, CLASS); + + DEFAULT_SETTINGS = new StdRulePriorityAwareSettings(groupingRules, matchRules); + } + + private static final DefaultArrangementSettingsSerializer SETTINGS_SERIALIZER = new DefaultArrangementSettingsSerializer(DEFAULT_SETTINGS); + @NotNull private static Set concat(@NotNull Set base, ArrangementSettingsToken... modifiers) { Set result = ContainerUtilRt.newHashSet(base); @@ -279,32 +311,14 @@ public class JavaRearranger implements Rearranger, @NotNull @Override - public StdArrangementSettings getDefaultSettings() { - List groupingRules = ContainerUtilRt.newArrayList(new ArrangementGroupingRule(GETTERS_AND_SETTERS)); - List matchRules = ContainerUtilRt.newArrayList(); - ArrangementSettingsToken[] visibility = {PUBLIC, PROTECTED, PACKAGE_PRIVATE, PRIVATE}; - for (ArrangementSettingsToken modifier : visibility) { - and(matchRules, FIELD, STATIC, FINAL, modifier); - } - for (ArrangementSettingsToken modifier : visibility) { - and(matchRules, FIELD, STATIC, modifier); - } - for (ArrangementSettingsToken modifier : visibility) { - and(matchRules, FIELD, FINAL, modifier); - } - for (ArrangementSettingsToken modifier : visibility) { - and(matchRules, FIELD, modifier); - } - and(matchRules, FIELD); - and(matchRules, CONSTRUCTOR); - and(matchRules, METHOD, STATIC); - and(matchRules, METHOD); - and(matchRules, ENUM); - and(matchRules, INTERFACE); - and(matchRules, CLASS, STATIC); - and(matchRules, CLASS); + public ArrangementSettingsSerializer getSerializer() { + return SETTINGS_SERIALIZER; + } - return new StdRulePriorityAwareSettings(groupingRules, matchRules); + @NotNull + @Override + public StdArrangementSettings getDefaultSettings() { + return DEFAULT_SETTINGS; } @Nullable diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java index 2330c739c96b..5d0b97cad71b 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java @@ -17,6 +17,7 @@ package com.intellij.psi.codeStyle.arrangement; import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider; import com.intellij.lang.Language; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Ref; @@ -40,7 +41,8 @@ import java.util.*; * @since 7/17/12 11:24 AM */ public class ArrangementUtil { - + private static final Logger LOG = Logger.getInstance(ArrangementUtil.class); + private ArrangementUtil() { } @@ -49,20 +51,28 @@ public class ArrangementUtil { @Nullable public static ArrangementSettings readExternal(@NotNull Element element, @NotNull Language language) { ArrangementSettingsSerializer serializer = getSerializer(language); + if (serializer == null) { + LOG.error("Can't find serializer for language: " + language.getDisplayName() + "(" + language.getID() + ")"); + return null; + } + return serializer.deserialize(element); } public static void writeExternal(@NotNull Element element, @NotNull ArrangementSettings settings, @NotNull Language language) { ArrangementSettingsSerializer serializer = getSerializer(language); + if (serializer == null) { + LOG.error("Can't find serializer for language: " + language.getDisplayName() + "(" + language.getID() + ")"); + return; + } + serializer.serialize(settings, element); } + @Nullable private static ArrangementSettingsSerializer getSerializer(@NotNull Language language) { Rearranger rearranger = Rearranger.EXTENSION.forLanguage(language); - if (rearranger instanceof ArrangementSettingsSerializer) { - return (ArrangementSettingsSerializer)rearranger; - } - return DefaultArrangementSettingsSerializer.INSTANCE; + return rearranger == null ? null : rearranger.getSerializer(); } //endregion diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementSettingsSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementSettingsSerializer.java index 147064ce23e7..a3be98f53c9a 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementSettingsSerializer.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementSettingsSerializer.java @@ -21,15 +21,14 @@ import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule; import com.intellij.psi.codeStyle.arrangement.match.DefaultArrangementEntryMatcherSerializer; import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher; import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule; -import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; -import com.intellij.psi.codeStyle.arrangement.std.StdArrangementSettings; -import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens; -import com.intellij.psi.codeStyle.arrangement.std.StdRulePriorityAwareSettings; +import com.intellij.psi.codeStyle.arrangement.std.*; +import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; /** @@ -40,9 +39,6 @@ import java.util.List; * @since 7/18/12 10:37 AM */ public class DefaultArrangementSettingsSerializer implements ArrangementSettingsSerializer { - - public static final ArrangementSettingsSerializer INSTANCE = new DefaultArrangementSettingsSerializer(Mixin.NULL); - private static final Logger LOG = Logger.getInstance("#" + DefaultArrangementSettingsSerializer.class.getName()); @NotNull @NonNls private static final String GROUPS_ELEMENT_NAME = "groups"; @@ -55,10 +51,16 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings @NotNull private final DefaultArrangementEntryMatcherSerializer myMatcherSerializer; @NotNull private final Mixin myMixin; + @NotNull private final ArrangementSettings myDefaultSettings; - public DefaultArrangementSettingsSerializer(@NotNull Mixin mixin) { + public DefaultArrangementSettingsSerializer(@NotNull StdArrangementSettings defaultSettings) { + this(Mixin.NULL, defaultSettings); + } + + public DefaultArrangementSettingsSerializer(@NotNull Mixin mixin, @NotNull StdArrangementSettings defaultSettings) { myMixin = mixin; myMatcherSerializer = new DefaultArrangementEntryMatcherSerializer(mixin); + myDefaultSettings = defaultSettings; } @Override @@ -68,9 +70,9 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings } StdArrangementSettings settings = (StdArrangementSettings)s; - List groupings = settings.getGroupings(); - if (!groupings.isEmpty()) { + final boolean isDefaultGroupings = groupings.equals(myDefaultSettings.getGroupings()); + if (!isDefaultGroupings) { Element groupingsElement = new Element(GROUPS_ELEMENT_NAME); holder.addContent(groupingsElement); for (ArrangementGroupingRule group : groupings) { @@ -82,7 +84,8 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings } List rules = settings.getRules(); - if (!rules.isEmpty()) { + final boolean isDefaultRules = rules.equals(myDefaultSettings.getRules()); + if (!isDefaultRules) { Element rulesElement = new Element(RULES_ELEMENT_NAME); holder.addContent(rulesElement); for (StdArrangementMatchRule rule : rules) { @@ -94,79 +97,95 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings @Nullable @Override public ArrangementSettings deserialize(@NotNull Element element) { - StdArrangementSettings result = new StdRulePriorityAwareSettings(); - Element groups = element.getChild(GROUPS_ELEMENT_NAME); - if (groups != null) { - for (Object group : groups.getChildren(GROUP_ELEMENT_NAME)) { - Element groupElement = (Element)group; + final List groupingRules = deserializeGropings(element, myDefaultSettings); + final List rules = deserializeRules(element, myDefaultSettings); + return new StdRulePriorityAwareSettings(groupingRules, rules); + } - // Grouping type. - String groupingTypeId = groupElement.getChildText(TYPE_ELEMENT_NAME); - ArrangementSettingsToken groupingType = StdArrangementTokens.byId(groupingTypeId); - if (groupingType == null) { - groupingType = myMixin.deserializeToken(groupingTypeId); + @NotNull + private List deserializeGropings(@NotNull Element element, @Nullable ArrangementSettings defaultSettings) { + Element groups = element.getChild(GROUPS_ELEMENT_NAME); + if (groups == null) { + return defaultSettings == null ? ContainerUtil.newSmartList() : defaultSettings.getGroupings(); + } + + final List groupings = new ArrayList(); + for (Object group : groups.getChildren(GROUP_ELEMENT_NAME)) { + Element groupElement = (Element)group; + + // Grouping type. + String groupingTypeId = groupElement.getChildText(TYPE_ELEMENT_NAME); + ArrangementSettingsToken groupingType = StdArrangementTokens.byId(groupingTypeId); + if (groupingType == null) { + groupingType = myMixin.deserializeToken(groupingTypeId); + } + if (groupingType == null) { + LOG.warn(String.format("Can't deserialize grouping type token by id '%s'", groupingTypeId)); + continue; + } + + // Order type. + String orderTypeId = groupElement.getChildText(ORDER_TYPE_ELEMENT_NAME); + ArrangementSettingsToken orderType = StdArrangementTokens.byId(orderTypeId); + if (orderType == null) { + orderType = myMixin.deserializeToken(orderTypeId); + } + if (orderType == null) { + LOG.warn(String.format("Can't deserialize grouping order type token by id '%s'", orderTypeId)); + continue; + } + groupings.add(new ArrangementGroupingRule(groupingType, orderType)); + } + return groupings; + } + + @NotNull + private List deserializeRules(@NotNull Element element, @Nullable ArrangementSettings defaultSettings) { + Element rulesElement = element.getChild(RULES_ELEMENT_NAME); + if (rulesElement == null) { + return defaultSettings instanceof StdArrangementSettings ? ((StdArrangementSettings)defaultSettings).getRules() : + ContainerUtil.newSmartList(); + } + + final List rules = new ArrayList(); + for (Object o : rulesElement.getChildren(RULE_ELEMENT_NAME)) { + Element ruleElement = (Element)o; + Element matcherElement = ruleElement.getChild(MATCHER_ELEMENT_NAME); + if (matcherElement == null) { + continue; + } + + StdArrangementEntryMatcher matcher = null; + for (Object c : matcherElement.getChildren()) { + matcher = myMatcherSerializer.deserialize((Element)c); + if (matcher != null) { + break; } - if (groupingType == null) { - LOG.warn(String.format("Can't deserialize grouping type token by id '%s'", groupingTypeId)); - continue; - } - - // Order type. - String orderTypeId = groupElement.getChildText(ORDER_TYPE_ELEMENT_NAME); - ArrangementSettingsToken orderType = StdArrangementTokens.byId(orderTypeId); + } + + if (matcher == null) { + return ContainerUtil.newSmartList(); + } + + Element orderTypeElement = ruleElement.getChild(ORDER_TYPE_ELEMENT_NAME); + ArrangementSettingsToken orderType = null; + if (orderTypeElement != null) { + String orderTypeId = orderTypeElement.getText(); + orderType = StdArrangementTokens.byId(orderTypeId); if (orderType == null) { orderType = myMixin.deserializeToken(orderTypeId); } if (orderType == null) { - LOG.warn(String.format("Can't deserialize grouping order type token by id '%s'", orderTypeId)); - continue; + LOG.warn(String.format("Can't deserialize matching rule order type for id '%s'. Falling back to default (%s)", + orderTypeId, ArrangementMatchRule.DEFAULT_ORDER_TYPE.getId())); } - result.addGrouping(new ArrangementGroupingRule(groupingType, orderType)); } - } - - Element rulesElement = element.getChild(RULES_ELEMENT_NAME); - if (rulesElement != null) { - for (Object o : rulesElement.getChildren(RULE_ELEMENT_NAME)) { - Element ruleElement = (Element)o; - Element matcherElement = ruleElement.getChild(MATCHER_ELEMENT_NAME); - if (matcherElement == null) { - continue; - } - - StdArrangementEntryMatcher matcher = null; - for (Object c : matcherElement.getChildren()) { - matcher = myMatcherSerializer.deserialize((Element)c); - if (matcher != null) { - break; - } - } - - if (matcher == null) { - return null; - } - - Element orderTypeElement = ruleElement.getChild(ORDER_TYPE_ELEMENT_NAME); - ArrangementSettingsToken orderType = null; - if (orderTypeElement != null) { - String orderTypeId = orderTypeElement.getText(); - orderType = StdArrangementTokens.byId(orderTypeId); - if (orderType == null) { - orderType = myMixin.deserializeToken(orderTypeId); - } - if (orderType == null) { - LOG.warn(String.format("Can't deserialize matching rule order type for id '%s'. Falling back to default (%s)", - orderTypeId, ArrangementMatchRule.DEFAULT_ORDER_TYPE.getId())); - } - } - if (orderType == null) { - orderType = ArrangementMatchRule.DEFAULT_ORDER_TYPE; - } - result.addRule(new StdArrangementMatchRule(matcher, orderType)); + if (orderType == null) { + orderType = ArrangementMatchRule.DEFAULT_ORDER_TYPE; } + rules.add(new StdArrangementMatchRule(matcher, orderType)); } - - return result; + return rules; } @Nullable diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java index d15dcd8e0cd6..57914fb7dfc8 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java @@ -90,4 +90,15 @@ public interface Rearranger { * negative as an indication that no blank lines adjustment is necessary */ int getBlankLines(@NotNull CodeStyleSettings settings, @Nullable E parent, @Nullable E previous, @NotNull E target); + + + /** + * @return serializer to save {@link com.intellij.psi.codeStyle.arrangement.ArrangementSettings arrangement settings}. + * Serializer is expected to be lazy and don't save + * {@link com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsAware.getDefaultSettings() default settings}. + *

+ * @see com.intellij.psi.codeStyle.arrangement.DefaultArrangementSettingsSerializer + */ + @NotNull + ArrangementSettingsSerializer getSerializer(); } diff --git a/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/ArrangementSettingsSerializationTest.java b/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/ArrangementSettingsSerializationTest.java index be2631fdb299..57c578da52e3 100644 --- a/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/ArrangementSettingsSerializationTest.java +++ b/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/ArrangementSettingsSerializationTest.java @@ -22,12 +22,13 @@ import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchConditio import com.intellij.psi.codeStyle.arrangement.std.StdArrangementSettings; import com.intellij.psi.codeStyle.arrangement.std.StdRulePriorityAwareSettings; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.FIELD; import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Grouping.OVERRIDDEN_METHODS; import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Order.BY_NAME; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; /** * @author Denis Zhdanov @@ -35,17 +36,108 @@ import static org.junit.Assert.assertEquals; */ public class ArrangementSettingsSerializationTest { - @Test - public void all() { - StdArrangementSettings settings = new StdRulePriorityAwareSettings(); - settings.addGrouping(new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); - ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); - settings.addRule(new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME)); - + private static Element doSerializationTest(@NotNull StdArrangementSettings settings, @NotNull StdArrangementSettings defaultSettings) { Element holder = new Element("holder"); - ArrangementSettingsSerializer instance = DefaultArrangementSettingsSerializer.INSTANCE; + ArrangementSettingsSerializer instance = new TestArrangementSettingsSerializer(defaultSettings); instance.serialize(settings, holder); ArrangementSettings restored = instance.deserialize(holder); assertEquals(settings, restored); + return holder; + } + + @Test + public void all() { + final StdArrangementSettings settings = new StdRulePriorityAwareSettings(); + settings.addGrouping(new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); + final ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); + settings.addRule(new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME)); + doSerializationTest(settings, new StdArrangementSettings()); + } + + @Test + public void testDefaultFilter() { + final StdArrangementSettings settings = new StdRulePriorityAwareSettings(); + settings.addGrouping(new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); + final ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); + settings.addRule(new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME)); + + final Element holder = doSerializationTest(settings, settings); + assertTrue(holder.getChildren().isEmpty()); + } + + @Test + public void testDefaultGroupingFilter() { + final ArrangementGroupingRule groupingRule = new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME); + final ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); + final StdArrangementMatchRule rule = new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME); + + final StdArrangementSettings settings = new StdRulePriorityAwareSettings(); + settings.addGrouping(groupingRule); + settings.addRule(rule); + final StdArrangementSettings defaultSettings = new StdRulePriorityAwareSettings(); + defaultSettings.addGrouping(groupingRule); + + final Element holder = doSerializationTest(settings, defaultSettings); + assertTrue(holder.getChildren().size() == 1); + assertNull(holder.getChild("groups")); + assertNotNull(holder.getChild("rules")); + } + + @Test + public void testDefaultRulesFilter() { + final ArrangementGroupingRule groupingRule = new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME); + final ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); + final StdArrangementMatchRule rule = new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME); + + final StdArrangementSettings settings = new StdRulePriorityAwareSettings(); + settings.addGrouping(groupingRule); + settings.addRule(rule); + final StdArrangementSettings defaultSettings = new StdRulePriorityAwareSettings(); + defaultSettings.addRule(rule); + + final Element holder = doSerializationTest(settings, defaultSettings); + assertTrue(holder.getChildren().size() == 1); + assertNotNull(holder.getChild("groups")); + assertNull(holder.getChild("rules")); + } + + @Test + public void testEmptyGroupings() throws Exception { + final StdArrangementSettings settings = new StdRulePriorityAwareSettings(); + final ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); + settings.addRule(new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME)); + + final StdArrangementSettings defaultSettings = new StdRulePriorityAwareSettings(); + defaultSettings.addGrouping(new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); + + final Element holder = doSerializationTest(settings, defaultSettings); + assertTrue(holder.getChildren().size() == 2); + final Element groups = holder.getChild("groups"); + assertNotNull(groups); + assertTrue(groups.getChildren().isEmpty()); + } + + @Test + public void testEmptyRules() throws Exception { + final StdArrangementSettings settings = new StdRulePriorityAwareSettings(); + settings.addGrouping(new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); + + final StdArrangementSettings defaultSettings = new StdRulePriorityAwareSettings(); + final ArrangementAtomMatchCondition condition = new ArrangementAtomMatchCondition(FIELD); + final StdArrangementMatchRule rule = new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), BY_NAME); + defaultSettings.addRule(rule); + + final Element holder = doSerializationTest(settings, defaultSettings); + assertTrue(holder.getChildren().size() == 2); + final Element rules = holder.getChild("rules"); + assertNotNull(rules); + assertTrue(rules.getChildren().isEmpty()); + } + + private static class TestArrangementSettingsSerializer extends DefaultArrangementSettingsSerializer { + + public TestArrangementSettingsSerializer(@NotNull StdArrangementSettings defaultSettings) { + super(defaultSettings); + } } } diff --git a/xml/impl/src/com/intellij/xml/arrangement/XmlRearranger.java b/xml/impl/src/com/intellij/xml/arrangement/XmlRearranger.java index 9e20743b76c9..12212ea8a6d3 100644 --- a/xml/impl/src/com/intellij/xml/arrangement/XmlRearranger.java +++ b/xml/impl/src/com/intellij/xml/arrangement/XmlRearranger.java @@ -5,9 +5,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.codeStyle.CodeStyleSettings; -import com.intellij.psi.codeStyle.arrangement.ArrangementSettings; -import com.intellij.psi.codeStyle.arrangement.ArrangementUtil; -import com.intellij.psi.codeStyle.arrangement.Rearranger; +import com.intellij.psi.codeStyle.arrangement.*; import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher; import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher; @@ -46,6 +44,8 @@ public class XmlRearranger Collections.emptyList(), DEFAULT_MATCH_RULES); } + private static final DefaultArrangementSettingsSerializer SETTINGS_SERIALIZER = new DefaultArrangementSettingsSerializer(DEFAULT_SETTINGS); + @NotNull public static StdArrangementMatchRule attrArrangementRule(@NotNull String nameFilter, @NotNull String namespaceFilter, @@ -56,6 +56,12 @@ public class XmlRearranger )), orderType); } + @NotNull + @Override + public ArrangementSettingsSerializer getSerializer() { + return SETTINGS_SERIALIZER; + } + @Nullable @Override public StdArrangementSettings getDefaultSettings() { From ba9f665d2b3f321c1099df383de578b329b109c8 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 21 Jan 2014 13:13:49 +0400 Subject: [PATCH 09/25] IDEA-72304 Namespace auto import does not work for EL functions --- .../impl/analysis/CreateNSDeclarationIntentionFix.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java index 2f61dd47f83c..88d639a09127 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java @@ -206,9 +206,11 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi @Override public boolean showHint(@NotNull final Editor editor) { - if (myToken == null) return false; - XmlToken token = (XmlToken)myToken.retrieve(); - if (token == null) return false; + XmlToken token = null; + if (myToken != null) { + token = (XmlToken)myToken.retrieve(); + if (token == null) return false; + } if (!XmlSettings.getInstance().SHOW_XML_ADD_IMPORT_HINTS || myNamespacePrefix.isEmpty()) { return false; } @@ -219,7 +221,7 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi final String message = ShowAutoImportPass.getMessage(namespaces.size() > 1, namespaces.iterator().next()); final String title = getTitle(); final ImportNSAction action = new ImportNSAction(namespaces, getFile(), element, editor, title); - if (element instanceof XmlTag) { + if (element instanceof XmlTag && token != null) { if (VisibleHighlightingPassFactory.calculateVisibleRange(editor).contains(token.getTextRange())) { HintManager.getInstance().showQuestionHint(editor, message, token.getTextOffset(), From 31b1b182e5b1e92bb0bcd3fc6cb016a2ee7c648a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 17 Jan 2014 16:37:16 +0400 Subject: [PATCH 10/25] duplicate code --- .../src/com/intellij/openapi/ui/Messages.java | 22 +++---------------- .../util/src/com/intellij/util/ui/UIUtil.java | 20 ++++++++++------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java index e95efbc12a66..9cad5112adc9 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -426,13 +426,7 @@ public class Messages { */ @OkCancelResult public static int showOkCancelDialog(Project project, String message, @NotNull String title, @NotNull String okText, @NotNull String cancelText, Icon icon) { - if (canShowMacSheetPanel()) { - int result = MacMessages.getInstance() - .showYesNoDialog(title, message, okText, cancelText, WindowManager.getInstance().suggestParentWindow(project)); - return result == YES ? OK : CANCEL; - } - - return showDialog(project, message, title, new String[]{okText, cancelText}, 0, icon) == 0 ? OK : CANCEL; + return showOkCancelDialog(project, message, title, okText, cancelText, icon, null); } /** @@ -1218,22 +1212,12 @@ public class Messages { actions[i].putValue(FOCUSED_ACTION, Boolean.TRUE); } - assignMnemonic(option, actions[i]); + UIUtil.assignMnemonic(option, actions[i]); } return actions; } - private static void assignMnemonic(@NotNull String option, Action action) { - int mnemoPos = option.indexOf("&"); - if (mnemoPos >= 0 && mnemoPos < option.length() - 2) { - String mnemoChar = option.substring(mnemoPos + 1, mnemoPos + 2).trim(); - if (mnemoChar.length() == 1) { - action.putValue(Action.MNEMONIC_KEY, Integer.valueOf(mnemoChar.charAt(0))); - } - } - } - @Override public void doCancelAction() { close(-1); diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index edb846107878..95d108478841 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -433,18 +433,22 @@ public class UIUtil { return ArrayUtil.toStringArray(lines); } - public static void setActionNameAndMnemonic(String text, Action action) { - int mnemoPos = text.indexOf('&'); - if (mnemoPos >= 0 && mnemoPos < text.length() - 2) { - String mnemoChar = text.substring(mnemoPos + 1, mnemoPos + 2).trim(); - if (mnemoChar.length() == 1) { - action.putValue(Action.MNEMONIC_KEY, Integer.valueOf((int)mnemoChar.charAt(0))); - } - } + public static void setActionNameAndMnemonic(@NotNull String text, @NotNull Action action) { + assignMnemonic(text, action); text = text.replaceAll("&", ""); action.putValue(Action.NAME, text); } + public static void assignMnemonic(@NotNull String text, @NotNull Action action) { + int mnemoPos = text.indexOf('&'); + if (mnemoPos >= 0 && mnemoPos < text.length() - 2) { + String mnemoChar = text.substring(mnemoPos + 1, mnemoPos + 2).trim(); + if (mnemoChar.length() == 1) { + action.putValue(Action.MNEMONIC_KEY, Integer.valueOf(mnemoChar.charAt(0))); + } + } + } + public static Font getLabelFont(@NotNull FontSize size) { return getFont(size, null); From 7ab28bba3189ffb5026d2ce12527ee58be69947d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 17 Jan 2014 17:53:33 +0400 Subject: [PATCH 11/25] notnull --- .../hint/ImplementationViewComponent.java | 4 ++-- .../intellij/usages/UsageViewPresentation.java | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java index 74c899efb35f..312978accbd8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ public class ImplementationViewComponent extends JPanel { private final ActionToolbar myToolbar; private JLabel myLabel; - public void setHint(final JBPopup hint, final String title) { + public void setHint(final JBPopup hint, @NotNull String title) { myHint = hint; myTitle = title; } diff --git a/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java b/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java index 3467dcc66d7e..832d59241fb8 100644 --- a/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java +++ b/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.usages; import com.intellij.usageView.UsageViewBundle; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -96,19 +97,21 @@ public class UsageViewPresentation { myShowCancelButton = showCancelButton; } + @NotNull public String getNonCodeUsagesString() { return myNonCodeUsagesString; } - public void setNonCodeUsagesString(String nonCodeUsagesString) { + public void setNonCodeUsagesString(@NotNull String nonCodeUsagesString) { myNonCodeUsagesString = nonCodeUsagesString; } + @NotNull public String getCodeUsagesString() { return myCodeUsagesString; } - public void setCodeUsagesString(String codeUsagesString) { + public void setCodeUsagesString(@NotNull String codeUsagesString) { myCodeUsagesString = codeUsagesString; } @@ -137,11 +140,12 @@ public class UsageViewPresentation { return myNotFoundActions; } + @NotNull public String getUsagesWord() { return myUsagesWord; } - public void setUsagesWord(final String usagesWord) { + public void setUsagesWord(@NotNull String usagesWord) { myUsagesWord = usagesWord; } @@ -177,11 +181,12 @@ public class UsageViewPresentation { return myDynamicCodeUsagesString; } + @NotNull public String getUsagesInGeneratedCodeString() { return myUsagesInGeneratedCodeString; } - public void setUsagesInGeneratedCodeString(String usagesInGeneratedCodeString) { + public void setUsagesInGeneratedCodeString(@NotNull String usagesInGeneratedCodeString) { myUsagesInGeneratedCodeString = usagesInGeneratedCodeString; } From aa16517acb1e5b042b8c6fe0edd4563eef183d29 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 13:53:23 +0400 Subject: [PATCH 12/25] notnull --- .../src/com/intellij/openapi/vfs/VirtualFileManager.java | 4 ++-- .../com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java index bb98e161f9da..b751bdaf8507 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,5 +168,5 @@ public abstract class VirtualFileManager implements ModificationTracker { public abstract void removeVirtualFileManagerListener(@NotNull VirtualFileManagerListener listener); - public abstract void notifyPropertyChanged(VirtualFile virtualFile, String property, Object oldValue, Object newValue); + public abstract void notifyPropertyChanged(@NotNull VirtualFile virtualFile, @NotNull String property, Object oldValue, Object newValue); } diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java index 4b3d65a9d203..59f56bd5b79d 100644 --- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFileManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -185,7 +185,7 @@ public class VirtualFileManagerImpl extends VirtualFileManagerEx { } @Override - public void notifyPropertyChanged(final VirtualFile virtualFile, final String property, final Object oldValue, final Object newValue) { + public void notifyPropertyChanged(@NotNull final VirtualFile virtualFile, @NotNull final String property, final Object oldValue, final Object newValue) { final Application application = ApplicationManager.getApplication(); final Runnable runnable = new Runnable() { @Override From 1e7e11bd20e3144d07fb297c807dda210888c796 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 13:54:07 +0400 Subject: [PATCH 13/25] replaced with reparseFiles --- .../src/com/intellij/util/FileContentUtilCore.java | 13 ++++++------- .../openapi/vfs/impl/http/VirtualFileImpl.java | 9 ++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/platform/core-api/src/com/intellij/util/FileContentUtilCore.java b/platform/core-api/src/com/intellij/util/FileContentUtilCore.java index 93833db7002c..54a26f62c31c 100644 --- a/platform/core-api/src/com/intellij/util/FileContentUtilCore.java +++ b/platform/core-api/src/com/intellij/util/FileContentUtilCore.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +27,7 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author peter @@ -38,12 +35,14 @@ import java.util.Set; public class FileContentUtilCore { @NonNls public static final String FORCE_RELOAD_REQUESTOR = "FileContentUtilCore.saveOrReload"; + public static void reparseFiles(@NotNull VirtualFile... files) { + reparseFiles(Arrays.asList(files)); + } public static void reparseFiles(@NotNull final Collection files) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { // files must be processed under one write action to prevent firing event for invalid files. - final Set events = new THashSet(); for (VirtualFile file : files) { saveOrReload(file, events); @@ -57,7 +56,7 @@ public class FileContentUtilCore { }); } - private static void saveOrReload(VirtualFile file, Collection events) { + private static void saveOrReload(VirtualFile file, @NotNull Collection events) { if (file == null || file.isDirectory() || !file.isValid()) { return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java index 82fd22cd03f7..3c354bc30fe2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java @@ -19,11 +19,9 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileSystem; -import com.intellij.openapi.vfs.newvfs.BulkFileListener; -import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent; import com.intellij.util.ArrayUtil; +import com.intellij.util.FileContentUtilCore; import com.intellij.util.UriUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,7 +29,6 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Collections; class VirtualFileImpl extends HttpVirtualFile { private final HttpFileSystemBase myFileSystem; @@ -55,9 +52,7 @@ class VirtualFileImpl extends HttpVirtualFile { VirtualFileImpl file = VirtualFileImpl.this; FileDocumentManager.getInstance().reloadFiles(file); if (!localFile.getFileType().equals(myInitialFileType)) { - VFilePropertyChangeEvent event = new VFilePropertyChangeEvent(this, file, PROP_NAME, file.getName(), file.getName(), false); - BulkFileListener publisher = ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES); - publisher.after(Collections.singletonList(event)); + FileContentUtilCore.reparseFiles(file); } } }); From 0d881cda74cafbe096b4b6fd4de310fa84820963 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 14:09:07 +0400 Subject: [PATCH 14/25] cleanup --- .../intellij/find/findUsages/JavaFindUsagesHandler.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java index 7e7430970502..ce0461886d82 100644 --- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java +++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,10 +45,7 @@ import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.targets.AliasingPsiTarget; import com.intellij.psi.targets.AliasingPsiTargetMapper; -import com.intellij.psi.util.MethodSignature; -import com.intellij.psi.util.PropertyUtil; -import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.PsiUtilCore; +import com.intellij.psi.util.*; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.refactoring.util.JavaNonCodeSearchElementDescriptionProvider; import com.intellij.refactoring.util.NonCodeSearchDescriptionLocation; @@ -127,7 +124,7 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{ elementsToSearch.add(parameters[idx]); } } - return elementsToSearch.toArray(new PsiElement[elementsToSearch.size()]); + return PsiUtilCore.toPsiElementArray(elementsToSearch); } From 99c78160ed13b39fcca9f0a41d7b8cc35721898c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 14:47:54 +0400 Subject: [PATCH 15/25] obey "new ArrayList(Collection)" contract about created list capacity --- .../src/com/intellij/util/containers/ContainerUtilRt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java index d3c76ae9c6de..7a6ff1562f93 100644 --- a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java +++ b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java @@ -126,7 +126,7 @@ public class ContainerUtilRt { @NotNull public static ArrayList newArrayList(@NotNull T... elements) { - ArrayList list = newArrayListWithCapacity(elements.length); + ArrayList list = new ArrayList(elements.length); Collections.addAll(list, elements); return list; } From a42cc19e9652efd049f98138109553d66102a796 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 16:43:54 +0400 Subject: [PATCH 16/25] allow to call remove() on iterator --- .../LockFreeCopyOnWriteArrayList.java | 18 ++++++--- .../util/containers/ContainerUtilTest.java | 40 ++++++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java b/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java index 3bbf2b8604c2..2ba9fb0602a0 100644 --- a/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java +++ b/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -880,7 +880,7 @@ class LockFreeCopyOnWriteArrayList implements List, RandomAccess { Object[] elements = array; if (elements.length == 0) return EmptyIterator.getInstance(); - return new COWIterator(elements, 0); + return new COWIterator(elements, 0); } /** @@ -916,10 +916,10 @@ class LockFreeCopyOnWriteArrayList implements List, RandomAccess { throw new IndexOutOfBoundsException("Index: " + index); } - return elements.length == 0 ? EmptyListIterator.getInstance() : new COWIterator(elements, index); + return elements.length == 0 ? EmptyListIterator.getInstance() : new COWIterator(elements, index); } - private static class COWIterator implements ListIterator { + private class COWIterator implements ListIterator { /** * Snapshot of the array */ @@ -928,6 +928,7 @@ class LockFreeCopyOnWriteArrayList implements List, RandomAccess { * Index of element to be returned by subsequent call to next. */ private int cursor; + private int lastRet = -1; // index of last element returned; -1 if no such private COWIterator(@NotNull Object[] elements, int initialCursor) { cursor = initialCursor; @@ -950,6 +951,7 @@ class LockFreeCopyOnWriteArrayList implements List, RandomAccess { if (!hasNext()) { throw new NoSuchElementException(); } + lastRet = cursor; return (E)snapshot[cursor++]; } @@ -974,7 +976,13 @@ class LockFreeCopyOnWriteArrayList implements List, RandomAccess { @Override public void remove() { - throw new UnsupportedOperationException(); + if (lastRet < 0) { + throw new IllegalStateException(); + } + @SuppressWarnings("unchecked") + E e = (E)snapshot[lastRet]; + lastRet = -1; + LockFreeCopyOnWriteArrayList.this.remove(e); } @Override diff --git a/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java b/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java index e579a1651121..a52bdbca47dc 100644 --- a/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -234,4 +234,42 @@ public class ContainerUtilTest extends TestCase { Iterator iterator = my.iterator(); assertSame(EmptyIterator.getInstance(), iterator); } + + public void testLockFreeCOWIteratorRemove() { + List seq = Arrays.asList("0", "1", "2", "3", "4"); + LockFreeCopyOnWriteArrayList my = (LockFreeCopyOnWriteArrayList)ContainerUtil.createLockFreeCopyOnWriteList(seq); + { + Iterator iterator = my.iterator(); + try { + iterator.remove(); + fail("must not be able to remove before next() call"); + } + catch (IllegalStateException ignored) { + } + } + int size = my.size(); + Iterator iterator = my.iterator(); + for (int i = 0; i Date: Mon, 20 Jan 2014 16:44:34 +0400 Subject: [PATCH 17/25] notnull --- .../com/intellij/openapi/actionSystem/ActionManager.java | 4 ++-- .../src/com/intellij/openapi/extensions/PluginId.java | 4 ++-- .../openapi/actionSystem/ex/ActionManagerEx.java | 8 ++++++-- .../openapi/actionSystem/impl/ActionManagerImpl.java | 9 +++++---- .../openapi/actionSystem/impl/ButtonToolbarImpl.java | 7 ++++--- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java index 504f55931a8e..5577664bf9f7 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java @@ -72,7 +72,7 @@ public abstract class ActionManager implements ApplicationComponent { * * @return An instance of ActionToolbar */ - public abstract ActionToolbar createActionToolbar(@NonNls String place, ActionGroup group, boolean horizontal); + public abstract ActionToolbar createActionToolbar(@NonNls String place, @NotNull ActionGroup group, boolean horizontal); /** * Returns action associated with the specified actionId. @@ -151,7 +151,7 @@ public abstract class ActionManager implements ApplicationComponent { * @return the created panel. * @since 5.1 */ - public abstract JComponent createButtonToolbar(final String actionPlace, final ActionGroup messageActionGroup); + public abstract JComponent createButtonToolbar(final String actionPlace, @NotNull ActionGroup messageActionGroup); public abstract AnAction getActionOrStub(@NonNls String id); diff --git a/platform/extensions/src/com/intellij/openapi/extensions/PluginId.java b/platform/extensions/src/com/intellij/openapi/extensions/PluginId.java index 15beeb67fcca..84fba8f3b547 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/PluginId.java +++ b/platform/extensions/src/com/intellij/openapi/extensions/PluginId.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class PluginId implements Comparable { } @Override - public int compareTo(PluginId o) { + public int compareTo(@NotNull PluginId o) { return myIdString.compareTo(o.myIdString); } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java index 757b0677a52c..ab2612311fee 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.intellij.openapi.actionSystem.ex; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.extensions.PluginId; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -31,7 +32,7 @@ public abstract class ActionManagerEx extends ActionManager { return (ActionManagerEx)getInstance(); } - public abstract ActionToolbar createActionToolbar(String place, ActionGroup group, boolean horizontal, boolean decorateButtons); + public abstract ActionToolbar createActionToolbar(String place, @NotNull ActionGroup group, boolean horizontal, boolean decorateButtons); public abstract void fireBeforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event); @@ -88,6 +89,7 @@ public abstract class ActionManagerEx extends ActionManager { } + @NotNull public abstract String[] getPluginActions(PluginId pluginId); public abstract void queueActionPerformedEvent(final AnAction action, DataContext context, AnActionEvent event); @@ -96,10 +98,12 @@ public abstract class ActionManagerEx extends ActionManager { public abstract boolean isTransparentOnlyActionsUpdateNow(); + @NotNull public List getAbbreviations() { return Collections.emptyList(); } + @NotNull public List findActionIdsByAbbreviation(String abbreviation) { return Collections.emptyList(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java index 923f788c1025..535034d4fadc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -203,12 +203,12 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat } @Override - public ActionToolbar createActionToolbar(final String place, final ActionGroup group, final boolean horizontal) { + public ActionToolbar createActionToolbar(final String place, @NotNull final ActionGroup group, final boolean horizontal) { return createActionToolbar(place, group, horizontal, false); } @Override - public ActionToolbar createActionToolbar(final String place, final ActionGroup group, final boolean horizontal, final boolean decorateButtons) { + public ActionToolbar createActionToolbar(final String place, @NotNull final ActionGroup group, final boolean horizontal, final boolean decorateButtons) { return new ActionToolbarImpl(place, group, horizontal, decorateButtons, myDataManager, this, (KeymapManagerEx)myKeymapManager); } @@ -338,7 +338,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat } @Override - public JComponent createButtonToolbar(final String actionPlace, final ActionGroup messageActionGroup) { + public JComponent createButtonToolbar(final String actionPlace, @NotNull final ActionGroup messageActionGroup) { return new ButtonToolbarImpl(actionPlace, messageActionGroup, myDataManager, this); } @@ -1030,6 +1030,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat }; } + @NotNull @Override public String[] getPluginActions(PluginId pluginName) { if (myPlugin2Id.containsKey(pluginName)){ diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ButtonToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ButtonToolbarImpl.java index 6b0a55fb207f..e3496b8dd654 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ButtonToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ButtonToolbarImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.application.ModalityState; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; @@ -40,7 +41,7 @@ public class ButtonToolbarImpl extends JPanel { private final ArrayList myActions = new ArrayList(); public ButtonToolbarImpl(final String place, - final ActionGroup actionGroup, + @NotNull ActionGroup actionGroup, DataManager dataManager, ActionManagerEx actionManager) { super(new GridBagLayout()); @@ -57,7 +58,7 @@ public class ButtonToolbarImpl extends JPanel { } - private void initButtons(final ActionGroup actionGroup) { + private void initButtons(@NotNull ActionGroup actionGroup) { final AnAction[] actions = actionGroup.getChildren(null); if (actions.length > 0) { From 245a416fb257598dd979a6ba01b2f5dd5193163b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 18:35:30 +0400 Subject: [PATCH 18/25] assertion removed in CR-IC-4018 is back --- .../codeInsight/daemon/impl/GeneralHighlightingPass.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java index 006d1f54e271..b27570da95e0 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java @@ -153,7 +153,12 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP visitors.add(visitor); } } - //LOG.assertTrue(!visitors.isEmpty(), list); + if (visitors.isEmpty()) { + LOG.error("No visitors registered. list=" + + list + + "; all visitors are:" + + Arrays.asList(Extensions.getExtensions(HighlightVisitor.EP_HIGHLIGHT_VISITOR, myProject))); + } HighlightVisitor[] visitorArray = visitors.toArray(new HighlightVisitor[visitors.size()]); Arrays.sort(visitorArray, VISITOR_ORDER_COMPARATOR); From b8772f1a42cca947b7be53b10e102866127bf192 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 18:38:16 +0400 Subject: [PATCH 19/25] decapitalize --- .../platform-resources-en/src/messages/FindBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/FindBundle.properties b/platform/platform-resources-en/src/messages/FindBundle.properties index 0dcd53a552e4..94433d20057c 100644 --- a/platform/platform-resources-en/src/messages/FindBundle.properties +++ b/platform/platform-resources-en/src/messages/FindBundle.properties @@ -102,7 +102,7 @@ find.progress.search.completed=Search completed find.scope.project.title=Project find.scope.module.title=Module {0} find.scope.directory.title=Directory {0} -find.scope.files.with.mask={0} Files with Mask {1} +find.scope.files.with.mask={0} Files with mask {1} find.usage.target.string.text=String ''{0}'' find.replace.invalid.replacement.string=You have entered malformed replacement string: ''{0}'' find.replace.invalid.replacement.string.title=Replace Error From 5feb54c77b6eeb51069536877fe41f725cd2ddea Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Jan 2014 19:07:00 +0400 Subject: [PATCH 20/25] notnull --- .../src/com/intellij/find/impl/FindManagerImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java index 936e379de8c9..6400db8c43db 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lang.ParserDefinition; import com.intellij.lexer.LayeredLexer; import com.intellij.lexer.Lexer; -import com.intellij.lexer.LexerUtil; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; @@ -55,7 +54,6 @@ import com.intellij.openapi.fileTypes.*; import com.intellij.openapi.fileTypes.impl.AbstractFileType; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -1056,7 +1054,8 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo } }); } - + + @NotNull public FindUsagesManager getFindUsagesManager() { return myFindUsagesManager; } From a677cc2dcdda439707e75dd0a271d9cd427f5af4 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Tue, 21 Jan 2014 14:39:08 +0400 Subject: [PATCH 21/25] mark root node as terminated if some nodes aren't final --- ...neralIdBasedToSMTRunnerEventsConvertor.java | 18 ++++++++++++++++-- .../testframework/sm/runner/SMTestProxy.java | 7 +++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java index 3a34a15e52e4..b156cda33c2a 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java @@ -94,9 +94,10 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP // We don't know whether process was destroyed by user // or it finished after all tests have been run - // Lets assume, if at finish all suites except root suite are passed + // Lets assume, if at finish all nodes except root suite have final state (passed, failed or ignored), // then all is ok otherwise process was terminated by user - if (myRunningTestNodes.isEmpty()) { + boolean completeTree = isTreeComplete(); + if (completeTree) { myTestsRootProxy.setFinished(); } else { logProblem("Unexpected running nodes: " + myRunningTestNodes); @@ -110,6 +111,19 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP }); } + private boolean isTreeComplete() { + if (!myRunningTestNodes.isEmpty()) { + return false; + } + List children = myTestsRootProxy.getChildren(); + for (SMTestProxy child : children) { + if (!child.isFinal() || child.wasTerminated()) { + return false; + } + } + return true; + } + @Override public void setPrinterProvider(@NotNull TestProxyPrinterProvider printerProvider) { myTestProxyPrinterProvider = printerProvider; diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index 009a3c251838..632be05a09b5 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -143,6 +143,13 @@ public class SMTestProxy extends AbstractTestProxy { return false; } + /** + * @return true if the state is final (PASSED, FAILED, IGNORED, TERMINATED) + */ + public boolean isFinal() { + return myState.isFinal(); + } + private void setStacktraceIfNotSet(@Nullable String stacktrace) { if (myStacktrace == null) myStacktrace = stacktrace; } From 8a38ae9eed5426df86ddbb48d5b777a5179cbeb8 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Tue, 21 Jan 2014 15:56:39 +0400 Subject: [PATCH 22/25] log problem if needed --- .../sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java index b156cda33c2a..72e984b9a75a 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java @@ -100,9 +100,11 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP if (completeTree) { myTestsRootProxy.setFinished(); } else { - logProblem("Unexpected running nodes: " + myRunningTestNodes); myTestsRootProxy.setTerminated(); } + if (!myRunningTestNodes.isEmpty()) { + logProblem("Unexpected running nodes: " + myRunningTestNodes); + } myNodeByIdMap.clear(); myRunningTestNodes.clear(); From 0982afc3ca48b3b799ce9b772143810faf115917 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Tue, 21 Jan 2014 16:11:14 +0400 Subject: [PATCH 23/25] IDEA-119467 Gradle: auto discovery of buildSrc project IDEA-98930 IDEA does not resolve dependencies in Gradle buildSrc/ project --- .../builder/ModelDependenciesBuilderImpl.java | 28 +++++ .../gradle/model/internal/buildSrcInit.gradle | 25 +++++ .../project/GradleExecutionHelper.java | 28 ++++- .../project/GradleProjectResolver.java | 105 +++++++++++++++--- .../builder/AbstractModelBuilderTest.java | 2 +- 5 files changed, 170 insertions(+), 18 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java index 31797941dbce..bec228fa344a 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java @@ -24,6 +24,7 @@ import org.gradle.plugins.ide.idea.IdeaPlugin; import org.gradle.plugins.ide.idea.model.IdeaModel; import org.gradle.plugins.ide.internal.IdeDependenciesExtractor; import org.gradle.tooling.model.idea.IdeaDependency; +import org.gradle.util.GradleVersion; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.GradleDependencyScope; import org.jetbrains.plugins.gradle.model.ModelBuilderService; @@ -148,6 +149,7 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { versionId.getClassifier() ); libraryDependency.setFile(fileDependency.getFile()); + attachGradleSdkSources(libraryDependency, fileDependency); dependencies.add(libraryDependency); } } @@ -156,6 +158,32 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { return new ProjectDependenciesModelImpl(project.getPath(), dependencies); } + private static void attachGradleSdkSources(IdeaSingleEntryLibraryDependencyImpl libraryDependency, + IdeDependenciesExtractor.IdeLocalFileDependency localFileDependency) { + final String libName = localFileDependency.getFile().getName(); + if (localFileDependency.getFile() == null || !libName.startsWith("gradle-")) return; + + File libOrPluginsFile = localFileDependency.getFile().getParentFile(); + if (libOrPluginsFile != null && ("plugins".equals(libOrPluginsFile.getName()))) { + libOrPluginsFile = libOrPluginsFile.getParentFile(); + } + + if (libOrPluginsFile != null && "lib".equals(libOrPluginsFile.getName()) && libOrPluginsFile.getParentFile() != null) { + File srcDir = new File(libOrPluginsFile.getParentFile(), "src"); + if (GradleVersion.current().compareTo(GradleVersion.version("1.9")) >= 0) { + int endIndex = libName.indexOf(GradleVersion.current().getVersion() + ".jar"); + if (endIndex != -1) { + String srcDirChild = libName.substring("gradle-".length(), endIndex - 1); + srcDir = new File(srcDir, srcDirChild); + } + } + + if (srcDir.isDirectory()) { + libraryDependency.setSource(srcDir); + } + } + } + @Nullable private static String findDeDuplicatedModuleName(Project project) { if (project.hasProperty(MODULE_PROPERTY)) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle new file mode 100644 index 000000000000..91140f2fcec6 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +allprojects { project -> + if(project.name == 'buildSrc') { + apply plugin: 'groovy' + dependencies { + compile gradleApi() + compile localGroovy() + } + } +} \ No newline at end of file diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java index 8e6df173dc0c..f12de5460942 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java @@ -355,22 +355,46 @@ public class GradleExecutionHelper { } @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - public static void setInitScript(LongRunningOperation longRunningOperation) { + public static boolean setInitScript(@NotNull LongRunningOperation longRunningOperation, boolean isBuildSrcProject) { try { InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/init.gradle"); - if (stream == null) return; + if (stream == null) return isBuildSrcProject; String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(GradleProjectResolver.class)); String s = FileUtil.loadTextAndClose(stream).replace("${JAR_PATH}", jarPath); + if(isBuildSrcProject) { + String buildSrcDefaultInitScript = getBuildSrcDefaultInitScript(); + if(buildSrcDefaultInitScript == null) return false; + s += buildSrcDefaultInitScript; + } + final File tempFile = FileUtil.createTempFile("ijinit", '.' + GradleConstants.EXTENSION, true); FileUtil.writeToFile(tempFile, s); String[] buildExecutorArgs = new String[]{"--init-script", tempFile.getAbsolutePath()}; longRunningOperation.withArguments(buildExecutorArgs); + + return true; } catch (Exception e) { LOG.warn("Can't use IJ gradle init script", e); + return false; + } + } + + @Nullable + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + public static String getBuildSrcDefaultInitScript() { + try { + InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle"); + if (stream == null) return null; + + return FileUtil.loadTextAndClose(stream); + } + catch (Exception e) { + LOG.warn("Can't use IJ gradle init script", e); + return null; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 87e7cfb2beca..efdaa69e7cf7 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -32,6 +32,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemDebugEnvironment; import com.intellij.openapi.util.KeyValue; import com.intellij.openapi.util.Pair; +import com.intellij.util.BooleanFunction; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; @@ -110,19 +111,19 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver>() { - @Override - public DataNode fun(ProjectConnection connection) { - try { - return doResolveProjectInfo( - new ProjectResolverContext(id, projectPath, settings, connection, listener, isPreviewMode), projectResolverChain); - } - catch (RuntimeException e) { - LOG.info("Gradle project resolve error", e); - throw projectResolverChain.getUserFriendlyError(e, projectPath, null); - } - } - }); + final DataNode resultProjectDataNode = myHelper.execute( + projectPath, settings, + new ProjectConnectionDataNodeFunction( + id, projectPath, settings, listener, isPreviewMode, projectResolverChain, false) + ); + + // auto-discover buildSrc project if needed + final String buildSrcProjectPath = projectPath + "/buildSrc"; + handleBuildSrcProject( + resultProjectDataNode, + new ProjectConnectionDataNodeFunction(id, buildSrcProjectPath, settings, listener, isPreviewMode, projectResolverChain, true) + ); + return resultProjectDataNode; } @Override @@ -133,7 +134,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver doResolveProjectInfo(@NotNull final ProjectResolverContext resolverCtx, - @NotNull final GradleProjectResolverExtension projectResolverChain) + @NotNull final GradleProjectResolverExtension projectResolverChain, + boolean isBuildSrcProject) throws IllegalArgumentException, IllegalStateException { final ProjectImportAction projectImportAction = new ProjectImportAction(resolverCtx.isPreviewMode()); @@ -165,7 +167,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver resultProjectDataNode, + @NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) { + + if (projectConnectionDataNodeFunction.myIsPreviewMode || GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) return; + + final DataNode buildSrcModuleDataNode = + ExternalSystemApiUtil.find(resultProjectDataNode, ProjectKeys.MODULE, new BooleanFunction>() { + @Override + public boolean fun(DataNode node) { + return projectConnectionDataNodeFunction.myProjectPath.equals(node.getData().getLinkedExternalProjectPath()); + } + }); + + // check if buildSrc project was already exposed in settings.gradle file + if (buildSrcModuleDataNode != null) return; + + final DataNode buildSrcProjectDataDataNode = myHelper.execute( + projectConnectionDataNodeFunction.myProjectPath, projectConnectionDataNodeFunction.mySettings, projectConnectionDataNodeFunction); + + if (buildSrcProjectDataDataNode != null) { + final DataNode moduleDataNode = ExternalSystemApiUtil.find(buildSrcProjectDataDataNode, ProjectKeys.MODULE); + if (moduleDataNode != null) { + for (DataNode libraryDataNode : ExternalSystemApiUtil.findAll(buildSrcProjectDataDataNode, ProjectKeys.LIBRARY)) { + resultProjectDataNode.createChild(libraryDataNode.getKey(), libraryDataNode.getData()); + } + + final DataNode newModuleDataNode = resultProjectDataNode.createChild(ProjectKeys.MODULE, moduleDataNode.getData()); + for (DataNode node : moduleDataNode.getChildren()) { + newModuleDataNode.createChild(node.getKey(), node.getData()); + } + } + } + } + + private class ProjectConnectionDataNodeFunction implements Function> { + @NotNull private final ExternalSystemTaskId myId; + @NotNull private final String myProjectPath; + @Nullable private final GradleExecutionSettings mySettings; + @NotNull private final ExternalSystemTaskNotificationListener myListener; + private final boolean myIsPreviewMode; + @NotNull private final GradleProjectResolverExtension myProjectResolverChain; + private final boolean myIsBuildSrcProject; + + public ProjectConnectionDataNodeFunction(@NotNull ExternalSystemTaskId id, + @NotNull String projectPath, + @Nullable GradleExecutionSettings settings, + @NotNull ExternalSystemTaskNotificationListener listener, + boolean isPreviewMode, + @NotNull GradleProjectResolverExtension projectResolverChain, + boolean isBuildSrcProject) { + myId = id; + myProjectPath = projectPath; + mySettings = settings; + myListener = listener; + myIsPreviewMode = isPreviewMode; + myProjectResolverChain = projectResolverChain; + myIsBuildSrcProject = isBuildSrcProject; + } + + @Override + public DataNode fun(ProjectConnection connection) { + try { + return doResolveProjectInfo( + new ProjectResolverContext(myId, myProjectPath, mySettings, connection, myListener, myIsPreviewMode), + myProjectResolverChain, myIsBuildSrcProject); + } + catch (RuntimeException e) { + LOG.info("Gradle project resolve error", e); + throw myProjectResolverChain.getUserFriendlyError(e, myProjectPath, null); + } + } + } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java index 835d7305bd1b..0cdd2f032b78 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java @@ -73,7 +73,7 @@ public abstract class AbstractModelBuilderTest { final ProjectImportAction projectImportAction = new ProjectImportAction(true); projectImportAction.addExtraProjectModelClasses(getModels()); BuildActionExecuter buildActionExecutor = connection.action(projectImportAction); - GradleExecutionHelper.setInitScript(buildActionExecutor); + GradleExecutionHelper.setInitScript(buildActionExecutor, false); allModels = buildActionExecutor.run(); assertNotNull(allModels); From b8ddcd45f5a21ae31352de44bea16ff507cd04b9 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Tue, 21 Jan 2014 16:24:41 +0400 Subject: [PATCH 24/25] Gradle: EA-53148 - NPE: AbstractExternalSystemConfigurable.getProjectName --- .../service/settings/AbstractExternalSystemConfigurable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java index b996f4d3cbcf..59b1e5f0dc74 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java @@ -190,7 +190,7 @@ public abstract class AbstractExternalSystemConfigurable< @NotNull protected String getProjectName(@NotNull String path) { File file = new File(path); - return file.isDirectory() ? file.getName() : file.getParentFile().getName(); + return file.isDirectory() || file.getParentFile() == null ? file.getName() : file.getParentFile().getName(); } private void prepareSystemSettings(@NotNull SystemSettings s) { From 82ddf7dd1c9a74737a1c5409049dc08ebb7e1886 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 21 Jan 2014 16:36:22 +0400 Subject: [PATCH 25/25] fixed empty headers and import (dependant in language level) for qt, gtk... skeletons. --- python/helpers/pycharm_generator_utils/constants.py | 2 +- .../helpers/pycharm_generator_utils/module_redeclarator.py | 6 +++++- .../jetbrains/python/sdk/skeletons/PySkeletonRefresher.java | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/python/helpers/pycharm_generator_utils/constants.py b/python/helpers/pycharm_generator_utils/constants.py index bb0093e62623..4ea8cf17309a 100644 --- a/python/helpers/pycharm_generator_utils/constants.py +++ b/python/helpers/pycharm_generator_utils/constants.py @@ -6,7 +6,7 @@ import string import time -VERSION = "1.132" +VERSION = "1.133" OUT_ENCODING = 'utf-8' diff --git a/python/helpers/pycharm_generator_utils/module_redeclarator.py b/python/helpers/pycharm_generator_utils/module_redeclarator.py index fdb4dd58cf10..83778790a1c5 100644 --- a/python/helpers/pycharm_generator_utils/module_redeclarator.py +++ b/python/helpers/pycharm_generator_utils/module_redeclarator.py @@ -127,8 +127,12 @@ class ModuleRedeclarator(object): for buf in self.classes_buffs: fname = build_output_name(mod_path, buf.name) dummy = fopen(fname, "w") + self.header_buf.flush(dummy) buf.flush(dummy) - data += "from " + buf.name + " import " + buf.name + "\n" + data += "from " + if version[0] >= 3: + data += "." + data += buf.name + " import " + buf.name + "\n" dummy.close() init.write(data) diff --git a/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java b/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java index 3fbc168acc1c..077ced33e0fc 100644 --- a/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java +++ b/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java @@ -267,6 +267,7 @@ public class PySkeletonRefresher { final String skeletonsPath = getSkeletonsPath(); final File skeletonsDir = new File(skeletonsPath); if (!skeletonsDir.exists()) { + //noinspection ResultOfMethodCallIgnored skeletonsDir.mkdirs(); } final String readablePath = FileUtil.getLocationRelativeToUserHome(homePath); @@ -446,7 +447,7 @@ public class PySkeletonRefresher { reader.close(); } } - catch (IOException e) { + catch (IOException ignored) { } return null; }