public ExpressionResult FindExpression(string text, int offset) { Init(text, offset); ExpressionFinder p = new ExpressionFinder(); lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(text)); Token t = lexer.NextToken(); // put all tokens in front of targetPosition into the EF-Parser while (t.EndLocation < targetPosition) { p.InformToken(t); t = lexer.NextToken(); } // put current token into EF-Parser if it cannot be continued (is simple operator) if (t.EndLocation == targetPosition && ((t.Kind <= Tokens.ColonAssign && t.Kind > Tokens.Identifier) || t.Kind == Tokens.EOL)) { p.InformToken(t); t = lexer.NextToken(); } // make sure semantic actions are executed p.Advance(); // remember current state, we'll use it to determine the context var block = p.CurrentBlock; ExpressionContext context = p.IsIdentifierExpected && !p.IsMissingModifier ? ExpressionContext.IdentifierExpected : GetContext(block); BitArray expectedSet; try { expectedSet = p.GetExpectedSet(); } catch (InvalidOperationException) { expectedSet = null; } // put current token into EF-Parser if (t.Location < targetPosition) { p.InformToken(t); } if (p.Errors.Any()) { foreach (var e in p.Errors) LoggingService.Warn("not expected: " + e); } if (p.NextTokenIsPotentialStartOfExpression) return new ExpressionResult("", new DomRegion(targetPosition.Line, targetPosition.Column), context, expectedSet); int lastExpressionStartOffset = LocationToOffset(p.CurrentBlock.lastExpressionStart); if (lastExpressionStartOffset < 0) return new ExpressionResult("", new DomRegion(targetPosition.Line, targetPosition.Column), context, expectedSet); return MakeResult(text, lastExpressionStartOffset, offset, context, expectedSet); }
public Lexer(TextReader reader, LexerMemento state) : base(reader, state) { if (!(state is VBLexerMemento)) throw new InvalidOperationException("state must be a VBLexerState"); var vbState = state as VBLexerMemento; ef = new ExpressionFinder(vbState.ExpressionFinder); lineEnd = vbState.LineEnd; isAtLineBegin = vbState.IsAtLineBegin; encounteredLineContinuation = vbState.EncounteredLineContinuation; misreadExclamationMarkAsTypeCharacter = vbState.MisreadExclamationMarkAsTypeCharacter; xmlModeStack = new Stack<XmlModeInfo>(vbState.XmlModeInfoStack.Select(i => (XmlModeInfo)i.Clone()).Reverse()); inXmlMode = vbState.InXmlMode; }
public ExpressionResult FindFullExpression(string text, int offset) { Init(text, offset); ExpressionFinder p = new ExpressionFinder(); lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(text)); Token t; Block block = Block.Default; var expressionDelimiters = new[] { Tokens.EOL, Tokens.Colon, Tokens.Dot, Tokens.TripleDot, Tokens.DotAt }; while (true) { t = lexer.NextToken(); p.InformToken(t); if (block == Block.Default && t.EndLocation > targetPosition) block = p.CurrentBlock; if (block != Block.Default && (block.isClosed || expressionDelimiters.Contains(t.Kind) && block == p.CurrentBlock)) break; if (t.Kind == Tokens.EOF) break; } if (p.Errors.Any()) { foreach (var e in p.Errors) LoggingService.Warn("not expected: " + e); } BitArray expectedSet; try { expectedSet = p.GetExpectedSet(); } catch (InvalidOperationException) { expectedSet = null; } int tokenOffset; if (t == null || t.Kind == Tokens.EOF) tokenOffset = text.Length; else tokenOffset = LocationToOffset(t.Location); int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart); if (lastExpressionStartOffset >= 0) { if (offset < tokenOffset) { // offset is in front of this token return MakeResult(text, lastExpressionStartOffset, tokenOffset, GetContext(block), expectedSet); } else { // offset is IN this token return MakeResult(text, lastExpressionStartOffset, offset, GetContext(block), expectedSet); } } else { return new ExpressionResult(null, GetContext(block)); } }
public Lexer(TextReader reader) : base(reader) { ef = new ExpressionFinder(); }
static int SmartIndentInternal(ITextEditor editor, int begin, int end) { ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(editor.Document.Text)); ExpressionFinder context = new ExpressionFinder(); Stack<string> indentation = new Stack<string>(); indentation.Push(string.Empty); List<int> eols = new List<int>(); bool inInterface = false; bool isMustOverride = false; bool isDeclare = false; bool isDelegate = false; Token currentToken = null; Token prevToken = null; int blockStart = 1; int lambdaNesting = 0; bool sawAttribute = false; while ((currentToken = lexer.NextToken()).Kind != Tokens.EOF) { if (context.InContext(Context.Attribute) && currentToken.Kind == Tokens.GreaterThan) sawAttribute = true; context.InformToken(currentToken); if (prevToken == null) prevToken = currentToken; if (currentToken.Kind == Tokens.MustOverride) isMustOverride = true; if (currentToken.Kind == Tokens.Delegate) isDelegate = true; if (currentToken.Kind == Tokens.Declare) isDeclare = true; if (currentToken.Kind == Tokens.EOL) { isDelegate = isDeclare = isMustOverride = sawAttribute = false; eols.Add(currentToken.Location.Line); } if (IsBlockEnd(currentToken, prevToken)) { // indent the lines inside the block // this is an End-statement // hence we indent from blockStart to the previous line int blockEnd = currentToken.Location.Line - 1; // if this is a lambda end include End-Statement in block // if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { // blockEnd++; // } ApplyToRange(editor, indentation, eols, blockStart, blockEnd, begin, end, sawAttribute); if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { Unindent(indentation); ApplyToRange(editor, indentation, eols, currentToken.Location.Line, currentToken.Location.Line, begin, end, sawAttribute); } if (currentToken.Kind == Tokens.Interface) inInterface = false; if (!inInterface && !isMustOverride && !isDeclare && !isDelegate) { Unindent(indentation); if (currentToken.Kind == Tokens.Select) Unindent(indentation); } // block start is this line (for the lines between two blocks) blockStart = currentToken.Location.Line; if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { blockStart++; lambdaNesting--; } } bool isMultiLineLambda; if (IsBlockStart(lexer, currentToken, prevToken, out isMultiLineLambda)) { // indent the lines between the last and this block // this is a Begin-statement // hence we indent from blockStart to the this line int lastVisualLine = FindNextEol(lexer); eols.Add(lastVisualLine); ApplyToRange(editor, indentation, eols, blockStart, lastVisualLine, begin, end, sawAttribute); if (isMultiLineLambda && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { lambdaNesting++; int endColumn = currentToken.Location.Column; int startColumn = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.GetLine(lastVisualLine).Offset).Length; if (startColumn < endColumn) Indent(editor, indentation, new string(' ', endColumn - startColumn - 1)); } if (!inInterface && !isMustOverride && !isDeclare && !isDelegate && !IsAutomaticPropertyWithDefaultValue(lexer, currentToken, prevToken)) { Indent(editor, indentation); if (currentToken.Kind == Tokens.Select) Indent(editor, indentation); } if (currentToken.Kind == Tokens.Interface) inInterface = true; // block start is the following line (for the lines inside a block) blockStart = lastVisualLine + 1; } prevToken = currentToken; } ApplyToRange(editor, indentation, eols, blockStart, editor.Document.TotalNumberOfLines, begin, end, sawAttribute); return (indentation.PeekOrDefault() ?? string.Empty).Length; }
void RunTest(string code, string expectedOutput) { ExpressionFinder p = new ExpressionFinder(); ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(code)); Token t; do { t = lexer.NextToken(); p.InformToken(t); } while (t.Kind != VBParser.Tokens.EOF); Console.WriteLine(p.Output); Assert.IsEmpty(p.Errors); Assert.AreEqual(expectedOutput, p.Output); }
static int GetArgumentIndex(ITextEditor editor) { ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, editor.Document.CreateReader()); ExpressionFinder ef = new ExpressionFinder(); Token t = lexer.NextToken(); while (t.Kind != Tokens.EOF && t.Location < editor.Caret.Position) { ef.InformToken(t); t = lexer.NextToken(); } return ef.ActiveArgument; }