mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Cleaner API for light token visiting
This commit is contained in:
@@ -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<Boolean> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<LighterASTNode> 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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user