LighterASTNode doneMarker = builder.rawLookup(tokenIdx) == state.braces[0].getLeftBraceType() ? builder.getLatestDoneMarker() : null; if (doneMarker != null && doneMarker.getStartOffset() == builder.rawTokenTypeStart(tokenIdx) && doneMarker.getTokenType() == TokenType.ERROR_ELEMENT) { parenList.add(Pair.create(((PsiBuilder.Marker)doneMarker).precede(), (PsiBuilder.Marker)null)); if (checkParens && (tokenType == state.braces[0].getLeftBraceType() || tokenType == state.braces[0].getRightBraceType() && !parenList.isEmpty())) { if (marker != null) { marker.done(chunkType); siblingList.addFirst(Pair.create(marker, 1)); marker = null; if (tokenType == state.braces[0].getRightBraceType()) { final Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair = parenList.removeFirst(); pair.first.done(chunkType); if (marker == null) { marker = builder.mark(); marker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null); marker.done(chunkType); siblingList.addFirst(Pair.create(marker, 1)); checkSiblingsRunnable.run(); c = current_position_(builder); if (marker != null) marker.drop(); for (Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair : parenList) { pair.first.drop();
private static void run_hooks_impl_(PsiBuilder builder, ErrorState state, @Nullable IElementType elementType) { if (state.hooks == null) return; PsiBuilder.Marker marker = elementType == null ? null : (PsiBuilder.Marker)builder.getLatestDoneMarker(); if (elementType != null && marker == null) { builder.mark().error("No expected done marker at offset " + builder.getCurrentOffset()); } while (state.hooks != null && state.hooks.level >= state.level) { if (state.hooks.level == state.level) { marker = ((Hook<Object>)state.hooks.hook).run(builder, marker, state.hooks.param); } state.hooks = state.hooks.next; } }
LighterASTNode doneMarker = builder.rawLookup(tokenIdx) == lBrace ? builder.getLatestDoneMarker() : null; if (doneMarker != null && doneMarker.getStartOffset() == builder.rawTokenTypeStart(tokenIdx) && doneMarker.getTokenType() == TokenType.ERROR_ELEMENT) { parens.add(Pair.create(((PsiBuilder.Marker)doneMarker).precede(), null)); if (lBrace != null && (tokenType == lBrace || tokenType == rBrace && !parens.isEmpty())) { if (marker != null) { marker.done(chunkType); siblings.addFirst(Pair.create(marker, 1)); marker = null; if (tokenType == rBrace) { Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair = parens.removeFirst(); pair.first.done(chunkType); if (marker == null) { marker = builder.mark(); marker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null); marker.done(chunkType); siblings.addFirst(Pair.create(marker, 1)); checkSiblings(chunkType, parens, siblings); c = current_position_(builder); if (marker != null) marker.drop(); for (Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair : parens) { pair.first.drop();
if (latestDoneMarker != null) { if (latestDoneMarker.getTokenType() == END_DIRECTIVE) { branchMarker.doneBefore(branchTokenType, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); currentMarker.drop(); branchMarker = null; break; branchMarker.doneBefore(branchTokenType, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); branchMarker = currentMarker.precede(); branchTokenType = CATCH_BRANCH; branchMarker.doneBefore(branchTokenType, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); branchMarker = currentMarker.precede(); branchTokenType = FINAL_BRANCH; currentMarker.error(TemplateToolkitBundle.message("ttk2.catch.final.end.expected")); currentMarker.drop(); currentMarker.error(TemplateToolkitBundle.message("ttk2.unexpected.token")); branchMarker.done(branchTokenType); branchMarker.precede().error(TemplateToolkitBundle.message("ttk2.error.unclosed.block.directive")); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);
if (latestDoneMarker != null) { if (latestDoneMarker.getTokenType() == END_DIRECTIVE) { branchMarker.doneBefore(branchTokenType, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); currentMarker.drop(); branchMarker = null; break; branchMarker.doneBefore(branchTokenType, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); branchMarker = currentMarker.precede(); branchTokenType = ELSIF_BRANCH; branchMarker.doneBefore(branchTokenType, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); branchMarker = currentMarker.precede(); branchTokenType = ELSE_BRANCH; currentMarker.error(TemplateToolkitBundle.message("ttk2.else.elsif.end.expected")); currentMarker.drop(); currentMarker.error(TemplateToolkitBundle.message("ttk2.unexpected.token")); branchMarker.done(branchTokenType); branchMarker.precede().error(TemplateToolkitBundle.message("ttk2.error.unclosed.block.directive")); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);
perlMarker.collapse(perlTokenType); perlMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); perlMarker.drop(); outerMarker.done(blockTokenType); recoverBlock = false; outerMarker.done(blockTokenType); outerMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); outerMarker.precede().error(TemplateToolkitBundle.message("ttk2.error.unclosed.perl.block"));
if (latestDoneMarker.getTokenType() == END_DIRECTIVE) { if (branchMarker != null) { branchMarker.doneBefore(CASE_BLOCK, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.DEFAULT_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); currentMarker.drop(); break; branchMarker.doneBefore(CASE_BLOCK, currentMarker); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.DEFAULT_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); branchMarker = currentMarker.precede(); currentMarker.drop(); branchMarker.done(CASE_BLOCK); branchMarker.setCustomEdgeTokenBinders(WhitespacesBinders.DEFAULT_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);
public static boolean parseFileAsString(PsiBuilder b, int l) { if (b.eof()) { return false; } if (isEndMarker(b)) { return false; } boolean gotItem = false; PsiBuilder.Marker stringMarker = b.mark(); while (!b.eof()) { if (isEndMarker(b)) { break; } boolean isLastToken = TemplateToolkitParserDefinition.WHITE_SPACES.contains(b.rawLookup(1)); PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(TT2_STRING_CONTENT); gotItem = true; if (isLastToken) { break; } } if (gotItem) { stringMarker.done(SQ_STRING_EXPR); } else { stringMarker.drop(); } return gotItem; }
/** * Parses nested-call like wrappers: <code>custom_token()</code>, converting custom token to sub and making custom nested * call wrapper * * @param nestedCallType wrapper element type * @return parsing result */ protected boolean parseCustomNestedCall(@NotNull PerlBuilder builder, int level, @NotNull IElementType nestedCallType) { PsiBuilder.Marker wrapperMarker = builder.mark(); if (PerlParserImpl.nested_call_inner( builder, level, (b, l) -> { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(SUB_NAME); return true; }, PerlParserImpl.optional_expression_parser_ )) { wrapperMarker.done(nestedCallType); return true; } wrapperMarker.rollbackTo(); return false; } }
public static boolean parseMasonNamedBlock(PsiBuilder b, int l, IElementType closeToken, IElementType statementTokenType) { boolean r = false; PsiBuilder.Marker methodMarker = b.mark(); b.advanceLexer(); PsiBuilder.Marker subMarker = b.mark(); if (PerlParserUtil.consumeToken(b, IDENTIFIER)) { subMarker.collapse(SUB_NAME); if (PerlParserUtil.consumeToken(b, HTML_MASON_TAG_CLOSER)) { PsiBuilder.Marker blockMarker = b.mark(); PerlParserProxy.block_content(b, l); if (b.getTokenType() == closeToken) { blockMarker.done(HTML_MASON_BLOCK); blockMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); b.advanceLexer(); methodMarker.done(statementTokenType); r = true; } } } if (!r) { methodMarker.rollbackTo(); } return r || MasonParserUtil.recoverToGreedy(b, closeToken, "Error"); } }
/** * Parses block content * * @param b builder * @param l level * @return result of end parsing. */ public static boolean parseBlockContent(PsiBuilder b, int l, PsiBuilder.Marker outerMarker, IElementType blockTokenType) { boolean r = false; while (!b.eof() && TemplateToolkitParser.element(b, l)) { LighterASTNode latestDoneMarker = b.getLatestDoneMarker(); if (latestDoneMarker != null && latestDoneMarker.getTokenType() == END_DIRECTIVE) { r = true; break; } } outerMarker.done(blockTokenType); if (!r) // this can happen on incomplete block, missing end { outerMarker.setCustomEdgeTokenBinders(WhitespacesBinders.DEFAULT_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); outerMarker.precede().error(TemplateToolkitBundle.message("ttk2.error.unclosed.block.directive")); } return r; }
public static boolean parseMasonMethod(PsiBuilder b, int l, IElementType closeToken, IElementType statementTokenType) { boolean r = false; PsiBuilder.Marker methodMarker = b.mark(); b.advanceLexer(); PsiBuilder.Marker subMarker = b.mark(); if (PerlParserUtil.consumeToken(b, SUB_NAME)) { subMarker.collapse(SUB_NAME); PerlParserProxy.method_signature(b, l); if (PerlParserUtil.consumeToken(b, MASON_TAG_CLOSER)) { PsiBuilder.Marker blockMarker = b.mark(); PerlParserProxy.block_content(b, l); if (b.getTokenType() == closeToken) { blockMarker.done(BLOCK); blockMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); b.advanceLexer(); methodMarker.done(statementTokenType); r = true; } } } if (!r) { methodMarker.rollbackTo(); } return r || MasonParserUtil.recoverToGreedy(b, closeToken, "Error"); }
private static void checkSiblings(IElementType chunkType, ArrayDeque<Pair<PsiBuilder.Marker, PsiBuilder.Marker>> parens, ArrayDeque<Pair<PsiBuilder.Marker, Integer>> siblings) { main: while (!siblings.isEmpty()) { Pair<PsiBuilder.Marker, PsiBuilder.Marker> parenPair = parens.peek(); int rating = siblings.getFirst().second; int count = 0; for (Pair<PsiBuilder.Marker, Integer> pair : siblings) { if (pair.second != rating || parenPair != null && pair.first == parenPair.second) break main; if (++count >= MAX_CHILDREN_IN_TREE) { PsiBuilder.Marker parentMarker = pair.first.precede(); parentMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null); while (count-- > 0) { siblings.removeFirst(); } parentMarker.done(chunkType); siblings.addFirst(Pair.create(parentMarker, rating + 1)); continue main; } } break; } }
@Override public boolean parseTerm(PsiBuilder b, int l) { IElementType tokenType = b.getTokenType(); if (tokenType == MOJO_BEGIN) { PsiBuilder.Marker subMarker = b.mark(); b.advanceLexer(); PsiBuilder.Marker blockMarker = b.mark(); PerlParserProxy.block_content(b, l); if (b.getTokenType() == MOJO_END) { blockMarker.done(BLOCK); blockMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); subMarker.done(SUB_EXPR); return true; } else { blockMarker.drop(); subMarker.rollbackTo(); } } return super.parseTerm(b, l); }
/** * Parses SQ string with optional conversion to the use_vars lp string * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean mapUseVars(PsiBuilder b, int l, Parser parser) { PsiBuilder.Marker m = b.mark(); boolean r = parser.parse(b, l); // fixme prepend last done marker if (r) { m.collapse(PARSABLE_STRING_USE_VARS); } else { m.drop(); } return r; }
@Override public boolean parse(BashPsiBuilder builder) { PsiBuilder.Marker marker = builder.mark(); //eat the "let" token builder.advanceLexer(); PsiBuilder.Marker letExpressionMarker = builder.mark(); //read the params and redirects boolean paramsAreFine = CommandParsingUtil.readCommandParams(builder, VALID_EXTRA_TOKENS); if (paramsAreFine) { letExpressionMarker.collapse(BashElementTypes.LET_LAZY_EXPRESSION); marker.done(LET_COMMAND); } else { letExpressionMarker.drop(); marker.drop(); builder.error("Expected an arithmetic expression"); } return true; } }
/** * Checks for version token and convert if necessary * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parsePerlVersion(PsiBuilder b, @SuppressWarnings("unused") int l) { if (VERSION_TOKENS.contains(b.getTokenType())) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(VERSION_ELEMENT); return true; } return false; }
private boolean readComposedValue(BashPsiBuilder builder) { PsiBuilder.Marker marker = builder.mark(); int count = 0; IElementType next = builder.getTokenType(true); while (validTokens.contains(next) || ParserUtil.isWordToken(next)) { builder.advanceLexer(); count++; next = builder.getTokenType(true); } if (count > 0) { marker.collapse(WORD); } else { marker.drop(); } return count > 0; }
private static boolean parseHas(PerlBuilder b, int l) { if (b.getTokenType() != RESERVED_HAS) { return false; } PerlBuilder.Marker m = b.mark(); PerlParserUtil.consumeToken(b, RESERVED_HAS); PerlBuilder.Marker wrapperMarker = b.mark(); if (PerlParserImpl.list_expr(b, l + 1)) { wrapperMarker.done(MOOSE_ATTRIBUTE_WRAPPER); m.done(MOOSE_HAS_EXPR); return true; } wrapperMarker.drop(); m.error("Incomplete has expression"); return true; }