From 5164e918d2bb758bb96a96c773396c2ccb50793f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Feb 2013 12:41:26 +0100 Subject: [PATCH] Cleaner API for light token visiting --- .../psi/impl/source/JavaLightStubBuilder.java | 109 +++++++++--------- .../lang/LighterLazyParseableNode.java | 10 +- .../intellij/lang/impl/ASTNodeBuilder.java | 34 ------ .../intellij/lang/impl/PsiBuilderImpl.java | 35 +++--- 4 files changed, 77 insertions(+), 111 deletions(-) delete mode 100644 platform/core-impl/src/com/intellij/lang/impl/ASTNodeBuilder.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java index 101dd2e02fc7..35ec9939c0f4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java @@ -18,8 +18,7 @@ package com.intellij.psi.impl.source; import com.intellij.lang.ASTNode; import com.intellij.lang.LighterAST; import com.intellij.lang.LighterASTNode; -import com.intellij.lang.impl.ASTNodeBuilder; -import com.intellij.openapi.util.Ref; +import com.intellij.lang.LighterLazyParseableNode; import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; @@ -33,11 +32,6 @@ import com.intellij.util.io.StringRef; import org.jetbrains.annotations.NotNull; public class JavaLightStubBuilder extends LightStubBuilder { - private static final TokenSet BLOCK_ELEMENTS = TokenSet.create( - JavaElementType.ANNOTATION, JavaElementType.CLASS, JavaElementType.ANONYMOUS_CLASS); - private static final TokenSet BLOCK_TOKENS = TokenSet.orSet( - TokenSet.create(JavaTokenType.AT), ElementType.CLASS_KEYWORD_BIT_SET); - @NotNull @Override protected StubElement createStubForFile(@NotNull PsiFile file, @NotNull LighterAST tree) { @@ -61,29 +55,12 @@ public class JavaLightStubBuilder extends LightStubBuilder { IElementType parentType = parent.getElementType(); IElementType nodeType = node.getElementType(); - if (nodeType == JavaElementType.PARAMETER && parentType != JavaElementType.PARAMETER_LIST) { - return true; - } - if (nodeType == JavaElementType.PARAMETER_LIST && parentType == JavaElementType.LAMBDA_EXPRESSION) { - return true; - } + if (checkByTypes(parentType, nodeType)) return true; if (nodeType == JavaElementType.CODE_BLOCK && node instanceof TreeElement) { - final Ref skip = Ref.create(true); - - ((TreeElement)node).acceptTree(new RecursiveTreeElementWalkingVisitor() { - @Override - protected void visitNode(TreeElement element) { - if (BLOCK_ELEMENTS.contains(element.getElementType())) { - skip.set(false); - stopWalking(); - return; - } - super.visitNode(element); - } - }); - - return skip.get(); + CodeBlockVisitor visitor = new CodeBlockVisitor(); + ((TreeElement)node).acceptTree(visitor); + return visitor.result; } return false; @@ -94,6 +71,18 @@ public class JavaLightStubBuilder extends LightStubBuilder { IElementType parentType = parent.getTokenType(); IElementType nodeType = node.getTokenType(); + if (checkByTypes(parentType, nodeType)) return true; + + if (nodeType == JavaElementType.CODE_BLOCK && node instanceof LighterLazyParseableNode) { + CodeBlockVisitor visitor = new CodeBlockVisitor(); + ((LighterLazyParseableNode)node).accept(visitor); + return visitor.result; + } + + return false; + } + + private static boolean checkByTypes(IElementType parentType, IElementType nodeType) { if (nodeType == JavaElementType.PARAMETER && parentType != JavaElementType.PARAMETER_LIST) { return true; } @@ -101,32 +90,44 @@ public class JavaLightStubBuilder extends LightStubBuilder { return true; } - if (nodeType == JavaElementType.CODE_BLOCK && node instanceof ASTNodeBuilder.ASTUnparsedNodeMarker) { - ASTNodeBuilder.ASTUnparsedNodeMarker nodeMarker = (ASTNodeBuilder.ASTUnparsedNodeMarker)node; - ASTNodeBuilder nodeBuilder = nodeMarker.getBuilder(); - boolean seenNew = false, skip = true; - - for (int i = nodeMarker.getStartLexemeIndex(), endIndex = nodeMarker.getEndLexemeIndex(); i < endIndex; ++i) { - IElementType type = nodeBuilder.getElementType(i); - if (type == JavaTokenType.NEW_KEYWORD) { - seenNew = true; - } - else if (seenNew && type == JavaTokenType.LBRACE) { // anonymous class - skip = false; - break; - } - else if (seenNew && type == JavaTokenType.SEMICOLON) { - seenNew = false; - } - else if (BLOCK_TOKENS.contains(type)) { // annotated local variables, type annotations, local classes - skip = false; - break; - } - } - - return skip; - } - return false; } + + private static class CodeBlockVisitor extends RecursiveTreeElementWalkingVisitor implements LighterLazyParseableNode.Visitor { + private static final TokenSet BLOCK_ELEMENTS = TokenSet.create( + JavaElementType.ANNOTATION, JavaElementType.CLASS, JavaElementType.ANONYMOUS_CLASS); + private static final TokenSet BLOCK_TOKENS = TokenSet.orSet( + TokenSet.create(JavaTokenType.AT), ElementType.CLASS_KEYWORD_BIT_SET); + + private boolean result = true; + private boolean seenNew = false; + + @Override + protected void visitNode(TreeElement element) { + if (BLOCK_ELEMENTS.contains(element.getElementType())) { + result = false; + stopWalking(); + return; + } + super.visitNode(element); + } + + @Override + public boolean visit(IElementType type) { + if (type == JavaTokenType.NEW_KEYWORD) { + seenNew = true; + } + else if (seenNew && type == JavaTokenType.LBRACE) { // anonymous class + result = false; + } + else if (seenNew && type == JavaTokenType.SEMICOLON) { + seenNew = false; + } + else if (BLOCK_TOKENS.contains(type)) { // annotated local variables, type annotations, local classes + result = false; + } + + return result; + } + } } diff --git a/platform/core-api/src/com/intellij/lang/LighterLazyParseableNode.java b/platform/core-api/src/com/intellij/lang/LighterLazyParseableNode.java index b7b899f1b74a..424072bb36c4 100644 --- a/platform/core-api/src/com/intellij/lang/LighterLazyParseableNode.java +++ b/platform/core-api/src/com/intellij/lang/LighterLazyParseableNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 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,7 +16,9 @@ package com.intellij.lang; import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; import com.intellij.util.CharTable; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface LighterLazyParseableNode extends LighterASTNode { @@ -26,4 +28,10 @@ public interface LighterLazyParseableNode extends LighterASTNode { CharTable getCharTable(); CharSequence getText(); + + interface Visitor { + boolean visit(IElementType type); + } + + boolean accept(@NotNull Visitor visitor); } diff --git a/platform/core-impl/src/com/intellij/lang/impl/ASTNodeBuilder.java b/platform/core-impl/src/com/intellij/lang/impl/ASTNodeBuilder.java deleted file mode 100644 index 86013d138565..000000000000 --- a/platform/core-impl/src/com/intellij/lang/impl/ASTNodeBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2000-2012 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.intellij.lang.impl; - -import com.intellij.psi.tree.IElementType; -import org.jetbrains.annotations.Nullable; - -/** - * @author Maxim.Mossienko - * @since 5.11.2011 - */ -public interface ASTNodeBuilder { - @Nullable - IElementType getElementType(int lexemeIndex); - - interface ASTUnparsedNodeMarker { - ASTNodeBuilder getBuilder(); - int getStartLexemeIndex(); - int getEndLexemeIndex(); - } -} diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index e0d559f1cbbc..365dc472cc56 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -61,7 +61,7 @@ import java.util.Map; /** * @author max */ -public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, ASTNodeBuilder { +public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private static final Logger LOG = Logger.getInstance("#com.intellij.lang.impl.PsiBuilderImpl"); // function stored in PsiBuilderImpl' user data which called during reparse when merge algorithm is not sure what to merge @@ -268,11 +268,6 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS public abstract int hc(); } - @Override - public IElementType getElementType(int lexemeIndex) { - return lexemeIndex < myLexemeCount && lexemeIndex >= 0 ? myLexTypes[lexemeIndex] : null; - } - public abstract static class ProductionMarker extends Node { protected int myLexemeIndex; protected WhitespacesAndCommentsBinder myEdgeTokenBinder; @@ -521,7 +516,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS private static class TokenNode extends Token implements LighterASTTokenNode { } - private static class LazyParseableToken extends Token implements LighterLazyParseableNode, ASTUnparsedNodeMarker { + private static class LazyParseableToken extends Token implements LighterLazyParseableNode { private MyTreeStructure myParent; private FlyweightCapableTreeStructure myParsed; private int myStartIndex; @@ -552,20 +547,16 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS } @Override - public ASTNodeBuilder getBuilder() { - return myBuilder; - } + public boolean accept(@NotNull Visitor visitor) { + for (int i = myStartIndex; i < myEndIndex; i++) { + IElementType type = myBuilder.myLexTypes[i]; + if (!visitor.visit(type)) { + return false; + } + } - @Override - public int getStartLexemeIndex() { - return myStartIndex; + return true; } - - @Override - public int getEndLexemeIndex() { - return myEndIndex; - } - } private static class DoneMarker extends ProductionMarker { @@ -1341,7 +1332,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS boolean oldIsErrorElement = oldNode instanceof PsiErrorElement; boolean newIsErrorElement = newNode.getTokenType() == TokenType.ERROR_ELEMENT; if (oldIsErrorElement != newIsErrorElement) return ThreeState.NO; - if (oldIsErrorElement && newIsErrorElement) { + if (oldIsErrorElement) { final PsiErrorElement e1 = (PsiErrorElement)oldNode; return Comparing.equal(e1.getErrorDescription(), getErrorMessage(newNode)) ? ThreeState.UNSURE : ThreeState.NO; } @@ -1421,7 +1412,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS boolean isForeign2 = n2.getTokenType() instanceof ForeignLeafType; if (isForeign1 != isForeign2) return false; - if (isForeign1 && isForeign2) { + if (isForeign1) { return n1.getText().equals(((ForeignLeafType)n2.getTokenType()).getValue()); }