public IEnumerable<SnippetCompletion> EnumSnippets(
		SymbolDefinition context,
		FGGrammar.TokenSet expectedTokens,
		SyntaxToken tokenLeft,
		Scope scope)
	{
		if (scope == null)
			yield break;
		
		var bodyScope = scope as BodyScope ?? scope.parentScope as BodyScope;
		if (bodyScope == null)
			yield break;
		
		var contextType = bodyScope.definition as TypeDefinitionBase;
		if (contextType == null || contextType.kind != SymbolKind.Class && contextType.kind != SymbolKind.Struct)
			yield break;
		
		context = contextType;
		
		if (tokenLeft == null || tokenLeft.parent == null || tokenLeft.parent.parent == null)
			yield break;
		
		if (tokenLeft.tokenKind != SyntaxToken.Kind.Punctuator)
			yield break;
		
		if (tokenLeft.text != "{" && tokenLeft.text != "}" && tokenLeft.text != ";")
			yield break;
		
		for (var i = contextType.members.Count; i --> 0; )
		{
			var member = contextType.members[i];
			if (member.kind == SymbolKind.Field)
			{
				var type = member.TypeOf();
				if (type == null || type.kind == SymbolKind.Error || !(type is TypeDefinitionBase))
					continue;
				
				var fieldName = member.name;
				if (string.IsNullOrEmpty(fieldName) || fieldName[0] == '.')
					continue;
				
				fieldName = char.ToUpperInvariant(fieldName[0]) + fieldName.Substring(1);
				var propertyName = fieldName;
				for (var suffix = 1; contextType.members.Contains(propertyName, -1); ++suffix)
					propertyName = fieldName + suffix.ToString();
				
				yield return new MyCompletion(propertyName, member, true);// "{0} {{ get {{...}} set {{...}} }}");
				yield return new MyCompletion(propertyName, member, false);// "{0} {{ get {{...}} }}");
			}
		}
	}
	public IEnumerable<SnippetCompletion> EnumSnippets(
		SymbolDefinition context,
		FGGrammar.TokenSet expectedTokens,
		SyntaxToken tokenLeft,
		Scope scope)
	{
		OverrideMethod.context = scope;
		
		if (tokenLeft == null || tokenLeft.parent == null || tokenLeft.parent.parent == null)
			yield break;
		
		if (tokenLeft.tokenKind != SyntaxToken.Kind.Keyword)
			yield break;
		
		if (tokenLeft.text != "override")
			yield break;
		
		var bodyScope = scope as BodyScope;
		if (bodyScope == null)
			yield break;
		
		var contextType = bodyScope.definition as TypeDefinitionBase;
		if (contextType == null || contextType.kind != SymbolKind.Class && contextType.kind != SymbolKind.Struct)
			yield break;
		
		var baseType = contextType.BaseType();
		if (baseType == null || baseType.kind != SymbolKind.Class && baseType.kind != SymbolKind.Struct)
			yield break;
		
		var overrideMethodCandidates = new List<MethodDefinition>();
		baseType.ListOverrideCandidates(overrideMethodCandidates, contextType.Assembly);
		if (overrideMethodCandidates.Count == 0)
			yield break;
		
		var textBuffer = FGTextBuffer.activeEditor.TextBuffer;
		var firstToken = tokenLeft.parent.parent.GetFirstLeaf().token;
		if (firstToken.formatedLine != tokenLeft.formatedLine)
		{
			firstToken = tokenLeft.formatedLine.tokens[0];
			while (firstToken.tokenKind <= SyntaxToken.Kind.LastWSToken)
				firstToken = firstToken.formatedLine.tokens[firstToken.TokenIndex + 1];
		}
		var tokenSpan = textBuffer.GetTokenSpan(firstToken.parent);
		OverrideMethod.overrideTextLength = FGTextBuffer.activeEditor.caretPosition.characterIndex - tokenSpan.StartPosition.index;
		
		foreach (var method in overrideMethodCandidates)
		{
			var methodGroup = contextType.FindName(method.name, -1, false) as MethodGroupDefinition;
			if (methodGroup != null)
			{
				bool skipThis = false;
				var signature = method.PrintParameters(method.GetParameters(), true);
				foreach (var m in methodGroup.methods)
				{
					if (method.NumTypeParameters == m.NumTypeParameters &&
						signature == m.PrintParameters(m.GetParameters()))
					{
						skipThis = true;
						break;
					}
				}
				if (skipThis)
					continue;
			}
			
			var overrideCompletion = new OverrideMethod(method);
			yield return overrideCompletion;
		}
	}
