diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/NameParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/NameParsingTests.cs index 92adda1188dbb..2e27356f4a1d9 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/NameParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/NameParsingTests.cs @@ -1490,5 +1490,179 @@ public void ParseGlobalAliasQualifiedNameAfterConditionalExpression() } EOF(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71379")] + public void ParseGenericNameInvocationWithPartiallyOmittedTypeArguments() + { + // Tests for partially closed generic type names where the first type argument is missing + var source = """ + class C + { + void M() + { + M<,int>(); // First argument omitted + M(); // Second argument omitted + M<,int,>(); // First and third arguments omitted (if we had 3 params) + } + } + """; + + UsingTree(source, + // (5,11): error CS1031: Type expected + // M<,int>(); // First argument omitted + Diagnostic(ErrorCode.ERR_TypeExpected, ",").WithLocation(5, 11), + // (6,18): error CS1031: Type expected + // M(); // Second argument omitted + Diagnostic(ErrorCode.ERR_TypeExpected, ">").WithLocation(6, 18), + // (7,11): error CS1031: Type expected + // M<,int,>(); // First and third arguments omitted (if we had 3 params) + Diagnostic(ErrorCode.ERR_TypeExpected, ",").WithLocation(7, 11), + // (7,16): error CS1031: Type expected + // M<,int,>(); // First and third arguments omitted (if we had 3 params) + Diagnostic(ErrorCode.ERR_TypeExpected, ">").WithLocation(7, 16)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.MethodDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T1"); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T2"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + // M<,int>() + N(SyntaxKind.ExpressionStatement); + { + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.GenericName); + { + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.SemicolonToken); + } + // M() + N(SyntaxKind.ExpressionStatement); + { + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.GenericName); + { + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.CommaToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.SemicolonToken); + } + // M<,int,>() + N(SyntaxKind.ExpressionStatement); + { + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.GenericName); + { + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } } }