|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
using InternalSyntax = Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class CrefLexerTests : DocumentationCommentLexerTestBase
{
[Fact]
public void TestLexIdentifiers()
{
AssertTokens("a", Token(SyntaxKind.IdentifierToken, "a"));
AssertTokens("\u0061", Token(SyntaxKind.IdentifierToken, "\u0061", "a"));
AssertTokens("a", Token(SyntaxKind.IdentifierToken, "a", "a"));
AssertTokens("ab", Token(SyntaxKind.IdentifierToken, "ab"));
AssertTokens("\u0061b", Token(SyntaxKind.IdentifierToken, "\u0061b", "ab"));
AssertTokens("a\u0062", Token(SyntaxKind.IdentifierToken, "a\u0062", "ab"));
AssertTokens("ab", Token(SyntaxKind.IdentifierToken, "ab", "ab"));
AssertTokens("ab", Token(SyntaxKind.IdentifierToken, "ab", "ab"));
}
[Fact]
public void TestLexKeywords()
{
AssertTokens("global", Token(SyntaxKind.IdentifierToken, contextualKind: SyntaxKind.GlobalKeyword));
AssertTokens("operator", Token(SyntaxKind.OperatorKeyword));
AssertTokens("explicit", Token(SyntaxKind.ExplicitKeyword));
AssertTokens("implicit", Token(SyntaxKind.ImplicitKeyword));
AssertTokens("ref", Token(SyntaxKind.RefKeyword));
AssertTokens("out", Token(SyntaxKind.OutKeyword));
AssertTokens("true", Token(SyntaxKind.TrueKeyword));
AssertTokens("false", Token(SyntaxKind.FalseKeyword));
AssertTokens("global", Token(SyntaxKind.IdentifierToken, "global", "global", SyntaxKind.GlobalKeyword));
AssertTokens("operator", Token(SyntaxKind.OperatorKeyword, "operator", "operator"));
AssertTokens("explicit", Token(SyntaxKind.ExplicitKeyword, "explicit", "explicit"));
AssertTokens("implicit", Token(SyntaxKind.ImplicitKeyword, "implicit", "implicit"));
AssertTokens("ref", Token(SyntaxKind.RefKeyword, "ref", "ref"));
AssertTokens("out", Token(SyntaxKind.OutKeyword, "out", "out"));
AssertTokens("true", Token(SyntaxKind.TrueKeyword, "true", "true"));
AssertTokens("false", Token(SyntaxKind.FalseKeyword, "false", "false"));
AssertTokens("global", Token(SyntaxKind.IdentifierToken, "global", "global", SyntaxKind.GlobalKeyword));
AssertTokens("operator", Token(SyntaxKind.OperatorKeyword, "operator", "operator"));
AssertTokens("explicit", Token(SyntaxKind.ExplicitKeyword, "explicit", "explicit"));
AssertTokens("implicit", Token(SyntaxKind.ImplicitKeyword, "implicit", "implicit"));
AssertTokens("ref", Token(SyntaxKind.RefKeyword, "ref", "ref"));
AssertTokens("out", Token(SyntaxKind.OutKeyword, "out", "out"));
AssertTokens("true", Token(SyntaxKind.TrueKeyword, "true", "true"));
AssertTokens("false", Token(SyntaxKind.FalseKeyword, "false", "false"));
}
[Fact]
public void TestLexVerbatimKeywords()
{
AssertTokens("@global", Token(SyntaxKind.IdentifierToken, "@global", "global"));
AssertTokens("@operator", Token(SyntaxKind.IdentifierToken, "@operator", "operator"));
AssertTokens("@explicit", Token(SyntaxKind.IdentifierToken, "@explicit", "explicit"));
AssertTokens("@implicit", Token(SyntaxKind.IdentifierToken, "@implicit", "implicit"));
AssertTokens("@ref", Token(SyntaxKind.IdentifierToken, "@ref", "ref"));
AssertTokens("@out", Token(SyntaxKind.IdentifierToken, "@out", "out"));
AssertTokens("@true", Token(SyntaxKind.IdentifierToken, "@true", "true"));
AssertTokens("@false", Token(SyntaxKind.IdentifierToken, "@false", "false"));
AssertTokens("@global", Token(SyntaxKind.IdentifierToken, "@global", "global"));
AssertTokens("@operator", Token(SyntaxKind.IdentifierToken, "@operator", "operator"));
AssertTokens("@explicit", Token(SyntaxKind.IdentifierToken, "@explicit", "explicit"));
AssertTokens("@implicit", Token(SyntaxKind.IdentifierToken, "@implicit", "implicit"));
AssertTokens("@ref", Token(SyntaxKind.IdentifierToken, "@ref", "ref"));
AssertTokens("@out", Token(SyntaxKind.IdentifierToken, "@out", "out"));
AssertTokens("@true", Token(SyntaxKind.IdentifierToken, "@true", "true"));
AssertTokens("@false", Token(SyntaxKind.IdentifierToken, "@false", "false"));
}
[Fact]
public void TestLexUnicodeEscapeKeywords()
{
AssertTokens("\\u0067lobal", Token(SyntaxKind.IdentifierToken, "\\u0067lobal", "global"));
AssertTokens("\\u006Fperator", Token(SyntaxKind.IdentifierToken, "\\u006Fperator", "operator"));
AssertTokens("\\u0065xplicit", Token(SyntaxKind.IdentifierToken, "\\u0065xplicit", "explicit"));
AssertTokens("\\u0069mplicit", Token(SyntaxKind.IdentifierToken, "\\u0069mplicit", "implicit"));
AssertTokens("\\u0072ef", Token(SyntaxKind.IdentifierToken, "\\u0072ef", "ref"));
AssertTokens("\\u006Fut", Token(SyntaxKind.IdentifierToken, "\\u006Fut", "out"));
AssertTokens("\\u0074rue", Token(SyntaxKind.IdentifierToken, "\\u0074rue", "true"));
AssertTokens("\\u0066alse", Token(SyntaxKind.IdentifierToken, "\\u0066alse", "false"));
}
[WorkItem(530519, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530519")]
[Fact]
public void TestLexUnicodeEscapeKeywordsWithEntities()
{
// BREAK: Dev11 treats these as verbatim identifiers.
AssertTokens("\u0067lobal", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u0067lobal"));
AssertTokens("\u006Fperator", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u006Fperator"));
AssertTokens("\u0065xplicit", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u0065xplicit"));
AssertTokens("\u0069mplicit", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u0069mplicit"));
AssertTokens("\u0072ef", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u0072ef"));
AssertTokens("\u006Fut", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u006Fut"));
AssertTokens("\u0074rue", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u0074rue"));
AssertTokens("\u0066alse", Token(SyntaxKind.XmlEntityLiteralToken, "\", "\\"), Token(SyntaxKind.IdentifierToken, "u0066alse"));
}
[Fact]
public void TestLexPunctuation()
{
AssertTokens(".", Token(SyntaxKind.DotToken));
AssertTokens(",", Token(SyntaxKind.CommaToken));
AssertTokens(":", Token(SyntaxKind.ColonToken));
AssertTokens("::", Token(SyntaxKind.ColonColonToken));
AssertTokens("(", Token(SyntaxKind.OpenParenToken));
AssertTokens(")", Token(SyntaxKind.CloseParenToken));
AssertTokens("[", Token(SyntaxKind.OpenBracketToken));
AssertTokens("]", Token(SyntaxKind.CloseBracketToken));
AssertTokens("?", Token(SyntaxKind.QuestionToken));
AssertTokens("??", Token(SyntaxKind.QuestionToken), Token(SyntaxKind.QuestionToken));
AssertTokens("*", Token(SyntaxKind.AsteriskToken));
AssertTokens("<", Token(SyntaxKind.BadToken, "<")); //illegal in attribute
AssertTokens(">", Token(SyntaxKind.GreaterThanToken));
// Special case: curly brackets become angle brackets.
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
AssertTokens(".", Token(SyntaxKind.DotToken, ".", "."));
AssertTokens(",", Token(SyntaxKind.CommaToken, ",", ","));
//AssertTokens(":", Token(SyntaxKind.ColonToken, ".", ":")); //not needed
AssertTokens("::", Token(SyntaxKind.ColonColonToken, "::", "::"));
AssertTokens("::", Token(SyntaxKind.ColonColonToken, "::", "::"));
AssertTokens("::", Token(SyntaxKind.ColonColonToken, "::", "::"));
AssertTokens("(", Token(SyntaxKind.OpenParenToken, "(", "("));
AssertTokens(")", Token(SyntaxKind.CloseParenToken, ")", ")"));
AssertTokens("[", Token(SyntaxKind.OpenBracketToken, "[", "["));
AssertTokens("]", Token(SyntaxKind.CloseBracketToken, "]", "]"));
AssertTokens("?", Token(SyntaxKind.QuestionToken, "?", "?"));
AssertTokens("??", Token(SyntaxKind.QuestionToken, "?", "?"), Token(SyntaxKind.QuestionToken, "?", "?"));
AssertTokens("*", Token(SyntaxKind.AsteriskToken, "*", "*"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
// Special case: curly brackets become angle brackets.
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
}
[Fact]
public void TestLexPunctuationSequences()
{
AssertTokens(":::", Token(SyntaxKind.ColonColonToken), Token(SyntaxKind.ColonToken));
AssertTokens("::::", Token(SyntaxKind.ColonColonToken), Token(SyntaxKind.ColonColonToken));
AssertTokens(":::::", Token(SyntaxKind.ColonColonToken), Token(SyntaxKind.ColonColonToken), Token(SyntaxKind.ColonToken));
// No null-coalescing in crefs
AssertTokens("???", Token(SyntaxKind.QuestionToken), Token(SyntaxKind.QuestionToken), Token(SyntaxKind.QuestionToken));
AssertTokens("????", Token(SyntaxKind.QuestionToken), Token(SyntaxKind.QuestionToken), Token(SyntaxKind.QuestionToken), Token(SyntaxKind.QuestionToken));
}
[Fact]
public void TestLexPunctuationSpecial()
{
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
AssertTokens("}", Token(SyntaxKind.GreaterThanToken, "}", ">"));
}
[Fact]
public void TestLexOperators()
{
// Single-character
AssertTokens("&", Token(SyntaxKind.XmlEntityLiteralToken, "&")); // Not valid XML
AssertTokens("~", Token(SyntaxKind.TildeToken));
AssertTokens("*", Token(SyntaxKind.AsteriskToken));
AssertTokens("/", Token(SyntaxKind.SlashToken));
AssertTokens("%", Token(SyntaxKind.PercentToken));
AssertTokens("|", Token(SyntaxKind.BarToken));
AssertTokens("^", Token(SyntaxKind.CaretToken));
// Multi-character
AssertTokens("+", Token(SyntaxKind.PlusToken));
AssertTokens("++", Token(SyntaxKind.PlusPlusToken));
AssertTokens("-", Token(SyntaxKind.MinusToken));
AssertTokens("--", Token(SyntaxKind.MinusMinusToken));
AssertTokens("<", Token(SyntaxKind.BadToken, "<"));
AssertTokens("<<", Token(SyntaxKind.BadToken, "<"), Token(SyntaxKind.BadToken, "<"));
AssertTokens("<=", Token(SyntaxKind.BadToken, "<"), Token(SyntaxKind.EqualsToken));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken));
AssertTokens(">>", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken));
AssertTokens(">>>", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken));
AssertTokens(">=", Token(SyntaxKind.GreaterThanEqualsToken));
AssertTokens("=", Token(SyntaxKind.EqualsToken));
AssertTokens("==", Token(SyntaxKind.EqualsEqualsToken));
AssertTokens("!", Token(SyntaxKind.ExclamationToken));
AssertTokens("!=", Token(SyntaxKind.ExclamationEqualsToken));
// Single-character
AssertTokens("&", Token(SyntaxKind.AmpersandToken, "&", "&")); // Fine
AssertTokens("~", Token(SyntaxKind.TildeToken, "~", "~"));
AssertTokens("*", Token(SyntaxKind.AsteriskToken, "*", "*"));
AssertTokens("/", Token(SyntaxKind.SlashToken, "/", "/"));
AssertTokens("%", Token(SyntaxKind.PercentToken, "%", "%"));
AssertTokens("|", Token(SyntaxKind.BarToken, "|", "|"));
AssertTokens("^", Token(SyntaxKind.CaretToken, "^", "^"));
// Multi-character
AssertTokens("+", Token(SyntaxKind.PlusToken, "+", "+"));
AssertTokens("++", Token(SyntaxKind.PlusPlusToken, "++", "++"));
AssertTokens("++", Token(SyntaxKind.PlusPlusToken, "++", "++"));
AssertTokens("++", Token(SyntaxKind.PlusPlusToken, "++", "++"));
AssertTokens("-", Token(SyntaxKind.MinusToken, "-", "-"));
AssertTokens("--", Token(SyntaxKind.MinusMinusToken, "--", "--"));
AssertTokens("--", Token(SyntaxKind.MinusMinusToken, "--", "--"));
AssertTokens("--", Token(SyntaxKind.MinusMinusToken, "--", "--"));
AssertTokens("<", Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<<", Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"));
AssertTokens("<=", Token(SyntaxKind.LessThanEqualsToken, "<=", "<="));
AssertTokens("<=", Token(SyntaxKind.LessThanEqualsToken, "<=", "<="));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">>", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">>", Token(SyntaxKind.GreaterThanToken, ">", ">"), Token(SyntaxKind.GreaterThanToken));
AssertTokens(">>", Token(SyntaxKind.GreaterThanToken, ">", ">"), Token(SyntaxKind.GreaterThanToken, ">", ">"));
AssertTokens(">=", Token(SyntaxKind.GreaterThanEqualsToken, ">=", ">="));
AssertTokens(">=", Token(SyntaxKind.GreaterThanEqualsToken, ">=", ">="));
AssertTokens(">=", Token(SyntaxKind.GreaterThanEqualsToken, ">=", ">="));
AssertTokens("=", Token(SyntaxKind.EqualsToken, "=", "="));
AssertTokens("==", Token(SyntaxKind.EqualsEqualsToken, "==", "=="));
AssertTokens("==", Token(SyntaxKind.EqualsEqualsToken, "==", "=="));
AssertTokens("==", Token(SyntaxKind.EqualsEqualsToken, "==", "=="));
AssertTokens("!", Token(SyntaxKind.ExclamationToken, "!", "!"));
AssertTokens("!=", Token(SyntaxKind.ExclamationEqualsToken, "!=", "!="));
AssertTokens("!=", Token(SyntaxKind.ExclamationEqualsToken, "!=", "!="));
AssertTokens("!=", Token(SyntaxKind.ExclamationEqualsToken, "!=", "!="));
}
[Fact]
public void TestLexOperatorSequence()
{
AssertTokens("+++", Token(SyntaxKind.PlusPlusToken), Token(SyntaxKind.PlusToken));
AssertTokens("++++", Token(SyntaxKind.PlusPlusToken), Token(SyntaxKind.PlusPlusToken));
AssertTokens("+++++", Token(SyntaxKind.PlusPlusToken), Token(SyntaxKind.PlusPlusToken), Token(SyntaxKind.PlusToken));
AssertTokens("---", Token(SyntaxKind.MinusMinusToken), Token(SyntaxKind.MinusToken));
AssertTokens("----", Token(SyntaxKind.MinusMinusToken), Token(SyntaxKind.MinusMinusToken));
AssertTokens("-----", Token(SyntaxKind.MinusMinusToken), Token(SyntaxKind.MinusMinusToken), Token(SyntaxKind.MinusToken));
AssertTokens("===", Token(SyntaxKind.EqualsEqualsToken), Token(SyntaxKind.EqualsToken));
AssertTokens("====", Token(SyntaxKind.EqualsEqualsToken), Token(SyntaxKind.EqualsEqualsToken));
AssertTokens("=====", Token(SyntaxKind.EqualsEqualsToken), Token(SyntaxKind.EqualsEqualsToken), Token(SyntaxKind.EqualsToken));
AssertTokens("<<<", Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"), Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens("<<<<", Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"), Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"));
AssertTokens("<<<<<", Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"), Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"), Token(SyntaxKind.LessThanToken, "<", "<"));
AssertTokens(">>>", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken));
AssertTokens(">>>>", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken));
AssertTokens(">>>>>", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken));
AssertTokens("!!=", Token(SyntaxKind.ExclamationToken), Token(SyntaxKind.ExclamationEqualsToken));
AssertTokens("<<=", Token(SyntaxKind.LessThanLessThanToken, "<<", "<<"), Token(SyntaxKind.EqualsToken));
AssertTokens(">>=", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanEqualsToken)); //fixed up by parser
AssertTokens(">>>=", Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanToken), Token(SyntaxKind.GreaterThanEqualsToken)); //fixed up by parser
AssertTokens("!==", Token(SyntaxKind.ExclamationEqualsToken), Token(SyntaxKind.EqualsToken));
AssertTokens("<==", Token(SyntaxKind.LessThanEqualsToken, "<=", "<="), Token(SyntaxKind.EqualsToken));
AssertTokens(">==", Token(SyntaxKind.GreaterThanEqualsToken), Token(SyntaxKind.EqualsToken));
AssertTokens("{", Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{{", Token(SyntaxKind.LessThanLessThanToken, "{{", "<<"));
AssertTokens("{{{", Token(SyntaxKind.LessThanLessThanToken, "{{", "<<"), Token(SyntaxKind.LessThanToken, "{", "<"));
AssertTokens("{{{{", Token(SyntaxKind.LessThanLessThanToken, "{{", "<<"), Token(SyntaxKind.LessThanLessThanToken, "{{", "<<"));
AssertTokens("{{{{{", Token(SyntaxKind.LessThanLessThanToken, "{{", "<<"), Token(SyntaxKind.LessThanLessThanToken, "{{", "<<"), Token(SyntaxKind.LessThanToken, "{", "<"));
}
[Fact]
public void TestLexBadEntity()
{
// Bad xml entities
AssertTokens("&", Token(SyntaxKind.XmlEntityLiteralToken, "&"));
AssertTokens("&&", Token(SyntaxKind.XmlEntityLiteralToken, "&"), Token(SyntaxKind.XmlEntityLiteralToken, "&"));
AssertTokens("&;", Token(SyntaxKind.XmlEntityLiteralToken, "&;"));
AssertTokens("&a;", Token(SyntaxKind.XmlEntityLiteralToken, "&a;"));
AssertTokens("&#;", Token(SyntaxKind.XmlEntityLiteralToken, "&#;"));
AssertTokens("&#x;", Token(SyntaxKind.XmlEntityLiteralToken, "&#x;"));
AssertTokens("&#a;", Token(SyntaxKind.XmlEntityLiteralToken, "&#"), Token(SyntaxKind.IdentifierToken, "a"), Token(SyntaxKind.BadToken, ";"));
AssertTokens("&#xg;", Token(SyntaxKind.XmlEntityLiteralToken, "&#x"), Token(SyntaxKind.IdentifierToken, "g"), Token(SyntaxKind.BadToken, ";"));
// Overflowing entities
AssertTokens("�", Token(SyntaxKind.XmlEntityLiteralToken, "�"));
AssertTokens("�", Token(SyntaxKind.XmlEntityLiteralToken, "�"));
// Long but not overflowing entities
AssertTokens("a", Token(SyntaxKind.IdentifierToken, "a", "a"));
AssertTokens("a", Token(SyntaxKind.IdentifierToken, "a", "a"));
}
[Fact]
public void TestLexBadXml()
{
AssertTokens("<", Token(SyntaxKind.BadToken, "<"));
AssertTokens(">", Token(SyntaxKind.GreaterThanToken));
}
[Fact]
public void TestLexEmpty()
{
AssertTokens("");
}
[Fact]
public void TestLexExamples()
{
AssertTokens("A.B.C",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "B"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "C"));
AssertTokens("A::B.this[ref int]",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.ColonColonToken),
Token(SyntaxKind.IdentifierToken, "B"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.ThisKeyword),
Token(SyntaxKind.OpenBracketToken),
Token(SyntaxKind.RefKeyword),
Token(SyntaxKind.IntKeyword),
Token(SyntaxKind.CloseBracketToken));
AssertTokens("A.operator +",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.OperatorKeyword),
Token(SyntaxKind.PlusToken));
AssertTokens("A.explicit operator B::C(out C?*, int)",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.ExplicitKeyword),
Token(SyntaxKind.OperatorKeyword),
Token(SyntaxKind.IdentifierToken, "B"),
Token(SyntaxKind.ColonColonToken),
Token(SyntaxKind.IdentifierToken, "C"),
Token(SyntaxKind.OpenParenToken),
Token(SyntaxKind.OutKeyword),
Token(SyntaxKind.IdentifierToken, "C"),
Token(SyntaxKind.QuestionToken),
Token(SyntaxKind.AsteriskToken),
Token(SyntaxKind.CommaToken),
Token(SyntaxKind.IntKeyword),
Token(SyntaxKind.CloseParenToken));
}
[WorkItem(530523, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530523")]
[Fact(Skip = "530523")]
public void TestLexNewline()
{
AssertTokens(@"A
.B",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "B"));
AssertTokens(@"A .B",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "B"));
}
[WorkItem(530523, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530523")]
[Fact(Skip = "530523")]
public void TestLexEntityInTrivia()
{
AssertTokens(@"A .B",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "B"));
}
[WorkItem(530523, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530523")]
[Fact(Skip = "530523")]
public void TestLexCSharpTrivia()
{
AssertTokens(@"A //comment
.B",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "B"));
AssertTokens(@"A /*comment*/.B",
Token(SyntaxKind.IdentifierToken, "A"),
Token(SyntaxKind.DotToken),
Token(SyntaxKind.IdentifierToken, "B"));
}
internal override IEnumerable<InternalSyntax.SyntaxToken> GetTokens(string text)
{
Assert.DoesNotContain("'", text, StringComparison.Ordinal);
using (var lexer = new InternalSyntax.Lexer(SourceText.From(text + "'"), TestOptions.RegularWithDocumentationComments))
{
while (true)
{
var token = lexer.Lex(InternalSyntax.LexerMode.XmlCrefQuote | InternalSyntax.LexerMode.XmlDocCommentStyleSingleLine | InternalSyntax.LexerMode.XmlDocCommentLocationInterior);
if (token.Kind == SyntaxKind.SingleQuoteToken)
{
break;
}
yield return token;
}
}
}
}
}
|