Esempio n. 3
0
	private new SyntaxToken ScanIdentifierOrKeyword(string line, ref int startAt)
	{
		bool identifier = false;
		int i = startAt;
		if (i >= line.Length)
			return null;
		
		char c = line[i];

		if (!char.IsLetter(c) && c != '_')
			return null;	
		++i;

		while (i < line.Length)
		{
			if (char.IsLetterOrDigit(line, i) || line[i] == '_')
				++i;
			else
				break;
		}
		
		var word = line.Substring(startAt, i - startAt);
		startAt = i;
		var token = new SyntaxToken(identifier ? SyntaxToken.Kind.Identifier : SyntaxToken.Kind.Keyword, word);
		
		if (token.tokenKind == SyntaxToken.Kind.Keyword && !IsKeyword(token.text) && !IsBuiltInType(token.text))
			token.tokenKind = SyntaxToken.Kind.Identifier;
		return token;
	}
Esempio n. 4
0
	protected override void Tokenize(string line, FGTextBuffer.FormatedLine formatedLine)
	{
		var tokens = new List<SyntaxToken>();
		formatedLine.tokens = tokens;

		int startAt = 0;
		int length = line.Length;
		SyntaxToken token;

		SyntaxToken ws = ScanWhitespace(line, ref startAt);
		if (ws != null)
		{
			tokens.Add(ws);
			ws.formatedLine = formatedLine;
		}

		var inactiveLine = formatedLine.regionTree.kind > FGTextBuffer.RegionTree.Kind.LastActive;
		
		while (startAt < length)
		{
			switch (formatedLine.blockState)
			{
				case FGTextBuffer.BlockState.None:
					ws = ScanWhitespace(line, ref startAt);
					if (ws != null)
					{
						tokens.Add(ws);
						ws.formatedLine = formatedLine;
						continue;
					}
					
					if (inactiveLine)
					{
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
						startAt = length;
						break;
					}

					if (line[startAt] == '#')
					{
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, "#") { formatedLine = formatedLine });
						++startAt;
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
						startAt = length;
						break;
					}
					
					if (line[startAt] == '/' && startAt < length - 1)
					{
						if (line[startAt + 1] == '/')
						{
							tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, "//") { formatedLine = formatedLine });
							startAt += 2;
							tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
							startAt = length;
							break;
						}
						else if (line[startAt + 1] == '*')
						{
							tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, "/*") { formatedLine = formatedLine });
							startAt += 2;
							formatedLine.blockState = FGTextBuffer.BlockState.CommentBlock;
							break;
						}
					}

					if (line[startAt] == '\'')
					{
						token = ScanCharLiteral(line, ref startAt);
						tokens.Add(token);
						token.formatedLine = formatedLine;
						break;
					}

					if (line[startAt] == '\"')
					{
						if (startAt < length - 2 && line[startAt + 1] == '\"' && line[startAt + 2] == '\"')
						{
							token = new SyntaxToken(SyntaxToken.Kind.VerbatimStringBegin, line.Substring(startAt, 3)) { formatedLine = formatedLine };
							tokens.Add(token);
							startAt += 3;
							formatedLine.blockState = FGTextBuffer.BlockState.StringBlock;
							break;
						}
	
						token = ScanStringLiteral(line, ref startAt);
						tokens.Add(token);
						token.formatedLine = formatedLine;
						break;
					}

					if (line[startAt] >= '0' && line[startAt] <= '9'
					    || startAt < length - 1 && line[startAt] == '.' && line[startAt + 1] >= '0' && line[startAt + 1] <= '9')
					{
						token = ScanNumericLiteral_JS(line, ref startAt);
						tokens.Add(token);
						token.formatedLine = formatedLine;
						break;
					}

					token = ScanIdentifierOrKeyword(line, ref startAt);
					if (token != null)
					{
						tokens.Add(token);
						token.formatedLine = formatedLine;
						break;
					}

					// Multi-character operators / punctuators
					// "++", "--", "<<", ">>", "<=", ">=", "==", "!=", "&&", "||", "??", "+=", "-=", "*=", "/=", "%=",
					// "&=", "|=", "^=", "<<=", ">>=", "=>", "::", "->", "^="
					var punctuatorStart = startAt++;
					if (startAt < line.Length)
					{
						switch (line[punctuatorStart])
						{
							case '?':
								if (line[startAt] == '?')
									++startAt;
								break;
							case '+':
								if (line[startAt] == '+' || line[startAt] == '=' || line[startAt] == '>')
									++startAt;
								break;
							case '-':
								if (line[startAt] == '-' || line[startAt] == '=')
									++startAt;
								break;
							case '<':
								if (line[startAt] == '=')
									++startAt;
								else if (line[startAt] == '<')
								{
									++startAt;
									if (startAt < line.Length && line[startAt] == '=')
										++startAt;
								}
								break;
							case '>':
								if (line[startAt] == '=')
									++startAt;
								else if (startAt < line.Length && line[startAt] == '>')
								{
									++startAt;
									if (line[startAt] == '=')
										++startAt;
								}
								break;
							case '=':
								if (line[startAt] == '=' || line[startAt] == '>')
									++startAt;
								break;
							case '&':
								if (line[startAt] == '=' || line[startAt] == '&')
									++startAt;
								break;
							case '|':
								if (line[startAt] == '=' || line[startAt] == '|')
									++startAt;
								break;
							case '*':
							case '/':
							case '%':
							case '^':
							case '!':
								if (line[startAt] == '=')
									++startAt;
								break;
							case ':':
								if (line[startAt] == ':')
									++startAt;
								break;
						}
					}
					tokens.Add(new SyntaxToken(SyntaxToken.Kind.Punctuator, line.Substring(punctuatorStart, startAt - punctuatorStart)) { formatedLine = formatedLine });
					break;

				case FGTextBuffer.BlockState.CommentBlock:
					int commentBlockEnd = line.IndexOf("*/", startAt, StringComparison.Ordinal);
					if (commentBlockEnd == -1)
					{
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
						startAt = length;
					}
					else
					{
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt, commentBlockEnd + 2 - startAt)) { formatedLine = formatedLine });
						startAt = commentBlockEnd + 2;
						formatedLine.blockState = FGTextBuffer.BlockState.None;
					}
					break;

				case FGTextBuffer.BlockState.StringBlock:
					int i = startAt;
					int closingQuote = line.IndexOf('\"', startAt);
					while (closingQuote != -1 && closingQuote < length - 2 &&
						(line[closingQuote + 1] != '\"' || line[closingQuote + 2] != '\"'))
					{
						i = closingQuote + 2;
						closingQuote = line.IndexOf('\"', i);
					}
					if (closingQuote == -1)
					{
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.VerbatimStringLiteral, line.Substring(startAt)) { formatedLine = formatedLine });
						startAt = length;
					}
					else
					{
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.VerbatimStringLiteral, line.Substring(startAt, closingQuote - startAt)) { formatedLine = formatedLine });
						startAt = closingQuote;
						tokens.Add(new SyntaxToken(SyntaxToken.Kind.VerbatimStringLiteral, line.Substring(startAt, 3)) { formatedLine = formatedLine });
						startAt += 3;
						formatedLine.blockState = FGTextBuffer.BlockState.None;
					}
					break;
			}
		}
	}
