diff --git a/eng/build.sh b/eng/build.sh
index 56b795582c062..3dfb1abe19534 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -134,7 +134,7 @@ while [[ $# > 0 ]]; do
# Bootstrap requires restore
restore=true
;;
- --runAnalyzers)
+ --runanalyzers)
run_analyzers=true
;;
--preparemachine)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 737db36bc298b..8b4f2f79ef5a2 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6161,9 +6161,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
'RefKind.Out' is not a valid ref kind for a return type.
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+ Cannot convert &method group '{0}' to delegate type '{0}'.
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
index bb399a899a306..b496637f10230 100644
--- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
+++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
@@ -108,6 +108,8 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.BinaryPattern(Microsoft.CodeA
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ImplicitObjectCreationExpression() -> Microsoft.CodeAnalysis.CSharp.Syntax.ImplicitObjectCreationExpressionSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ImplicitObjectCreationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList, Microsoft.CodeAnalysis.CSharp.Syntax.InitializerExpressionSyntax initializer) -> Microsoft.CodeAnalysis.CSharp.Syntax.ImplicitObjectCreationExpressionSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ImplicitObjectCreationExpression(Microsoft.CodeAnalysis.SyntaxToken newKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList, Microsoft.CodeAnalysis.CSharp.Syntax.InitializerExpressionSyntax initializer) -> Microsoft.CodeAnalysis.CSharp.Syntax.ImplicitObjectCreationExpressionSyntax
+static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseTypeName(string text, int offset = 0, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions options = null, bool consumeFullText = true) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax
+static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseTypeName(string text, int offset, bool consumeFullText) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitFunctionPointerType(Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitFunctionPointerType(Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax node) -> TResult
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedPattern(Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedPatternSyntax
@@ -122,6 +124,7 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.UnaryPattern(Microsoft.CodeAn
*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.ArgumentList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax
*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.Initializer.get -> Microsoft.CodeAnalysis.CSharp.Syntax.InitializerExpressionSyntax
*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.NewKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken
+*REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseTypeName(string text, int offset = 0, bool consumeFullText = true) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitBinaryPattern(Microsoft.CodeAnalysis.CSharp.Syntax.BinaryPatternSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitImplicitObjectCreationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ImplicitObjectCreationExpressionSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedPatternSyntax node) -> void
diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs
index b0db58c46bfaa..f5cdcce077d8d 100644
--- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs
+++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs
@@ -1693,9 +1693,19 @@ public static NameSyntax ParseName(string text, int offset = 0, bool consumeFull
///
/// Parse a TypeNameSyntax node using the grammar rule for type names.
///
- public static TypeSyntax ParseTypeName(string text, int offset = 0, bool consumeFullText = true)
+ // Backcompat overload, do not remove
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static TypeSyntax ParseTypeName(string text, int offset, bool consumeFullText)
{
- using (var lexer = MakeLexer(text, offset))
+ return ParseTypeName(text, offset, options: null, consumeFullText);
+ }
+
+ ///
+ /// Parse a TypeNameSyntax node using the grammar rule for type names.
+ ///
+ public static TypeSyntax ParseTypeName(string text, int offset = 0, CSharpParseOptions? options = null, bool consumeFullText = true)
+ {
+ using (var lexer = MakeLexer(text, offset, options))
using (var parser = MakeParser(lexer))
{
var node = parser.ParseTypeName();
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index a1924c6ebf5a1..1a8004fc3f922 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index d9a530e84eb07..03c3c6663f339 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 632b32d3d72a5..b9c7f9bf939c1 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 9cd5d7f83c014..763f00a2cd940 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index b21f9bcb5040d..63fbd921641ae 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 20c77c2f6ab39..a1ed2032dc585 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 2d014f4cf7182..ca1ef88e8b19a 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 8ba6cb43d24f7..c92dc56d99995 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 99fb70350029a..94c8ad1e39ddc 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 912a29e99895f..7a89322f9afe5 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 621451fb9231a..c3d8f5337bba6 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index e359cb495481e..63a9a0ec7a770 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 2f2b8ba804289..46ed73372fee8 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -23,8 +23,8 @@
-
- Cannot convert & method group '{0}' to non-function pointer type '{1}'.
+
+ Cannot convert &method group '{0}' to non-function pointer type '{1}'.
@@ -123,8 +123,8 @@
-
- Cannot convert a & method group '{0}' to delegate type '{0}'.
+
+ Cannot convert &method group '{0}' to delegate type '{0}'.
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs
index cce15a5950a60..00b9ffd547b0e 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs
@@ -3670,10 +3670,10 @@ static void M()
}");
comp.VerifyDiagnostics(
- // (6,22): error CS8801: Cannot convert & method group 'M' to non-function pointer type 'void*'.
+ // (6,22): error CS8801: Cannot convert &method group 'M' to non-function pointer type 'void*'.
// void* ptr1 = &M;
Diagnostic(ErrorCode.ERR_AddressOfToNonFunctionPointer, "&M").WithArguments("M", "void*").WithLocation(6, 22),
- // (7,22): error CS8801: Cannot convert & method group 'M' to non-function pointer type 'void*'.
+ // (7,22): error CS8801: Cannot convert &method group 'M' to non-function pointer type 'void*'.
// void* ptr2 = (void*)&M;
Diagnostic(ErrorCode.ERR_AddressOfToNonFunctionPointer, "(void*)&M").WithArguments("M", "void*").WithLocation(7, 22)
);
@@ -3722,10 +3722,10 @@ unsafe void M()
// (8,24): error CS0119: 'Action' is a type, which is not valid in the given context
// Action ptr1 = (Action)&M;
Diagnostic(ErrorCode.ERR_BadSKunknown, "Action").WithArguments("System.Action", "type").WithLocation(8, 24),
- // (9,23): error CS8800: Cannot convert a & method group 'M' to delegate type 'M'.
+ // (9,23): error CS8800: Cannot convert &method group 'M' to delegate type 'M'.
// Action ptr2 = (Action)(&M);
Diagnostic(ErrorCode.ERR_CannotConvertAddressOfToDelegate, "(Action)(&M)").WithArguments("M", "System.Action").WithLocation(9, 23),
- // (10,23): error CS8800: Cannot convert a & method group 'M' to delegate type 'M'.
+ // (10,23): error CS8800: Cannot convert &method group 'M' to delegate type 'M'.
// Action ptr3 = &M;
Diagnostic(ErrorCode.ERR_CannotConvertAddressOfToDelegate, "&M").WithArguments("M", "System.Action").WithLocation(10, 23)
);
@@ -3774,10 +3774,10 @@ unsafe void M()
// (7,19): error CS0119: 'C' is a type, which is not valid in the given context
// C ptr1 = (C)&M;
Diagnostic(ErrorCode.ERR_BadSKunknown, "C").WithArguments("C", "type").WithLocation(7, 19),
- // (8,18): error CS8801: Cannot convert & method group 'M' to non-function pointer type 'C'.
+ // (8,18): error CS8801: Cannot convert &method group 'M' to non-function pointer type 'C'.
// C ptr2 = (C)(&M);
Diagnostic(ErrorCode.ERR_AddressOfToNonFunctionPointer, "(C)(&M)").WithArguments("M", "C").WithLocation(8, 18),
- // (9,18): error CS8801: Cannot convert & method group 'M' to non-function pointer type 'C'.
+ // (9,18): error CS8801: Cannot convert &method group 'M' to non-function pointer type 'C'.
// C ptr3 = &M;
Diagnostic(ErrorCode.ERR_AddressOfToNonFunctionPointer, "&M").WithArguments("M", "C").WithLocation(9, 18)
);
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs
index 6a06bee1c0ffb..9802202ffe8e2 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs
@@ -29,6 +29,28 @@ private CompilationVerifier CompileAndVerifyFunctionPointers(CSharpCompilation c
return CompileAndVerify(compilation, verify: Verification.Skipped, expectedOutput: expectedOutput);
}
+ [Fact]
+ public void UsingAliasTest()
+ {
+ var comp = CreateCompilationWithFunctionPointers(@"
+using s = delegate*;");
+
+ comp.VerifyDiagnostics(
+ // (2,1): hidden CS8019: Unnecessary using directive.
+ // using s = delegate*;
+ Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using s = ").WithLocation(2, 1),
+ // (2,11): error CS1041: Identifier expected; 'delegate' is a keyword
+ // using s = delegate*;
+ Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "delegate").WithArguments("", "delegate").WithLocation(2, 11),
+ // (2,25): error CS0116: A namespace cannot directly contain members such as fields or methods
+ // using s = delegate*;
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, ">").WithLocation(2, 25),
+ // (2,26): error CS1022: Type or namespace definition, or end-of-file expected
+ // using s = delegate*;
+ Diagnostic(ErrorCode.ERR_EOFExpected, ";").WithLocation(2, 26)
+ );
+ }
+
[Fact]
public void ImplicitConversionToVoid()
{
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs
index 92f9545ced62a..d8ad314d4da38 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs
@@ -3598,7 +3598,7 @@ enum Color
// (40,15): error CS0211: Cannot take the address of the given expression
// p = &(() => 1); //CS0211
Diagnostic(ErrorCode.ERR_InvalidAddrOp, "() => 1").WithLocation(40, 15),
- // (41,13): error CS8801: Cannot convert & method group 'M' to non-function pointer type 'int*'.
+ // (41,13): error CS8801: Cannot convert &method group 'M' to non-function pointer type 'int*'.
// p = &M; //CS0211
Diagnostic(ErrorCode.ERR_AddressOfToNonFunctionPointer, "&M").WithArguments("M", "int*").WithLocation(41, 13),
// (42,15): error CS0211: Cannot take the address of the given expression
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/FunctionPointerTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/FunctionPointerTests.cs
index 382022f27aef5..665c142977acf 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/FunctionPointerTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/FunctionPointerTests.cs
@@ -3106,5 +3106,44 @@ public void FunctionPointerArrayInTypeArgument()
}
EOF();
}
+
+ [Fact]
+ public void UsingAlias()
+ {
+ UsingNode("using t = delegate*;", options: TestOptions.RegularPreview,
+ // (1,11): error CS1041: Identifier expected; 'delegate' is a keyword
+ // using t = delegate*;
+ Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "delegate").WithArguments("", "delegate").WithLocation(1, 11),
+ // (1,25): error CS0116: A namespace cannot directly contain members such as fields or methods
+ // using t = delegate*;
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, ">").WithLocation(1, 25),
+ // (1,26): error CS1022: Type or namespace definition, or end-of-file expected
+ // using t = delegate*;
+ Diagnostic(ErrorCode.ERR_EOFExpected, ";").WithLocation(1, 26)
+ );
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.UsingDirective);
+ {
+ N(SyntaxKind.UsingKeyword);
+ N(SyntaxKind.NameEquals);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "t");
+ }
+ N(SyntaxKind.EqualsToken);
+ }
+ M(SyntaxKind.IdentifierName);
+ {
+ M(SyntaxKind.IdentifierToken);
+ }
+ M(SyntaxKind.SemicolonToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs
index bac8d43fd3701..12bf83026ee57 100644
--- a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs
@@ -588,5 +588,21 @@ public void TestParenthesizedLambdaNoParameterList_ExpressionBody()
body: SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1)));
Assert.Equal(fullySpecified.ToFullString(), lambda.ToFullString());
}
+
+ [Fact]
+ public void TestParseNameWithOptions()
+ {
+ var type = "delegate*";
+
+ var parsedWith8 = SyntaxFactory.ParseTypeName(type, options: TestOptions.Regular8);
+ parsedWith8.GetDiagnostics().Verify(
+ // (1,1): error CS8652: The feature 'function pointers' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // delegate*
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("function pointers").WithLocation(1, 1)
+ );
+
+ var parsedWithPreview = SyntaxFactory.ParseTypeName(type, options: TestOptions.RegularPreview);
+ parsedWithPreview.GetDiagnostics().Verify();
+ }
}
}
diff --git a/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt b/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt
index 8b137891791fe..3be2c921b772c 100644
--- a/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt
+++ b/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt
@@ -1 +1,3 @@
-
+Shared Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseTypeName(text As String, offset As Integer = 0, options As Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions = Nothing, consumeFullText As Boolean = True) -> Microsoft.CodeAnalysis.VisualBasic.Syntax.TypeSyntax
+Shared Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseTypeName(text As String, offset As Integer, consumeFullText As Boolean) -> Microsoft.CodeAnalysis.VisualBasic.Syntax.TypeSyntax
+*REMOVED*Shared Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseTypeName(text As String, offset As Integer = 0, consumeFullText As Boolean = True) -> Microsoft.CodeAnalysis.VisualBasic.Syntax.TypeSyntax
diff --git a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb
index 4a064d6849090..5b17efc0222db 100644
--- a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb
+++ b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb
@@ -15,6 +15,7 @@ Imports Microsoft.CodeAnalysis.VisualBasic.SyntaxFacts
Imports InternalSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Imports Microsoft.CodeAnalysis.Syntax
Imports System.Collections.Immutable
+Imports System.ComponentModel
Namespace Microsoft.CodeAnalysis.VisualBasic
@@ -191,14 +192,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
'''
''' The input string
''' The starting offset in the string
- Public Shared Function ParseTypeName(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As TypeSyntax
- Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
+ Public Shared Function ParseTypeName(text As String, Optional offset As Integer = 0, Optional options As VisualBasicParseOptions = Nothing, Optional consumeFullText As Boolean = True) As TypeSyntax
+ Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), If(options, VisualBasicParseOptions.Default))
p.GetNextToken()
Dim node = p.ParseGeneralType()
Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), TypeSyntax)
End Using
End Function
+ '' Backcompat overload, do not touch
+ '''
+ ''' Parse a type name.
+ '''
+ ''' The input string
+ ''' The starting offset in the string
+
+ Public Shared Function ParseTypeName(text As String, offset As Integer, consumeFullText As Boolean) As TypeSyntax
+ Return ParseTypeName(text, offset, options:=Nothing, consumeFullText)
+ End Function
+
'''
''' Parse an expression.
'''
diff --git a/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb b/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb
index 0eb9346399c19..429e675ddb546 100644
--- a/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb
+++ b/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb
@@ -109,5 +109,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Assert.Equal(expected, literalMethod.Invoke(Nothing, {value}).ToString())
End Sub
+
+
+ Public Shared Sub TestParseTypeNameOptions()
+ Dim options As VisualBasicParseOptions = TestOptions.Regular
+ Dim code = "
+#If Variable
+String
+#Else
+Integer
+#End If"
+
+ Dim type1 = SyntaxFactory.ParseTypeName(code, options:=options.WithPreprocessorSymbols(New KeyValuePair(Of String, Object)("Variable", "True")))
+ Assert.Equal("String", type1.ToString())
+
+ Dim type2 = SyntaxFactory.ParseTypeName(code, options:=options)
+ Assert.Equal("Integer", type2.ToString())
+ End Sub
End Class
End Namespace
diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/LessAndGreaterThanCompletionSession.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/LessAndGreaterThanCompletionSession.cs
index 0fec74e8a9c4c..efe914d0f9f85 100644
--- a/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/LessAndGreaterThanCompletionSession.cs
+++ b/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/LessAndGreaterThanCompletionSession.cs
@@ -35,6 +35,7 @@ public override bool CheckOpeningPoint(IBraceCompletionSession session, Cancella
// type argument or parameter list
if (!token.CheckParent(n => n.LessThanToken == token) &&
!token.CheckParent(n => n.LessThanToken == token) &&
+ !token.CheckParent(n => n.LessThanToken == token) &&
!PossibleTypeArgument(snapshot, token, cancellationToken))
{
return false;
diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs
index da55d50df7de0..7eb9a06a509dd 100644
--- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs
+++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs
@@ -392,6 +392,19 @@ public void Method() { }
CheckStart(session.Session);
}
+ [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
+ public void FunctionPointerStartSession()
+ {
+ var code = @"
+class C
+{
+ delegate*$$";
+
+ using var session = CreateSession(code);
+ Assert.NotNull(session);
+ CheckStart(session.Session);
+ }
+
internal Holder CreateSession(string code)
{
return CreateSession(
diff --git a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs
index b3abe0fe98fe4..bcdc962400e3f 100644
--- a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs
+++ b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs
@@ -11109,17 +11109,17 @@ public async Task ExtractMethodInInterface()
var code = @"
interface Program
{
- void Foo();
+ void Goo();
void Test()
{
- [|Foo();|]
+ [|Goo();|]
}
}";
var expected = @"
interface Program
{
- void Foo();
+ void Goo();
void Test()
{
@@ -11128,7 +11128,7 @@ void Test()
void NewMethod()
{
- Foo();
+ Goo();
}
}";
await TestExtractMethodAsync(code, expected);
@@ -11139,18 +11139,18 @@ void NewMethod()
public async Task ExtractMethodInExpressionBodiedConstructors()
{
var code = @"
-class Foo
+class Goo
{
private readonly string _bar;
- private Foo(string bar) => _bar = [|bar|];
+ private Goo(string bar) => _bar = [|bar|];
}";
var expected = @"
-class Foo
+class Goo
{
private readonly string _bar;
- private Foo(string bar) => _bar = GetBar(bar);
+ private Goo(string bar) => _bar = GetBar(bar);
private static string GetBar(string bar)
{
@@ -11165,18 +11165,18 @@ private static string GetBar(string bar)
public async Task ExtractMethodInExpressionBodiedFinalizers()
{
var code = @"
-class Foo
+class Goo
{
bool finalized;
- ~Foo() => finalized = [|true|];
+ ~Goo() => finalized = [|true|];
}";
var expected = @"
-class Foo
+class Goo
{
bool finalized;
- ~Foo() => finalized = NewMethod();
+ ~Goo() => finalized = NewMethod();
private static bool NewMethod()
{
@@ -11185,5 +11185,65 @@ private static bool NewMethod()
}";
await TestExtractMethodAsync(code, expected);
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)]
+ public async Task ExtractMethodInvolvingFunctionPointer()
+ {
+ var code = @"
+class C
+{
+ void M(delegate*> ptr1)
+ {
+ string s = null;
+ _ = [|ptr1()|](ref s);
+ }
+}";
+
+ var expected = @"
+class C
+{
+ void M(delegate*> ptr1)
+ {
+ string s = null;
+ _ = NewMethod(ptr1)(ref s);
+ }
+
+ private static delegate*[ NewMethod(delegate*> ptr1)
+ {
+ return ptr1();
+ }
+}";
+
+ await TestExtractMethodAsync(code, expected);
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)]
+ public async Task ExtractMethodInvolvingFunctionPointerWithTypeParameter()
+ {
+ var code = @"
+class C
+{
+ void M(delegate* ptr1)
+ {
+ _ = [|ptr1|]();
+ }
+}";
+
+ var expected = @"
+class C
+{
+ void M(delegate* ptr1)
+ {
+ _ = GetPtr1(ptr1)();
+ }
+
+ private static delegate* GetPtr1(delegate* ptr1)
+ {
+ return ptr1;
+ }
+}";
+
+ await TestExtractMethodAsync(code, expected);
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/BoolKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/BoolKeywordRecommenderTests.cs
index bf7bf2133a5df..91b826f74bf10 100644
--- a/src/EditorFeatures/CSharpTest2/Recommendations/BoolKeywordRecommenderTests.cs
+++ b/src/EditorFeatures/CSharpTest2/Recommendations/BoolKeywordRecommenderTests.cs
@@ -716,5 +716,41 @@ void Method()
}
}");
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointerType()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ delegate*<$$");
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointerTypeAfterComma()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ delegate* await VerifyAbsenceAsync(@"sealed $$");
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotAfterStatic()
- => await VerifyAbsenceAsync(@"static $$");
+ public async Task TestAfterStatic()
+ {
+ await VerifyAbsenceAsync(SourceCodeKind.Regular, @"static $$");
+ await VerifyKeywordAsync(SourceCodeKind.Script, @"static $$");
+ }
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotAfterStaticPublic()
- => await VerifyAbsenceAsync(@"static public $$");
+ public async Task TestAfterStaticPublic()
+ {
+ await VerifyAbsenceAsync(SourceCodeKind.Regular, @"static public $$");
+ await VerifyKeywordAsync(SourceCodeKind.Script, @"static public $$");
+ }
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotAfterDelegate()
- => await VerifyAbsenceAsync(@"delegate $$");
+ public async Task TestAfterDelegate()
+ => await VerifyKeywordAsync(@"delegate $$");
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestDelegateAsArgument()
@@ -297,25 +312,25 @@ await VerifyKeywordAsync(
[WorkItem(538804, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538804")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotInTypeOf()
+ public async Task TestInTypeOf()
{
- await VerifyAbsenceAsync(AddInsideMethod(
+ await VerifyKeywordAsync(AddInsideMethod(
@"typeof($$"));
}
[WorkItem(538804, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538804")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotInDefault()
+ public async Task TestInDefault()
{
- await VerifyAbsenceAsync(AddInsideMethod(
+ await VerifyKeywordAsync(AddInsideMethod(
@"default($$"));
}
[WorkItem(538804, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538804")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotInSizeOf()
+ public async Task TestInSizeOf()
{
- await VerifyAbsenceAsync(AddInsideMethod(
+ await VerifyKeywordAsync(AddInsideMethod(
@"sizeof($$"));
}
@@ -345,15 +360,24 @@ void M()
Action a = async $$");
}
- [WorkItem(607197, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/607197")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
- public async Task TestNotAfterAsyncInMemberDeclaration()
+ public async Task TestAfterAsyncInMemberDeclaration()
{
- await VerifyAbsenceAsync(@"
+ await VerifyKeywordAsync(@"
using System;
class C
{
async $$");
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointerTypeList()
+ {
+ await VerifyKeywordAsync(@"
+using System;
+class C
+{
+ delegate*<$$");
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/DoubleKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/DoubleKeywordRecommenderTests.cs
index 8980c66c24379..d46f9d7045d6c 100644
--- a/src/EditorFeatures/CSharpTest2/Recommendations/DoubleKeywordRecommenderTests.cs
+++ b/src/EditorFeatures/CSharpTest2/Recommendations/DoubleKeywordRecommenderTests.cs
@@ -716,5 +716,41 @@ void Method()
}
}");
}
+
+ [Fact]
+ public async Task TestInFunctionPointerType()
+ {
+ await VerifyKeywordAsync(@"
+class Program
+{
+ delegate*<$$");
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointerTypeAfterComma()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ delegate* await VerifyAbsenceAsync(@"class c { async async $$ }");
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointerType()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ delegate*<$$");
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointerTypeAfterComma()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ delegate* a)
}
}");
}
+
+ [Fact]
+ [Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointer01()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ delegate*<$$");
+ }
+
+ [Fact]
+ [Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ public async Task TestInFunctionPointer02()
+ {
+ await VerifyKeywordAsync(@"
+class C
+{
+ C()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsFixedVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs
index 8dbf7de3c6521..b5081139e73cf 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs
@@ -29,6 +29,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs
index db432b9629afa..f39a27021420c 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsFixedVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs
index b8b32d1cb216f..df9ea614df9a3 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsFixedVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DelegateKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DelegateKeywordRecommender.cs
index b886fdc317d11..5aa496c15e460 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DelegateKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DelegateKeywordRecommender.cs
@@ -30,13 +30,18 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
{
return
context.IsGlobalStatementContext ||
- (context.IsNonAttributeExpressionContext && !context.IsConstantExpressionContext) ||
+ ValidTypeContext(context) ||
IsAfterAsyncKeywordInExpressionContext(context, cancellationToken) ||
context.IsTypeDeclarationContext(
validModifiers: s_validModifiers,
validTypeDeclarations: SyntaxKindSet.ClassInterfaceStructTypeDeclarations,
canBePartial: false,
cancellationToken: cancellationToken);
+
+ static bool ValidTypeContext(CSharpSyntaxContext context)
+ => (context.IsNonAttributeExpressionContext || context.IsTypeContext)
+ && !context.IsConstantExpressionContext
+ && !context.LeftToken.IsTopLevelOfUsingAliasDirective();
}
private static bool IsAfterAsyncKeywordInExpressionContext(CSharpSyntaxContext context, CancellationToken cancellationToken)
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs
index 231cb1cdabb6c..c3a3bc1b062af 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsFixedVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs
index 62e20da2ca7a2..6d20d03968bf9 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs
@@ -53,6 +53,7 @@ protected static bool IsDynamicTypeContext(
syntaxTree.IsPossibleCastTypeContext(position, context.LeftToken, cancellationToken) ||
context.IsObjectCreationTypeContext ||
context.IsGenericTypeArgumentContext ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
syntaxTree.IsDefaultExpressionContext(position, context.LeftToken) ||
syntaxTree.IsAfterKeyword(position, SyntaxKind.ConstKeyword, cancellationToken) ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs
index f48d39680e2c2..fd53561cc484e 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsFixedVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs
index 928b3bb852378..c34583e01b4f0 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs
@@ -37,6 +37,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsAnyExpressionContext ||
context.IsObjectCreationTypeContext ||
context.IsIsOrAsTypeContext ||
+ context.IsFunctionPointerTypeArgumentContext ||
syntaxTree.IsAfterKeyword(position, SyntaxKind.ConstKeyword, cancellationToken) ||
syntaxTree.IsAfterKeyword(position, SyntaxKind.RefKeyword, cancellationToken) ||
syntaxTree.IsAfterKeyword(position, SyntaxKind.ReadOnlyKeyword, cancellationToken) ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntKeywordRecommender.cs
index 57e0242b0b096..c5339a86c4ef1 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs
index 2ff8ac4878d6f..92d34e3becdba 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs
index 4479016e01d4f..d469abd5acbb3 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsParameterTypeContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs
index c9399497b6609..56ca9f17bd512 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs
@@ -42,7 +42,8 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
private static bool IsRefReadOnlyContext(CSharpSyntaxContext context)
=> context.TargetToken.IsKind(SyntaxKind.RefKeyword) &&
- context.TargetToken.Parent.IsKind(SyntaxKind.RefType);
+ (context.TargetToken.Parent.IsKind(SyntaxKind.RefType) ||
+ (context.TargetToken.Parent.IsKind(SyntaxKind.Parameter) && context.IsFunctionPointerTypeArgumentContext));
private static bool IsValidContextForType(CSharpSyntaxContext context, CancellationToken cancellationToken)
{
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs
index dcc3a37da2b21..a9b60e470b6ef 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs
index c7d29756fc646..99583e36c6920 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs
index 1f9f1a9492010..426356918afd9 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
context.IsParameterTypeContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs
index 2ce88ad7a9cfd..b2c9399b27e2a 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs
index cd604bffd5304..46d37b1f13c3e 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs
index 9f544c325f9ff..40d5c34ab1c5f 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs
@@ -28,6 +28,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsGlobalStatementContext ||
context.IsObjectCreationTypeContext ||
(context.IsGenericTypeArgumentContext && !context.TargetToken.Parent.HasAncestor()) ||
+ context.IsFunctionPointerTypeArgumentContext ||
context.IsEnumBaseListContext ||
context.IsIsOrAsTypeContext ||
context.IsLocalVariableDeclarationContext ||
diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VoidKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VoidKeywordRecommender.cs
index b71d225e8c693..669b793586557 100644
--- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VoidKeywordRecommender.cs
+++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VoidKeywordRecommender.cs
@@ -43,6 +43,7 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
context.IsTypeOfExpressionContext ||
syntaxTree.IsSizeOfExpressionContext(position, context.LeftToken) ||
context.IsDelegateReturnTypeContext ||
+ context.IsFunctionPointerTypeArgumentContext ||
IsUnsafeLocalVariableDeclarationContext(context) ||
IsUnsafeParameterTypeContext(context) ||
IsUnsafeCastTypeContext(context) ||
diff --git a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.TypeParameterCollector.cs b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.TypeParameterCollector.cs
index bf7c8639091f3..0cbdef5ec3ed0 100644
--- a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.TypeParameterCollector.cs
+++ b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.TypeParameterCollector.cs
@@ -29,6 +29,15 @@ public override void VisitDynamicType(IDynamicTypeSymbol dynamicTypeSymbol)
{
}
+ public override void VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol)
+ {
+ symbol.Signature.ReturnType.Accept(this);
+ foreach (var param in symbol.Signature.Parameters)
+ {
+ param.Type.Accept(this);
+ }
+ }
+
public override void VisitArrayType(IArrayTypeSymbol arrayTypeSymbol)
=> arrayTypeSymbol.ElementType.Accept(this);
diff --git a/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs b/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs
index c9957ea9c5baf..071b9cee1ef01 100644
--- a/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs
+++ b/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs
@@ -129,6 +129,9 @@ public static Glyph GetGlyph(this ISymbol symbol)
case SymbolKind.PointerType:
return ((IPointerTypeSymbol)symbol).PointedAtType.GetGlyph();
+ case SymbolKind.FunctionPointer:
+ return Glyph.Intrinsic;
+
case SymbolKind.Property:
{
var propertySymbol = (IPropertySymbol)symbol;
diff --git a/src/VisualStudio/CSharp/Impl/ChangeSignature/CSharpChangeSignatureViewModelFactoryService.cs b/src/VisualStudio/CSharp/Impl/ChangeSignature/CSharpChangeSignatureViewModelFactoryService.cs
index b6bdedfb1bb1d..cc8873e430c61 100644
--- a/src/VisualStudio/CSharp/Impl/ChangeSignature/CSharpChangeSignatureViewModelFactoryService.cs
+++ b/src/VisualStudio/CSharp/Impl/ChangeSignature/CSharpChangeSignatureViewModelFactoryService.cs
@@ -16,6 +16,8 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.ChangeSignature
[ExportLanguageService(typeof(IChangeSignatureViewModelFactoryService), LanguageNames.CSharp), Shared]
internal class CSharpChangeSignatureViewModelFactoryService : ChangeSignatureViewModelFactoryService
{
+ private static readonly CSharpParseOptions s_langVersionLatestParseOptions = new CSharpParseOptions(LanguageVersion.Preview);
+
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public CSharpChangeSignatureViewModelFactoryService()
@@ -44,7 +46,9 @@ public override SymbolDisplayPart[] GeneratePreviewDisplayParts(AddedParameterVi
return parts.ToArray();
}
- public override bool IsTypeNameValid(string typeName) => !SyntaxFactory.ParseTypeName(typeName).ContainsDiagnostics;
+ // Use LangVersion Preview to ensure that all types parse correctly. If the user types in a type only available
+ // in a preview version, they'll get a diagnostic after everything is generated
+ public override bool IsTypeNameValid(string typeName) => !SyntaxFactory.ParseTypeName(typeName, options: s_langVersionLatestParseOptions).ContainsDiagnostics;
public override SyntaxNode GetTypeNode(string typeName) => SyntaxFactory.ParseTypeName(typeName);
}
diff --git a/src/VisualStudio/VisualBasic/Impl/ChangeSignature/VisualBasicChangeSignatureViewModelFactoryService.vb b/src/VisualStudio/VisualBasic/Impl/ChangeSignature/VisualBasicChangeSignatureViewModelFactoryService.vb
index a232641052967..52b2a5fb64948 100644
--- a/src/VisualStudio/VisualBasic/Impl/ChangeSignature/VisualBasicChangeSignatureViewModelFactoryService.vb
+++ b/src/VisualStudio/VisualBasic/Impl/ChangeSignature/VisualBasicChangeSignatureViewModelFactoryService.vb
@@ -41,7 +41,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.ChangeSignature
End Function
Public Overrides Function IsTypeNameValid(typeName As String) As Boolean
- Return Not SyntaxFactory.ParseTypeName(typeName).ContainsDiagnostics
+ Static visualBasicParseOptions As New VisualBasicParseOptions(LanguageVersion.Latest)
+ Return Not SyntaxFactory.ParseTypeName(typeName, options:=visualBasicParseOptions).ContainsDiagnostics
End Function
Public Overrides Function GetTypeNode(typeName As String) As SyntaxNode
diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
index 151186d7377e7..bbf110a00e076 100644
--- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
+++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
@@ -200,13 +200,17 @@ public override SyntaxNode ParameterDeclaration(string name, SyntaxNode type, Sy
initializer != null ? SyntaxFactory.EqualsValueClause((ExpressionSyntax)initializer) : null);
}
- internal static SyntaxTokenList GetParameterModifiers(RefKind refKind)
+ internal static SyntaxTokenList GetParameterModifiers(RefKind refKind, bool forFunctionPointerReturnParameter = false)
=> refKind switch
{
RefKind.None => new SyntaxTokenList(),
RefKind.Out => SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.OutKeyword)),
RefKind.Ref => SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.RefKeyword)),
- RefKind.In => SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.InKeyword)),
+ // Note: RefKind.RefReadonly == RefKind.In. Function Pointers must use the correct
+ // ref kind syntax when generating for the return parameter vs other parameters.
+ // The return parameter must use ref readonly, like regular methods.
+ RefKind.In when !forFunctionPointerReturnParameter => SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.InKeyword)),
+ RefKind.RefReadOnly when forFunctionPointerReturnParameter => SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.RefKeyword), SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)),
_ => throw ExceptionUtilities.UnexpectedValue(refKind),
};
diff --git a/src/Workspaces/CSharpTest/Formatting/FormattingTests_FunctionPointers.cs b/src/Workspaces/CSharpTest/Formatting/FormattingTests_FunctionPointers.cs
index 8f0d8f4ea71a4..7f9bc9ed9bab1 100644
--- a/src/Workspaces/CSharpTest/Formatting/FormattingTests_FunctionPointers.cs
+++ b/src/Workspaces/CSharpTest/Formatting/FormattingTests_FunctionPointers.cs
@@ -29,5 +29,24 @@ unsafe class C
await AssertFormatAsync(expected, content);
}
+
+ [Fact]
+ public async Task FormatFunctionPointerWithCallingConvention()
+ {
+ // TODO(https://github.com/dotnet/roslyn/issues/44312): add a space after the "int"s in the baseline and make this test still pass
+ var content = @"
+unsafe class C
+{
+ delegate *cdecl < int, int> functionPointer;
+}";
+
+ var expected = @"
+unsafe class C
+{
+ delegate* cdecl functionPointer;
+}";
+
+ await AssertFormatAsync(expected, content);
+ }
}
}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs
new file mode 100644
index 0000000000000..31e9b64f12fc3
--- /dev/null
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.FunctionPointerTypeSymbolKey.cs
@@ -0,0 +1,36 @@
+// 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.
+
+namespace Microsoft.CodeAnalysis
+{
+ internal partial struct SymbolKey
+ {
+ private static class FunctionPointerTypeSymbolKey
+ {
+ public static void Create(IFunctionPointerTypeSymbol symbol, SymbolKeyWriter visitor)
+ {
+ visitor.WriteRefKind(symbol.Signature.RefKind);
+ visitor.WriteSymbolKey(symbol.Signature.ReturnType);
+ visitor.WriteRefKindArray(symbol.Signature.Parameters);
+ visitor.WriteParameterTypesArray(symbol.Signature.Parameters);
+ }
+
+ public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
+ {
+ var returnRefKind = reader.ReadRefKind();
+ var returnType = reader.ReadSymbolKey();
+ using var paramRefKinds = reader.ReadRefKindArray();
+ using var paramTypes = reader.ReadSymbolKeyArray();
+
+ if (paramTypes.IsDefault || !(returnType.GetAnySymbol() is ITypeSymbol returnTypeSymbol))
+ {
+ return default;
+ }
+
+ return new SymbolKeyResolution(reader.Compilation.CreateFunctionPointerTypeSymbol(
+ returnTypeSymbol, returnRefKind, paramTypes.ToImmutable(), paramRefKinds.ToImmutable()));
+ }
+ }
+ }
+}
diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs
index cbf4cdc0388b0..0249a8db8a077 100644
--- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs
+++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs
@@ -38,7 +38,7 @@ public Reader()
{
_readString = ReadString;
_readBoolean = ReadBoolean;
- _readRefKind = () => (RefKind)ReadInteger();
+ _readRefKind = ReadRefKind;
}
protected virtual void Initialize(string data, CancellationToken cancellationToken)
@@ -192,6 +192,11 @@ public PooledArrayBuilder ReadArray(Func readFunction)
EatCloseParen();
return builder;
}
+
+ public RefKind ReadRefKind()
+ {
+ return (RefKind)ReadInteger();
+ }
}
private class RemoveAssemblySymbolKeysReader : Reader]