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);
		}
Example #2
0
		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));
			}
		}
Example #4
0
		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;
		}
Example #6
0
		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;
		}