Esempio n. 5
0
	protected static SyntaxToken ScanNumericLiteral_JS(string line, ref int startAt)
	{
		bool hex = false;
		bool point = false;
		bool exponent = false;
		var i = startAt;

		SyntaxToken token;

		char c;
		if (line[i] == '0' && i < line.Length - 1 && (line[i + 1] == 'x'))
		{
			i += 2;
			hex = true;
			while (i < line.Length)
			{
				c = line[i];
				if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F')
					++i;
				else
					break;
			}
		}
		else
		{
			while (i < line.Length && line[i] >= '0' && line[i] <= '9')
				++i;
		}

		if (i > startAt && i < line.Length)
		{
			c = line[i];
			if (c == 'l' || c == 'L')
			{
				++i;
				token = new SyntaxToken(SyntaxToken.Kind.IntegerLiteral, line.Substring(startAt, i - startAt));
				startAt = i;
				return token;
			}
		}

		if (hex)
		{
			token = new SyntaxToken(SyntaxToken.Kind.IntegerLiteral, line.Substring(startAt, i - startAt));
			startAt = i;
			return token;
		}

		while (i < line.Length)
		{
			c = line[i];

			if (!point && !exponent && c == '.')
			{
				if (i < line.Length - 1 && line[i+1] >= '0' && line[i+1] <= '9')
				{
					point = true;
					++i;
					continue;
				}
				else
				{
					break;
				}
			}
			if (!exponent && i > startAt && (c == 'e' || c == 'E'))
			{
				exponent = true;
				++i;
				if (i < line.Length && (line[i] == '-' || line[i] == '+'))
					++i;
				continue;
			}
			if (c == 'f' || c == 'F' || c == 'd' || c == 'D')
			{
				point = true;
				++i;
				break;
			}
			if (c < '0' || c > '9')
				break;
			++i;
		}
		token = new SyntaxToken(
			point || exponent ? SyntaxToken.Kind.RealLiteral : SyntaxToken.Kind.IntegerLiteral,
			line.Substring(startAt, i - startAt));
		startAt = i;
		return token;
	}
