private static bool NeedAutoinsertCloseBracket(CachingLexer lexer) { using (LexerStateCookie.Create(lexer)) { TokenNodeType typedToken = lexer.TokenType; // find the leftmost non-closed bracket (including typed) of typed class so that there are no opened brackets of other type var bracketMatcher = new PsiBracketMatcher(); TokenNodeType tokenType = typedToken; int leftParenthPos = lexer.CurrentPosition; do { if (tokenType == typedToken && bracketMatcher.IsStackEmpty()) { leftParenthPos = lexer.CurrentPosition; } else if (!bracketMatcher.ProceedStack(tokenType)) { break; } lexer.Advance(-1); } while ((tokenType = lexer.TokenType) != null); // Try to find the matched pair bracket lexer.CurrentPosition = leftParenthPos; return(!bracketMatcher.FindMatchingBracket(lexer)); } }
private TokenNodeType PreprocessInactiveBranch() { TokenNodeType tokenType; using (LexerStateCookie.Create(myLexer)) { while (myLexer.TokenType == FSharpTokenType.WHITESPACE) { myLexer.Advance(); } tokenType = myLexer.TokenType; } if (tokenType == FSharpTokenType.PP_IF_SECTION) { myState.InIfBlock(false, false); return(PreprocessInactiveLine()); } if (tokenType == FSharpTokenType.PP_ENDIF) { myState.FromIfBlock(); return(myState.Condition ? PreprocessLine() : PreprocessInactiveLine()); } if (tokenType == FSharpTokenType.PP_ELSE_SECTION) { myState.SwitchBranch(); return(myState.Condition ? PreprocessLine() : PreprocessInactiveLine()); } return(PreprocessInactiveLine()); }
// smart backspaces expecteed that GetExtraStub return not null value, "foo " is typical value protected override string GetExtraStub(CachingLexer lexer, int offset) { using (LexerStateCookie.Create(lexer)) { lexer.FindTokenAt(offset); if (!(lexer.TokenType is CppTokenNodeType)) { return("foo "); } } return(base.GetExtraStub(lexer, offset)); }
public override string CalculateInjectionIndent(CachingLexer lexer, ITextControl textControl) { var offset = textControl.Caret.DocumentOffset(); using (LexerStateCookie.Create(lexer)) { if (!lexer.FindTokenAt(offset.Offset)) { return(""); } var tt = lexer.TokenType; while (tt != null) { lexer.Advance(-1); tt = lexer.TokenType; if (tt == ShaderLabTokenType.CG_PROGRAM || tt == ShaderLabTokenType.CG_INCLUDE || tt == ShaderLabTokenType.HLSL_PROGRAM || tt == ShaderLabTokenType.HLSL_INCLUDE || tt == ShaderLabTokenType.GLSL_PROGRAM || tt == ShaderLabTokenType.GLSL_INCLUDE) { break; } } if (tt != null) { var doc = textControl.Document; var lineStart = doc.GetLineStartOffset(doc.GetCoordsByOffset(lexer.TokenStart).Line); lexer.FindTokenAt(lineStart); tt = lexer.TokenType; Assertion.AssertNotNull(tt, "Lexer.TokenType may not be null"); while (tt.IsWhitespace) { lexer.Advance(); tt = lexer.TokenType; } var tokenLineStart = doc.GetLineStartOffset(doc.GetCoordsByOffset(lexer.TokenStart).Line); return(doc.GetText(new TextRange(tokenLineStart, lexer.TokenStart))); } } return(""); }
public override TokenNodeType _locateToken() { var token = base._locateToken(); // The "unquoted string literal" inside a property attribute is both // delimited by parens, and can contain them, mismatched. We can't do // that solely with regex in the .lex file. Note that we can only get // this while in PARENS lexical state, so we have had an LPAREN if (token == ShaderLabTokenType.UNQUOTED_STRING_LITERAL) { var unquotedStringLiteralStart = BufferStart; var lastNonWhitespaceCookie = LexerStateCookie.Create(this); LexerStateCookie.Common?beforeLastRParenCookie = null; LexerStateCookie.Common?beforeCommaCookie = null; do { // Get the next token. This will update TokenStart and TokenEnd var nextToken = base._locateToken(); // BAD_CHARACTER is a hard delimiter for unquoted string literal. // Roll back, avoiding trailing whitespace if (nextToken == ShaderLabTokenType.BAD_CHARACTER) { lastNonWhitespaceCookie.Dispose(); BufferStart = unquotedStringLiteralStart; return(token); } // COMMA should be a hard delimiter, but it messes up checking for the // last RPAREN. E.g. `[Header(something), foo]` should roll back to // beforeLastRParenCookie, while `[Header(something, whatever)]` should // roll back to beforeCommaCookie if (nextToken == ShaderLabTokenType.COMMA) { if (beforeCommaCookie.HasValue) { beforeCommaCookie.Value.Dispose(); BufferStart = unquotedStringLiteralStart; return(token); } beforeCommaCookie = lastNonWhitespaceCookie; } // This RPAREN might be part of the unquoted string literal, or it // might be the last RPAREN in the attribute. If we've seen a comma // before this, this RPAREN is likely the end of the attribute, but // the unquoted string literal ends at the COMMA, so roll back there if (nextToken == ShaderLabTokenType.RPAREN) { if (beforeCommaCookie.HasValue) { beforeCommaCookie.Value.Dispose(); BufferStart = unquotedStringLiteralStart; return(token); } beforeLastRParenCookie = lastNonWhitespaceCookie; } // Found the end of the attribute, roll back to the last RPAREN if // there is one, else to the last non-whitespace token. Also, switch // to BRACKETS (we're not consuming RBRACK, or whatever followed the // final RPAREN right now) if (nextToken == ShaderLabTokenType.RBRACK || nextToken == ShaderLabTokenType.NEW_LINE) { if (beforeLastRParenCookie.HasValue) { beforeLastRParenCookie.Value.Dispose(); SetState(PARENS); } else { lastNonWhitespaceCookie.Dispose(); } BufferStart = unquotedStringLiteralStart; return(token); } // Track the last bit of non-whitespace if (nextToken != ShaderLabTokenType.WHITESPACE) { lastNonWhitespaceCookie = LexerStateCookie.Create(this); } } while (BufferEnd < EOFPos); } return(token); }
private TokenNodeType PreprocessIfSection() { using (LexerStateCookie.Create(myLexer)) myState.InIfBlock(myPreprocessor.Preprocess(myLexer, myDefinedConstants), true); return(PreprocessLine()); }