From 0ab2173c425cfb43a092c65b310e7546650f7956 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Wed, 10 Jun 2015 18:56:06 +0300 Subject: [PATCH] UP-4237 Exception: @NotNull parameter 'type' of com/intellij/psi/impl/source/tree/CompositeElement. Perform lazy initialization of the code which touches JspElementType --- .../completion/JavaCompletionContributor.java | 2 +- .../completion/JavaCompletionData.java | 101 +++++++++++------- .../completion/ModifierChooser.java | 2 +- 3 files changed, 63 insertions(+), 42 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 5c42a1f0deaa..88019cd763c4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -124,7 +124,7 @@ public class JavaCompletionContributor extends CompletionContributor { return new AnnotationTypeFilter(); } - if (JavaCompletionData.DECLARATION_START.accepts(position) || + if (JavaCompletionData.DECLARATION_START.getValue().accepts(position) || JavaCompletionData.isInsideParameterList(position) || psiElement().inside(psiElement(PsiJavaCodeReferenceElement.class).withParent(psiAnnotation())).accepts(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index 67670d5d2d18..5da35bb89eba 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -20,6 +20,8 @@ import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.TailTypes; import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; import com.intellij.codeInsight.lookup.*; +import com.intellij.openapi.util.AtomicNotNullLazyValue; +import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PsiJavaElementPattern; import com.intellij.pom.java.LanguageLevel; @@ -37,6 +39,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import static com.intellij.patterns.PsiJavaPatterns.*; import static com.intellij.patterns.StandardPatterns.not; @@ -86,33 +89,39 @@ public class JavaCompletionData extends JavaAwareCompletionData { new StartElementFilter() ); - static final ElementFilter END_OF_BLOCK = new OrFilter( - new AndFilter( - new LeftNeighbour( - new OrFilter( + static final NotNullLazyValue END_OF_BLOCK = new AtomicNotNullLazyValue() { + @NotNull + @Override + protected ElementFilter compute() { + return new OrFilter( + new AndFilter( + new LeftNeighbour( + new OrFilter( new AndFilter ( - new TextFilter(BLOCK_FINALIZERS), - new NotFilter ( - new SuperParentFilter(new ClassFilter(PsiAnnotation.class)) - ) + new TextFilter(BLOCK_FINALIZERS), + new NotFilter ( + new SuperParentFilter(new ClassFilter(PsiAnnotation.class)) + ) ), new TextFilter("*/"), new TokenTypeFilter(JspElementType.HOLDER_TEMPLATE_DATA), new ClassFilter(OuterLanguageElement.class), new AndFilter( - new TextFilter(")"), - new NotFilter( - new OrFilter( - new ParentElementFilter(new ClassFilter(PsiExpressionList.class)), - new ParentElementFilter(new ClassFilter(PsiParameterList.class)), - new ParentElementFilter(new ClassFilter(PsiTypeCastExpression.class)) - ) + new TextFilter(")"), + new NotFilter( + new OrFilter( + new ParentElementFilter(new ClassFilter(PsiExpressionList.class)), + new ParentElementFilter(new ClassFilter(PsiParameterList.class)), + new ParentElementFilter(new ClassFilter(PsiTypeCastExpression.class)) ) + ) ))), - new NotFilter(new TextFilter(".")) - ), - START_OF_CODE_FRAGMENT - ); + new NotFilter(new TextFilter(".")) + ), + START_OF_CODE_FRAGMENT + ); + } + }; static final ElementPattern START_SWITCH = psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchStatement.class)); @@ -132,9 +141,15 @@ public class JavaCompletionData extends JavaAwareCompletionData { PsiKeyword.CHAR, PsiKeyword.BYTE }; - private static final ElementFilter CLASS_BODY = new OrFilter( - new AfterElementFilter(new TextFilter("{")), - new ScopeFilter(new ClassFilter(JspClassLevelDeclarationStatement.class))); + private static final NotNullLazyValue CLASS_BODY = new AtomicNotNullLazyValue() { + @NotNull + @Override + protected ElementFilter compute() { + return new OrFilter( + new AfterElementFilter(new TextFilter("{")), + new ScopeFilter(new ClassFilter(JspClassLevelDeclarationStatement.class))); + } + }; public static final ElementPattern START_FOR = psiElement().afterLeaf(psiElement().withText("(").afterLeaf("for")).withParents(PsiJavaCodeReferenceElement.class, @@ -166,25 +181,31 @@ public class JavaCompletionData extends JavaAwareCompletionData { defineScopeEquivalence(PsiMethod.class, JavaCodeFragment.class); } - public static final ElementPattern DECLARATION_START = psiElement().andNot(psiElement().afterLeaf("@", ".")). - andOr( - psiElement().and(new FilterPattern(CLASS_BODY)). + public static final NotNullLazyValue> DECLARATION_START = new NotNullLazyValue>() { + @NotNull + @Override + protected ElementPattern compute() { + return psiElement().andNot(psiElement().afterLeaf("@", ".")). andOr( - new FilterPattern(END_OF_BLOCK), - psiElement().afterLeaf(or( - psiElement().inside(PsiModifierList.class), - psiElement().withElementType(JavaTokenType.GT).inside(PsiTypeParameterList.class) - ))), - psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiMember.class), - psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClassLevelDeclarationStatement.class) - ); + psiElement().and(new FilterPattern(CLASS_BODY.getValue())). + andOr( + new FilterPattern(END_OF_BLOCK.getValue()), + psiElement().afterLeaf(or( + psiElement().inside(PsiModifierList.class), + psiElement().withElementType(JavaTokenType.GT).inside(PsiTypeParameterList.class) + ))), + psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiMember.class), + psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClassLevelDeclarationStatement.class) + ); + } + }; private void declareCompletionSpaces() { declareFinalScope(PsiFile.class); { // Class body - final CompletionVariant variant = new CompletionVariant(CLASS_BODY); + final CompletionVariant variant = new CompletionVariant(CLASS_BODY.getValue()); variant.includeScopeClass(PsiClass.class, true); registerVariant(variant); } @@ -219,7 +240,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { // position { final ElementFilter position = new AndFilter( - new NotFilter(CLASS_BODY), + new NotFilter(CLASS_BODY.getValue()), new NotFilter(new AfterElementFilter(new ContentFilter(new TextFilter(PsiKeyword.EXTENDS)))), new NotFilter(new AfterElementFilter(new ContentFilter(new TextFilter(PsiKeyword.IMPLEMENTS)))), new NotFilter(new LeftNeighbour(new LeftNeighbour(new TextFilter("<", ",")))), @@ -240,7 +261,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { // position { final ElementFilter position = new AndFilter( - new NotFilter(CLASS_BODY), + new NotFilter(CLASS_BODY.getValue()), new NotFilter(new BeforeElementFilter(new ContentFilter(new TextFilter(PsiKeyword.EXTENDS)))), new NotFilter(new AfterElementFilter(new ContentFilter(new TextFilter(PsiKeyword.IMPLEMENTS)))), new NotFilter(new LeftNeighbour(new LeftNeighbour(new TextFilter("<", ",")))), @@ -476,7 +497,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.PACKAGE), TailType.HUMBLE_SPACE_BEFORE_WORD)); result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.IMPORT), TailType.HUMBLE_SPACE_BEFORE_WORD)); } - else if (END_OF_BLOCK.isAcceptable(position, position) && PsiTreeUtil.getParentOfType(position, PsiMember.class) == null) { + else if (END_OF_BLOCK.getValue().isAcceptable(position, position) && PsiTreeUtil.getParentOfType(position, PsiMember.class) == null) { result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.IMPORT), TailType.HUMBLE_SPACE_BEFORE_WORD)); } } @@ -589,7 +610,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { return true; } - return END_OF_BLOCK.isAcceptable(position, position); + return END_OF_BLOCK.getValue().isAcceptable(position, position); } static void addExpectedTypeMembers(CompletionParameters parameters, final CompletionResultSet result) { @@ -656,7 +677,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { .accepts(position); boolean typeFragment = position.getContainingFile() instanceof PsiTypeCodeFragment && PsiTreeUtil.prevVisibleLeaf(position) == null; - boolean declaration = DECLARATION_START.accepts(position); + boolean declaration = DECLARATION_START.getValue().accepts(position); boolean expressionPosition = isExpressionPosition(position); boolean inGenerics = PsiTreeUtil.getParentOfType(position, PsiReferenceParameterList.class) != null; if (START_FOR.accepts(position) || @@ -723,7 +744,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { return false; } - if (END_OF_BLOCK.isAcceptable(position, position) && + if (END_OF_BLOCK.getValue().isAcceptable(position, position) && PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, true, PsiMember.class) != null) { return true; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java b/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java index 3762bb671c15..807144519108 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java @@ -130,7 +130,7 @@ public class ModifierChooser { PsiElement prev = FilterPositionUtil.searchNonSpaceNonCommentBack(element); if (parent instanceof PsiJavaFile || parent instanceof PsiClass) { - if (prev == null || JavaCompletionData.END_OF_BLOCK.isAcceptable(element, prev.getParent())) { + if (prev == null || JavaCompletionData.END_OF_BLOCK.getValue().isAcceptable(element, prev.getParent())) { return true; } }