use of com.intellij.psi.tree.IElementType in project intellij-elixir by KronicDeth.
the class GeneratedParserUtilBase method nextTokenIs.
public static boolean nextTokenIs(PsiBuilder builder, String frameName, IElementType... tokens) {
ErrorState state = ErrorState.get(builder);
if (state.completionState != null)
return true;
boolean track = !state.suppressErrors && state.predicateCount < 2 && state.predicateSign;
if (!track)
return nextTokenIsFast(builder, tokens);
IElementType tokenType = builder.getTokenType();
if (isNotEmpty(frameName)) {
addVariantInner(state, builder.rawTokenIndex(), frameName);
} else {
for (IElementType token : tokens) {
addVariant(builder, state, token);
}
}
if (tokenType == null)
return false;
for (IElementType token : tokens) {
if (tokenType == token)
return true;
}
return false;
}
use of com.intellij.psi.tree.IElementType in project intellij-elixir by KronicDeth.
the class GeneratedParserUtilBase method exit_section_impl_.
private static void exit_section_impl_(ErrorState state, Frame frame, PsiBuilder builder, @Nullable IElementType elementType, boolean result, boolean pinned, @Nullable Parser eatMore) {
int initialPos = builder.rawTokenIndex();
boolean willFail = !result && !pinned;
replace_variants_with_name_(state, frame, builder, result, pinned);
int lastErrorPos = getLastVariantPos(state, initialPos);
if (!state.suppressErrors && eatMore != null) {
state.suppressErrors = true;
final boolean eatMoreFlagOnce = !builder.eof() && eatMore.parse(builder, frame.level + 1);
boolean eatMoreFlag = eatMoreFlagOnce || !result && frame.position == initialPos && lastErrorPos > frame.position;
PsiBuilderImpl.ProductionMarker latestDoneMarker = (pinned || result) && (state.altMode || elementType != null) && eatMoreFlagOnce ? (PsiBuilderImpl.ProductionMarker) builder.getLatestDoneMarker() : null;
PsiBuilder.Marker extensionMarker = null;
IElementType extensionTokenType = null;
// whitespace prefix makes the very first frame offset bigger than marker start offset which is always 0
if (latestDoneMarker != null && frame.position >= latestDoneMarker.getStartIndex() && frame.position <= latestDoneMarker.getEndIndex()) {
extensionMarker = ((PsiBuilder.Marker) latestDoneMarker).precede();
extensionTokenType = latestDoneMarker.getTokenType();
((PsiBuilder.Marker) latestDoneMarker).drop();
}
// advance to the last error pos
// skip tokens until lastErrorPos. parseAsTree might look better here...
int parenCount = 0;
while ((eatMoreFlag || parenCount > 0) && builder.rawTokenIndex() < lastErrorPos) {
IElementType tokenType = builder.getTokenType();
if (state.braces != null) {
if (tokenType == state.braces[0].getLeftBraceType())
parenCount++;
else if (tokenType == state.braces[0].getRightBraceType())
parenCount--;
}
if (!(builder.rawTokenIndex() < lastErrorPos))
break;
builder.advanceLexer();
eatMoreFlag = eatMore.parse(builder, frame.level + 1);
}
boolean errorReported = frame.errorReportedAt == initialPos || !result && frame.errorReportedAt >= frame.position;
if (errorReported) {
if (eatMoreFlag) {
builder.advanceLexer();
parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
}
} else if (eatMoreFlag) {
errorReported = reportError(builder, state, frame, null, true, true);
parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
} else if (eatMoreFlagOnce || (!result && frame.position != builder.rawTokenIndex()) || frame.errorReportedAt > initialPos) {
errorReported = reportError(builder, state, frame, null, true, false);
} else if (!result && pinned && frame.errorReportedAt < 0) {
errorReported = reportError(builder, state, frame, elementType, false, false);
}
if (extensionMarker != null) {
extensionMarker.done(extensionTokenType);
}
state.suppressErrors = false;
if (errorReported || result) {
state.clearVariants(true, 0);
state.clearVariants(false, 0);
state.lastExpectedVariantPos = -1;
}
} else if (!result && pinned && frame.errorReportedAt < 0) {
// do not report if there are errors beyond current position
if (lastErrorPos == initialPos) {
// do not force, inner recoverRoot might have skipped some tokens
reportError(builder, state, frame, elementType, false, false);
} else if (lastErrorPos > initialPos) {
// set error pos here as if it is reported for future reference
frame.errorReportedAt = lastErrorPos;
}
}
// propagate errorReportedAt up the stack to avoid duplicate reporting
Frame prevFrame = willFail && eatMore == null ? null : state.currentFrame;
if (prevFrame != null && prevFrame.errorReportedAt < frame.errorReportedAt) {
prevFrame.errorReportedAt = frame.errorReportedAt;
}
}
use of com.intellij.psi.tree.IElementType in project intellij-elixir by KronicDeth.
the class StackFrame method terminatorType.
public IElementType terminatorType() {
String promoter = getPromoter();
Base group = getGroup();
IElementType terminatorType;
if (Base.isHeredocPromoter(promoter)) {
terminatorType = group.heredocTerminatorType;
} else {
terminatorType = group.terminatorType;
}
return terminatorType;
}
use of com.intellij.psi.tree.IElementType in project intellij-elixir by KronicDeth.
the class ElixirPsiImplUtil method quotedChildNodes.
private static OtpErlangObject quotedChildNodes(@NotNull Parent parent, @NotNull OtpErlangList metadata, @NotNull ASTNode... children) {
OtpErlangObject quoted;
final int childCount = children.length;
if (childCount == 0) {
quoted = parent.quoteEmpty();
} else {
List<OtpErlangObject> quotedParentList = new LinkedList<OtpErlangObject>();
List<Integer> codePointList = null;
for (ASTNode child : children) {
IElementType elementType = child.getElementType();
if (elementType == parent.getFragmentType()) {
codePointList = parent.addFragmentCodePoints(codePointList, child);
} else if (elementType == ElixirTypes.ESCAPED_CHARACTER) {
codePointList = parent.addEscapedCharacterCodePoints(codePointList, child);
} else if (elementType == ElixirTypes.ESCAPED_EOL) {
codePointList = parent.addEscapedEOL(codePointList, child);
} else if (elementType == ElixirTypes.HEXADECIMAL_ESCAPE_PREFIX) {
codePointList = addChildTextCodePoints(codePointList, child);
} else if (elementType == ElixirTypes.INTERPOLATION) {
if (codePointList != null) {
quotedParentList.add(elixirString(codePointList));
codePointList = null;
}
ElixirInterpolation childElement = (ElixirInterpolation) child.getPsi();
quotedParentList.add(childElement.quote());
} else if (elementType == ElixirTypes.QUOTE_HEXADECIMAL_ESCAPE_SEQUENCE || elementType == ElixirTypes.SIGIL_HEXADECIMAL_ESCAPE_SEQUENCE) {
codePointList = parent.addHexadecimalEscapeSequenceCodePoints(codePointList, child);
} else {
throw new NotImplementedException("Can't quote " + child);
}
}
if (codePointList != null && quotedParentList.isEmpty()) {
quoted = parent.quoteLiteral(codePointList);
} else {
if (codePointList != null) {
quotedParentList.add(elixirString(codePointList));
}
OtpErlangObject[] quotedStringElements = new OtpErlangObject[quotedParentList.size()];
quotedParentList.toArray(quotedStringElements);
OtpErlangTuple binaryConstruction = quotedFunctionCall("<<>>", metadata, quotedStringElements);
quoted = parent.quoteBinary(binaryConstruction);
}
}
return quoted;
}
use of com.intellij.psi.tree.IElementType in project intellij-elixir by KronicDeth.
the class ElixirPsiImplUtil method quote.
@Contract(pure = true)
@NotNull
public static OtpErlangObject quote(@NotNull final Heredoc heredoc) {
ElixirHeredocPrefix heredocPrefix = heredoc.getHeredocPrefix();
int prefixLength = heredocPrefix.getTextLength();
Deque<ASTNode> alignedNodeQueue = new LinkedList<ASTNode>();
List<HeredocLine> heredocLineList = heredoc.getHeredocLineList();
IElementType fragmentType = heredoc.getFragmentType();
for (HeredocLine line : heredocLineList) {
queueChildNodes(line, fragmentType, prefixLength, alignedNodeQueue);
}
Queue<ASTNode> mergedNodeQueue = mergeFragments(alignedNodeQueue, heredoc.getFragmentType(), heredoc.getManager());
ASTNode[] mergedNodes = new ASTNode[mergedNodeQueue.size()];
mergedNodeQueue.toArray(mergedNodes);
return quotedChildNodes(heredoc, mergedNodes);
}
Aggregations