Esempio n. 6
0
	protected static SyntaxToken ScanStringLiteral(string line, ref int startAt)
	{
		var i = startAt + 1;
		while (i < line.Length)
		{
			if (line[i] == '\"')
			{
				++i;
				break;
			}
			if (line[i] == '\\' && i < line.Length - 1)
				++i;
			++i;
		}
		var token = new SyntaxToken(SyntaxToken.Kind.StringLiteral, line.Substring(startAt, i - startAt));
		startAt = i;
		return token;
	}
Esempio n. 7
0
	protected static SyntaxToken ScanWord(string line, ref int startAt)
	{
		int i = startAt;
		while (i < line.Length)
		{
			if (!Char.IsLetterOrDigit(line, i) && line[i] != '_')
				break;
			++i;
		}
		var token = new SyntaxToken(SyntaxToken.Kind.Identifier, line.Substring(startAt, i - startAt));
		startAt = i;
		return token;
	}
Esempio n. 8
0
	protected static SyntaxToken ScanWhitespace(string line, ref int startAt)
	{
		int i = startAt;
		while (i < line.Length && (line[i] == ' ' || line[i] == '\t'))
			++i;
		if (i == startAt)
			return null;

		var token = new SyntaxToken(SyntaxToken.Kind.Whitespace, line.Substring(startAt, i - startAt));
		startAt = i;
		return token;
	}
Esempio n. 9
0
	public static IEnumerable<SnippetCompletion> EnumSnippets(SymbolDefinition context, FGGrammar.TokenSet expected, SyntaxToken tokenLeft, Scope scope)
	{
		foreach (var snippet in snippets)
		{
			var text = snippet.Value;
			if (IsValid(ref text, context, expected))
				yield return new SnippetCompletion(snippet.Key + "...");
		}
		
		if (snippetsProviders == null)
		{
			snippetsProviders = new List<ISnippetProvider>();
			var types = typeof(CodeSnippets).Assembly.GetTypes();
			foreach (var type in types)
				if (typeof(ISnippetProvider).IsAssignableFrom(type) && type.IsClass && !type.IsAbstract)
					try
					{
						var instance = System.Activator.CreateInstance(type) as ISnippetProvider;
						snippetsProviders.Add(instance);
					}
					catch (System.Exception e)
					{
						Debug.LogException(e);
					}
				
		}
		
		foreach (var snippetsProvider in snippetsProviders)
		{
			foreach (var snippet in snippetsProvider.EnumSnippets(context, expected, tokenLeft, scope))
				yield return snippet;
		}
	}
