Parsing dynamic in extension receiver position
This commit is contained in:
@@ -1527,7 +1527,8 @@ public class JetParsing extends AbstractJetParsing {
|
||||
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
IElementType lookahead = lookahead(1);
|
||||
if (at(IDENTIFIER) && lookahead(1) != DOT && lookahead != LT && lookahead != LPAR && at(DYNAMIC_KEYWORD)) {
|
||||
IElementType lookahead2 = lookahead(2);
|
||||
if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) {
|
||||
PsiBuilder.Marker dynamicType = mark();
|
||||
advance(); // DYNAMIC_KEYWORD
|
||||
dynamicType.done(DYNAMIC_TYPE);
|
||||
|
||||
+4
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.jet.lang.parsing;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
|
||||
// TODO: comments go to wrong place when an empty element is created, see IElementType.isLeftBound()
|
||||
@@ -29,4 +31,6 @@ public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
|
||||
void restoreJoiningComplexTokensState();
|
||||
void enableJoiningComplexTokens();
|
||||
void disableJoiningComplexTokens();
|
||||
|
||||
boolean isWhitespaceOrComment(@NotNull IElementType elementType);
|
||||
}
|
||||
|
||||
+7
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.jet.lang.parsing;
|
||||
|
||||
import com.intellij.lang.impl.PsiBuilderAdapter;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SemanticWhitespaceAwarePsiBuilderAdapter extends PsiBuilderAdapter implements SemanticWhitespaceAwarePsiBuilder {
|
||||
|
||||
@@ -62,4 +64,9 @@ public class SemanticWhitespaceAwarePsiBuilderAdapter extends PsiBuilderAdapter
|
||||
public void disableJoiningComplexTokens() {
|
||||
myBuilder.disableJoiningComplexTokens();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitespaceOrComment(@NotNull IElementType elementType) {
|
||||
return myBuilder.isWhitespaceOrComment(elementType);
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -19,9 +19,12 @@ package org.jetbrains.jet.lang.parsing;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.impl.PsiBuilderAdapter;
|
||||
import com.intellij.lang.impl.PsiBuilderImpl;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import com.intellij.util.containers.Stack;
|
||||
@@ -35,10 +38,36 @@ public class SemanticWhitespaceAwarePsiBuilderImpl extends PsiBuilderAdapter imp
|
||||
|
||||
private final Stack<Boolean> newlinesEnabled = new Stack<Boolean>();
|
||||
|
||||
private final PsiBuilderImpl delegateImpl;
|
||||
|
||||
public SemanticWhitespaceAwarePsiBuilderImpl(PsiBuilder delegate) {
|
||||
super(delegate);
|
||||
newlinesEnabled.push(true);
|
||||
joinComplexTokens.push(true);
|
||||
|
||||
delegateImpl = findPsiBuilderImpl(delegate);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilderImpl findPsiBuilderImpl(PsiBuilder builder) {
|
||||
// This is a hackish workaround for PsiBuilder interface not exposing isWhitespaceOrComment() method
|
||||
// We have to unwrap all the adapters to find an Impl inside
|
||||
while (true) {
|
||||
if (builder instanceof PsiBuilderImpl) {
|
||||
return (PsiBuilderImpl) builder;
|
||||
}
|
||||
if (!(builder instanceof PsiBuilderAdapter)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
builder = ((PsiBuilderAdapter) builder).getDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitespaceOrComment(@NotNull IElementType elementType) {
|
||||
assert delegateImpl != null : "PsiBuilderImpl not found";
|
||||
return delegateImpl.whitespaceOrComment(elementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+32
-2
@@ -30,8 +30,7 @@ public class TruncatedSemanticWhitespaceAwarePsiBuilder extends SemanticWhitespa
|
||||
|
||||
@Override
|
||||
public boolean eof() {
|
||||
if (super.eof()) return true;
|
||||
return myEOFPosition >= 0 && getCurrentOffset() >= myEOFPosition;
|
||||
return super.eof() || isOffsetBeyondEof(getCurrentOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,4 +45,35 @@ public class TruncatedSemanticWhitespaceAwarePsiBuilder extends SemanticWhitespa
|
||||
return super.getTokenType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType lookAhead(int steps) {
|
||||
if (eof()) return null;
|
||||
|
||||
int rawLookAheadSteps = rawLookAhead(steps);
|
||||
if (isOffsetBeyondEof(rawTokenTypeStart(rawLookAheadSteps))) return null;
|
||||
|
||||
return super.rawLookup(rawLookAheadSteps);
|
||||
}
|
||||
|
||||
private int rawLookAhead(int steps) {
|
||||
// This code reproduces the behavior of PsiBuilderImpl.lookAhead(), but returns a number of raw steps instead of a token type
|
||||
// This is required for implementing truncated builder behavior
|
||||
int cur = 0;
|
||||
while (steps > 0) {
|
||||
cur++;
|
||||
|
||||
IElementType rawTokenType = rawLookup(cur);
|
||||
while (rawTokenType != null && isWhitespaceOrComment(rawTokenType)) {
|
||||
cur++;
|
||||
rawTokenType = rawLookup(cur);
|
||||
}
|
||||
|
||||
steps--;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
private boolean isOffsetBeyondEof(int offsetFromCurrent) {
|
||||
return myEOFPosition >= 0 && offsetFromCurrent >= myEOFPosition;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user