diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs index 3f240228e88fb..fee4dd5258e00 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs @@ -294,6 +294,11 @@ public static SyntaxToken MissingToken(SyntaxTriviaList leading, SyntaxKind kind /// The raw text of the identifier name, including any escapes or leading '@' character. public static SyntaxToken Identifier(string text) { + if (text == null) + { + throw new ArgumentNullException(nameof(text)); + } + return new SyntaxToken(Syntax.InternalSyntax.SyntaxFactory.Identifier(ElasticMarker.UnderlyingNode, text, ElasticMarker.UnderlyingNode)); } @@ -306,6 +311,11 @@ public static SyntaxToken Identifier(string text) /// A list of trivia immediately following the token. public static SyntaxToken Identifier(SyntaxTriviaList leading, string text, SyntaxTriviaList trailing) { + if (text == null) + { + throw new ArgumentNullException(nameof(text)); + } + return new SyntaxToken(Syntax.InternalSyntax.SyntaxFactory.Identifier(leading.Node, text, trailing.Node)); } @@ -319,6 +329,16 @@ public static SyntaxToken Identifier(SyntaxTriviaList leading, string text, Synt /// A list of trivia immediately following the token. public static SyntaxToken VerbatimIdentifier(SyntaxTriviaList leading, string text, string valueText, SyntaxTriviaList trailing) { + if (text == null) + { + throw new ArgumentNullException(nameof(text)); + } + + if (valueText == null) + { + throw new ArgumentNullException(nameof(valueText)); + } + if (text.StartsWith("@", StringComparison.Ordinal)) { throw new ArgumentException("text should not start with an @ character."); @@ -340,6 +360,16 @@ public static SyntaxToken VerbatimIdentifier(SyntaxTriviaList leading, string te /// public static SyntaxToken Identifier(SyntaxTriviaList leading, SyntaxKind contextualKind, string text, string valueText, SyntaxTriviaList trailing) { + if (text == null) + { + throw new ArgumentNullException(nameof(text)); + } + + if (valueText == null) + { + throw new ArgumentNullException(nameof(valueText)); + } + return new SyntaxToken(InternalSyntax.SyntaxFactory.Identifier(contextualKind, leading.Node, text, valueText, trailing.Node)); } diff --git a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs index bc2e73ce0a952..fd82f128d4e10 100644 --- a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs @@ -714,5 +714,21 @@ public void TestParseMethodsKeepParseOptionsInTheTree() var typeName = SyntaxFactory.ParseTypeName("", options: parseOptions); Assert.Same(parseOptions, typeName.SyntaxTree.Options); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17637")] + public void Identifier_Null_ThrowsArgumentNullException() + { + Assert.Throws(() => SyntaxFactory.Identifier(text: null)); + Assert.Throws(() => + SyntaxFactory.Identifier(SyntaxFactory.TriviaList(), text: null, SyntaxFactory.TriviaList())); + Assert.Throws(() => + SyntaxFactory.Identifier(SyntaxFactory.TriviaList(), SyntaxKind.IdentifierName, text: null, valueText: "value", SyntaxFactory.TriviaList())); + Assert.Throws(() => + SyntaxFactory.Identifier(SyntaxFactory.TriviaList(), SyntaxKind.IdentifierName, text: "text", valueText: null, SyntaxFactory.TriviaList())); + Assert.Throws(() => + SyntaxFactory.VerbatimIdentifier(SyntaxFactory.TriviaList(), text: null, valueText: "value", SyntaxFactory.TriviaList())); + Assert.Throws(() => + SyntaxFactory.VerbatimIdentifier(SyntaxFactory.TriviaList(), text: "text", valueText: null, SyntaxFactory.TriviaList())); + } } }