Esempio n. 10
0
        protected override void Tokenize(string line, FGTextBuffer.FormatedLine formatedLine)
        {
            var tokens = new List<SyntaxToken>();
            formatedLine.tokens = tokens;

            int startAt = 0;
            int length = line.Length;
            SyntaxToken token;

            SyntaxToken ws = ScanWhitespace(line, ref startAt);
            if (ws != null)
            {
            tokens.Add(ws);
            ws.formatedLine = formatedLine;
            }

            if (formatedLine.blockState == FGTextBuffer.BlockState.None && startAt < length && line[startAt] == '#')
            {
            tokens.Add(new SyntaxToken(SyntaxToken.Kind.Preprocessor, "#") { formatedLine = formatedLine });
            ++startAt;

            ws = ScanWhitespace(line, ref startAt);
            if (ws != null)
            {
                tokens.Add(ws);
                ws.formatedLine = formatedLine;
            }

            var error = false;
            var commentsOnly = false;
            var preprocessorCommentsAllowed = true;

            token = ScanWord(line, ref startAt);
            if (Array.BinarySearch(preprocessorKeywords, token.text) < 0)
            {
                token.tokenKind = SyntaxToken.Kind.PreprocessorDirectiveExpected;
                tokens.Add(token);
                token.formatedLine = formatedLine;

                error = true;
            }
            else
            {
                token.tokenKind = SyntaxToken.Kind.Preprocessor;
                tokens.Add(token);
                token.formatedLine = formatedLine;

                ws = ScanWhitespace(line, ref startAt);
                if (ws != null)
                {
                    tokens.Add(ws);
                    ws.formatedLine = formatedLine;
                }

                if (token.text == "if")
                {
                    bool active = ParsePPOrExpression(line, formatedLine, ref startAt);
                    bool inactiveParent = formatedLine.regionTree.kind > FGTextBuffer.RegionTree.Kind.LastActive;
                    if (active && !inactiveParent)
                    {
                        OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.If);
                        commentsOnly = true;
                    }
                    else
                    {
                        OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.InactiveIf);
                        commentsOnly = true;
                    }
                }
                else if (token.text == "elif")
                {
                    bool active = ParsePPOrExpression(line, formatedLine, ref startAt);
                    bool inactiveParent = formatedLine.regionTree.kind > FGTextBuffer.RegionTree.Kind.LastActive;
                    if (formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.If ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.Elif ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveElif)
                    {
                        OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.InactiveElif);
                    }
                    else if (formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveIf)
                    {
                        inactiveParent = formatedLine.regionTree.parent.kind > FGTextBuffer.RegionTree.Kind.LastActive;
                        if (active && !inactiveParent)
                        {
                            OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.Elif);
                        }
                        else
                        {
                            OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.InactiveElif);
                        }
                    }
                    else
                    {
                        token.tokenKind = SyntaxToken.Kind.PreprocessorUnexpectedDirective;
                    }
                }
                else if (token.text == "else")
                {
                    if (formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.If ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.Elif)
                    {
                        OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.InactiveElse);
                    }
                    else if (formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveIf ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveElif)
                    {
                        bool inactiveParent = formatedLine.regionTree.parent.kind > FGTextBuffer.RegionTree.Kind.LastActive;
                        if (inactiveParent)
                            OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.InactiveElse);
                        else
                            OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.Else);
                    }
                    else
                    {
                        token.tokenKind = SyntaxToken.Kind.PreprocessorUnexpectedDirective;
                    }
                }
                else if (token.text == "endif")
                {
                    if (formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.If ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.Elif ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.Else ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveIf ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveElif ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveElse)
                    {
                        CloseRegion(formatedLine);
                    }
                    else
                    {
                        token.tokenKind = SyntaxToken.Kind.PreprocessorUnexpectedDirective;
                    }
                }
                else if (token.text == "region")
                {
                    var inactive = formatedLine.regionTree.kind > FGTextBuffer.RegionTree.Kind.LastActive;
                    if (inactive)
                    {
                        OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.InactiveRegion);
                    }
                    else
                    {
                        OpenRegion(formatedLine, FGTextBuffer.RegionTree.Kind.Region);
                    }
                    preprocessorCommentsAllowed = false;
                }
                else if (token.text == "endregion")
                {
                    if (formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.Region ||
                        formatedLine.regionTree.kind == FGTextBuffer.RegionTree.Kind.InactiveRegion)
                    {
                        CloseRegion(formatedLine);
                    }
                    else
                    {
                        token.tokenKind = SyntaxToken.Kind.PreprocessorUnexpectedDirective;
                    }
                    preprocessorCommentsAllowed = false;
                }
                else if (token.text == "define" || token.text == "undef")
                {
                    var symbol = FGParser.ScanIdentifierOrKeyword(line, ref startAt);
                    if (symbol != null && symbol.text != "true" && symbol.text != "false")
                    {
                        symbol.tokenKind = SyntaxToken.Kind.PreprocessorSymbol;
                        formatedLine.tokens.Add(symbol);
                        symbol.formatedLine = formatedLine;

                        scriptDefinesChanged = true;

                        var inactive = formatedLine.regionTree.kind > FGTextBuffer.RegionTree.Kind.LastActive;
                        if (!inactive)
                        {
                            if (token.text == "define")
                            {
                                if (!scriptDefines.Contains(symbol.text))
                                {
                                    scriptDefines.Add(symbol.text);
                                    //scriptDefinesChanged = true;
                                }
                            }
                            else
                            {
                                if (scriptDefines.Contains(symbol.text))
                                {
                                    scriptDefines.Remove(symbol.text);
                                    //scriptDefinesChanged = true;
                                }
                            }
                        }
                    }
                }
                else if (token.text == "error" || token.text == "warning")
                {
                    preprocessorCommentsAllowed = false;
                }
            }

            if (!preprocessorCommentsAllowed)
            {
                ws = ScanWhitespace(line, ref startAt);
                if (ws != null)
                {
                    tokens.Add(ws);
                    ws.formatedLine = formatedLine;
                }
                if (startAt < length)
                {
                    var textArgument = line.Substring(startAt);
                    textArgument.TrimEnd(new [] {' ', '\t'});
                    tokens.Add(new SyntaxToken(SyntaxToken.Kind.PreprocessorArguments, textArgument) { formatedLine = formatedLine });
                    startAt = length - textArgument.Length;
                    if (startAt < length)
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.Whitespace, line.Substring(startAt)) { formatedLine = formatedLine });
                }
                return;
            }

            while (startAt < length)
            {
                ws = ScanWhitespace(line, ref startAt);
                if (ws != null)
                {
                    tokens.Add(ws);
                    ws.formatedLine = formatedLine;
                    continue;
                }

                var firstChar = line[startAt];
                if (startAt < length - 1 && firstChar == '/' && line[startAt + 1] == '/')
                {
                    tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
                    break;
                }
                else if (commentsOnly)
                {
                    tokens.Add(new SyntaxToken(SyntaxToken.Kind.PreprocessorCommentExpected, line.Substring(startAt)) { formatedLine = formatedLine });
                    break;
                }

                if (char.IsLetterOrDigit(firstChar) || firstChar == '_')
                {
                    token = ScanWord(line, ref startAt);
                    token.tokenKind = SyntaxToken.Kind.PreprocessorArguments;
                    tokens.Add(token);
                    token.formatedLine = formatedLine;
                }
                else if (firstChar == '"')
                {
                    token = ScanStringLiteral(line, ref startAt);
                    token.tokenKind = SyntaxToken.Kind.PreprocessorArguments;
                    tokens.Add(token);
                    token.formatedLine = formatedLine;
                }
                else if (firstChar == '\'')
                {
                    token = ScanCharLiteral(line, ref startAt);
                    token.tokenKind = SyntaxToken.Kind.PreprocessorArguments;
                    tokens.Add(token);
                    token.formatedLine = formatedLine;
                }
                else
                {
                    token = new SyntaxToken(SyntaxToken.Kind.PreprocessorArguments, firstChar.ToString()) { formatedLine = formatedLine };
                    tokens.Add(token);
                    ++startAt;
                }

                if (error)
                {
                    token.tokenKind = SyntaxToken.Kind.PreprocessorDirectiveExpected;
                }
            }

            return;
            }

            var inactiveLine = formatedLine.regionTree.kind > FGTextBuffer.RegionTree.Kind.LastActive;

            while (startAt < length)
            {
            switch (formatedLine.blockState)
            {
                case FGTextBuffer.BlockState.None:
                    ws = ScanWhitespace(line, ref startAt);
                    if (ws != null)
                    {
                        tokens.Add(ws);
                        ws.formatedLine = formatedLine;
                        continue;
                    }

                    if (inactiveLine)
                    {
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
                        startAt = length;
                        break;
                    }

                    if (line[startAt] == '/' && startAt < length - 1)
                    {
                        if (line[startAt + 1] == '/')
                        {
                            tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, "//") { formatedLine = formatedLine });
                            startAt += 2;
                            tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
                            startAt = length;
                            break;
                        }
                        else if (line[startAt + 1] == '*')
                        {
                            tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, "/*") { formatedLine = formatedLine });
                            startAt += 2;
                            formatedLine.blockState = FGTextBuffer.BlockState.CommentBlock;
                            break;
                        }
                    }

                    if (line[startAt] == '\'')
                    {
                        token = ScanCharLiteral(line, ref startAt);
                        tokens.Add(token);
                        token.formatedLine = formatedLine;
                        break;
                    }

                    if (line[startAt] == '\"')
                    {
                        token = ScanStringLiteral(line, ref startAt);
                        tokens.Add(token);
                        token.formatedLine = formatedLine;
                        break;
                    }

                    if (startAt < length - 1 && line[startAt] == '@' && line[startAt + 1] == '\"')
                    {
                        token = new SyntaxToken(SyntaxToken.Kind.VerbatimStringBegin, line.Substring(startAt, 2)) { formatedLine = formatedLine };
                        tokens.Add(token);
                        startAt += 2;
                        formatedLine.blockState = FGTextBuffer.BlockState.StringBlock;
                        break;
                    }

                    if (line[startAt] >= '0' && line[startAt] <= '9'
                        || startAt < length - 1 && line[startAt] == '.' && line[startAt + 1] >= '0' && line[startAt + 1] <= '9')
                    {
                        token = ScanNumericLiteral(line, ref startAt);
                        tokens.Add(token);
                        token.formatedLine = formatedLine;
                        break;
                    }

                    token = ScanIdentifierOrKeyword(line, ref startAt);
                    if (token != null)
                    {
                        tokens.Add(token);
                        token.formatedLine = formatedLine;
                        break;
                    }

                    // Multi-character operators / punctuators
                    // "++", "--", "<<", ">>", "<=", ">=", "==", "!=", "&&", "||", "??", "+=", "-=", "*=", "/=", "%=",
                    // "&=", "|=", "^=", "<<=", ">>=", "=>", "::"
                    var punctuatorStart = startAt++;
                    if (startAt < line.Length)
                    {
                        switch (line[punctuatorStart])
                        {
                            case '?':
                                if (line[startAt] == '?')
                                    ++startAt;
                                break;
                            case '+':
                                if (line[startAt] == '+' || line[startAt] == '=')
                                    ++startAt;
                                break;
                            case '-':
                                if (line[startAt] == '-' || line[startAt] == '=')
                                    ++startAt;
                                break;
                            case '<':
                                if (line[startAt] == '=')
                                    ++startAt;
                                else if (line[startAt] == '<')
                                {
                                    ++startAt;
                                    if (startAt < line.Length && line[startAt] == '=')
                                        ++startAt;
                                }
                                break;
                            case '>':
                                if (line[startAt] == '=')
                                    ++startAt;
                                //else if (startAt < line.Length && line[startAt] == '>')
                                //{
                                //    ++startAt;
                                //    if (line[startAt] == '=')
                                //        ++startAt;
                                //}
                                break;
                            case '=':
                                if (line[startAt] == '=' || line[startAt] == '>')
                                    ++startAt;
                                break;
                            case '&':
                                if (line[startAt] == '=' || line[startAt] == '&')
                                    ++startAt;
                                break;
                            case '|':
                                if (line[startAt] == '=' || line[startAt] == '|')
                                    ++startAt;
                                break;
                            case '*':
                            case '/':
                            case '%':
                            case '^':
                            case '!':
                                if (line[startAt] == '=')
                                    ++startAt;
                                break;
                            case ':':
                                if (line[startAt] == ':')
                                    ++startAt;
                                break;
                        }
                    }
                    tokens.Add(new SyntaxToken(SyntaxToken.Kind.Punctuator, line.Substring(punctuatorStart, startAt - punctuatorStart)) { formatedLine = formatedLine });
                    break;

                case FGTextBuffer.BlockState.CommentBlock:
                    int commentBlockEnd = line.IndexOf("*/", startAt);
                    if (commentBlockEnd == -1)
                    {
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt)) { formatedLine = formatedLine });
                        startAt = length;
                    }
                    else
                    {
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.Comment, line.Substring(startAt, commentBlockEnd + 2 - startAt)) { formatedLine = formatedLine });
                        startAt = commentBlockEnd + 2;
                        formatedLine.blockState = FGTextBuffer.BlockState.None;
                    }
                    break;

                case FGTextBuffer.BlockState.StringBlock:
                    int i = startAt;
                    int closingQuote = line.IndexOf('\"', startAt);
                    while (closingQuote != -1 && closingQuote < length - 1 && line[closingQuote + 1] == '\"')
                    {
                        i = closingQuote + 2;
                        closingQuote = line.IndexOf('\"', i);
                    }
                    if (closingQuote == -1)
                    {
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.VerbatimStringLiteral, line.Substring(startAt)) { formatedLine = formatedLine });
                        startAt = length;
                    }
                    else
                    {
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.VerbatimStringLiteral, line.Substring(startAt, closingQuote - startAt)) { formatedLine = formatedLine });
                        startAt = closingQuote;
                        tokens.Add(new SyntaxToken(SyntaxToken.Kind.VerbatimStringLiteral, line.Substring(startAt, 1)) { formatedLine = formatedLine });
                        ++startAt;
                        formatedLine.blockState = FGTextBuffer.BlockState.None;
                    }
                    break;
            }
            }
        }
