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, IDENTIFIER)) { subMarker.collapse(SUB); PerlParserImpl.method_signature(b, l); if (PerlParserUtil.consumeToken(b, MASON_TAG_CLOSER)) { PsiBuilder.Marker blockMarker = b.mark(); PerlParserImpl.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 || recoverToGreedy(b, closeToken, "Error"); }
/** * Checks for version token and convert if necessary * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parsePerlVersion(PsiBuilder b, int l) { if (b.getTokenType() == NUMBER_VERSION) return consumeToken(b, NUMBER_VERSION); else if (VERSION_TOKENS.contains(b.getTokenType())) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(NUMBER_VERSION); return true; } return false; }
/** * Checks and parses pragma to package token * * @param b PerlBuilder * @param l parsing level * @param sourceTokenType source token type * @param targetTokenType token type to collapse to * @return result */ public static boolean checkAndCollapseToken( PsiBuilder b, int l, IElementType sourceTokenType, IElementType targetTokenType) { if (b.getTokenType() == sourceTokenType) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(targetTokenType); return true; } return false; }
/** * Parsing label declaration LABEL: * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parseLabelDeclaration(PsiBuilder b, int l) { if (CONVERTABLE_TOKENS.contains(b.getTokenType()) && b.lookAhead(1) == COLON) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(LABEL); b.advanceLexer(); return true; } return false; }
/** * Joining several regex tokens into one to lighten PSI tree. Temporary solution, until regex * parsing is implemented * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean joinRegexTokens(PsiBuilder b, int l) { if (b.getTokenType() == REGEX_TOKEN) { PsiBuilder.Marker m = b.mark(); while (b.getTokenType() == REGEX_TOKEN) b.advanceLexer(); m.collapse(REGEX_TOKEN); return true; } return false; }
public static boolean convertBracedString(PsiBuilder b, int l) { if (CONVERTABLE_TOKENS.contains(b.getTokenType()) && b.lookAhead(1) == RIGHT_BRACE) { // fixme shouldn't we add string_sq here? PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(STRING_CONTENT); return true; } return false; }
// @todo this is really raw public static boolean parseVariableAttributes(PsiBuilder b, int l) { PsiBuilder.Marker m = null; while (!b.eof() && !VARIABLE_ATTRIBUTE_STOP_TOKENS.contains(b.getTokenType())) { if (m == null) m = b.mark(); b.advanceLexer(); } if (m != null) m.collapse(VAR_ATTRIBUTE); return true; }
/** * Checks and parses bareword filehandle for <FH> operations * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parseReadHandle(PsiBuilder b, int l) { IElementType currentTokenType = b.getTokenType(); IElementType nextTokenType = b.lookAhead(1); if (CONVERTABLE_TOKENS.contains(currentTokenType) && nextTokenType == OPERATOR_GT_NUMERIC) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(HANDLE); return true; } return false; }
/** * Merges sequence [package] identifier to a package * * @param b PerlBuilder * @param l parsing level * @return result */ public static boolean mergePackageName(PsiBuilder b, int l) { IElementType tokenType = b.getTokenType(); if (tokenType == PACKAGE) { b.advanceLexer(); return true; } else if (PACKAGE_TOKENS.contains(tokenType) && CONVERTABLE_TOKENS.contains(b.lookAhead(1))) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); b.advanceLexer(); m.collapse(PACKAGE); return true; } else if (PACKAGE_TOKENS.contains(tokenType) // explicit package name, like Foo::->method() || CONVERTABLE_TOKENS.contains(tokenType) // single word package ) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(PACKAGE); return true; } return false; }
/** * Completes namespace, invoked when we are 100% sure that PACKAGE_IDENTIFIER is a package * * @param b Perlbuilder * @param l parsing level * @return parsing result */ public static boolean convertPackageIdentifier(PsiBuilder b, int l) { IElementType currentTokenType = b.getTokenType(); if (currentTokenType == PACKAGE) { b.advanceLexer(); return true; } else if (PACKAGE_TOKENS.contains(currentTokenType)) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(PACKAGE); return true; } return false; }
/** * Replaces identifier as a variable name * * @param b Perlbuilder * @param l parsing level * @return parsing result */ public static boolean convertIdentifier(PsiBuilder b, int l, IElementType tokenType) { IElementType currentTokenType = b.getTokenType(); if (currentTokenType == tokenType) { b.advanceLexer(); return true; } else if (CONVERTABLE_TOKENS.contains(currentTokenType)) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(tokenType); return true; } return false; }
public static boolean parseSubPrototype(PsiBuilder b, int l) { PsiBuilder.Marker m = null; IElementType tokenType = b.getTokenType(); while (!b.eof() && (tokenType != RIGHT_PAREN)) { if (m == null) m = b.mark(); b.advanceLexer(); tokenType = b.getTokenType(); } if (m != null) m.collapse(SUB_PROTOTYPE_TOKEN); return true; }
// @todo this is really raw public static boolean parseSubAttributes(PsiBuilder b, int l) { PsiBuilder.Marker m = null; IElementType tokenType = b.getTokenType(); while (!b.eof() && tokenType != LEFT_BRACE && tokenType != SEMICOLON && tokenType != EMBED_MARKER_SEMICOLON) { if (m == null) m = b.mark(); b.advanceLexer(); tokenType = b.getTokenType(); } if (m != null) m.collapse(SUB_ATTRIBUTE); return true; }
private static void advanceGtToken(final PsiBuilder builder, final IElementType type) { final PsiBuilder.Marker gtToken = builder.mark(); if (type == JavaTokenType.GTGTGTEQ) { PsiBuilderUtil.advance(builder, 4); } else if (type == JavaTokenType.GTGTGT || type == JavaTokenType.GTGTEQ) { PsiBuilderUtil.advance(builder, 3); } else if (type == JavaTokenType.GTGT || type == JavaTokenType.GE) { PsiBuilderUtil.advance(builder, 2); } else { gtToken.drop(); builder.advanceLexer(); return; } gtToken.collapse(type); }
/** * parser for print/say/printf filehandle * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parsePrintHandle(PsiBuilder b, int l) { IElementType currentTokenType = b.getTokenType(); IElementType nextTokenType = b.lookAhead(1); assert b instanceof PerlBuilder; if (CONVERTABLE_TOKENS.contains(currentTokenType) // it's identifier && !PRINT_HANDLE_NEGATE_SUFFIX.contains(nextTokenType) // no negation tokens && !PerlSubUtil.BUILT_IN.contains( b.getTokenText()) // it's not built in. crude, probably we should check any known sub ) { PsiBuilder.Marker m = b.mark(); b.advanceLexer(); m.collapse(HANDLE); return true; } return false; }
@Override public boolean parseStatement(PsiBuilder b, int l) { IElementType tokenType = b.getTokenType(); boolean r = false; PsiBuilder.Marker m = b.mark(); if (tokenType == MASON_BLOCK_OPENER) { PsiBuilder.Marker statementMarker = b.mark(); b.advanceLexer(); if (PerlParserImpl.expr(b, l, -1)) { // parseStatement filter if (PerlParserUtil.consumeToken(b, MASON_EXPR_FILTER_PIPE)) { while (b.getTokenType() == IDENTIFIER) { PsiBuilder.Marker fm = b.mark(); b.advanceLexer(); fm.collapse(SUB); fm.precede().done(METHOD); if (!PerlParserUtil.consumeToken(b, OPERATOR_COMMA)) { break; } } } } if (r = endOrRecover(b, MASON_BLOCK_CLOSER)) { statementMarker.done(STATEMENT); } } if (tokenType == MASON_CALL_OPENER) { PsiBuilder.Marker statementMarker = b.mark(); b.advanceLexer(); PerlParserImpl.expr(b, l, -1); if (r = endOrRecover(b, MASON_CALL_CLOSER)) { statementMarker.done(MASON_CALL_STATEMENT); } } else if (tokenType == MASON_CLASS_OPENER) { r = parsePerlBlock(b, l, MASON_CLASS_CLOSER); } else if (tokenType == MASON_INIT_OPENER) { r = parsePerlBlock(b, l, MASON_INIT_CLOSER); } else if (tokenType == MASON_PERL_OPENER) { r = parsePerlBlock(b, l, MASON_PERL_CLOSER); } else if (tokenType == MASON_FLAGS_OPENER) { b.advanceLexer(); PsiBuilder.Marker statementMarker = b.mark(); while (!b.eof() && b.getTokenType() != MASON_FLAGS_CLOSER) { if (!PerlParserImpl.expr(b, l, -1)) { break; } } statementMarker.done(MASON_FLAGS_STATEMENT); r = endOrRecover(b, MASON_FLAGS_CLOSER); } else if (tokenType == MASON_DOC_OPENER) { b.advanceLexer(); PerlParserUtil.consumeToken(b, COMMENT_BLOCK); r = endOrRecover(b, MASON_DOC_CLOSER); } else if (tokenType == MASON_TEXT_OPENER) { b.advanceLexer(); PsiBuilder.Marker stringMarker = b.mark(); if (PerlParserUtil.consumeToken(b, STRING_CONTENT)) { stringMarker.done(MASON_TEXT_BLOCK); } else { stringMarker.drop(); } r = endOrRecover(b, MASON_TEXT_CLOSER); } else if (tokenType == MASON_METHOD_OPENER) { r = parseMasonMethod(b, l, MASON_METHOD_CLOSER, MASON_METHOD_DEFINITION); } else if (tokenType == MASON_FILTER_OPENER) { r = parseMasonMethod(b, l, MASON_FILTER_CLOSER, MASON_FILTER_DEFINITION); } else if (tokenType == MASON_OVERRIDE_OPENER) { r = parseMasonMethod(b, l, MASON_OVERRIDE_CLOSER, MASON_OVERRIDE_DEFINITION); } else if (SIMPLE_MASON_NAMED_BLOCKS.contains(tokenType)) // simple named blocks { PsiBuilder.Marker statementMarker = b.mark(); b.advanceLexer(); IElementType closeToken = RESERVED_OPENER_TO_CLOSER_MAP.get(tokenType); if (PerlParserUtil.convertIdentifier(b, l, MASON_METHOD_MODIFIER_NAME)) { if (PerlParserUtil.consumeToken(b, MASON_TAG_CLOSER)) { PsiBuilder.Marker blockMarker = b.mark(); PerlParserImpl.block_content(b, l); blockMarker.done(BLOCK); blockMarker.setCustomEdgeTokenBinders( WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER); if (r = PerlParserUtil.consumeToken(b, closeToken)) { statementMarker.done(RESERVED_TO_STATEMENT_MAP.get(tokenType)); statementMarker = null; } } } if (statementMarker != null) { statementMarker.drop(); } r = r || recoverToGreedy(b, closeToken, "Error"); } if (r) { m.drop(); } else { m.rollbackTo(); } return r || super.parseStatement(b, l); }
public static void collapse( @NotNull final PsiBuilder.Marker marker, @NotNull final IElementType elementType) { marker.collapse(elementType); }
/** * Parses tokens as variables name; replaces: * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parseVariableName(PsiBuilder b, int l) { IElementType currentTokenType = b.getTokenType(); IElementType nextTokenType = b.rawLookup(1); PsiBuilder.Marker m; // while (currentTokenType == SIGIL_SCALAR // sigil is here // && POST_SIGILS_SUFFIXES.contains(nextTokenType) // next can be variable name // ) // { // if (m == null) // m = b.mark(); // b.advanceLexer(); // currentTokenType = nextTokenType; // nextTokenType = b.rawLookup(1); // } // // if (m != null) // m.collapse(SCALAR_SIGILS); // checking for scalar cast if (currentTokenType == SIGIL_SCALAR && POST_SIGILS_SUFFIXES.contains(b.lookAhead(1))) return false; // $package:: // $package::var if (PACKAGE_TOKENS.contains(currentTokenType)) { PsiBuilder.Marker mp = b.mark(); b.advanceLexer(); mp.collapse(PACKAGE); if (CONVERTABLE_TOKENS.contains(nextTokenType)) { PsiBuilder.Marker mv = b.mark(); b.advanceLexer(); mv.collapse(VARIABLE_NAME); } return true; } // $var else if (POSSIBLE_VARIABLE_NAME.contains(currentTokenType)) { if (currentTokenType == OPERATOR_BITWISE_XOR && CONTROL_VARIABLE_NAMES.contains(nextTokenType)) // branch for $^] { m = b.mark(); b.advanceLexer(); b.advanceLexer(); m.collapse(VARIABLE_NAME); } else { PsiBuilder.Marker mv = b.mark(); b.advanceLexer(); mv.collapse(VARIABLE_NAME); } return true; } // ${var} else if (currentTokenType == LEFT_BRACE) { b.advanceLexer(); currentTokenType = nextTokenType; nextTokenType = b.lookAhead(1); // ${package::} // ${package::var} if (PACKAGE_TOKENS.contains(currentTokenType)) { PsiBuilder.Marker mp = b.mark(); b.advanceLexer(); mp.collapse(PACKAGE); if (CONVERTABLE_TOKENS.contains(nextTokenType) && b.lookAhead(1) == RIGHT_BRACE) { PsiBuilder.Marker mv = b.mark(); b.advanceLexer(); mv.collapse(VARIABLE_NAME); b.advanceLexer(); return true; } else if (nextTokenType == RIGHT_BRACE) { b.advanceLexer(); return true; } } // ${var} else if (POSSIBLE_VARIABLE_NAME.contains(currentTokenType) && nextTokenType == RIGHT_BRACE) { PsiBuilder.Marker mv = b.mark(); b.advanceLexer(); mv.collapse(VARIABLE_NAME); b.advanceLexer(); return true; } } return false; }