Esempio n. 11
0
		public void InsertMissingToken(string errorMessage)
		{
			//Debug.Log("Missing at line " + (currentLine + 1) + "\n" + errorMessage);

			var missingAtLine = currentLine;
			var missingAtIndex = currentTokenIndex;
			while (true)
			{
				if (--missingAtIndex < 0)
				{
					if (--missingAtLine < 0)
					{
						missingAtLine = missingAtIndex = 0;
						break;
					}
					missingAtIndex = lines[missingAtLine].tokens.Count;
					continue;
				}
				var tokenKind = lines[missingAtLine].tokens[missingAtIndex].tokenKind;
				if (tokenKind > SyntaxToken.Kind.LastWSToken)
				{
					++missingAtIndex;
					break;
				}
				else if (tokenKind == SyntaxToken.Kind.Missing)
				{
					ErrorToken = lines[missingAtLine].tokens[missingAtIndex].parent;
					return;
				}
			}

			var missingLine = lines[missingAtLine];
			//for (var i = missingAtIndex; i < missingLine.tokens.Count; ++i)
			//{
			//	var token = missingLine.tokens[i];
			//	if (token.parent != null)
			//		++token.parent.tokenIndex;
			//}

			var missingToken = new SyntaxToken(SyntaxToken.Kind.Missing, string.Empty) { style = null, formatedLine = missingLine };
			missingLine.tokens.Insert(missingAtIndex, missingToken);
			var leaf = ErrorParseTreeNode.AddToken(missingToken);
			leaf.missing = true;
			leaf.syntaxError = errorMessage;
			leaf.grammarNode = ErrorGrammarNode;
			//leaf.line = CurrentLine() - 1;

			if (ErrorToken == null)
				ErrorToken = leaf;

			if (missingAtLine == currentLine)
				++currentTokenIndex;
		}
Esempio n. 12
0
		public bool CollectCompletions(TokenSet tokenSet)
		{
			var result = (CurrentGrammarNode ?? CsGrammar.instance.r_compilationUnit).CollectCompletions(tokenSet, this, grammar.tokenIdentifier);
			if (CurrentGrammarNode != null && tokenSet.Matches(Instance.tokenIdentifier))
			{
				currentTokenCache = new SyntaxToken(SyntaxToken.Kind.Identifier, "special");
				currentTokenCache.tokenId = grammar.tokenIdentifier;
				Lookahead(CurrentGrammarNode, 1);
				currentTokenCache = null;
			}
			return result;
		}
Esempio n. 13
0
		public Scanner(CsGrammar grammar, FGTextBuffer.FormatedLine[] formatedLines, string fileName)
		{
			this.grammar = grammar;
			this.fileName = fileName;
			lines = formatedLines;
				
			if (EOF == null)
				EOF = new SyntaxToken(SyntaxToken.Kind.EOF, string.Empty) { tokenId = grammar.tokenEOF };
		}