diff --git a/Compilers.sln b/Compilers.sln
index 07d8da2518545..e14ec5a431f96 100644
--- a/Compilers.sln
+++ b/Compilers.sln
@@ -69,8 +69,6 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VisualBasicErrorFactsGenera
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "AnalyzerDriver", "src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.shproj", "{D0BC9BE7-24F6-40CA-8DC6-FCB93BD44B34}"
EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedCollections", "src\Compilers\Core\SharedCollections\SharedCollections.shproj", "{C1930979-C824-496B-A630-70F5369A636F}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpWinRTTest", "src\Compilers\CSharp\Test\WinRT\CSharpWinRTTest.csproj", "{FCFA8808-A1B6-48CC-A1EA-0B8CA8AEDA8E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vbc", "src\Compilers\VisualBasic\vbc\vbc.csproj", "{E58EE9D7-1239-4961-A0C1-F9EC3952C4C1}"
@@ -142,7 +140,6 @@ Global
src\Dependencies\CodeAnalysis.Metadata\Microsoft.CodeAnalysis.Metadata.projitems*{afde6bea-5038-4a4a-a88e-dbd2e4088eed}*SharedItemsImports = 4
src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{afde6bea-5038-4a4a-a88e-dbd2e4088eed}*SharedItemsImports = 4
src\Compilers\CSharp\CSharpAnalyzerDriver\CSharpAnalyzerDriver.projitems*{b501a547-c911-4a05-ac6e-274a50dff30e}*SharedItemsImports = 4
- src\Compilers\Core\SharedCollections\SharedCollections.projitems*{c1930979-c824-496b-a630-70f5369a636f}*SharedItemsImports = 13
src\Test\Utilities\Shared\TestUtilities.projitems*{ccbd3438-3e84-40a9-83ad-533f23bcfca5}*SharedItemsImports = 4
src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{cd77a8cc-2885-47a7-b99c-fbf13353400b}*SharedItemsImports = 13
src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{d0bc9be7-24f6-40ca-8dc6-fcb93bd44b34}*SharedItemsImports = 13
@@ -1052,7 +1049,6 @@ Global
{6AA96934-D6B7-4CC8-990D-DB6B9DD56E34} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC}
{909B656F-6095-4AC2-A5AB-C3F032315C45} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC}
{D0BC9BE7-24F6-40CA-8DC6-FCB93BD44B34} = {A41D1B99-F489-4C43-BBDF-96D61B19A6B9}
- {C1930979-C824-496B-A630-70F5369A636F} = {A41D1B99-F489-4C43-BBDF-96D61B19A6B9}
{FCFA8808-A1B6-48CC-A1EA-0B8CA8AEDA8E} = {32A48625-F0AD-419D-828B-A50BDABA38EA}
{E58EE9D7-1239-4961-A0C1-F9EC3952C4C1} = {C65C6143-BED3-46E6-869E-9F0BE6E84C37}
{E3CD2895-76A8-4D11-A316-EA67CB5EA42C} = {32A48625-F0AD-419D-828B-A50BDABA38EA}
diff --git a/build/Targets/Dependencies.props b/build/Targets/Dependencies.props
index d77e580f8e396..2687bdedb8af5 100644
--- a/build/Targets/Dependencies.props
+++ b/build/Targets/Dependencies.props
@@ -35,7 +35,7 @@
4.1.04.1.04.0.1
- 1.4.1-beta-24322-03
+ 1.4.1-beta-24410-024.0.14.1.04.0.1
diff --git a/build/Targets/VSL.Imports.targets b/build/Targets/VSL.Imports.targets
index 0610b862e08f9..941dbc951ea93 100644
--- a/build/Targets/VSL.Imports.targets
+++ b/build/Targets/VSL.Imports.targets
@@ -58,35 +58,18 @@
-
-
- true
-
-
+
-
+
-
-
-
-
- true
-
-
-
-
- true
-
-
-
-
$(VSLToolsPath)\Strong Name Keys\35MSSharedLib1024.snk$(RoslynPublicKey)31BF3856AD364E35
+ true
@@ -207,7 +190,7 @@
$(RoslynAssemblyVersionBase)
-
-
- true
- Cannot sign an unofficial build.
-
-
$(BUILD_BUILDNUMBER)
- A build number must be specified for a signed build.
+ A build number must be specified for a signed build.
@@ -48,7 +42,7 @@
-
+ $(RoslynAssemblyVersionBase).0$(RoslynFileVersionBase).$(BuildNumberFiveDigitDateStamp)
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs
index 3077e20b340b3..8875b1bf3239e 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Query.cs
@@ -648,7 +648,7 @@ private UnboundLambda MakeQueryUnboundLambda(RangeVariableMap qvm, ImmutableArra
{
return MakeQueryUnboundLambda(expression, new QueryUnboundLambdaState(this, qvm, parameters, (LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, DiagnosticBag diagnostics) =>
{
- return lambdaBodyBinder.BindLambdaExpressionAsBlock(RefKind.None, expression, diagnostics);
+ return lambdaBodyBinder.BindLambdaExpressionAsBlock(expression, diagnostics);
}));
}
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
index 28775e3dbefc9..84bd721321623 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
@@ -3661,13 +3661,15 @@ internal BoundBlock BindExpressionBodyAsBlock(ArrowExpressionClauseSyntax expres
///
/// Binds a lambda with expression e as either { return e;} or { e; }.
///
- public BoundBlock BindLambdaExpressionAsBlock(RefKind refKind, ExpressionSyntax body, DiagnosticBag diagnostics)
+ public BoundBlock BindLambdaExpressionAsBlock(ExpressionSyntax body, DiagnosticBag diagnostics)
{
- Binder bodyBinder = this.GetBinder(refKind != RefKind.None ? body.Parent : body);
+ Binder bodyBinder = this.GetBinder(body);
Debug.Assert(bodyBinder != null);
- BoundExpression expression = bodyBinder.BindValue(body, diagnostics, refKind != RefKind.None ? BindValueKind.RefReturn : BindValueKind.RValue);
- return bodyBinder.CreateBlockFromExpression(body, bodyBinder.GetDeclaredLocalsForScope(body), refKind, expression, body, diagnostics);
+ RefKind refKind;
+ var expressionSyntax = ((ExpressionSyntax)body).SkipRef(out refKind);
+ BoundExpression expression = bodyBinder.BindValue(expressionSyntax, diagnostics, refKind != RefKind.None ? BindValueKind.RefReturn : BindValueKind.RValue);
+ return bodyBinder.CreateBlockFromExpression(body, bodyBinder.GetDeclaredLocalsForScope(body), refKind, expression, expressionSyntax, diagnostics);
}
internal virtual ImmutableArray Locals
diff --git a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableBinder.cs b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableBinder.cs
index 2b5e08a5bf77c..d2761466c6608 100644
--- a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableBinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableBinder.cs
@@ -27,8 +27,7 @@ protected override ImmutableArray BuildLocals()
internal override ImmutableArray GetDeclaredLocalsForScope(CSharpSyntaxNode scopeDesignator)
{
- if (ScopeDesignator == scopeDesignator ||
- ScopeDesignator.Kind() == SyntaxKind.RefExpression && ScopeDesignator == scopeDesignator.Parent)
+ if (ScopeDesignator == scopeDesignator)
{
return this.Locals;
}
diff --git a/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs b/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs
index c3b758769fac1..0d595ed65b37f 100644
--- a/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs
+++ b/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs
@@ -127,7 +127,10 @@ private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
bool hasErrors = pattern.HasErrors;
var constantValue = pattern.ConstantValue;
- if (!hasErrors && (object)constantValue != null && this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
+ if (!hasErrors &&
+ (object)constantValue != null &&
+ pattern.Value.Type == SwitchGoverningType &&
+ this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
{
diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
hasErrors = true;
@@ -142,7 +145,7 @@ private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
bool hasErrors = pattern.HasErrors;
if (defaultLabel != null)
{
- diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
+ diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
hasErrors = true;
}
diff --git a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
index 7191c404d3412..e2e50b13b418e 100644
--- a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
+++ b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
@@ -890,9 +890,7 @@ protected override BoundBlock BindLambdaBody(LambdaSymbol lambdaSymbol, Binder l
{
if (this.IsExpressionLambda)
{
- var refKind = CodeAnalysis.RefKind.None;
- var body = ((ExpressionSyntax)this.Body).SkipRef(out refKind);
- return lambdaBodyBinder.BindLambdaExpressionAsBlock(refKind, body, diagnostics);
+ return lambdaBodyBinder.BindLambdaExpressionAsBlock((ExpressionSyntax)this.Body, diagnostics);
}
else
{
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
index 82778fb86b0cf..2f3222e9dc310 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
+++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
@@ -6127,24 +6127,6 @@ internal static string ERR_MultiTypeInDeclaration {
}
}
- ///
- /// Looks up a localized string similar to '{0}' cannot be assigned a reference because it is not a by-reference local.
- ///
- internal static string ERR_MustBeRefAssignable {
- get {
- return ResourceManager.GetString("ERR_MustBeRefAssignable", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Expected a by-reference local.
- ///
- internal static string ERR_MustBeRefAssignableLocal {
- get {
- return ResourceManager.GetString("ERR_MustBeRefAssignableLocal", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to In order for '{0}' to be applicable as a short circuit operator, its declaring type '{1}' must define operator true and operator false.
///
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index c888bca760b96..c1938bd9be965 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -4806,12 +4806,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Struct members cannot return 'this' or other instance members by reference
-
- '{0}' cannot be assigned a reference because it is not a by-reference local
-
-
- Expected a by-reference local
-
Cannot initialize a by-value variable with a reference
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index e060e17920eb8..00ed27157ec75 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1391,44 +1391,35 @@ internal enum ErrorCode
ERR_MustHaveRefReturn = 8150,
ERR_RefReturnMustHaveIdentityConversion = 8151,
ERR_CloseUnimplementedInterfaceMemberWrongRefReturn = 8152,
- ERR_VoidReturningMethodCannotReturnByRef = 8153,
+ ERR_RefReturningCallInExpressionTree = 8153,
ERR_BadIteratorReturnRef = 8154,
ERR_BadRefReturnExpressionTree = 8155,
- ERR_RefReturningCallInExpressionTree = 8156,
-
- ERR_RefReturnLvalueExpected = 8157,
- ERR_RefReturnNonreturnableLocal = 8158,
- ERR_RefReturnNonreturnableLocal2 = 8159,
- ERR_RefReturnRangeVariable = 8160,
- ERR_RefReturnRangeVariable2 = 8170,
- ERR_RefReturnReadonly = 8171,
- ERR_RefReturnReadonlyStatic = 8172,
- ERR_RefReturnReadonly2 = 8173,
- ERR_RefReturnReadonlyStatic2 = 8174,
- ERR_RefReturnCall = 8175,
- ERR_RefReturnCall2 = 8176,
- ERR_RefReturnParameter = 8177,
- ERR_RefReturnParameter2 = 8178,
- ERR_RefReturnLocal = 8179,
- ERR_RefReturnLocal2 = 8180,
- ERR_RefReturnStructThis = 8181,
-
- // Available = 8182, 8183
-
- ERR_MustBeRefAssignable = 8184,
- ERR_MustBeRefAssignableLocal = 8185,
- ERR_InitializeByValueVariableWithReference = 8186,
- ERR_InitializeByReferenceVariableWithValue = 8187,
- ERR_RefAssignmentMustHaveIdentityConversion = 8188,
- ERR_ByReferenceVariableMustBeInitialized = 8189,
-
- ERR_AnonDelegateCantUseLocal = 8190,
- ERR_BadIteratorLocalType = 8191,
- ERR_BadAsyncLocalType = 8192,
- ERR_RefReturningCallAndAwait = 8193,
+ ERR_RefReturnLvalueExpected = 8156,
+ ERR_RefReturnNonreturnableLocal = 8157,
+ ERR_RefReturnNonreturnableLocal2 = 8158,
+ ERR_RefReturnRangeVariable = 8159,
+ ERR_RefReturnReadonly = 8160,
+ ERR_RefReturnReadonlyStatic = 8161,
+ ERR_RefReturnReadonly2 = 8162,
+ ERR_RefReturnReadonlyStatic2 = 8163,
+ ERR_RefReturnCall = 8164,
+ ERR_RefReturnCall2 = 8165,
+ ERR_RefReturnParameter = 8166,
+ ERR_RefReturnParameter2 = 8167,
+ ERR_RefReturnLocal = 8168,
+ ERR_RefReturnLocal2 = 8169,
+ ERR_RefReturnStructThis = 8170,
+ ERR_InitializeByValueVariableWithReference = 8171,
+ ERR_InitializeByReferenceVariableWithValue = 8172,
+ ERR_RefAssignmentMustHaveIdentityConversion = 8173,
+ ERR_ByReferenceVariableMustBeInitialized = 8174,
+ ERR_AnonDelegateCantUseLocal = 8175,
+ ERR_BadIteratorLocalType = 8176,
+ ERR_BadAsyncLocalType = 8177,
+ ERR_RefReturningCallAndAwait = 8178,
#endregion diagnostics for ref locals and ref returns introduced in C# 7
- // Available = 8194, 8195
+ // Available = 8179-8195
#region diagnostics for out var
ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList = 8196,
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs
index 9ffba0b17a3dd..f9a6e656e1180 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs
@@ -121,6 +121,17 @@ public static SourceLocalSymbol MakeLocal(
return new LocalWithInitializer(containingSymbol, binder, typeSyntax, identifierToken, initializer, declarationKind);
}
+ ///
+ ///
+ /// Binder that owns the scope for the local, the one that returns it in its array.
+ ///
+ ///
+ /// Enclosing binder for the location where the local is declared, if different from the .
+ /// It should be used to bind something at that location.
+ ///
+ ///
+ ///
+ ///
public static SourceLocalSymbol MakeOutVariable(
Symbol containingSymbol,
Binder scopeBinder,
@@ -129,7 +140,12 @@ public static SourceLocalSymbol MakeOutVariable(
SyntaxToken identifierToken,
CSharpSyntaxNode context)
{
- return new OutLocalSymbol(containingSymbol, scopeBinder, enclosingBinderOpt, typeSyntax, identifierToken, context);
+ if (typeSyntax.IsVar)
+ {
+ return new PossiblyImplicitlyTypedOutVarLocalSymbol(containingSymbol, scopeBinder, enclosingBinderOpt, typeSyntax, identifierToken, context);
+ }
+
+ return new SourceLocalSymbol(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, LocalDeclarationKind.RegularVariable);
}
internal override bool IsImportedFromMetadata
@@ -581,14 +597,15 @@ protected override TypeSymbol InferTypeOfVarVariable(DiagnosticBag diagnostics)
}
///
- /// Symbol for an out variable local.
+ /// Symbol for an out variable local that might require type inference during overload resolution, i.e.
+ /// its type is syntactically 'var'.
///
- private class OutLocalSymbol : SourceLocalSymbol
+ private class PossiblyImplicitlyTypedOutVarLocalSymbol : SourceLocalSymbol
{
private readonly CSharpSyntaxNode _containingInvocation;
private readonly Binder _enclosingBinderOpt;
- public OutLocalSymbol(
+ public PossiblyImplicitlyTypedOutVarLocalSymbol(
Symbol containingSymbol,
Binder scopeBinder,
Binder enclosingBinderOpt,
diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs
index bce6baa227300..55b636f7448ed 100644
--- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs
@@ -1354,6 +1354,7 @@ private static bool NormalizeTaskTypesInType(CSharpCompilation compilation, ref
switch (type.Kind)
{
case SymbolKind.NamedType:
+ case SymbolKind.ErrorType:
{
var namedType = (NamedTypeSymbol)type;
var changed = type.IsTupleType ?
@@ -1369,6 +1370,13 @@ private static bool NormalizeTaskTypesInType(CSharpCompilation compilation, ref
type = arrayType;
return changed;
}
+ case SymbolKind.PointerType:
+ {
+ var pointerType = (PointerTypeSymbol)type;
+ var changed = NormalizeTaskTypesInPointer(compilation, ref pointerType);
+ type = pointerType;
+ return changed;
+ }
}
return false;
}
@@ -1456,6 +1464,18 @@ private static bool NormalizeTaskTypesInArray(CSharpCompilation compilation, ref
return true;
}
+ private static bool NormalizeTaskTypesInPointer(CSharpCompilation compilation, ref PointerTypeSymbol pointerType)
+ {
+ var pointedAtType = pointerType.PointedAtType;
+ if (!NormalizeTaskTypesInType(compilation, ref pointedAtType))
+ {
+ return false;
+ }
+ // Preserve custom modifiers but without normalizing those types.
+ pointerType = new PointerTypeSymbol(pointedAtType, pointerType.CustomModifiers);
+ return true;
+ }
+
internal static Cci.TypeReferenceWithAttributes GetTypeRefWithAttributes(
this TypeSymbol type,
CSharpCompilation declaringCompilation,
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs
index bee22b376341d..8c01cc9c6ef9f 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs
@@ -1272,13 +1272,12 @@ class Derived : Base
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (13,29): error CS8893: 'Derived.Method1()' must not return by reference to match overridden member 'Base.Method1()'
- // public override ref int Method1() { return ref field; }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method1").WithArguments("Derived.Method1()", "Base.Method1()", "not ").WithLocation(13, 29),
- // (14,25): error CS8893: 'Derived.Method2(ref int)' must return by reference to match overridden member 'Base.Method2(ref int)'
- // public override int Method2(ref int i) { return i; }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method2").WithArguments("Derived.Method2(ref int)", "Base.Method2(ref int)", "").WithLocation(14, 25)
- );
+ // (13,29): error CS8148: 'Derived.Method1()' must not return by reference to match overridden member 'Base.Method1()'
+ // public override ref int Method1() { return ref field; }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method1").WithArguments("Derived.Method1()", "Base.Method1()", "not ").WithLocation(13, 29),
+ // (14,25): error CS8148: 'Derived.Method2(ref int)' must return by reference to match overridden member 'Base.Method2(ref int)'
+ // public override int Method2(ref int i) { return i; }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method2").WithArguments("Derived.Method2(ref int)", "Base.Method2(ref int)", "").WithLocation(14, 25));
}
[Fact]
@@ -1418,13 +1417,12 @@ class Derived : Base
}
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (15,29): error CS8893: 'Derived.Proprty1' must not return by reference to match overridden member 'Base.Proprty1'
- // public override ref int Proprty1 { get { return ref field; } }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Proprty1").WithArguments("Derived.Proprty1", "Base.Proprty1", "not ").WithLocation(15, 29),
- // (16,25): error CS8893: 'Derived.Property2' must return by reference to match overridden member 'Base.Property2'
- // public override int Property2 { get { return 0; } }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property2").WithArguments("Derived.Property2", "Base.Property2", "").WithLocation(16, 25)
- );
+ // (15,29): error CS8148: 'Derived.Proprty1' must not return by reference to match overridden member 'Base.Proprty1'
+ // public override ref int Proprty1 { get { return ref field; } }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Proprty1").WithArguments("Derived.Proprty1", "Base.Proprty1", "not ").WithLocation(15, 29),
+ // (16,25): error CS8148: 'Derived.Property2' must return by reference to match overridden member 'Base.Property2'
+ // public override int Property2 { get { return 0; } }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property2").WithArguments("Derived.Property2", "Base.Property2", "").WithLocation(16, 25));
}
[Fact]
@@ -1478,13 +1476,12 @@ class Derived : Base
}
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (15,29): error CS8893: 'Derived.this[int, int]' must not return by reference to match overridden member 'Base.this[int, int]'
- // public override ref int this[int x, int y] { get { return ref field; } }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, int]", "Base.this[int, int]", "not ").WithLocation(15, 29),
- // (16,25): error CS8893: 'Derived.this[int, string]' must return by reference to match overridden member 'Base.this[int, string]'
- // public override int this[int x, string y] { get { return field; } }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, string]", "Base.this[int, string]", "").WithLocation(16, 25)
- );
+ // (15,29): error CS8148: 'Derived.this[int, int]' must not return by reference to match overridden member 'Base.this[int, int]'
+ // public override ref int this[int x, int y] { get { return ref field; } }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, int]", "Base.this[int, int]", "not ").WithLocation(15, 29),
+ // (16,25): error CS8148: 'Derived.this[int, string]' must return by reference to match overridden member 'Base.this[int, string]'
+ // public override int this[int x, string y] { get { return field; } }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, string]", "Base.this[int, string]", "").WithLocation(16, 25));
}
///
@@ -2052,31 +2049,30 @@ class Derived : Base
}
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (16,16): warning CS0114: 'Derived.Method3()' hides inherited member 'Base.Method3()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
- // public int Method3() { return 0; } //wrong return type
- Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Method3").WithArguments("Derived.Method3()", "Base.Method3()").WithLocation(16, 16),
- // (18,28): error CS8893: 'Derived.Method5(ref object)' must return by reference to match overridden member 'Base.Method5(ref object)'
- // public override object Method5(ref object o) { return null; } //wrong by-value return
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method5").WithArguments("Derived.Method5(ref object)", "Base.Method5(ref object)", "").WithLocation(18, 28),
- // (19,32): error CS8893: 'Derived.Method6(ref object)' must not return by reference to match overridden member 'Base.Method6(ref object)'
- // public override ref object Method6(ref object o) { return ref o; } //wrong by-ref return
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method6").WithArguments("Derived.Method6(ref object)", "Base.Method6(ref object)", "not ").WithLocation(19, 32),
- // (15,19): warning CS0114: 'Derived.Method2()' hides inherited member 'Base.Method2()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
- // public object Method2() { return null; } //missed override keyword
- Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Method2").WithArguments("Derived.Method2()", "Base.Method2()").WithLocation(15, 19),
- // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method2()'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method2()").WithLocation(12, 7),
- // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method4(int)'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method4(int)").WithLocation(12, 7),
- // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method3()'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method3()").WithLocation(12, 7),
- // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method1()'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method1()").WithLocation(12, 7)
- );
+ // (16,16): warning CS0114: 'Derived.Method3()' hides inherited member 'Base.Method3()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
+ // public int Method3() { return 0; } //wrong return type
+ Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Method3").WithArguments("Derived.Method3()", "Base.Method3()").WithLocation(16, 16),
+ // (18,28): error CS8148: 'Derived.Method5(ref object)' must return by reference to match overridden member 'Base.Method5(ref object)'
+ // public override object Method5(ref object o) { return null; } //wrong by-value return
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method5").WithArguments("Derived.Method5(ref object)", "Base.Method5(ref object)", "").WithLocation(18, 28),
+ // (19,32): error CS8148: 'Derived.Method6(ref object)' must not return by reference to match overridden member 'Base.Method6(ref object)'
+ // public override ref object Method6(ref object o) { return ref o; } //wrong by-ref return
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method6").WithArguments("Derived.Method6(ref object)", "Base.Method6(ref object)", "not ").WithLocation(19, 32),
+ // (15,19): warning CS0114: 'Derived.Method2()' hides inherited member 'Base.Method2()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
+ // public object Method2() { return null; } //missed override keyword
+ Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Method2").WithArguments("Derived.Method2()", "Base.Method2()").WithLocation(15, 19),
+ // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method3()'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method3()").WithLocation(12, 7),
+ // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method2()'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method2()").WithLocation(12, 7),
+ // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method1()'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method1()").WithLocation(12, 7),
+ // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method4(int)'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method4(int)").WithLocation(12, 7));
}
[Fact]
@@ -2121,67 +2117,66 @@ public override object Property7 { set { } }
}
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (23,25): error CS1715: 'Derived.Property3': type must be 'object' to match overridden member 'Base.Property3'
- // public override int Property3 { get; set; } //wrong type
- Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "Property3").WithArguments("Derived.Property3", "Base.Property3", "object").WithLocation(23, 25),
- // (28,45): error CS0546: 'Derived.Property6.set': cannot override because 'Base.Property6' does not have an overridable set accessor
- // public override object Property6 { get; set; }
- Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived.Property6.set", "Base.Property6").WithLocation(28, 45),
- // (29,40): error CS0546: 'Derived.Property7.set': cannot override because 'Base.Property7' does not have an overridable set accessor
- // public override object Property7 { set { } }
- Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived.Property7.set", "Base.Property7").WithLocation(29, 40),
- // (30,40): error CS0545: 'Derived.Property8.get': cannot override because 'Base.Property8' does not have an overridable get accessor
- // public override object Property8 { get; set; }
- Diagnostic(ErrorCode.ERR_NoGetToOverride, "get").WithArguments("Derived.Property8.get", "Base.Property8").WithLocation(30, 40),
- // (31,40): error CS0545: 'Derived.Property9.get': cannot override because 'Base.Property9' does not have an overridable get accessor
- // public override object Property9 { get { return null; } }
- Diagnostic(ErrorCode.ERR_NoGetToOverride, "get").WithArguments("Derived.Property9.get", "Base.Property9").WithLocation(31, 40),
- // (35,32): error CS8893: 'Derived.Property10' must not return by reference to match overridden member 'Base.Property10'
- // public override ref object Property10 { get { return ref o; } }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property10").WithArguments("Derived.Property10", "Base.Property10", "not ").WithLocation(35, 32),
- // (36,28): error CS8893: 'Derived.Property11' must return by reference to match overridden member 'Base.Property11'
- // public override object Property11 { get { return null; } }
- Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property11").WithArguments("Derived.Property11", "Base.Property11", "").WithLocation(36, 28),
- // (22,19): warning CS0114: 'Derived.Property2' hides inherited member 'Base.Property2'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
- // public object Property2 { get; set; } //missed override keyword
- Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Property2").WithArguments("Derived.Property2", "Base.Property2").WithLocation(22, 19),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property5.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property5.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property11.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property11.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property3.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property3.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property2.set'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property2.set").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property9.set'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property9.set").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property10.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property10.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property3.set'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property3.set").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property7.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property7.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property1.set'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property1.set").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property1.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property1.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property2.get'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property2.get").WithLocation(19, 7),
- // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property4.set'
- // class Derived : Base
- Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property4.set").WithLocation(19, 7)
- );
+ // (23,25): error CS1715: 'Derived.Property3': type must be 'object' to match overridden member 'Base.Property3'
+ // public override int Property3 { get; set; } //wrong type
+ Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "Property3").WithArguments("Derived.Property3", "Base.Property3", "object").WithLocation(23, 25),
+ // (28,45): error CS0546: 'Derived.Property6.set': cannot override because 'Base.Property6' does not have an overridable set accessor
+ // public override object Property6 { get; set; }
+ Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived.Property6.set", "Base.Property6").WithLocation(28, 45),
+ // (29,40): error CS0546: 'Derived.Property7.set': cannot override because 'Base.Property7' does not have an overridable set accessor
+ // public override object Property7 { set { } }
+ Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived.Property7.set", "Base.Property7").WithLocation(29, 40),
+ // (30,40): error CS0545: 'Derived.Property8.get': cannot override because 'Base.Property8' does not have an overridable get accessor
+ // public override object Property8 { get; set; }
+ Diagnostic(ErrorCode.ERR_NoGetToOverride, "get").WithArguments("Derived.Property8.get", "Base.Property8").WithLocation(30, 40),
+ // (31,40): error CS0545: 'Derived.Property9.get': cannot override because 'Base.Property9' does not have an overridable get accessor
+ // public override object Property9 { get { return null; } }
+ Diagnostic(ErrorCode.ERR_NoGetToOverride, "get").WithArguments("Derived.Property9.get", "Base.Property9").WithLocation(31, 40),
+ // (35,32): error CS8148: 'Derived.Property10' must not return by reference to match overridden member 'Base.Property10'
+ // public override ref object Property10 { get { return ref o; } }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property10").WithArguments("Derived.Property10", "Base.Property10", "not ").WithLocation(35, 32),
+ // (36,28): error CS8148: 'Derived.Property11' must return by reference to match overridden member 'Base.Property11'
+ // public override object Property11 { get { return null; } }
+ Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property11").WithArguments("Derived.Property11", "Base.Property11", "").WithLocation(36, 28),
+ // (22,19): warning CS0114: 'Derived.Property2' hides inherited member 'Base.Property2'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
+ // public object Property2 { get; set; } //missed override keyword
+ Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Property2").WithArguments("Derived.Property2", "Base.Property2").WithLocation(22, 19),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property1.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property1.get").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property3.set'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property3.set").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property2.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property2.get").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property2.set'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property2.set").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property3.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property3.get").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property1.set'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property1.set").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property11.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property11.get").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property4.set'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property4.set").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property9.set'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property9.set").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property7.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property7.get").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property5.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property5.get").WithLocation(19, 7),
+ // (19,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Property10.get'
+ // class Derived : Base
+ Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property10.get").WithLocation(19, 7));
}
[Fact]
@@ -2490,19 +2485,18 @@ class Class : Interface
}
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (10,15): error CS8897: 'Class' does not implement interface member 'Interface.Method4(ref object)'. 'Class.Method4(ref object)' cannot implement 'Interface.Method4(ref object)' because it does not return by value
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method4(ref object)", "Class.Method4(ref object)", "value").WithLocation(10, 15),
- // (10,15): error CS0535: 'Class' does not implement interface member 'Interface.Method2(int)'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Method2(int)").WithLocation(10, 15),
- // (10,15): error CS8897: 'Class' does not implement interface member 'Interface.Method3(ref object)'. 'Class.Method3(ref object)' cannot implement 'Interface.Method3(ref object)' because it does not return by reference
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method3(ref object)", "Class.Method3(ref object)", "reference").WithLocation(10, 15),
- // (10,15): error CS0535: 'Class' does not implement interface member 'Interface.Method1()'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Method1()").WithLocation(10, 15)
- );
+ // (10,15): error CS8152: 'Class' does not implement interface member 'Interface.Method4(ref object)'. 'Class.Method4(ref object)' cannot implement 'Interface.Method4(ref object)' because it does not return by value
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method4(ref object)", "Class.Method4(ref object)", "value").WithLocation(10, 15),
+ // (10,15): error CS0535: 'Class' does not implement interface member 'Interface.Method2(int)'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Method2(int)").WithLocation(10, 15),
+ // (10,15): error CS8152: 'Class' does not implement interface member 'Interface.Method3(ref object)'. 'Class.Method3(ref object)' cannot implement 'Interface.Method3(ref object)' because it does not return by reference
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method3(ref object)", "Class.Method3(ref object)", "reference").WithLocation(10, 15),
+ // (10,15): error CS0535: 'Class' does not implement interface member 'Interface.Method1()'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Method1()").WithLocation(10, 15));
}
[Fact]
@@ -2543,28 +2537,27 @@ public object Property5 { set { } }
}
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property2.set'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property2.set").WithLocation(17, 15),
- // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property3.get'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property3.get").WithLocation(17, 15),
- // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property5.get'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property5.get").WithLocation(17, 15),
- // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property7.set'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property7.set").WithLocation(17, 15),
- // (17,15): error CS8897: 'Class' does not implement interface member 'Interface.Property8'. 'Class.Property8' cannot implement 'Interface.Property8' because it does not return by reference
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property8", "Class.Property8", "reference").WithLocation(17, 15),
- // (17,15): error CS8897: 'Class' does not implement interface member 'Interface.Property9'. 'Class.Property9' cannot implement 'Interface.Property9' because it does not return by value
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property9", "Class.Property9", "value").WithLocation(17, 15),
- // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property1'
- // class Class : Interface
- Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property1").WithLocation(17, 15)
- );
+ // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property2.set'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property2.set").WithLocation(17, 15),
+ // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property3.get'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property3.get").WithLocation(17, 15),
+ // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property5.get'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property5.get").WithLocation(17, 15),
+ // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property7.set'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property7.set").WithLocation(17, 15),
+ // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.Property8'. 'Class.Property8' cannot implement 'Interface.Property8' because it does not return by reference
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property8", "Class.Property8", "reference").WithLocation(17, 15),
+ // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.Property9'. 'Class.Property9' cannot implement 'Interface.Property9' because it does not return by value
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property9", "Class.Property9", "value").WithLocation(17, 15),
+ // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property1'
+ // class Class : Interface
+ Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property1").WithLocation(17, 15));
}
[Fact]
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
index 7b4888107633d..42ae4b004c174 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
@@ -1193,13 +1193,13 @@ static void M()
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (11,22): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (11,22): error CS8149: By-reference returns may only be used in by-reference returning methods.
// ME(() => ref i);
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "i").WithLocation(11, 22),
- // (12,20): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (12,20): error CS8149: By-reference returns may only be used in by-reference returning methods.
// ME(() => { return ref i; });
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(12, 20),
- // (13,23): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (13,23): error CS8149: By-reference returns may only be used in by-reference returning methods.
// ME(delegate { return ref i; });
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(13, 23));
}
@@ -1223,13 +1223,13 @@ static void M()
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (9,33): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (9,33): error CS8149: By-reference returns may only be used in by-reference returning methods.
// var e = new E(() => ref i);
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "i").WithLocation(9, 33),
- // (10,27): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (10,27): error CS8149: By-reference returns may only be used in by-reference returning methods.
// e = new E(() => { return ref i; });
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(10, 27),
- // (11,30): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (11,30): error CS8149: By-reference returns may only be used in by-reference returning methods.
// e = new E(delegate { return ref i; });
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(11, 30));
}
@@ -1268,10 +1268,10 @@ static void M()
";
CreateCompilationWithMscorlib45(text).VerifyDiagnostics(
- // (18,13): error CS8084: By-value returns may only be used in by-value returning methods.
+ // (18,13): error CS8150: By-value returns may only be used in by-value returning methods.
// return i;
Diagnostic(ErrorCode.ERR_MustHaveRefReturn, "return").WithLocation(18, 13),
- // (23,17): error CS8083: By-reference returns may only be used in by-reference returning methods.
+ // (23,17): error CS8149: By-reference returns may only be used in by-reference returning methods.
// return ref i;
Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(23, 17));
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs
index 8b943824e6e20..f5deb19a620bd 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs
@@ -293,7 +293,7 @@ class Test
// (28,20): error CS0103: The name 'List2' does not exist in the current context
// s = nameof(List2<>.Add);
Diagnostic(ErrorCode.ERR_NameNotInContext, "List2<>").WithArguments("List2").WithLocation(28, 20),
- // (31,20): error CS8083: An alias-qualified name is not an expression.
+ // (31,20): error CS8149: An alias-qualified name is not an expression.
// s = nameof(global::Program); // not an expression
Diagnostic(ErrorCode.ERR_AliasQualifiedNameNotAnExpression, "global::Program").WithLocation(31, 20),
// (32,20): error CS0305: Using the generic type 'Test' requires 1 type arguments
@@ -305,7 +305,7 @@ class Test
// (33,20): error CS0841: Cannot use local variable 'b' before it is declared
// s = nameof(b); // cannot use before declaration
Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "b").WithArguments("b").WithLocation(33, 20),
- // (35,20): error CS8084: Type parameters are not allowed on a method group as an argument to 'nameof'.
+ // (35,20): error CS8150: Type parameters are not allowed on a method group as an argument to 'nameof'.
// s = nameof(System.Linq.Enumerable.Select); // type parameters not allowed on method group in nameof
Diagnostic(ErrorCode.ERR_NameofMethodGroupWithTypeParameters, "System.Linq.Enumerable.Select").WithLocation(35, 20),
// (43,13): error CS0103: The name 'nameof' does not exist in the current context
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs
index 76882060ed28d..b7e2808a80390 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs
@@ -11822,7 +11822,7 @@ static object Test1(out int x, out int x2)
parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
- // (7,23): error CS8927: Reference to an implicitly-typed out variable 'x1' is not permitted in the same argument list.
+ // (7,23): error CS8181: Reference to an implicitly-typed out variable 'x1' is not permitted in the same argument list.
// out x1);
Diagnostic(ErrorCode.ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList, "x1").WithArguments("x1").WithLocation(7, 23)
);
@@ -11863,7 +11863,7 @@ static object Test1(out int x, int x2)
parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
- // (7,25): error CS8927: Reference to an implicitly-typed out variable 'x1' is not permitted in the same argument list.
+ // (7,25): error CS8181: Reference to an implicitly-typed out variable 'x1' is not permitted in the same argument list.
// Test1(out x1,
Diagnostic(ErrorCode.ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList, "x1").WithArguments("x1").WithLocation(7, 25)
);
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs
index 7321fbd1fba66..d0b7eef02ac4d 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs
@@ -744,6 +744,113 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil man
Assert.Equal("System.Threading.Tasks.Task)>", normalized.ToTestDisplayString());
}
+ [Fact]
+ public void NormalizeTaskTypes_Pointers()
+ {
+ string source =
+@"unsafe class C
+{
+#pragma warning disable CS0169
+ static C>* F0;
+#pragma warning restore CS0169
+}
+struct MyTask
+{
+ public static MyTaskMethodBuilder CreateAsyncMethodBuilder() => new MyTaskMethodBuilder();
+}
+struct MyTaskMethodBuilder
+{
+}";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.UnsafeDebugDll);
+ compilation.VerifyDiagnostics(
+ // (4,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C>')
+ // static C>* F0;
+ Diagnostic(ErrorCode.ERR_ManagedAddr, "C>*").WithArguments("C>").WithLocation(4, 12));
+
+ var type = compilation.GetMember("C.F0").Type;
+ var normalized = type.NormalizeTaskTypes(compilation);
+ Assert.Equal("C>*", type.ToTestDisplayString());
+ Assert.Equal("C>*", normalized.ToTestDisplayString());
+ }
+
+ [Fact]
+ public void NormalizeTaskTypes_PointersCustomModifiers()
+ {
+ var ilSource =
+@".class public C
+{
+ .field public static class MyTask modopt(class MyTask) *[] F0
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
+}
+.class public MyTask
+{
+ .method public hidebysig static class MyTaskMethodBuilder CreateAsyncMethodBuilder() cil managed { ldnull ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
+}
+.class public MyTaskMethodBuilder
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
+}
+";
+ var source =
+@"";
+ var reference = CompileIL(ilSource);
+ var compilation = CreateCompilationWithMscorlib45(source, references: new[] { reference });
+ compilation.VerifyDiagnostics();
+
+ var type = compilation.GetMember("C.F0").Type;
+ var normalized = type.NormalizeTaskTypes(compilation);
+ Assert.Equal("MyTask modopt(MyTask) *[]", type.ToTestDisplayString());
+ Assert.Equal("System.Threading.Tasks.Task modopt(MyTask) *[]", normalized.ToTestDisplayString());
+ }
+
+ [Fact]
+ public void NormalizeTaskTypes_Errors()
+ {
+ string source =
+@"class C
+{
+#pragma warning disable CS0169
+ static A F0;
+ static MyTask F1;
+#pragma warning restore CS0169
+}
+struct MyTask
+{
+ public static MyTaskMethodBuilder CreateAsyncMethodBuilder() => new MyTaskMethodBuilder();
+}
+struct MyTask
+{
+ public static MyTaskMethodBuilder CreateAsyncMethodBuilder() => new MyTaskMethodBuilder();
+}
+struct MyTaskMethodBuilder
+{
+}
+struct MyTaskMethodBuilder
+{
+}";
+ var compilation = CreateCompilationWithMscorlib45(source);
+ compilation.VerifyDiagnostics(
+ // (5,19): error CS0246: The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)
+ // static MyTask F1;
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("B").WithLocation(5, 19),
+ // (4,12): error CS0246: The type or namespace name 'A<,>' could not be found (are you missing a using directive or an assembly reference?)
+ // static A F0;
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A<,>").WithLocation(4, 12));
+
+ var type = compilation.GetMember("C.F0").Type;
+ Assert.Equal(TypeKind.Error, type.TypeKind);
+ var normalized = type.NormalizeTaskTypes(compilation);
+ Assert.Equal("A", type.ToTestDisplayString());
+ Assert.Equal("A", normalized.ToTestDisplayString());
+
+ type = compilation.GetMember("C.F1").Type;
+ Assert.Equal(TypeKind.Error, ((NamedTypeSymbol)type).TypeArguments[0].TypeKind);
+ normalized = type.NormalizeTaskTypes(compilation);
+ Assert.Equal("MyTask", type.ToTestDisplayString());
+ Assert.Equal("System.Threading.Tasks.Task", normalized.ToTestDisplayString());
+ }
+
[Fact]
public void NormalizeTaskTypes_Inner()
{
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs
index 05deb4071af05..236c86ac81f66 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs
@@ -1163,5 +1163,62 @@ public static double MakeNaN(int x)
var comp = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
+ [Fact, WorkItem(12573, "https://github.com/dotnet/roslyn/issues/12573")]
+ public void EnumAndUnderlyingType()
+ {
+ var source =
+@"using System;
+
+class Program
+{
+ public static void Main(string[] args)
+ {
+ M(0);
+ M(0L);
+ M((byte)0);
+ M(EnumA.ValueA);
+ M(2);
+ }
+
+ public static void M(object value)
+ {
+ switch (value)
+ {
+ case 0:
+ Console.WriteLine(""0"");
+ break;
+ case 0L:
+ Console.WriteLine(""0L"");
+ break;
+ case (byte)0:
+ Console.WriteLine(""(byte)0"");
+ break;
+ case EnumA.ValueA:
+ Console.WriteLine(""EnumA.ValueA"");
+ break;
+ default:
+ Console.WriteLine(""Default"");
+ break;
+ }
+ }
+}
+
+public enum EnumA
+{
+ ValueA,
+ ValueB,
+ ValueC
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
+ compilation.VerifyDiagnostics();
+ var expectedOutput =
+@"0
+0L
+(byte)0
+EnumA.ValueA
+Default";
+ var comp = CompileAndVerify(compilation, expectedOutput: expectedOutput);
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturns.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturns.cs
index 63c0006e46bb2..d59e151e98cfb 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturns.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturns.cs
@@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
{
public class RefLocalsAndReturnsTests : CompilingTestBase
{
- internal static CSharpCompilation CreateCompilationRef(
+ private static CSharpCompilation CreateCompilationRef(
string text,
IEnumerable references = null,
CSharpCompilationOptions options = null,
@@ -31,7 +31,7 @@ void A()
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (6,17): error CS8935: A declaration of a by-reference variable must have an initializer
+ // (6,17): error CS8174: A declaration of a by-reference variable must have an initializer
// ref int x;
Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "x").WithLocation(6, 17),
// (6,17): warning CS0168: The variable 'x' is declared but never used
@@ -55,7 +55,7 @@ void A()
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (7,17): error CS8933: Cannot initialize a by-reference variable with a value
+ // (7,17): error CS8172: Cannot initialize a by-reference variable with a value
// ref int x = a;
Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "x = a").WithLocation(7, 17)
);
@@ -76,7 +76,7 @@ void A()
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (8,13): error CS8932: Cannot initialize a by-value variable with a reference
+ // (8,13): error CS8171: Cannot initialize a by-value variable with a reference
// var y = ref x;
Diagnostic(ErrorCode.ERR_InitializeByValueVariableWithReference, "y = ref x").WithLocation(8, 13)
);
@@ -120,19 +120,19 @@ ref int E()
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (6,20): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (6,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref 2 + 2;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "2 + 2").WithLocation(6, 20),
- // (11,20): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (11,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref 2;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "2").WithLocation(11, 20),
- // (16,20): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (16,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref null;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "null").WithLocation(16, 20),
- // (23,20): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (23,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref VoidMethod();
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "VoidMethod()").WithLocation(23, 20),
- // (30,20): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (30,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref P1;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "P1").WithArguments("Test.P1").WithLocation(30, 20)
);
@@ -161,19 +161,19 @@ void VoidMethod(){}
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (9,27): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (9,27): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// D1 d1 = () => ref 2 + 2;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "2 + 2").WithLocation(9, 27),
- // (10,27): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (10,27): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// D1 d2 = () => ref 2;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "2").WithLocation(10, 27),
- // (11,27): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (11,27): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// D2 d3 = () => ref null;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "null").WithLocation(11, 27),
- // (12,27): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (12,27): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// D2 d4 = () => ref VoidMethod();
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "VoidMethod()").WithLocation(12, 27),
- // (13,27): error CS8910: An expression cannot be used in this context because it may not be returned by reference
+ // (13,27): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// D1 d5 = () => ref P1;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "P1").WithArguments("Test.P1").WithLocation(13, 27));
}
@@ -234,16 +234,16 @@ ref char Test1(char arg1, S1 arg2)
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (18,24): error CS8924: Cannot return local 'l' by reference because it is not a ref local
+ // (18,24): error CS8168: Cannot return local 'l' by reference because it is not a ref local
// return ref l;
Diagnostic(ErrorCode.ERR_RefReturnLocal, "l").WithArguments("l").WithLocation(18, 24),
- // (28,24): error CS8925: Cannot return a member of local 'l' by reference because it is not a ref local
+ // (28,24): error CS8169: Cannot return a member of local 'l' by reference because it is not a ref local
// return ref l.x;
Diagnostic(ErrorCode.ERR_RefReturnLocal2, "l").WithArguments("l").WithLocation(28, 24),
- // (37,24): error CS8922: Cannot return a parameter by reference 'arg1' because it is not a ref or out parameter
+ // (37,24): error CS8166: Cannot return a parameter by reference 'arg1' because it is not a ref or out parameter
// return ref arg1;
Diagnostic(ErrorCode.ERR_RefReturnParameter, "arg1").WithArguments("arg1").WithLocation(37, 24),
- // (46,24): error CS8923: Cannot return or a member of parameter 'arg2' by reference because it is not a ref or out parameter
+ // (46,24): error CS8167: Cannot return or a member of parameter 'arg2' by reference because it is not a ref or out parameter
// return ref arg2.x;
Diagnostic(ErrorCode.ERR_RefReturnParameter2, "arg2").WithArguments("arg2").WithLocation(46, 24)
);
@@ -292,13 +292,13 @@ ref char Test1()
// (13,30): error CS1657: Cannot use 'ro' as a ref or out value because it is a 'foreach iteration variable'
// ref char r = ref ro;
Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "ro").WithArguments("ro", "foreach iteration variable").WithLocation(13, 30),
- // (18,24): error CS8924: Cannot return local 'ro' by reference because it is not a ref local
+ // (18,24): error CS8168: Cannot return local 'ro' by reference because it is not a ref local
// return ref ro;
Diagnostic(ErrorCode.ERR_RefReturnLocal, "ro").WithArguments("ro").WithLocation(18, 24),
// (23,30): error CS1655: Cannot use fields of 'ro' as a ref or out value because it is a 'foreach iteration variable'
// ref char r = ref ro.x;
Diagnostic(ErrorCode.ERR_RefReadonlyLocal2Cause, "ro.x").WithArguments("ro", "foreach iteration variable").WithLocation(23, 30),
- // (28,24): error CS8925: Cannot return a member of local 'ro' by reference because it is not a ref local
+ // (28,24): error CS8169: Cannot return a member of local 'ro' by reference because it is not a ref local
// return ref ro.x;
Diagnostic(ErrorCode.ERR_RefReturnLocal2, "ro").WithArguments("ro").WithLocation(28, 24)
);
@@ -514,25 +514,25 @@ ref char Test2()
// (65,33): error CS0192: A readonly field cannot be used as a ref or out value (except in a constructor)
// ref char temp = ref i1;
Diagnostic(ErrorCode.ERR_RefReadonly, "i1").WithLocation(65, 33),
- // (68,24): error CS8916: A readonly field cannot be returned by reference
+ // (68,24): error CS8160: A readonly field cannot be returned by reference
// return ref i1;
Diagnostic(ErrorCode.ERR_RefReturnReadonly, "i1").WithLocation(68, 24),
// (72,33): error CS1649: Members of readonly field 'Test.i2' cannot be used as a ref or out value (except in a constructor)
// ref char temp = ref i2.x;
Diagnostic(ErrorCode.ERR_RefReadonly2, "i2.x").WithArguments("Test.i2").WithLocation(72, 33),
- // (75,24): error CS8918: Members of readonly field 'Test.i2' cannot be returned by reference
+ // (75,24): error CS8162: Members of readonly field 'Test.i2' cannot be returned by reference
// return ref i2.x;
Diagnostic(ErrorCode.ERR_RefReturnReadonly2, "i2.x").WithArguments("Test.i2").WithLocation(75, 24),
// (83,33): error CS0199: A static readonly field cannot be used as a ref or out value (except in a static constructor)
// ref char temp = ref s1;
Diagnostic(ErrorCode.ERR_RefReadonlyStatic, "s1").WithLocation(83, 33),
- // (86,24): error CS8917: A static readonly field cannot be returned by reference
+ // (86,24): error CS8161: A static readonly field cannot be returned by reference
// return ref s1;
Diagnostic(ErrorCode.ERR_RefReturnReadonlyStatic, "s1").WithLocation(86, 24),
// (90,33): error CS1651: Fields of static readonly field 'Test.s2' cannot be used as a ref or out value (except in a static constructor)
// ref char temp = ref s2.x;
Diagnostic(ErrorCode.ERR_RefReadonlyStatic2, "s2.x").WithArguments("Test.s2").WithLocation(90, 33),
- // (93,24): error CS8919: Fields of static readonly field 'Test.s2' cannot be returned by reference
+ // (93,24): error CS8163: Fields of static readonly field 'Test.s2' cannot be returned by reference
// return ref s2.x;
Diagnostic(ErrorCode.ERR_RefReturnReadonlyStatic2, "s2.x").WithArguments("Test.s2").WithLocation(93, 24)
);
@@ -598,31 +598,31 @@ static ref char Test1()
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (10,24): error CS8927: Struct members cannot return 'this' or other instance members by reference
+ // (10,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
// return ref this;
Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithArguments("this").WithLocation(10, 24),
- // (15,24): error CS8927: Struct members cannot return 'this' or other instance members by reference
+ // (15,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
// return ref x;
Diagnostic(ErrorCode.ERR_RefReturnStructThis, "x").WithArguments("this").WithLocation(15, 24),
- // (20,24): error CS8927: Struct members cannot return 'this' or other instance members by reference
+ // (20,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
// return ref this.x;
Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this.x").WithArguments("this").WithLocation(20, 24),
- // (36,32): error CS8924: Cannot return local 'M1' by reference because it is not a ref local
+ // (36,32): error CS8168: Cannot return local 'M1' by reference because it is not a ref local
// return ref Foo(ref M1);
Diagnostic(ErrorCode.ERR_RefReturnLocal, "M1").WithArguments("M1").WithLocation(36, 32),
- // (36,24): error CS8920: Cannot return by reference a result of 'Test.Foo(ref char)' because the argument passed to parameter 'arg' cannot be returned by reference
+ // (36,24): error CS8164: Cannot return by reference a result of 'Test.Foo(ref char)' because the argument passed to parameter 'arg' cannot be returned by reference
// return ref Foo(ref M1);
Diagnostic(ErrorCode.ERR_RefReturnCall, "Foo(ref M1)").WithArguments("Test.Foo(ref char)", "arg").WithLocation(36, 24),
- // (41,32): error CS8925: Cannot return a member of local 'M2' by reference because it is not a ref local
+ // (41,32): error CS8169: Cannot return a member of local 'M2' by reference because it is not a ref local
// return ref Foo(ref M2.x);
Diagnostic(ErrorCode.ERR_RefReturnLocal2, "M2").WithArguments("M2").WithLocation(41, 32),
- // (41,24): error CS8920: Cannot return by reference a result of 'Test.Foo(ref char)' because the argument passed to parameter 'arg' cannot be returned by reference
+ // (41,24): error CS8164: Cannot return by reference a result of 'Test.Foo(ref char)' because the argument passed to parameter 'arg' cannot be returned by reference
// return ref Foo(ref M2.x);
Diagnostic(ErrorCode.ERR_RefReturnCall, "Foo(ref M2.x)").WithArguments("Test.Foo(ref char)", "arg").WithLocation(41, 24),
- // (46,32): error CS8924: Cannot return local 'M2' by reference because it is not a ref local
+ // (46,32): error CS8168: Cannot return local 'M2' by reference because it is not a ref local
// return ref Foo(ref M2).x;
Diagnostic(ErrorCode.ERR_RefReturnLocal, "M2").WithArguments("M2").WithLocation(46, 32),
- // (46,24): error CS8921: Cannot return by reference a member of result of 'Test.Foo(ref Test.S1)' because the argument passed to parameter 'arg' cannot be returned by reference
+ // (46,24): error CS8165: Cannot return by reference a member of result of 'Test.Foo(ref Test.S1)' because the argument passed to parameter 'arg' cannot be returned by reference
// return ref Foo(ref M2).x;
Diagnostic(ErrorCode.ERR_RefReturnCall2, "Foo(ref M2)").WithArguments("Test.Foo(ref Test.S1)", "arg").WithLocation(46, 24));
}
@@ -702,22 +702,22 @@ ref char Test1(char arg1, S1 arg2)
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (18,24): error CS8911: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
+ // (18,24): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
// return ref r;
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(18, 24),
- // (28,24): error CS8911: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
+ // (28,24): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
// return ref r;
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(28, 24),
- // (38,24): error CS8912: Cannot return by reference a member of 'r' because it was initialized to a value that cannot be returned by reference
+ // (38,24): error CS8158: Cannot return by reference a member of 'r' because it was initialized to a value that cannot be returned by reference
// return ref r.x;
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal2, "r").WithArguments("r").WithLocation(38, 24),
- // (47,24): error CS8911: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
+ // (47,24): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
// return ref r;
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(47, 24),
- // (56,24): error CS8911: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
+ // (56,24): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
// return ref r;
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(56, 24),
- // (65,24): error CS8912: Cannot return by reference a member of 'r' because it was initialized to a value that cannot be returned by reference
+ // (65,24): error CS8158: Cannot return by reference a member of 'r' because it was initialized to a value that cannot be returned by reference
// return ref r.x;
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal2, "r").WithArguments("r").WithLocation(65, 24)
@@ -786,19 +786,19 @@ ref char Test1(char arg1, S1 arg2)
}";
var comp = CreateCompilationRef(text);
comp.VerifyDiagnostics(
- // (19,24): error CS8911: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
+ // (19,24): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
// return ref r; //1
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(19, 24),
- // (25,24): error CS8912: Cannot return by reference a member of 'r' because it was initialized to a value that cannot be returned by reference
+ // (25,24): error CS8158: Cannot return by reference a member of 'r' because it was initialized to a value that cannot be returned by reference
// return ref r.x; //2
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal2, "r").WithArguments("r").WithLocation(25, 24),
// (34,24): error CS0103: The name 'r' does not exist in the current context
// return ref r;
Diagnostic(ErrorCode.ERR_NameNotInContext, "r").WithArguments("r").WithLocation(34, 24),
- // (43,24): error CS8911: Cannot return 'valid' by reference because it was initialized to a value that cannot be returned by reference
+ // (43,24): error CS8157: Cannot return 'valid' by reference because it was initialized to a value that cannot be returned by reference
// return ref valid; //4
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "valid").WithArguments("valid").WithLocation(43, 24),
- // (52,24): error CS8911: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
+ // (52,24): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
// return ref r; //5
Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(52, 24),
// (18,30): error CS0165: Use of unassigned local variable 'r'
@@ -842,23 +842,21 @@ ref char Foo2(ref char c, ref char b)
var options = TestOptions.Regular;
var comp = CreateCompilationWithMscorlib45(text, parseOptions: options);
comp.VerifyDiagnostics(
- // (14,13): error CS8894: By-reference returns may only be used in methods that return by reference
- // return ref b;
- Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(14, 13),
- // (19,13): error CS8895: By-value returns may only be used in methods that return by value
- // return c;
- Diagnostic(ErrorCode.ERR_MustHaveRefReturn, "return").WithLocation(19, 13),
- // (6,18): warning CS0168: The variable 'Foo' is declared but never used
- // ref char Foo(ref char a, ref char b)
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo").WithArguments("Foo").WithLocation(6, 18),
- // (12,14): warning CS0168: The variable 'Foo1' is declared but never used
- // char Foo1(ref char a, ref char b)
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo1").WithArguments("Foo1").WithLocation(12, 14),
- // (17,18): warning CS0168: The variable 'Foo2' is declared but never used
- // ref char Foo2(ref char c, ref char b)
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo2").WithArguments("Foo2").WithLocation(17, 18)
-
- );
+ // (14,13): error CS8149: By-reference returns may only be used in methods that return by reference
+ // return ref b;
+ Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(14, 13),
+ // (19,13): error CS8150: By-value returns may only be used in methods that return by value
+ // return c;
+ Diagnostic(ErrorCode.ERR_MustHaveRefReturn, "return").WithLocation(19, 13),
+ // (6,18): warning CS0168: The variable 'Foo' is declared but never used
+ // ref char Foo(ref char a, ref char b)
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo").WithArguments("Foo").WithLocation(6, 18),
+ // (12,14): warning CS0168: The variable 'Foo1' is declared but never used
+ // char Foo1(ref char a, ref char b)
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo1").WithArguments("Foo1").WithLocation(12, 14),
+ // (17,18): warning CS0168: The variable 'Foo2' is declared but never used
+ // ref char Foo2(ref char c, ref char b)
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo2").WithArguments("Foo2").WithLocation(17, 18));
}
[Fact]
@@ -886,41 +884,39 @@ public static void Main()
var options = TestOptions.Regular;
var comp = CreateCompilationWithMscorlib45(text, parseOptions: options);
comp.VerifyDiagnostics(
- // (9,50): error CS8894: By-reference returns may only be used in methods that return by reference
- // char Foo1(ref char a, ref char b) => ref b;
- Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "b").WithLocation(9, 50),
- // (11,50): error CS8895: By-value returns may only be used in methods that return by value
- // ref char Foo2(ref char c, ref char b) => c;
- Diagnostic(ErrorCode.ERR_MustHaveRefReturn, "c").WithLocation(11, 50),
- // (16,54): error CS8940: Cannot use ref local 'r' inside an anonymous method, lambda expression, or query expression
- // ref char Moo1(ref char a, ref char b) => ref r;
- Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "r").WithArguments("r").WithLocation(16, 54),
- // (16,54): error CS8896: The return expression must be of type 'char' because this method returns by reference
- // ref char Moo1(ref char a, ref char b) => ref r;
- Diagnostic(ErrorCode.ERR_RefReturnMustHaveIdentityConversion, "r").WithArguments("char").WithLocation(16, 54),
- // (17,46): error CS8940: Cannot use ref local 'r' inside an anonymous method, lambda expression, or query expression
- // char Moo3(ref char a, ref char b) => r;
- Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "r").WithArguments("r").WithLocation(17, 46),
- // (17,46): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
- // char Moo3(ref char a, ref char b) => r;
- Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "r").WithArguments("int", "char").WithLocation(17, 46),
- // (7,18): warning CS0168: The variable 'Foo' is declared but never used
- // ref char Foo(ref char a, ref char b) => ref a;
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo").WithArguments("Foo").WithLocation(7, 18),
- // (9,14): warning CS0168: The variable 'Foo1' is declared but never used
- // char Foo1(ref char a, ref char b) => ref b;
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo1").WithArguments("Foo1").WithLocation(9, 14),
- // (11,18): warning CS0168: The variable 'Foo2' is declared but never used
- // ref char Foo2(ref char c, ref char b) => c;
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo2").WithArguments("Foo2").WithLocation(11, 18),
- // (16,18): warning CS0168: The variable 'Moo1' is declared but never used
- // ref char Moo1(ref char a, ref char b) => ref r;
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Moo1").WithArguments("Moo1").WithLocation(16, 18),
- // (17,14): warning CS0168: The variable 'Moo3' is declared but never used
- // char Moo3(ref char a, ref char b) => r;
- Diagnostic(ErrorCode.WRN_UnreferencedVar, "Moo3").WithArguments("Moo3").WithLocation(17, 14)
- );
+ // (9,50): error CS8149: By-reference returns may only be used in methods that return by reference
+ // char Foo1(ref char a, ref char b) => ref b;
+ Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "b").WithLocation(9, 50),
+ // (11,50): error CS8150: By-value returns may only be used in methods that return by value
+ // ref char Foo2(ref char c, ref char b) => c;
+ Diagnostic(ErrorCode.ERR_MustHaveRefReturn, "c").WithLocation(11, 50),
+ // (16,54): error CS8175: Cannot use ref local 'r' inside an anonymous method, lambda expression, or query expression
+ // ref char Moo1(ref char a, ref char b) => ref r;
+ Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "r").WithArguments("r").WithLocation(16, 54),
+ // (16,54): error CS8151: The return expression must be of type 'char' because this method returns by reference
+ // ref char Moo1(ref char a, ref char b) => ref r;
+ Diagnostic(ErrorCode.ERR_RefReturnMustHaveIdentityConversion, "r").WithArguments("char").WithLocation(16, 54),
+ // (17,46): error CS8175: Cannot use ref local 'r' inside an anonymous method, lambda expression, or query expression
+ // char Moo3(ref char a, ref char b) => r;
+ Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "r").WithArguments("r").WithLocation(17, 46),
+ // (17,46): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
+ // char Moo3(ref char a, ref char b) => r;
+ Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "r").WithArguments("int", "char").WithLocation(17, 46),
+ // (7,18): warning CS0168: The variable 'Foo' is declared but never used
+ // ref char Foo(ref char a, ref char b) => ref a;
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo").WithArguments("Foo").WithLocation(7, 18),
+ // (9,14): warning CS0168: The variable 'Foo1' is declared but never used
+ // char Foo1(ref char a, ref char b) => ref b;
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo1").WithArguments("Foo1").WithLocation(9, 14),
+ // (11,18): warning CS0168: The variable 'Foo2' is declared but never used
+ // ref char Foo2(ref char c, ref char b) => c;
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Foo2").WithArguments("Foo2").WithLocation(11, 18),
+ // (16,18): warning CS0168: The variable 'Moo1' is declared but never used
+ // ref char Moo1(ref char a, ref char b) => ref r;
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Moo1").WithArguments("Moo1").WithLocation(16, 18),
+ // (17,14): warning CS0168: The variable 'Moo3' is declared but never used
+ // char Moo3(ref char a, ref char b) => r;
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "Moo3").WithArguments("Moo3").WithLocation(17, 14));
}
-
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SwitchTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SwitchTests.cs
index af77df4633cce..438c80a240ec6 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SwitchTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SwitchTests.cs
@@ -359,14 +359,14 @@ public static void Main()
}
}";
CreateCompilationWithMscorlib(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(
- // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default'
+ // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default:'
// default: //CS0152
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "default:").WithArguments("default:").WithLocation(15, 13)
);
CreateCompilationWithMscorlib(text, parseOptions: TestOptions.Regular6WithV7SwitchBinder).VerifyDiagnostics(
- // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default'
+ // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default:'
// default: //CS0152
- Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "default:").WithArguments("default").WithLocation(15, 13)
+ Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "default:").WithArguments("default:").WithLocation(15, 13)
);
CreateCompilationWithMscorlib(text).VerifyDiagnostics(
// (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default:'
@@ -1135,9 +1135,9 @@ static void Main() { }
// (9,17): error CS7036: There is no argument given that corresponds to the required formal parameter 'o' of 'C.M(object)'
// M();
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("o", "C.M(object)").WithLocation(9, 17),
- // (12,13): error CS0152: The switch statement contains multiple cases with the label value '0'
+ // (12,13): error CS8120: The switch case has already been handled by a previous case.
// case 0:
- Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 0:").WithArguments("0").WithLocation(12, 13)
+ Diagnostic(ErrorCode.ERR_PatternIsSubsumed, "case 0:").WithLocation(12, 13)
);
}
diff --git a/src/Compilers/Core/CodeAnalysisTest/Text/StringTextDecodingTests.cs b/src/Compilers/Core/CodeAnalysisTest/Text/StringTextDecodingTests.cs
index c4a56bd49b927..91b90dbb69cfe 100644
--- a/src/Compilers/Core/CodeAnalysisTest/Text/StringTextDecodingTests.cs
+++ b/src/Compilers/Core/CodeAnalysisTest/Text/StringTextDecodingTests.cs
@@ -44,7 +44,7 @@ private static SourceText CreateMemoryStreamBasedEncodedText(byte[] bytes,
using (var stream = new MemoryStream(buffer, 0, bytes.Length, writable: true, publiclyVisible: true))
{
- return EncodedStringText.Create(stream, getEncoding, readEncodingOpt, algorithm);
+ return EncodedStringText.Create(stream, new Lazy(getEncoding), readEncodingOpt, algorithm);
}
}
diff --git a/src/Compilers/Core/Portable/EncodedStringText.cs b/src/Compilers/Core/Portable/EncodedStringText.cs
index 01402eaaa05dc..1847452e0aa4e 100644
--- a/src/Compilers/Core/Portable/EncodedStringText.cs
+++ b/src/Compilers/Core/Portable/EncodedStringText.cs
@@ -24,7 +24,7 @@ internal static class EncodedStringText
/// 2. CodePage 1252.
/// 3. Latin1.
///
- private static readonly Encoding s_fallbackEncoding = GetFallbackEncoding();
+ private static readonly Lazy s_fallbackEncoding = new Lazy(GetFallbackEncoding);
private static Encoding GetFallbackEncoding()
{
@@ -74,14 +74,14 @@ internal static SourceText Create(Stream stream,
bool canBeEmbedded = false)
{
return Create(stream,
- () => s_fallbackEncoding,
+ s_fallbackEncoding,
defaultEncoding: defaultEncoding,
checksumAlgorithm: checksumAlgorithm,
canBeEmbedded: canBeEmbedded);
}
// internal for testing
- internal static SourceText Create(Stream stream, Func getEncoding,
+ internal static SourceText Create(Stream stream, Lazy getEncoding,
Encoding defaultEncoding = null,
SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithm.Sha1,
bool canBeEmbedded = false)
@@ -104,7 +104,7 @@ internal static SourceText Create(Stream stream, Func getEncoding,
try
{
- return Decode(stream, defaultEncoding ?? getEncoding(), checksumAlgorithm, throwIfBinaryDetected: detectEncoding);
+ return Decode(stream, defaultEncoding ?? getEncoding.Value, checksumAlgorithm, throwIfBinaryDetected: detectEncoding);
}
catch (DecoderFallbackException e)
{
diff --git a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
index 53cf943d116ce..c889e9c4580d8 100644
--- a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
+++ b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
@@ -1739,7 +1739,11 @@ public void WriteMetadataAndIL(PdbWriter pdbWriterOpt, Stream metadataStream, St
Debug.Assert(mvidFixup.IsDefault);
Debug.Assert(mvidStringFixup.IsDefault);
- var rootBuilder = new MetadataRootBuilder(metadata, module.Properties.TargetRuntimeVersion);
+ // TODO (https://github.com/dotnet/roslyn/issues/3905):
+ // InterfaceImpl table emitted by Roslyn is not compliant with ECMA spec.
+ // Once fixed enable validation in DEBUG builds.
+ var rootBuilder = new MetadataRootBuilder(metadata, module.Properties.TargetRuntimeVersion, suppressValidation: true);
+
rootBuilder.Serialize(metadataBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0);
metadataSizes = rootBuilder.Sizes;
@@ -1789,7 +1793,10 @@ public void BuildMetadataAndIL(
public MetadataRootBuilder GetRootBuilder()
{
- return new MetadataRootBuilder(metadata, module.Properties.TargetRuntimeVersion);
+ // TODO (https://github.com/dotnet/roslyn/issues/3905):
+ // InterfaceImpl table emitted by Roslyn is not compliant with ECMA spec.
+ // Once fixed enable validation in DEBUG builds.
+ return new MetadataRootBuilder(metadata, module.Properties.TargetRuntimeVersion, suppressValidation: true);
}
public PortablePdbBuilder GetPortablePdbBuilder(MetadataSizes typeSystemMetadataSizes, MethodDefinitionHandle debugEntryPoint, Func, BlobContentId> deterministicIdProviderOpt)
@@ -2612,8 +2619,10 @@ private void PopulateModuleTableRow(out Blob mvidFixup)
else
{
// The guid will be filled in later:
- mvidHandle = metadata.ReserveGuid(out mvidFixup);
- new BlobWriter(mvidFixup).WriteBytes(0, mvidFixup.Length);
+ var reservedGuid = metadata.ReserveGuid();
+ mvidFixup = reservedGuid.Content;
+ mvidHandle = reservedGuid.Handle;
+ reservedGuid.CreateWriter().WriteBytes(0, mvidFixup.Length);
}
metadata.AddModule(
@@ -2787,7 +2796,7 @@ private int[] SerializeMethodBodies(BlobBuilder ilBuilder, PdbWriter pdbWriterOp
var lastLocalVariableHandle = default(LocalVariableHandle);
var lastLocalConstantHandle = default(LocalConstantHandle);
- var encoder = new MethodBodiesEncoder(ilBuilder);
+ var encoder = new MethodBodyStreamEncoder(ilBuilder);
var mvidStringHandle = default(UserStringHandle);
mvidStringFixup = default(Blob);
@@ -2843,7 +2852,7 @@ private int[] SerializeMethodBodies(BlobBuilder ilBuilder, PdbWriter pdbWriterOp
return bodyOffsets;
}
- private int SerializeMethodBody(MethodBodiesEncoder encoder, IMethodBody methodBody, StandaloneSignatureHandle localSignatureHandleOpt, ref UserStringHandle mvidStringHandle, ref Blob mvidStringFixup)
+ private int SerializeMethodBody(MethodBodyStreamEncoder encoder, IMethodBody methodBody, StandaloneSignatureHandle localSignatureHandleOpt, ref UserStringHandle mvidStringHandle, ref Blob mvidStringFixup)
{
int ilLength = methodBody.IL.Length;
var exceptionRegions = methodBody.ExceptionRegions;
@@ -2852,35 +2861,34 @@ private int SerializeMethodBody(MethodBodiesEncoder encoder, IMethodBody methodB
// Check if an identical method body has already been serialized.
// If so, use the RVA of the already serialized one.
// Note that we don't need to rewrite the fake tokens in the body before looking it up.
- int bodyOffset;
// Don't do small body method caching during deterministic builds until this issue is fixed
// https://github.com/dotnet/roslyn/issues/7595
+ int bodyOffset;
if (!_deterministic && isSmallBody && _smallMethodBodies.TryGetValue(methodBody.IL, out bodyOffset))
{
return bodyOffset;
}
- MethodBodyAttributes attributes =
- (methodBody.LocalsAreZeroed ? MethodBodyAttributes.InitLocals : 0) |
- (MayUseSmallExceptionHeaders(exceptionRegions) ? 0 : MethodBodyAttributes.LargeExceptionRegions);
-
- var bodyEncoder = encoder.AddMethodBody(methodBody.MaxStack, exceptionRegions.Length, localSignatureHandleOpt, attributes);
-
- Blob ilBlob;
- var ehEncoder = bodyEncoder.WriteInstructions(methodBody.IL, out bodyOffset, out ilBlob);
+ var encodedBody = encoder.AddMethodBody(
+ codeSize: methodBody.IL.Length,
+ maxStack: methodBody.MaxStack,
+ exceptionRegionCount: exceptionRegions.Length,
+ hasSmallExceptionRegions: MayUseSmallExceptionHeaders(exceptionRegions),
+ localVariablesSignature: localSignatureHandleOpt,
+ attributes: (methodBody.LocalsAreZeroed ? MethodBodyAttributes.InitLocals : 0));
// Don't do small body method caching during deterministic builds until this issue is fixed
// https://github.com/dotnet/roslyn/issues/7595
if (isSmallBody && !_deterministic)
{
- _smallMethodBodies.Add(methodBody.IL, bodyOffset);
+ _smallMethodBodies.Add(methodBody.IL, encodedBody.Offset);
}
- SubstituteFakeTokens(ilBlob, methodBody.IL, ref mvidStringHandle, ref mvidStringFixup);
- SerializeMethodBodyExceptionHandlerTable(ehEncoder, exceptionRegions);
+ WriteInstructions(encodedBody.Instructions, methodBody.IL, ref mvidStringHandle, ref mvidStringFixup);
+ SerializeMethodBodyExceptionHandlerTable(encodedBody.ExceptionRegions, exceptionRegions);
- return bodyOffset;
+ return encodedBody.Offset;
}
///
@@ -3033,13 +3041,13 @@ private UserStringHandle GetOrAddUserString(string str)
return default(UserStringHandle);
}
- private UserStringHandle ReserveUserString(int length, out Blob fixup)
+ private ReservedBlob ReserveUserString(int length)
{
if (!_userStringTokenOverflow)
{
try
{
- return metadata.ReserveUserString(length, out fixup);
+ return metadata.ReserveUserString(length);
}
catch (ImageFormatLimitationException)
{
@@ -3048,8 +3056,7 @@ private UserStringHandle ReserveUserString(int length, out Blob fixup)
}
}
- fixup = default(Blob);
- return default(UserStringHandle);
+ return default(ReservedBlob);
}
internal const uint LiteralMethodDefinitionToken = 0x80000000;
@@ -3057,15 +3064,18 @@ private UserStringHandle ReserveUserString(int length, out Blob fixup)
internal const uint SourceDocumentIndex = 0x20000000;
internal const uint ModuleVersionIdStringToken = 0x80000000;
- private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL, ref UserStringHandle mvidStringHandle, ref Blob mvidStringFixup)
+ private void WriteInstructions(Blob finalIL, ImmutableArray generatedIL, ref UserStringHandle mvidStringHandle, ref Blob mvidStringFixup)
{
// write the raw body first and then patch tokens:
- var writer = new BlobWriter(blob);
+ var writer = new BlobWriter(finalIL);
+
+ writer.WriteBytes(generatedIL);
+ writer.Offset = 0;
int offset = 0;
- while (offset < methodBodyIL.Length)
+ while (offset < generatedIL.Length)
{
- var operandType = InstructionOperandTypes.ReadOperandType(methodBodyIL, ref offset);
+ var operandType = InstructionOperandTypes.ReadOperandType(generatedIL, ref offset);
switch (operandType)
{
case OperandType.InlineField:
@@ -3073,7 +3083,7 @@ private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL,
case OperandType.InlineTok:
case OperandType.InlineType:
{
- int pseudoToken = ReadInt32(methodBodyIL, offset);
+ int pseudoToken = ReadInt32(generatedIL, offset);
int token = 0;
// If any bits in the high-order byte of the pseudotoken are nonzero, replace the opcode with Ldc_i4
// and either clear the high-order byte in the pseudotoken or ignore the pseudotoken.
@@ -3083,7 +3093,7 @@ private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL,
int tokenMask = pseudoToken & unchecked((int)0xff000000);
if (tokenMask != 0 && (uint)pseudoToken != 0xffffffff)
{
- Debug.Assert(ReadByte(methodBodyIL, offset - 1) == (byte)ILOpCode.Ldtoken);
+ Debug.Assert(ReadByte(generatedIL, offset - 1) == (byte)ILOpCode.Ldtoken);
writer.Offset = offset - 1;
writer.WriteByte((byte)ILOpCode.Ldc_i4);
switch ((uint)tokenMask)
@@ -3112,7 +3122,7 @@ private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL,
{
writer.Offset = offset;
- int pseudoToken = ReadInt32(methodBodyIL, offset);
+ int pseudoToken = ReadInt32(generatedIL, offset);
UserStringHandle handle;
if ((uint)pseudoToken == ModuleVersionIdStringToken)
@@ -3124,7 +3134,9 @@ private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL,
{
const int guidStringLength = 36;
Debug.Assert(guidStringLength == default(Guid).ToString().Length);
- mvidStringHandle = ReserveUserString(guidStringLength, out mvidStringFixup);
+ var reserved = ReserveUserString(guidStringLength);
+ mvidStringHandle = reserved.Handle;
+ mvidStringFixup = reserved.Content;
}
handle = mvidStringHandle;
@@ -3148,7 +3160,7 @@ private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL,
break;
case OperandType.InlineSwitch:
- int argCount = ReadInt32(methodBodyIL, offset);
+ int argCount = ReadInt32(generatedIL, offset);
// skip switch arguments count and arguments
offset += (argCount + 1) * 4;
break;
@@ -3179,13 +3191,11 @@ private void SubstituteFakeTokens(Blob blob, ImmutableArray methodBodyIL,
private void SerializeMethodBodyExceptionHandlerTable(ExceptionRegionEncoder encoder, ImmutableArray regions)
{
- encoder.StartRegions();
-
foreach (var region in regions)
{
var exceptionType = region.ExceptionType;
- encoder.AddRegion(
+ encoder.Add(
region.HandlerKind,
region.TryStartOffset,
region.TryLength,
@@ -3194,8 +3204,6 @@ private void SerializeMethodBodyExceptionHandlerTable(ExceptionRegionEncoder enc
(exceptionType != null) ? GetTypeHandle(exceptionType) : default(EntityHandle),
region.FilterDecisionStartOffset);
}
-
- encoder.EndRegions();
}
private static bool MayUseSmallExceptionHeaders(ImmutableArray exceptionRegions)
diff --git a/src/Compilers/Core/Portable/PEWriter/PeWriter.cs b/src/Compilers/Core/Portable/PEWriter/PeWriter.cs
index 867da2a243b39..c2bc248d44d95 100644
--- a/src/Compilers/Core/Portable/PEWriter/PeWriter.cs
+++ b/src/Compilers/Core/Portable/PEWriter/PeWriter.cs
@@ -198,8 +198,7 @@ public static bool WritePeToStream(
deterministicIdProvider);
var peBlob = new BlobBuilder();
- BlobContentId peContentId;
- peBuilder.Serialize(peBlob, out peContentId);
+ var peContentId = peBuilder.Serialize(peBlob);
PatchModuleVersionIds(mvidFixup, mvidStringFixup, peContentId.Guid);
diff --git a/src/Compilers/Core/Portable/project.json b/src/Compilers/Core/Portable/project.json
index 49d61edd5ceda..e4ac18df55618 100644
--- a/src/Compilers/Core/Portable/project.json
+++ b/src/Compilers/Core/Portable/project.json
@@ -1,8 +1,8 @@
{
"supports": {},
"dependencies": {
- "System.Collections.Immutable": "1.2.0",
- "System.Reflection.Metadata": "1.4.1-beta-24322-03"
+ "System.Collections.Immutable": "1.2.0",
+ "System.Reflection.Metadata": "1.4.1-beta-24410-02"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": {}
diff --git a/src/Dependencies/Metadata/project.json b/src/Dependencies/Metadata/project.json
index f79e9c8f5114d..32e4a1a3951e1 100644
--- a/src/Dependencies/Metadata/project.json
+++ b/src/Dependencies/Metadata/project.json
@@ -1,7 +1,7 @@
{
"supports": {},
"dependencies": {
- "System.Reflection.Metadata": "1.4.1-beta-24322-03"
+ "System.Reflection.Metadata": "1.4.1-beta-24410-02"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": {}
diff --git a/src/Dependencies/PooledObjects/Microsoft.CodeAnalysis.PooledObjects.shproj b/src/Dependencies/PooledObjects/Microsoft.CodeAnalysis.PooledObjects.shproj
index 6274cf7f1762a..d00c5194a1adb 100644
--- a/src/Dependencies/PooledObjects/Microsoft.CodeAnalysis.PooledObjects.shproj
+++ b/src/Dependencies/PooledObjects/Microsoft.CodeAnalysis.PooledObjects.shproj
@@ -1,7 +1,7 @@
- c1930979-c824-496b-a630-70f5369a636f
+ cd77a8cc-2885-47a7-b99c-fbf13353400b14.0
diff --git a/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj b/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj
index a5cff4cd926e4..ffea03529173a 100644
--- a/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj
+++ b/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj
@@ -211,7 +211,7 @@
-
+
diff --git a/src/EditorFeatures/CSharpTest/CodeActions/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.cs
index b86307ae8d736..08327c4efcf47 100644
--- a/src/EditorFeatures/CSharpTest/CodeActions/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.cs
+++ b/src/EditorFeatures/CSharpTest/CodeActions/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.cs
@@ -293,6 +293,23 @@ private int GetProp()
}", compareTokens: false);
}
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsReplacePropertyWithMethods)]
+ public async Task TestComputedPropWithTrailingTriviaAfterArrow()
+ {
+ await TestAsync(
+@"class C
+{
+ public int [||]Prop => /* return 42 */ 42;
+}",
+@"class C
+{
+ public int GetProp()
+ {
+ return /* return 42 */ 42;
+ }
+}", compareTokens: false);
+ }
+
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsReplacePropertyWithMethods)]
public async Task TestAbstractProperty()
{
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs
index f91133d9ad385..12dee49297f84 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs
@@ -497,7 +497,16 @@ await TestAsync(
public async Task TestAssignmentExpressionWithConversionInNonAsyncFunction()
{
await TestMissingAsync(
-@"using System . Threading . Tasks ; class TestClass { private Task MyTestMethod1Async ( ) { long myInt = [|MyIntMethodAsync ( )|] ; } private Task < int > MyIntMethodAsync ( ) { return Task . FromResult ( result : 1 ) ; } } ");
+@"using System . Threading . Tasks ;
+class TestClass {
+ private Task MyTestMethod1Async ( ) {
+ long myInt = [|MyIntMethodAsync ( )|] ;
+ }
+
+ private Task < int > MyIntMethodAsync ( ) {
+ return Task . FromResult ( result : 1 ) ;
+ }
+} ");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAsyncTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs
similarity index 88%
rename from src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAsyncTests.cs
rename to src/EditorFeatures/CSharpTest/Diagnostics/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs
index 14e6b4a6ea5f6..a710f25b17c2d 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAsyncTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs
@@ -1,17 +1,23 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System;
-using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
-using Microsoft.CodeAnalysis.CSharp.CodeFixes.Async;
+using Microsoft.CodeAnalysis.CSharp.MakeMethodAsynchronous;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslyn.Test.Utilities;
+using System;
+using System.Threading.Tasks;
using Xunit;
-namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.Async
+namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.MakeMethodAsynchronous
{
- public partial class AddAsyncTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
+ public partial class MakeMethodAsynchronousTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
{
+ internal override Tuple CreateDiagnosticProviderAndFixer(Workspace workspace)
+ {
+ return new Tuple(
+ null, new CSharpMakeMethodAsynchronousCodeFixProvider());
+ }
+
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAsync)]
public async Task AwaitInVoidMethodWithModifiers()
{
@@ -33,13 +39,41 @@ public static void Test()
class Program
{
- public static async void Test()
+ public static async void TestAsync()
{
await Task.Delay(1);
}
}";
await TestAsync(initial, expected);
}
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAsync)]
+ public async Task AwaitInVoidMethodWithModifiers2()
+ {
+ var initial =
+@"using System;
+using System.Threading.Tasks;
+
+class Program
+{
+ public static void Test()
+ {
+ [|await Task.Delay(1);|]
+ }
+}";
+
+ var expected =
+@"using System;
+using System.Threading.Tasks;
+
+class Program
+{
+ public static async Task TestAsync()
+ {
+ await Task.Delay(1);
+ }
+}";
+ await TestAsync(initial, expected, index: 1);
+ }
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAsync)]
public async Task AwaitInTaskMethodNoModifiers()
@@ -62,7 +96,7 @@ Task Test()
class Program
{
- async Task Test()
+ async Task TestAsync()
{
await Task.Delay(1);
}
@@ -91,7 +125,7 @@ class Program
class Program
{
- public/*Comment*/static/*Comment*/async Task/*Comment*/Test()
+ public/*Comment*/static/*Comment*/async Task/*Comment*/TestAsync()
{
await Task.Delay(1);
}
@@ -176,7 +210,7 @@ void Test()
@"using System.Threading.Tasks;
class Program
{
- async void Test()
+ async void TestAsync()
{
await Task.Delay(1);
}
@@ -201,7 +235,7 @@ Task Test()
@"using System.Threading.Tasks;
class Program
{
- async Task Test()
+ async Task TestAsync()
{
await Task.Delay(1);
}
@@ -226,7 +260,7 @@ Task Test()
@"using System.Threading.Tasks;
class Program
{
- async Task Test()
+ async Task TestAsync()
{
await Task.Delay(1);
}
@@ -251,7 +285,7 @@ int Test()
@"using System.Threading.Tasks;
class Program
{
- async Task Test()
+ async Task TestAsync()
{
await Task.Delay(1);
}
@@ -274,7 +308,7 @@ void Test()
var expected =
@"class Program
{
- async void Test()
+ async void TestAsync()
{
await Task.Delay(1);
}
@@ -297,7 +331,7 @@ Task Test()
var expected =
@"class Program
{
- async Task Test()
+ async Task TestAsync()
{
await Task.Delay(1);
}
@@ -320,7 +354,7 @@ Task Test()
var expected =
@"class Program
{
- async Task Test()
+ async Task TestAsync()
{
await Task.Delay(1);
}
@@ -343,7 +377,7 @@ int Test()
var expected =
@"class Program
{
- async System.Threading.Tasks.Task Test()
+ async System.Threading.Tasks.Task TestAsync()
{
await Task.Delay(1);
}
@@ -366,7 +400,7 @@ Program Test()
var expected =
@"class Program
{
- async System.Threading.Tasks.Task Test()
+ async System.Threading.Tasks.Task TestAsync()
{
await Task.Delay(1);
}
@@ -389,7 +423,7 @@ asdf Test()
var expected =
@"class Program
{
- async System.Threading.Tasks.Task Test()
+ async System.Threading.Tasks.Task TestAsync()
{
await Task.Delay(1);
}
@@ -456,10 +490,5 @@ static async void Main()
}
}");
}
-
- internal override Tuple CreateDiagnosticProviderAndFixer(Workspace workspace)
- {
- return new Tuple(null, new CSharpAddAsyncCodeFixProvider());
- }
}
}
diff --git a/src/EditorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs b/src/EditorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs
index 40f4949536aad..0e25c4fe26412 100644
--- a/src/EditorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs
+++ b/src/EditorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs
@@ -1850,5 +1850,24 @@ void Foo()
}";
await TestAsync(text, "global::System.Collections.Generic.IEnumerable", testPosition: false);
}
+
+ [WorkItem(12755, "https://github.com/dotnet/roslyn/issues/12755")]
+ [Fact, Trait(Traits.Feature, Traits.Features.TypeInferenceService)]
+ public async Task TestObjectCreationBeforeArrayIndexing()
+ {
+ var text =
+@"using System;
+class C
+{
+ void M()
+ {
+ int[] array;
+ C p = new [||]
+ array[4] = 4;
+ }
+}";
+
+ await TestAsync(text, "global::C", testNode: false);
+ }
}
}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/EditorLayerExtensionManager.cs b/src/EditorFeatures/Core/Implementation/EditorLayerExtensionManager.cs
index 2af1bd32981ef..8cb52768eebc9 100644
--- a/src/EditorFeatures/Core/Implementation/EditorLayerExtensionManager.cs
+++ b/src/EditorFeatures/Core/Implementation/EditorLayerExtensionManager.cs
@@ -69,11 +69,11 @@ public override void HandleException(object provider, Exception exception)
{
base.HandleException(provider, exception);
- _errorReportingService?.ShowErrorInfoForCodeFix(
- codefixName: provider.GetType().Name,
- OnEnable: () => { EnableProvider(provider); LogEnableProvider(provider); },
- OnEnableAndIgnore: () => { EnableProvider(provider); IgnoreProvider(provider); LogEnableAndIgnoreProvider(provider); },
- OnClose: () => LogLeaveDisabled(provider));
+ _errorReportingService?.ShowErrorInfo(String.Format(WorkspacesResources._0_encountered_an_error_and_has_been_disabled, provider.GetType().Name),
+ new ErrorReportingUI(WorkspacesResources.Show_Stack_Trace, ErrorReportingUI.UIKind.HyperLink, () => ShowDetailedErrorInfo(exception), closeAfterAction: false),
+ new ErrorReportingUI(WorkspacesResources.Enable, ErrorReportingUI.UIKind.Button, () => { EnableProvider(provider); LogEnableProvider(provider); }),
+ new ErrorReportingUI(WorkspacesResources.Enable_and_ignore_future_errors, ErrorReportingUI.UIKind.Button, () => { EnableProvider(provider); LogEnableProvider(provider); }),
+ new ErrorReportingUI(String.Empty, ErrorReportingUI.UIKind.Close, () => LogLeaveDisabled(provider)));
}
else
{
@@ -93,6 +93,11 @@ public override void HandleException(object provider, Exception exception)
_errorLoggerService?.LogException(provider, exception);
}
+ private void ShowDetailedErrorInfo(Exception exception)
+ {
+ _errorReportingService.ShowDetailedErrorInfo(exception);
+ }
+
private static void LogLeaveDisabled(object provider)
{
LogAction(CodefixInfobar_LeaveDisabled, provider);
diff --git a/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingService.cs b/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingService.cs
index 47ab1704e5ecc..7a9fb43684a47 100644
--- a/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingService.cs
+++ b/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingService.cs
@@ -8,9 +8,9 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Workspaces
{
internal class EditorErrorReportingService : IErrorReportingService
{
- public void ShowErrorInfoForCodeFix(string codefixName, Action OnEnable, Action OnEnableAndIgnore, Action OnClose)
+ public void ShowDetailedErrorInfo(Exception exception)
{
- ShowErrorInfo($"{codefixName} crashed");
+ Logger.Log(FunctionId.Extension_Exception, exception.StackTrace);
}
public void ShowErrorInfo(string message, params ErrorReportingUI[] items)
diff --git a/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj b/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj
index ad2f2dc3bef80..1e180a5bfc497 100644
--- a/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj
+++ b/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj
@@ -167,7 +167,7 @@
-
+
@@ -618,4 +618,4 @@
-
+
\ No newline at end of file
diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/Async/AddAsyncTests.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/MakeMethodAsynchronous/MakeMethodAsynchronousTests.vb
similarity index 84%
rename from src/EditorFeatures/VisualBasicTest/Diagnostics/Async/AddAsyncTests.vb
rename to src/EditorFeatures/VisualBasicTest/Diagnostics/MakeMethodAsynchronous/MakeMethodAsynchronousTests.vb
index 1bd958cfee680..033a32035b39a 100644
--- a/src/EditorFeatures/VisualBasicTest/Diagnostics/Async/AddAsyncTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/MakeMethodAsynchronous/MakeMethodAsynchronousTests.vb
@@ -2,17 +2,23 @@
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
-Imports Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
+Imports Microsoft.CodeAnalysis.VisualBasic.MakeMethodAsynchronous
-Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
- Public Class AddAsyncTests
+Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.MakeMethodAsynchronous
+ Public Class MakeMethodAsynchronousTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
+ Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As Tuple(Of DiagnosticAnalyzer, CodeFixProvider)
+ Return Tuple.Create(Of DiagnosticAnalyzer, CodeFixProvider)(
+ Nothing,
+ New VisualBasicMakeMethodAsynchronousCodeFixProvider())
+ End Function
+
Public Async Function TestAwaitInSubNoModifiers() As Task
Await TestAsync(
NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Sub Test() \n [|Await Task.Delay(1)|] \n End Sub \n End Module"),
- NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Async Sub Test() \n Await Task.Delay(1) \n End Sub \n End Module")
+ NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Async Sub TestAsync() \n Await Task.Delay(1) \n End Sub \n End Module")
)
End Function
@@ -20,7 +26,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Public Async Function TestAwaitInSubWithModifiers() As Task
Await TestAsync(
NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Public Shared Sub Test() \n [|Await Task.Delay(1)|] \n End Sub \n End Module"),
- NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Public Shared Async Sub Test() \n Await Task.Delay(1) \n End Sub \n End Module")
+ NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Public Shared Async Sub TestAsync() \n Await Task.Delay(1) \n End Sub \n End Module")
)
End Function
@@ -28,7 +34,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Public Async Function TestAwaitInFunctionNoModifiers() As Task
Await TestAsync(
NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Function Test() As Integer \n [|Await Task.Delay(1)|] \n Function Sub \n End Module"),
- NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Async Function Test() As Task(Of Integer) \n Await Task.Delay(1) \n Function Sub \n End Module")
+ NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Async Function TestAsync() As Task(Of Integer) \n Await Task.Delay(1) \n Function Sub \n End Module")
)
End Function
@@ -36,7 +42,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Public Async Function TestAwaitInFunctionWithModifiers() As Task
Await TestAsync(
NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Public Shared Function Test() As Integer \n [|Await Task.Delay(1)|] \n Function Sub \n End Module"),
- NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Public Shared Async Function Test() As Task(Of Integer) \n Await Task.Delay(1) \n Function Sub \n End Module")
+ NewLines("Imports System \n Imports System.Threading.Tasks \n Module Program \n Public Shared Async Function TestAsync() As Task(Of Integer) \n Await Task.Delay(1) \n Function Sub \n End Module")
)
End Function
@@ -91,7 +97,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Dim expected =
- Async Function rtrt() As Task
+ Async Function rtrtAsync() As Task
Await Nothing
End Function
@@ -108,13 +114,30 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Dim expected =
- Async Sub rtrt()
+ Async Sub rtrtAsync()
Await Nothing
End Sub
Await TestAsync(initial, expected)
End Function
+
+ Public Async Function TestBadAwaitInNonAsyncVoidMethod1() As Task
+ Dim initial =
+
+ Sub rtrt()
+ [|Await Nothing|]
+ End Sub
+
+ Dim expected =
+
+ Async Function rtrtAsync() As Threading.Tasks.Task
+ Await Nothing
+ End Function
+
+ Await TestAsync(initial, expected, index:=1)
+ End Function
+
Public Async Function TestBadAwaitInNonAsyncFunction() As Task
Dim initial =
@@ -125,7 +148,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Dim expected =
- Async Function rtrt() As Task
+ Async Function rtrtAsync() As Task
Await Nothing
End Function
@@ -142,7 +165,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Dim expected =
- Async Function rtrt() As Task(Of Integer)
+ Async Function rtrtAsync() As Task(Of Integer)
Await Nothing
End Function
@@ -159,7 +182,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Dim expected =
- Async Function rtrt() As Threading.Tasks.Task(Of Integer)
+ Async Function rtrtAsync() As Threading.Tasks.Task(Of Integer)
Await Nothing
End Function
@@ -179,7 +202,7 @@ End Class
Dim expected =
Class Program
- Async Function rtrt() As Task
+ Async Function rtrtAsync() As Task
Await Nothing
End Function
End Class
@@ -200,7 +223,7 @@ End Class
Dim expected =
Class Program
- Async Function rtrt() As Task(Of Integer)
+ Async Function rtrtAsync() As Task(Of Integer)
Await Nothing
End Function
End Class
@@ -221,7 +244,7 @@ End Class
Dim expected =
Class Program
- Async Function rtrt() As System.Threading.Tasks.Task(Of Integer)
+ Async Function rtrtAsync() As System.Threading.Tasks.Task(Of Integer)
Await Nothing
End Function
End Class
@@ -242,7 +265,7 @@ End Class
Dim expected =
Class Program
- Async Function rtrt() As System.Threading.Tasks.Task(Of Program)
+ Async Function rtrtAsync() As System.Threading.Tasks.Task(Of Program)
Await Nothing
End Function
End Class
@@ -263,7 +286,7 @@ End Class
Dim expected =
Class Program
- Async Function rtrt() As System.Threading.Tasks.Task(Of asdf)
+ Async Function rtrtAsync() As System.Threading.Tasks.Task(Of asdf)
Await Nothing
End Function
End Class
@@ -288,11 +311,5 @@ End Module
Await TestMissingAsync(initial)
End Function
-
- Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As Tuple(Of DiagnosticAnalyzer, CodeFixProvider)
- Return Tuple.Create(Of DiagnosticAnalyzer, CodeFixProvider)(
- Nothing,
- New VisualBasicAddAsyncCodeFixProvider())
- End Function
End Class
End Namespace
diff --git a/src/Features/CSharp/Portable/CSharpFeatures.csproj b/src/Features/CSharp/Portable/CSharpFeatures.csproj
index df90dcedee2e0..c2fe6118634f4 100644
--- a/src/Features/CSharp/Portable/CSharpFeatures.csproj
+++ b/src/Features/CSharp/Portable/CSharpFeatures.csproj
@@ -66,7 +66,6 @@
-
@@ -329,6 +328,7 @@
+
diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs
index a189d87ffca87..d39049e97648f 100644
--- a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs
+++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs
@@ -548,15 +548,6 @@ internal static string Make_0_return_Task_instead_of_void {
}
}
- ///
- /// Looks up a localized string similar to Make the containing scope 'async'..
- ///
- internal static string Make_the_containing_scope_async {
- get {
- return ResourceManager.GetString("Make_the_containing_scope_async", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to <member name> = .
///
diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx
index ee60746116c07..a6ead4e6be7e9 100644
--- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx
+++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx
@@ -255,9 +255,6 @@
Insert 'await'.
-
- Make the containing scope 'async'.
-
Make {0} return Task instead of void.
diff --git a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAsyncCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAsyncCodeFixProvider.cs
deleted file mode 100644
index 905fa1d2525c9..0000000000000
--- a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAsyncCodeFixProvider.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Immutable;
-using System.Composition;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.CodeFixes;
-using Microsoft.CodeAnalysis.CodeFixes.Async;
-using Microsoft.CodeAnalysis.CSharp.Extensions;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Formatting;
-using Microsoft.CodeAnalysis.Shared.Extensions;
-
-namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.Async
-{
- [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.AddAsync), Shared]
- internal class CSharpAddAsyncCodeFixProvider : AbstractAddAsyncCodeFixProvider
- {
- ///
- /// The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
- ///
- private const string CS4032 = nameof(CS4032);
-
- ///
- /// The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
- ///
- private const string CS4033 = nameof(CS4033);
-
- ///
- /// The 'await' operator can only be used within an async lambda expression. Consider marking this method with the 'async' modifier.
- ///
- private const string CS4034 = nameof(CS4034);
-
- public override ImmutableArray FixableDiagnosticIds
- {
- get { return ImmutableArray.Create(CS4032, CS4033, CS4034); }
- }
-
- protected override string GetDescription(Diagnostic diagnostic, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken)
- {
- return CSharpFeaturesResources.Make_the_containing_scope_async;
- }
-
- protected override async Task GetNewRoot(SyntaxNode root, SyntaxNode oldNode, SemanticModel semanticModel, Diagnostic diagnostic, Document document, CancellationToken cancellationToken)
- {
- var nodeToModify = GetContainingMember(oldNode);
- if (nodeToModify == null)
- {
- return null;
- }
-
- var modifiedNode = await ConvertToAsync(nodeToModify, semanticModel, document, cancellationToken).ConfigureAwait(false);
- if (modifiedNode != null)
- {
- return root.ReplaceNode(nodeToModify, modifiedNode);
- }
-
- return null;
- }
-
- private static SyntaxNode GetContainingMember(SyntaxNode oldNode)
- {
- foreach (var node in oldNode.Ancestors())
- {
- switch (node.Kind())
- {
- case SyntaxKind.ParenthesizedLambdaExpression:
- case SyntaxKind.SimpleLambdaExpression:
- case SyntaxKind.AnonymousMethodExpression:
- if ((node as AnonymousFunctionExpressionSyntax)?.AsyncKeyword.Kind() != SyntaxKind.AsyncKeyword)
- {
- return node;
- }
- break;
- case SyntaxKind.MethodDeclaration:
- if ((node as MethodDeclarationSyntax)?.Modifiers.Any(SyntaxKind.AsyncKeyword) == false)
- {
- return node;
- }
- break;
- default:
- continue;
- }
- }
-
- return null;
- }
-
- private Task ConvertToAsync(SyntaxNode node, SemanticModel semanticModel, Document document, CancellationToken cancellationToken)
- {
- return node.TypeSwitch(
- (MethodDeclarationSyntax methodNode) => ConvertMethodToAsync(document, semanticModel, methodNode, cancellationToken),
- (ParenthesizedLambdaExpressionSyntax parenthesizedLambda) => Task.FromResult(ConvertParenthesizedLambdaToAsync(parenthesizedLambda)),
- (SimpleLambdaExpressionSyntax simpleLambda) => Task.FromResult(ConvertSimpleLambdaToAsync(simpleLambda)),
- (AnonymousMethodExpressionSyntax anonymousMethod) => Task.FromResult(ConvertAnonymousMethodToAsync(anonymousMethod)),
- @default => Task.FromResult(null));
- }
-
- private static SyntaxNode ConvertParenthesizedLambdaToAsync(ParenthesizedLambdaExpressionSyntax parenthesizedLambda)
- {
- return SyntaxFactory.ParenthesizedLambdaExpression(
- SyntaxFactory.Token(SyntaxKind.AsyncKeyword),
- parenthesizedLambda.ParameterList,
- parenthesizedLambda.ArrowToken,
- parenthesizedLambda.Body)
- .WithTriviaFrom(parenthesizedLambda)
- .WithAdditionalAnnotations(Formatter.Annotation);
- }
-
- private static SyntaxNode ConvertSimpleLambdaToAsync(SimpleLambdaExpressionSyntax simpleLambda)
- {
- return SyntaxFactory.SimpleLambdaExpression(
- SyntaxFactory.Token(SyntaxKind.AsyncKeyword),
- simpleLambda.Parameter,
- simpleLambda.ArrowToken,
- simpleLambda.Body)
- .WithTriviaFrom(simpleLambda)
- .WithAdditionalAnnotations(Formatter.Annotation);
- }
-
- private static SyntaxNode ConvertAnonymousMethodToAsync(AnonymousMethodExpressionSyntax anonymousMethod)
- {
- return SyntaxFactory.AnonymousMethodExpression(
- SyntaxFactory.Token(SyntaxKind.AsyncKeyword),
- anonymousMethod.DelegateKeyword,
- anonymousMethod.ParameterList,
- anonymousMethod.Block)
- .WithTriviaFrom(anonymousMethod)
- .WithAdditionalAnnotations(Formatter.Annotation);
- }
-
- protected override SyntaxNode AddAsyncKeyword(SyntaxNode node)
- {
- var methodNode = node as MethodDeclarationSyntax;
- if (methodNode == null)
- {
- return null;
- }
-
- return methodNode
- .AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword))
- .WithAdditionalAnnotations(Formatter.Annotation);
- }
-
- protected override SyntaxNode AddAsyncKeywordAndTaskReturnType(SyntaxNode node, ITypeSymbol existingReturnType, INamedTypeSymbol taskTypeSymbol)
- {
- var methodNode = node as MethodDeclarationSyntax;
- if (methodNode == null)
- {
- return null;
- }
-
- if (taskTypeSymbol == null)
- {
- return null;
- }
-
- var returnType = taskTypeSymbol.Construct(existingReturnType).GenerateTypeSyntax();
- return AddAsyncKeyword(methodNode.WithReturnType(returnType));
- }
-
- protected override bool DoesConversionExist(Compilation compilation, ITypeSymbol source, ITypeSymbol destination)
- {
- return compilation.ClassifyConversion(source, destination).Exists;
- }
- }
-}
diff --git a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs
index 49f5431d1af8e..82e2076a1c31d 100644
--- a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs
+++ b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs
@@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
@@ -17,7 +19,7 @@
namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.Async
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.AddAwait), Shared]
- internal class CSharpAddAwaitCodeFixProvider : AbstractAddAsyncAwaitCodeFixProvider
+ internal class CSharpAddAwaitCodeFixProvider : AbstractAddAwaitCodeFixProvider
{
///
/// Because this call is not awaited, execution of the current method continues before the call is completed.
@@ -36,10 +38,20 @@ internal class CSharpAddAwaitCodeFixProvider : AbstractAddAsyncAwaitCodeFixProvi
public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0029, CS4014, CS4016);
- protected override string GetDescription(Diagnostic diagnostic, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken) =>
- CSharpFeaturesResources.Insert_await;
+ protected override async Task GetDescriptionAndNodeAsync(
+ SyntaxNode root, SyntaxNode oldNode, SemanticModel semanticModel, Diagnostic diagnostic, Document document, CancellationToken cancellationToken)
+ {
+ var newRoot = await GetNewRootAsync(
+ root, oldNode, semanticModel, diagnostic, document, cancellationToken).ConfigureAwait(false);
+ if (newRoot == null)
+ {
+ return default(DescriptionAndNode);
+ }
+
+ return new DescriptionAndNode(CSharpFeaturesResources.Insert_await, newRoot);
+ }
- protected override Task GetNewRoot(
+ private Task GetNewRootAsync(
SyntaxNode root,
SyntaxNode oldNode,
SemanticModel semanticModel,
diff --git a/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs
new file mode 100644
index 0000000000000..dabb0290fefc7
--- /dev/null
+++ b/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs
@@ -0,0 +1,87 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+using System.Composition;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp.Extensions;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.MakeMethodAsynchronous;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+
+namespace Microsoft.CodeAnalysis.CSharp.MakeMethodAsynchronous
+{
+ [ExportCodeFixProvider(LanguageNames.CSharp), Shared]
+ internal class CSharpMakeMethodAsynchronousCodeFixProvider : AbstractMakeMethodAsynchronousCodeFixProvider
+ {
+ private const string CS4032 = nameof(CS4032); // The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
+ private const string CS4033 = nameof(CS4033); // The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
+ private const string CS4034 = nameof(CS4034); // The 'await' operator can only be used within an async lambda expression. Consider marking this method with the 'async' modifier.
+
+ private static readonly SyntaxToken s_asyncToken = SyntaxFactory.Token(SyntaxKind.AsyncKeyword);
+
+ public override ImmutableArray FixableDiagnosticIds { get; } =
+ ImmutableArray.Create(CS4032, CS4033, CS4034);
+
+ protected override bool IsMethodOrAnonymousFunction(SyntaxNode node)
+ {
+ return node.IsKind(SyntaxKind.MethodDeclaration) || node.IsAnyLambdaOrAnonymousMethod();
+ }
+
+ protected override SyntaxNode AddAsyncTokenAndFixReturnType(
+ bool keepVoid, IMethodSymbol methodSymbolOpt, SyntaxNode node,
+ INamedTypeSymbol taskType, INamedTypeSymbol taskOfTType)
+ {
+ return node.TypeSwitch(
+ (MethodDeclarationSyntax method) => FixMethod(keepVoid, methodSymbolOpt, method, taskType, taskOfTType),
+ (AnonymousMethodExpressionSyntax method) => FixAnonymousMethod(method),
+ (ParenthesizedLambdaExpressionSyntax lambda) => FixParenthesizedLambda(lambda),
+ (SimpleLambdaExpressionSyntax lambda) => FixSimpleLambda(lambda),
+ _ => node);
+ }
+
+ private SyntaxNode FixMethod(
+ bool keepVoid, IMethodSymbol methodSymbol, MethodDeclarationSyntax method,
+ ITypeSymbol taskType, INamedTypeSymbol taskOfTType)
+ {
+ var newReturnType = method.ReturnType;
+
+ if (methodSymbol.ReturnsVoid)
+ {
+ if (!keepVoid)
+ {
+ newReturnType = taskType.GenerateTypeSyntax();
+ }
+ }
+ else
+ {
+ if (!IsTaskLike(methodSymbol.ReturnType, taskType, taskOfTType))
+ {
+ // If it's not already Task-like, then wrap the existing return type
+ // in Task<>.
+ newReturnType = taskOfTType.Construct(methodSymbol.ReturnType).GenerateTypeSyntax();
+ }
+ }
+
+ var newModifiers = method.Modifiers.Add(s_asyncToken);
+ return method.WithReturnType(newReturnType).WithModifiers(newModifiers);
+ }
+
+ private SyntaxNode FixParenthesizedLambda(ParenthesizedLambdaExpressionSyntax lambda)
+ {
+ return lambda.WithoutLeadingTrivia()
+ .WithAsyncKeyword(s_asyncToken.WithPrependedLeadingTrivia(lambda.GetLeadingTrivia()));
+ }
+
+ private SyntaxNode FixSimpleLambda(SimpleLambdaExpressionSyntax lambda)
+ {
+ return lambda.WithoutLeadingTrivia()
+ .WithAsyncKeyword(s_asyncToken.WithPrependedLeadingTrivia(lambda.GetLeadingTrivia()));
+ }
+
+ private SyntaxNode FixAnonymousMethod(AnonymousMethodExpressionSyntax method)
+ {
+ return method.WithoutLeadingTrivia()
+ .WithAsyncKeyword(s_asyncToken.WithPrependedLeadingTrivia(method.GetLeadingTrivia()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs b/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs
index 357cb1f696722..1088def4cedc7 100644
--- a/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs
+++ b/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs
@@ -132,8 +132,13 @@ private static SyntaxNode GetGetMethod(
if (propertyDeclaration.ExpressionBody != null)
{
- var returnStatement = SyntaxFactory.ReturnStatement(propertyDeclaration.ExpressionBody.Expression)
- .WithSemicolonToken(propertyDeclaration.SemicolonToken);
+ var returnKeyword = SyntaxFactory.Token(SyntaxKind.ReturnKeyword)
+ .WithTrailingTrivia(propertyDeclaration.ExpressionBody.ArrowToken.TrailingTrivia);
+
+ var returnStatement = SyntaxFactory.ReturnStatement(
+ returnKeyword,
+ propertyDeclaration.ExpressionBody.Expression,
+ propertyDeclaration.SemicolonToken);
statements.Add(returnStatement);
}
else
diff --git a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.ProjectSymbolReference.cs b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.ProjectSymbolReference.cs
index 20d90a98cb559..3c02f29ed2c26 100644
--- a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.ProjectSymbolReference.cs
+++ b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.ProjectSymbolReference.cs
@@ -47,21 +47,11 @@ protected override CodeActionPriority GetPriority(Document document)
if (document.Project.Id == _project.Id)
{
- if (!SearchResult.DesiredNameDiffersFromSourceName())
+ if (SearchResult.DesiredNameMatchesSourceName(document))
{
// The name doesn't change. This is a normal priority action.
return CodeActionPriority.Medium;
}
-
- // We need to update the source name. If all we're doing is changing the
- // casing, and this is a case insensitive language, then this is just a
- // normal priority action. Otherwise, this wil be low priority.
- var syntaxFacts = document.GetLanguageService();
- if (!syntaxFacts.IsCaseSensitive &&
- SearchResult.DesiredNameDiffersFromSourceNameOnlyByCase())
- {
- return CodeActionPriority.Medium;
- }
}
// This is a weaker match. This should be lower than all other fixes.
diff --git a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.Reference.cs b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.Reference.cs
index e1099ef9ced7b..dbfdcd787a0fb 100644
--- a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.Reference.cs
+++ b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.Reference.cs
@@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
internal abstract partial class AbstractAddImportCodeFixProvider
{
- private abstract class Reference : IComparable, IEquatable
+ private abstract class Reference : IEquatable
{
protected readonly AbstractAddImportCodeFixProvider provider;
public readonly SearchResult SearchResult;
@@ -24,7 +24,7 @@ protected Reference(AbstractAddImportCodeFixProvider provider
this.SearchResult = searchResult;
}
- public virtual int CompareTo(Reference other)
+ public int CompareTo(Document document, Reference other)
{
// If references have different weights, order by the ones with lower weight (i.e.
// they are better matches).
@@ -38,7 +38,36 @@ public virtual int CompareTo(Reference other)
return 1;
}
- // If the weight are the same, just order them based on their names.
+ if (this.SearchResult.DesiredNameMatchesSourceName(document))
+ {
+ if (!other.SearchResult.DesiredNameMatchesSourceName(document))
+ {
+ // Prefer us as our name doesn't need to change.
+ return -1;
+ }
+ }
+ else
+ {
+ if (other.SearchResult.DesiredNameMatchesSourceName(document))
+ {
+ // Prefer them as their name doesn't need to change.
+ return 1;
+ }
+ else
+ {
+ // Both our names need to change. Sort by the name we're
+ // changing to.
+ var diff = StringComparer.OrdinalIgnoreCase.Compare(
+ this.SearchResult.DesiredName, other.SearchResult.DesiredName);
+ if (diff != 0)
+ {
+ return diff;
+ }
+ }
+ }
+
+ // If the weights are the same and no names changed, just order
+ // them based on the namespace we're adding an import for.
return INamespaceOrTypeSymbolExtensions.CompareNameParts(
this.SearchResult.NameParts, other.SearchResult.NameParts);
}
diff --git a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReference.cs b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReference.cs
index 1db72b539b73c..daa4ecf13b6aa 100644
--- a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReference.cs
+++ b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReference.cs
@@ -26,19 +26,6 @@ public SymbolReference(AbstractAddImportCodeFixProvider provi
protected abstract Glyph? GetGlyph(Document document);
protected abstract bool CheckForExistingImport(Project project);
- public override int CompareTo(Reference other)
- {
- var diff = base.CompareTo(other);
- if (diff != 0)
- {
- return diff;
- }
-
- var name1 = this.SymbolResult.DesiredName;
- var name2 = (other as SymbolReference)?.SymbolResult.DesiredName;
- return StringComparer.Ordinal.Compare(name1, name2);
- }
-
public override bool Equals(object obj)
{
var equals = base.Equals(obj);
@@ -88,6 +75,13 @@ public override async Task CreateCodeActionAsync(
return null;
}
+ if (!this.SearchResult.DesiredNameMatchesSourceName(document))
+ {
+ // The name is going to change. Make it clear in the description that
+ // this is going to happen.
+ description = $"{this.SearchResult.DesiredName} - {description}";
+ }
+
return new OperationBasedCodeAction(description, GetGlyph(document), GetPriority(document),
c => this.GetOperationsAsync(document, node, placeSystemNamespaceFirst, c),
this.GetIsApplicableCheck(document.Project));
diff --git a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReferenceFinder.cs b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReferenceFinder.cs
index 7b36d278a005c..e19030d5575ca 100644
--- a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReferenceFinder.cs
+++ b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolReferenceFinder.cs
@@ -74,10 +74,10 @@ private INamespaceSymbol MapToCompilationNamespaceIfPossible(INamespaceSymbol co
return _semanticModel.Compilation.GetCompilationNamespace(containingNamespace) ?? containingNamespace;
}
- internal Task> FindInAllSymbolsInProjectAsync(
- Project project, bool exact, CancellationToken cancellationToken)
+ internal Task> FindInAllSymbolsInStartingProjectAsync(
+ bool exact, CancellationToken cancellationToken)
{
- var searchScope = new AllSymbolsProjectSearchScope(_owner, project, exact, cancellationToken);
+ var searchScope = new AllSymbolsProjectSearchScope(_owner, _document.Project, exact, cancellationToken);
return DoAsync(searchScope);
}
@@ -91,11 +91,11 @@ internal Task> FindInSourceSymbolsInProjectAsync(
}
internal Task> FindInMetadataSymbolsAsync(
- Solution solution, IAssemblySymbol assembly, PortableExecutableReference metadataReference,
+ IAssemblySymbol assembly, PortableExecutableReference metadataReference,
bool exact, CancellationToken cancellationToken)
{
var searchScope = new MetadataSymbolsSearchScope(
- _owner, solution, assembly, metadataReference, exact, cancellationToken);
+ _owner, _document.Project.Solution, assembly, metadataReference, exact, cancellationToken);
return DoAsync(searchScope);
}
@@ -153,7 +153,7 @@ private List DeDupeAndSortReferences(List allR
.Distinct()
.Where(NotNull)
.Where(NotGlobalNamespace)
- .Order()
+ .OrderBy((r1, r2) => r1.CompareTo(_document, r2))
.ToList();
}
diff --git a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolResult.cs b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolResult.cs
index 11e5aeaf2fdeb..5b6c869d31ab2 100644
--- a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolResult.cs
+++ b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.SymbolResult.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
@@ -49,6 +50,27 @@ public bool DesiredNameDiffersFromSourceNameOnlyByCase()
return StringComparer.OrdinalIgnoreCase.Equals(
this.NameNode.GetFirstToken().ValueText, this.DesiredName);
}
+
+ public bool DesiredNameMatchesSourceName(Document document)
+ {
+ if (!this.DesiredNameDiffersFromSourceName())
+ {
+ // Names match in any language.
+ return true;
+ }
+
+ var syntaxFacts = document.GetLanguageService();
+
+ // Names differ. But in a case insensitive language they may match.
+ if (!syntaxFacts.IsCaseSensitive &&
+ this.DesiredNameDiffersFromSourceNameOnlyByCase())
+ {
+ return true;
+ }
+
+ // Name are totally different in any language.
+ return false;
+ }
}
private struct SymbolResult where T : ISymbol
diff --git a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.cs
index 09ac9f304b4fc..bc36903e9a2d1 100644
--- a/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.cs
+++ b/src/Features/Core/Portable/CodeFixes/AddImport/AbstractAddImportCodeFixProvider.cs
@@ -160,8 +160,8 @@ private async Task> FindResultsAsync(
// First search the current project to see if any symbols (source or metadata) match the
// search string.
- await FindResultsInAllProjectSymbolsAsync(
- project, allReferences, finder, exact, cancellationToken).ConfigureAwait(false);
+ await FindResultsInAllSymbolsInStartingProjectAsync(
+ allReferences, finder, exact, cancellationToken).ConfigureAwait(false);
// Only bother doing this for host workspaces. We don't want this for
// things like the Interactive workspace as we can't even add project
@@ -186,11 +186,11 @@ await FindResultsInAllProjectSymbolsAsync(
return allReferences;
}
- private async Task FindResultsInAllProjectSymbolsAsync(
- Project project, List allSymbolReferences,
- SymbolReferenceFinder finder, bool exact, CancellationToken cancellationToken)
+ private async Task FindResultsInAllSymbolsInStartingProjectAsync(
+ List allSymbolReferences, SymbolReferenceFinder finder,
+ bool exact, CancellationToken cancellationToken)
{
- var references = await finder.FindInAllSymbolsInProjectAsync(project, exact, cancellationToken).ConfigureAwait(false);
+ var references = await finder.FindInAllSymbolsInStartingProjectAsync(exact, cancellationToken).ConfigureAwait(false);
AddRange(allSymbolReferences, references);
}
@@ -272,7 +272,7 @@ private async Task FindResultsInUnreferencedMetadataSymbolsAsync(
if (assembly != null)
{
findTasks.Add(finder.FindInMetadataSymbolsAsync(
- project.Solution, assembly, reference, exact, linkedTokenSource.Token));
+ assembly, reference, exact, linkedTokenSource.Token));
}
}
diff --git a/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAsyncCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAsyncCodeFixProvider.cs
deleted file mode 100644
index 2ae03a8e0c2f8..0000000000000
--- a/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAsyncCodeFixProvider.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.FindSymbols;
-using Microsoft.CodeAnalysis.LanguageServices;
-
-namespace Microsoft.CodeAnalysis.CodeFixes.Async
-{
- internal abstract partial class AbstractAddAsyncCodeFixProvider : AbstractAddAsyncAwaitCodeFixProvider
- {
- protected const string SystemThreadingTasksTask = "System.Threading.Tasks.Task";
- protected const string SystemThreadingTasksTaskT = "System.Threading.Tasks.Task`1";
- protected abstract SyntaxNode AddAsyncKeyword(SyntaxNode methodNode);
- protected abstract SyntaxNode AddAsyncKeywordAndTaskReturnType(SyntaxNode methodNode, ITypeSymbol existingReturnType, INamedTypeSymbol taskTypeSymbol);
- protected abstract bool DoesConversionExist(Compilation compilation, ITypeSymbol source, ITypeSymbol destination);
-
- protected async Task ConvertMethodToAsync(Document document, SemanticModel semanticModel, SyntaxNode methodNode, CancellationToken cancellationToken)
- {
- var methodSymbol = semanticModel.GetDeclaredSymbol(methodNode, cancellationToken) as IMethodSymbol;
-
- if (methodSymbol.ReturnsVoid)
- {
- return AddAsyncKeyword(methodNode);
- }
-
- var returnType = methodSymbol.ReturnType;
- var compilation = semanticModel.Compilation;
-
- var taskSymbol = compilation.GetTypeByMetadataName(SystemThreadingTasksTask);
- var genericTaskSymbol = compilation.GetTypeByMetadataName(SystemThreadingTasksTaskT);
- if (taskSymbol == null)
- {
- return null;
- }
-
- if (returnType is IErrorTypeSymbol)
- {
- // The return type of the method will not bind. This could happen for a lot of reasons.
- // The type may not actually exist or the user could just be missing a using/import statement.
- // We're going to try and see if there are any known types that have the same name as
- // our return type, and then check if those are convertible to Task. If they are then
- // we assume the user just has a missing using. If they are not, we wrap the return
- // type in a generic Task.
- var typeName = returnType.Name;
- var syntaxFacts = document.Project.LanguageServices.GetService();
- var results = await SymbolFinder.FindDeclarationsAsync(
- document.Project, typeName, ignoreCase: syntaxFacts.IsCaseSensitive, filter: SymbolFilter.Type, cancellationToken: cancellationToken).ConfigureAwait(false);
-
- if (results.OfType().Any(s => DoesConversionExist(compilation, s, taskSymbol)))
- {
- return AddAsyncKeyword(methodNode);
- }
-
- return AddAsyncKeywordAndTaskReturnType(methodNode, returnType, genericTaskSymbol);
- }
-
- if (DoesConversionExist(compilation, returnType, taskSymbol))
- {
- return AddAsyncKeyword(methodNode);
- }
-
- return AddAsyncKeywordAndTaskReturnType(methodNode, returnType, genericTaskSymbol);
- }
- }
-}
diff --git a/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAsyncAwaitCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAwaitCodeFixProvider.cs
similarity index 53%
rename from src/Features/Core/Portable/CodeFixes/Async/AbstractAddAsyncAwaitCodeFixProvider.cs
rename to src/Features/Core/Portable/CodeFixes/Async/AbstractAddAwaitCodeFixProvider.cs
index 7649b1c64f0b4..5d84473cd3935 100644
--- a/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAsyncAwaitCodeFixProvider.cs
+++ b/src/Features/Core/Portable/CodeFixes/Async/AbstractAddAwaitCodeFixProvider.cs
@@ -1,30 +1,32 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
namespace Microsoft.CodeAnalysis.CodeFixes.Async
{
- internal abstract partial class AbstractAddAsyncAwaitCodeFixProvider : AbstractAsyncCodeFix
+ internal abstract partial class AbstractAddAwaitCodeFixProvider : AbstractAsyncCodeFix
{
- protected abstract string GetDescription(Diagnostic diagnostic, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken);
- protected abstract Task GetNewRoot(SyntaxNode root, SyntaxNode oldNode, SemanticModel semanticModel, Diagnostic diagnostic, Document document, CancellationToken cancellationToken);
+ protected abstract Task GetDescriptionAndNodeAsync(
+ SyntaxNode root, SyntaxNode oldNode, SemanticModel semanticModel, Diagnostic diagnostic, Document document, CancellationToken cancellationToken);
- protected override async Task GetCodeFix(SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
+ protected override async Task GetCodeActionAsync(
+ SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
- var newRoot = await this.GetNewRoot(root, node, semanticModel, diagnostic, document, cancellationToken).ConfigureAwait(false);
- if (newRoot != null)
+ var data = await this.GetDescriptionAndNodeAsync(root, node, semanticModel, diagnostic, document, cancellationToken).ConfigureAwait(false);
+ if (data.Node == null)
{
- return new MyCodeAction(
- this.GetDescription(diagnostic, node, semanticModel, cancellationToken),
- token => Task.FromResult(document.WithSyntaxRoot(newRoot)));
+ return null;
}
- return null;
+ return new MyCodeAction(
+ data.Description,
+ c => Task.FromResult(document.WithSyntaxRoot(data.Node)));
}
protected static bool TryGetExpressionType(
@@ -51,5 +53,17 @@ public MyCodeAction(string title, Func> create
{
}
}
+
+ protected struct DescriptionAndNode
+ {
+ public readonly string Description;
+ public readonly SyntaxNode Node;
+
+ public DescriptionAndNode(string description, SyntaxNode node)
+ {
+ Description = description;
+ Node = node;
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/CodeFixes/Async/AbstractAsyncCodeFix.cs b/src/Features/Core/Portable/CodeFixes/Async/AbstractAsyncCodeFix.cs
index e682ff9f47aaf..1e3abdbe5021c 100644
--- a/src/Features/Core/Portable/CodeFixes/Async/AbstractAsyncCodeFix.cs
+++ b/src/Features/Core/Portable/CodeFixes/Async/AbstractAsyncCodeFix.cs
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -11,7 +12,8 @@ namespace Microsoft.CodeAnalysis.CodeFixes.Async
{
internal abstract partial class AbstractAsyncCodeFix : CodeFixProvider
{
- protected abstract Task GetCodeFix(SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostic, CancellationToken cancellationToken);
+ protected abstract Task GetCodeActionAsync(
+ SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostic, CancellationToken cancellationToken);
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
@@ -25,11 +27,11 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
var diagnostic = context.Diagnostics.FirstOrDefault();
- var codeAction = await GetCodeFix(root, node, context.Document, diagnostic, context.CancellationToken).ConfigureAwait(false);
-
+ var codeAction = await GetCodeActionAsync(
+ root, node, context.Document, diagnostic, context.CancellationToken).ConfigureAwait(false);
if (codeAction != null)
{
- context.RegisterCodeFix(codeAction, diagnostic);
+ context.RegisterCodeFix(codeAction, context.Diagnostics);
}
}
@@ -46,4 +48,4 @@ private bool TryGetNode(SyntaxNode root, TextSpan span, out SyntaxNode node)
return node != null;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/CodeFixes/Async/AbstractChangeToAsyncCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Async/AbstractChangeToAsyncCodeFixProvider.cs
index 75efc23bc06fb..ccc879f3d625a 100644
--- a/src/Features/Core/Portable/CodeFixes/Async/AbstractChangeToAsyncCodeFixProvider.cs
+++ b/src/Features/Core/Portable/CodeFixes/Async/AbstractChangeToAsyncCodeFixProvider.cs
@@ -12,22 +12,23 @@ internal abstract partial class AbstractChangeToAsyncCodeFixProvider : AbstractA
protected abstract Task GetDescription(Diagnostic diagnostic, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken);
protected abstract Task> GetRootInOtherSyntaxTree(SyntaxNode node, SemanticModel semanticModel, Diagnostic diagnostic, CancellationToken cancellationToken);
- protected override async Task GetCodeFix(SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
+ protected override async Task GetCodeActionAsync(
+ SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var result = await GetRootInOtherSyntaxTree(node, semanticModel, diagnostic, cancellationToken).ConfigureAwait(false);
- if (result != null)
+ if (result == null)
{
- var syntaxTree = result.Item1;
- var newRoot = result.Item2;
- var otherDocument = document.Project.Solution.GetDocument(syntaxTree);
- return new MyCodeAction(
- await this.GetDescription(diagnostic, node, semanticModel, cancellationToken).ConfigureAwait(false),
- token => Task.FromResult(otherDocument.WithSyntaxRoot(newRoot)));
+ return null;
}
- return null;
+ var syntaxTree = result.Item1;
+ var newRoot = result.Item2;
+ var otherDocument = document.Project.Solution.GetDocument(syntaxTree);
+ return new MyCodeAction(
+ await this.GetDescription(diagnostic, node, semanticModel, cancellationToken).ConfigureAwait(false),
+ token => Task.FromResult(otherDocument.WithSyntaxRoot(newRoot)));
}
private class MyCodeAction : CodeAction.DocumentChangeAction
diff --git a/src/Features/Core/Portable/CodeFixes/CodeFixContextExtensions.cs b/src/Features/Core/Portable/CodeFixes/CodeFixContextExtensions.cs
index b9d045b97c0ed..8a1226e45a66a 100644
--- a/src/Features/Core/Portable/CodeFixes/CodeFixContextExtensions.cs
+++ b/src/Features/Core/Portable/CodeFixes/CodeFixContextExtensions.cs
@@ -24,10 +24,13 @@ internal static void RegisterFixes(this CodeFixContext context, IEnumerable
internal static void RegisterFixes(this CodeFixContext context, IEnumerable actions, ImmutableArray diagnostics)
{
- foreach (var action in actions)
+ if (actions != null)
{
- context.RegisterCodeFix(action, diagnostics);
+ foreach (var action in actions)
+ {
+ context.RegisterCodeFix(action, diagnostics);
+ }
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/Features.csproj b/src/Features/Core/Portable/Features.csproj
index fc6f5f5189de1..056a089bed8a6 100644
--- a/src/Features/Core/Portable/Features.csproj
+++ b/src/Features/Core/Portable/Features.csproj
@@ -110,8 +110,7 @@
-
-
+
@@ -242,6 +241,7 @@
+
diff --git a/src/Features/Core/Portable/FeaturesResources.Designer.cs b/src/Features/Core/Portable/FeaturesResources.Designer.cs
index 900dd818cccb8..8ee89a72d4a6a 100644
--- a/src/Features/Core/Portable/FeaturesResources.Designer.cs
+++ b/src/Features/Core/Portable/FeaturesResources.Designer.cs
@@ -1620,6 +1620,42 @@ internal static string location_unknown {
}
}
+ ///
+ /// Looks up a localized string similar to Make containing scope async.
+ ///
+ internal static string Make_containing_scope_async {
+ get {
+ return ResourceManager.GetString("Make_containing_scope_async", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Make containing scope async (return Task).
+ ///
+ internal static string Make_containing_scope_async_return_Task {
+ get {
+ return ResourceManager.GetString("Make_containing_scope_async_return_Task", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Make method async.
+ ///
+ internal static string Make_method_async {
+ get {
+ return ResourceManager.GetString("Make_method_async", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Make method async (return Task).
+ ///
+ internal static string Make_method_async_return_Task {
+ get {
+ return ResourceManager.GetString("Make_method_async_return_Task", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Make method synchronous..
///
diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx
index bcbe9ba029b16..e81918e95442e 100644
--- a/src/Features/Core/Portable/FeaturesResources.resx
+++ b/src/Features/Core/Portable/FeaturesResources.resx
@@ -1046,6 +1046,18 @@ This version used in: {2}
Remove tag
+
+ Make containing scope async
+
+
+ Make containing scope async (return Task)
+
+
+ Make method async
+
+
+ Make method async (return Task)
+
(Unknown)
diff --git a/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodAsyncOrSyncCodeFixProvider.cs b/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodAsyncOrSyncCodeFixProvider.cs
new file mode 100644
index 0000000000000..0a4895e721451
--- /dev/null
+++ b/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodAsyncOrSyncCodeFixProvider.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Rename;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Roslyn.Utilities;
+
+namespace Microsoft.CodeAnalysis.MakeMethodAsyncOrSync
+{
+ internal abstract class AbstractMakeMethodAsyncOrAsyncCodeFixProvider : CodeFixProvider
+ {
+ protected abstract bool IsMethodOrAnonymousFunction(SyntaxNode node);
+ protected abstract SyntaxNode AddAsyncTokenAndFixReturnType(
+ bool keepVoid, IMethodSymbol methodSymbolOpt, SyntaxNode node,
+ INamedTypeSymbol taskType, INamedTypeSymbol taskOfTType);
+
+ public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
+
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var diagnostic = context.Diagnostics.First();
+ var cancellationToken = context.CancellationToken;
+
+ var node = GetContainingFunction(diagnostic, cancellationToken);
+ if (node == null)
+ {
+ return;
+ }
+
+ var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) as IMethodSymbol;
+
+ // If it's a void returning method, offer to keep the void return type, or convert to
+ // a Task return type.
+ if (symbol?.MethodKind == MethodKind.Ordinary &&
+ symbol.ReturnsVoid)
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: true, cancellationToken: c)),
+ context.Diagnostics);
+
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async_return_Task, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: false, cancellationToken: c)),
+ context.Diagnostics);
+ }
+ else
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: false, cancellationToken: c)),
+ context.Diagnostics);
+ }
+ }
+
+ private const string AsyncSuffix = "Async";
+
+ private async Task FixNodeAsync(
+ Document document, Diagnostic diagnostic,
+ bool keepVoid, CancellationToken cancellationToken)
+ {
+ var node = GetContainingFunction(diagnostic, cancellationToken);
+
+ // See if we're on an actual method declaration (otherwise we're on a lambda declaration).
+ // If we're on a method declaration, we'll get an IMethodSymbol back. In that case, check
+ // if it has the 'Async' suffix, and remove that suffix if so.
+ var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var methodSymbolOpt = semanticModel.GetDeclaredSymbol(node) as IMethodSymbol;
+
+ if (methodSymbolOpt?.MethodKind == MethodKind.Ordinary &&
+ !methodSymbolOpt.Name.EndsWith(AsyncSuffix))
+ {
+ return await RenameThenAddAsyncTokenAsync(
+ keepVoid, document, node, methodSymbolOpt, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ return await AddAsyncTokenAsync(
+ keepVoid, document, methodSymbolOpt, node, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ private SyntaxNode GetContainingFunction(Diagnostic diagnostic, CancellationToken cancellationToken)
+ {
+ var token = diagnostic.Location.FindToken(cancellationToken);
+ var node = token.GetAncestor(IsMethodOrAnonymousFunction);
+ return node;
+ }
+
+ private async Task RenameThenAddAsyncTokenAsync(
+ bool keepVoid, Document document, SyntaxNode node,
+ IMethodSymbol methodSymbol, CancellationToken cancellationToken)
+ {
+ var name = methodSymbol.Name;
+ var newName = name + AsyncSuffix;
+ var solution = document.Project.Solution;
+
+ // Store the path to this node. That way we can find it post rename.
+ var syntaxPath = new SyntaxPath(node);
+
+ // Rename the method to add the 'Async' suffix, then add the 'async' keyword.
+ var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, solution.Options, cancellationToken).ConfigureAwait(false);
+ var newDocument = newSolution.GetDocument(document.Id);
+ var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+
+ SyntaxNode newNode;
+ if (syntaxPath.TryResolve(newRoot, out newNode))
+ {
+ var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken);
+ return await AddAsyncTokenAsync(keepVoid, newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false);
+ }
+
+ return newSolution;
+ }
+
+ private async Task AddAsyncTokenAsync(
+ bool keepVoid, Document document, IMethodSymbol methodSymbolOpt,
+ SyntaxNode node, CancellationToken cancellationToken)
+ {
+ var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
+ var taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
+ var taskOfTType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
+
+ var newNode = AddAsyncTokenAndFixReturnType(keepVoid, methodSymbolOpt, node, taskType, taskOfTType)
+ .WithAdditionalAnnotations(Formatter.Annotation);
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var newRoot = root.ReplaceNode(node, newNode);
+
+ var newDocument = document.WithSyntaxRoot(newRoot);
+ return newDocument.Project.Solution;
+ }
+
+ private class MyCodeAction : CodeAction.SolutionChangeAction
+ {
+ public MyCodeAction(string title, Func> createChangedSolution)
+ : base(title, createChangedSolution, equivalenceKey: title)
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodAsynchronousCodeFixProvider.cs b/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodAsynchronousCodeFixProvider.cs
new file mode 100644
index 0000000000000..7d596e1ea25d1
--- /dev/null
+++ b/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodAsynchronousCodeFixProvider.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Rename;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Roslyn.Utilities;
+
+namespace Microsoft.CodeAnalysis.MakeMethodAsynchronous
+{
+ internal abstract class AbstractMakeMethodAsynchronousCodeFixProvider : CodeFixProvider
+ {
+ protected abstract bool IsMethodOrAnonymousFunction(SyntaxNode node);
+ protected abstract SyntaxNode AddAsyncTokenAndFixReturnType(
+ bool keepVoid, IMethodSymbol methodSymbolOpt, SyntaxNode node,
+ INamedTypeSymbol taskType, INamedTypeSymbol taskOfTType);
+
+ public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
+
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var diagnostic = context.Diagnostics.First();
+ var cancellationToken = context.CancellationToken;
+
+ var node = GetContainingFunction(diagnostic, cancellationToken);
+ if (node == null)
+ {
+ return;
+ }
+
+ var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) as IMethodSymbol;
+
+ // If it's a void returning method, offer to keep the void return type, or convert to
+ // a Task return type.
+ if (symbol?.MethodKind == MethodKind.Ordinary &&
+ symbol.ReturnsVoid)
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: true, cancellationToken: c)),
+ context.Diagnostics);
+
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async_return_Task, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: false, cancellationToken: c)),
+ context.Diagnostics);
+ }
+ else
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: false, cancellationToken: c)),
+ context.Diagnostics);
+ }
+ }
+
+ private const string AsyncSuffix = "Async";
+
+ private async Task FixNodeAsync(
+ Document document, Diagnostic diagnostic,
+ bool keepVoid, CancellationToken cancellationToken)
+ {
+ var node = GetContainingFunction(diagnostic, cancellationToken);
+
+ // See if we're on an actual method declaration (otherwise we're on a lambda declaration).
+ // If we're on a method declaration, we'll get an IMethodSymbol back. In that case, check
+ // if it has the 'Async' suffix, and remove that suffix if so.
+ var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var methodSymbolOpt = semanticModel.GetDeclaredSymbol(node) as IMethodSymbol;
+
+ if (methodSymbolOpt?.MethodKind == MethodKind.Ordinary &&
+ !methodSymbolOpt.Name.EndsWith(AsyncSuffix))
+ {
+ return await RenameThenAddAsyncTokenAsync(
+ keepVoid, document, node, methodSymbolOpt, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ return await AddAsyncTokenAsync(
+ keepVoid, document, methodSymbolOpt, node, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ private SyntaxNode GetContainingFunction(Diagnostic diagnostic, CancellationToken cancellationToken)
+ {
+ var token = diagnostic.Location.FindToken(cancellationToken);
+ var node = token.GetAncestor(IsMethodOrAnonymousFunction);
+ return node;
+ }
+
+ private async Task RenameThenAddAsyncTokenAsync(
+ bool keepVoid, Document document, SyntaxNode node,
+ IMethodSymbol methodSymbol, CancellationToken cancellationToken)
+ {
+ var name = methodSymbol.Name;
+ var newName = name + AsyncSuffix;
+ var solution = document.Project.Solution;
+
+ // Store the path to this node. That way we can find it post rename.
+ var syntaxPath = new SyntaxPath(node);
+
+ // Rename the method to add the 'Async' suffix, then add the 'async' keyword.
+ var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, solution.Options, cancellationToken).ConfigureAwait(false);
+ var newDocument = newSolution.GetDocument(document.Id);
+ var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+
+ SyntaxNode newNode;
+ if (syntaxPath.TryResolve(newRoot, out newNode))
+ {
+ var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken);
+ return await AddAsyncTokenAsync(keepVoid, newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false);
+ }
+
+ return newSolution;
+ }
+
+ private async Task AddAsyncTokenAsync(
+ bool keepVoid, Document document, IMethodSymbol methodSymbolOpt,
+ SyntaxNode node, CancellationToken cancellationToken)
+ {
+ var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
+ var taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
+ var taskOfTType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
+
+ var newNode = AddAsyncTokenAndFixReturnType(keepVoid, methodSymbolOpt, node, taskType, taskOfTType)
+ .WithAdditionalAnnotations(Formatter.Annotation);
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var newRoot = root.ReplaceNode(node, newNode);
+
+ var newDocument = document.WithSyntaxRoot(newRoot);
+ return newDocument.Project.Solution;
+ }
+
+ private class MyCodeAction : CodeAction.SolutionChangeAction
+ {
+ public MyCodeAction(string title, Func> createChangedSolution)
+ : base(title, createChangedSolution, equivalenceKey: title)
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodSynchronousCodeFixProvider.cs b/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodSynchronousCodeFixProvider.cs
new file mode 100644
index 0000000000000..b608ef6fdf182
--- /dev/null
+++ b/src/Features/Core/Portable/MakeMethodAsyncOrSync/AbstractMakeMethodSynchronousCodeFixProvider.cs
@@ -0,0 +1,108 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Rename;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Roslyn.Utilities;
+
+namespace Microsoft.CodeAnalysis.MakeMethodSynchronous
+{
+ internal abstract class AbstractMakeMethodSynchronousCodeFixProvider : CodeFixProvider
+ {
+ public static readonly string EquivalenceKey = FeaturesResources.Make_method_synchronous;
+
+ protected abstract bool IsMethodOrAnonymousFunction(SyntaxNode node);
+ protected abstract SyntaxNode RemoveAsyncTokenAndFixReturnType(IMethodSymbol methodSymbolOpt, SyntaxNode node, ITypeSymbol taskType, ITypeSymbol taskOfTType);
+
+ public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
+
+ public override Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(c => FixNodeAsync(context.Document, context.Diagnostics.First(), c)),
+ context.Diagnostics);
+ return SpecializedTasks.EmptyTask;
+ }
+
+ private const string AsyncSuffix = "Async";
+
+ private async Task FixNodeAsync(
+ Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
+ {
+ var token = diagnostic.Location.FindToken(cancellationToken);
+ var node = token.GetAncestor(IsMethodOrAnonymousFunction);
+
+ // See if we're on an actual method declaration (otherwise we're on a lambda declaration).
+ // If we're on a method declaration, we'll get an IMethodSymbol back. In that case, check
+ // if it has the 'Async' suffix, and remove that suffix if so.
+ var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var methodSymbolOpt = semanticModel.GetDeclaredSymbol(node) as IMethodSymbol;
+
+ if (methodSymbolOpt?.MethodKind == MethodKind.Ordinary &&
+ methodSymbolOpt.Name.Length > AsyncSuffix.Length &&
+ methodSymbolOpt.Name.EndsWith(AsyncSuffix))
+ {
+ return await RenameThenRemoveAsyncTokenAsync(document, node, methodSymbolOpt, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ return await RemoveAsyncTokenAsync(document, methodSymbolOpt, node, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ private async Task RenameThenRemoveAsyncTokenAsync(Document document, SyntaxNode node, IMethodSymbol methodSymbol, CancellationToken cancellationToken)
+ {
+ var name = methodSymbol.Name;
+ var newName = name.Substring(0, name.Length - AsyncSuffix.Length);
+ var solution = document.Project.Solution;
+
+ // Store the path to this node. That way we can find it post rename.
+ var syntaxPath = new SyntaxPath(node);
+
+ // Rename the method to remove the 'Async' suffix, then remove the 'async' keyword.
+ var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, solution.Options, cancellationToken).ConfigureAwait(false);
+ var newDocument = newSolution.GetDocument(document.Id);
+ var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+
+ SyntaxNode newNode;
+ if (syntaxPath.TryResolve(newRoot, out newNode))
+ {
+ var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken);
+ return await RemoveAsyncTokenAsync(newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false);
+ }
+
+ return newSolution;
+ }
+
+ private async Task RemoveAsyncTokenAsync(Document document, IMethodSymbol methodSymbolOpt, SyntaxNode node, CancellationToken cancellationToken)
+ {
+ var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
+ var taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
+ var taskOfTType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
+
+ var newNode = RemoveAsyncTokenAndFixReturnType(methodSymbolOpt, node, taskType, taskOfTType)
+ .WithAdditionalAnnotations(Formatter.Annotation);
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var newRoot = root.ReplaceNode(node, newNode);
+
+ var newDocument = document.WithSyntaxRoot(newRoot);
+ return newDocument.Project.Solution;
+ }
+
+ private class MyCodeAction : CodeAction.SolutionChangeAction
+ {
+ public MyCodeAction(Func> createChangedSolution)
+ : base(FeaturesResources.Make_method_synchronous, createChangedSolution, AbstractMakeMethodSynchronousCodeFixProvider.EquivalenceKey)
+ {
+ }
+ }
+ }
+}
diff --git a/src/Features/Core/Portable/MakeMethodAsynchronous/AbstractMakeMethodAsynchronousCodeFixProvider.cs b/src/Features/Core/Portable/MakeMethodAsynchronous/AbstractMakeMethodAsynchronousCodeFixProvider.cs
new file mode 100644
index 0000000000000..4303aacc15ae4
--- /dev/null
+++ b/src/Features/Core/Portable/MakeMethodAsynchronous/AbstractMakeMethodAsynchronousCodeFixProvider.cs
@@ -0,0 +1,172 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Rename;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Roslyn.Utilities;
+
+namespace Microsoft.CodeAnalysis.MakeMethodAsynchronous
+{
+ internal abstract class AbstractMakeMethodAsynchronousCodeFixProvider : CodeFixProvider
+ {
+ protected abstract bool IsMethodOrAnonymousFunction(SyntaxNode node);
+ protected abstract SyntaxNode AddAsyncTokenAndFixReturnType(
+ bool keepVoid, IMethodSymbol methodSymbolOpt, SyntaxNode node,
+ INamedTypeSymbol taskType, INamedTypeSymbol taskOfTType);
+
+ public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
+
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var diagnostic = context.Diagnostics.First();
+ var cancellationToken = context.CancellationToken;
+
+ var node = GetContainingFunction(diagnostic, cancellationToken);
+ if (node == null)
+ {
+ return;
+ }
+
+ var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) as IMethodSymbol;
+
+ // If it's a void returning method, offer to keep the void return type, or convert to
+ // a Task return type.
+ if (symbol?.MethodKind == MethodKind.Ordinary &&
+ symbol.ReturnsVoid)
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: true, cancellationToken: c)),
+ context.Diagnostics);
+
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async_return_Task, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: false, cancellationToken: c)),
+ context.Diagnostics);
+ }
+ else
+ {
+ context.RegisterCodeFix(
+ new MyCodeAction(FeaturesResources.Make_method_async, c => FixNodeAsync(
+ context.Document, diagnostic, keepVoid: false, cancellationToken: c)),
+ context.Diagnostics);
+ }
+ }
+
+ private const string AsyncSuffix = "Async";
+
+ private async Task FixNodeAsync(
+ Document document, Diagnostic diagnostic,
+ bool keepVoid, CancellationToken cancellationToken)
+ {
+ var node = GetContainingFunction(diagnostic, cancellationToken);
+
+ // See if we're on an actual method declaration (otherwise we're on a lambda declaration).
+ // If we're on a method declaration, we'll get an IMethodSymbol back. In that case, check
+ // if it has the 'Async' suffix, and remove that suffix if so.
+ var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var methodSymbolOpt = semanticModel.GetDeclaredSymbol(node) as IMethodSymbol;
+
+ if (methodSymbolOpt?.MethodKind == MethodKind.Ordinary &&
+ !methodSymbolOpt.Name.EndsWith(AsyncSuffix))
+ {
+ return await RenameThenAddAsyncTokenAsync(
+ keepVoid, document, node, methodSymbolOpt, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ return await AddAsyncTokenAsync(
+ keepVoid, document, methodSymbolOpt, node, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ private SyntaxNode GetContainingFunction(Diagnostic diagnostic, CancellationToken cancellationToken)
+ {
+ var token = diagnostic.Location.FindToken(cancellationToken);
+ var node = token.GetAncestor(IsMethodOrAnonymousFunction);
+ return node;
+ }
+
+ private async Task RenameThenAddAsyncTokenAsync(
+ bool keepVoid, Document document, SyntaxNode node,
+ IMethodSymbol methodSymbol, CancellationToken cancellationToken)
+ {
+ var name = methodSymbol.Name;
+ var newName = name + AsyncSuffix;
+ var solution = document.Project.Solution;
+
+ // Store the path to this node. That way we can find it post rename.
+ var syntaxPath = new SyntaxPath(node);
+
+ // Rename the method to add the 'Async' suffix, then add the 'async' keyword.
+ var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, solution.Options, cancellationToken).ConfigureAwait(false);
+ var newDocument = newSolution.GetDocument(document.Id);
+ var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+
+ SyntaxNode newNode;
+ if (syntaxPath.TryResolve(newRoot, out newNode))
+ {
+ var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken);
+ return await AddAsyncTokenAsync(keepVoid, newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false);
+ }
+
+ return newSolution;
+ }
+
+ private async Task AddAsyncTokenAsync(
+ bool keepVoid, Document document, IMethodSymbol methodSymbolOpt,
+ SyntaxNode node, CancellationToken cancellationToken)
+ {
+ var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
+ var taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
+ var taskOfTType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
+
+ var newNode = AddAsyncTokenAndFixReturnType(keepVoid, methodSymbolOpt, node, taskType, taskOfTType)
+ .WithAdditionalAnnotations(Formatter.Annotation);
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var newRoot = root.ReplaceNode(node, newNode);
+
+ var newDocument = document.WithSyntaxRoot(newRoot);
+ return newDocument.Project.Solution;
+ }
+
+ protected static bool IsTaskLike(
+ ITypeSymbol returnType, ITypeSymbol taskType, INamedTypeSymbol taskOfTType)
+ {
+ if (returnType.Equals(taskType))
+ {
+ return true;
+ }
+
+ if (returnType.OriginalDefinition.Equals(taskOfTType))
+ {
+ return true;
+ }
+
+ if (returnType.IsErrorType() &&
+ returnType.Name.Equals("Task"))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private class MyCodeAction : CodeAction.SolutionChangeAction
+ {
+ public MyCodeAction(string title, Func> createChangedSolution)
+ : base(title, createChangedSolution, equivalenceKey: title)
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Features/VisualBasic/Portable/BasicFeatures.vbproj b/src/Features/VisualBasic/Portable/BasicFeatures.vbproj
index 709b2fac11d23..69896b253a52d 100644
--- a/src/Features/VisualBasic/Portable/BasicFeatures.vbproj
+++ b/src/Features/VisualBasic/Portable/BasicFeatures.vbproj
@@ -91,7 +91,6 @@
-
@@ -352,6 +351,7 @@
+
diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAsyncCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAsyncCodeFixProvider.vb
deleted file mode 100644
index ea13f481ca3f2..0000000000000
--- a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAsyncCodeFixProvider.vb
+++ /dev/null
@@ -1,111 +0,0 @@
-' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-Imports System.Collections.Immutable
-Imports System.Composition
-Imports System.Threading
-Imports Microsoft.CodeAnalysis
-Imports Microsoft.CodeAnalysis.CodeFixes
-Imports Microsoft.CodeAnalysis.CodeFixes.Async
-Imports Microsoft.CodeAnalysis.Formatting
-Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
-
-Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
-
- Friend Class VisualBasicAddAsyncCodeFixProvider
- Inherits AbstractAddAsyncCodeFixProvider
-
- Friend Const BC36937 As String = "BC36937" ' error BC36937: 'Await' can only be used when contained within a method or lambda expression marked with the 'Async' modifier.
- Friend Const BC37057 As String = "BC37057" ' error BC37057: 'Await' can only be used within an Async method. Consider marking this method with the 'Async' modifier and changing its return type to 'Task'.
- Friend Const BC37058 As String = "BC37058" ' error BC37058: 'Await' can only be used within an Async method. Consider marking this method with the 'Async' modifier and changing its return type to 'Task'.
- Friend Const BC37059 As String = "BC37059" ' error BC37059: 'Await' can only be used within an Async lambda expression. Consider marking this expression with the 'Async' modifier and changing its return type to 'Task'.
-
- Friend Shared ReadOnly Ids As ImmutableArray(Of String) = ImmutableArray.Create(BC36937, BC37057, BC37058, BC37059)
-
- Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String)
- Get
- Return Ids
- End Get
- End Property
-
- Protected Overrides Function GetDescription(diagnostic As Diagnostic, node As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As String
- Return VBFeaturesResources.Make_the_containing_scope_Async
- End Function
-
- Protected Overrides Async Function GetNewRoot(root As SyntaxNode, oldNode As SyntaxNode, semanticModel As SemanticModel, diagnostic As Diagnostic, document As Document, cancellationToken As CancellationToken) As Task(Of SyntaxNode)
- Dim methodNode = GetContainingMember(oldNode)
- If methodNode Is Nothing Then
- Return Nothing
- End If
- Return root.ReplaceNode(methodNode, Await ConvertToAsync(methodNode, semanticModel, document, cancellationToken).ConfigureAwait(False))
- End Function
-
- Private Shared Function GetContainingMember(oldNode As SyntaxNode) As StatementSyntax
-
- Dim lambda = oldNode.GetAncestor(Of LambdaExpressionSyntax)
- If lambda IsNot Nothing Then
- Return TryCast(lambda.ChildNodes().FirstOrDefault(Function(a) _
- a.IsKind(SyntaxKind.FunctionLambdaHeader) Or
- a.IsKind(SyntaxKind.SubLambdaHeader)),
- StatementSyntax)
- End If
-
- Dim ancestor As MethodBlockBaseSyntax = oldNode.GetAncestor(Of MethodBlockBaseSyntax)
- If ancestor IsNot Nothing Then
- Return TryCast(ancestor.ChildNodes().FirstOrDefault(Function(a) _
- a.IsKind(SyntaxKind.SubStatement) Or
- a.IsKind(SyntaxKind.FunctionStatement)),
- StatementSyntax)
- End If
-
- Return Nothing
- End Function
-
- Private Async Function ConvertToAsync(node As StatementSyntax, semanticModel As SemanticModel, document As Document, cancellationToken As CancellationToken) As Task(Of SyntaxNode)
- Dim methodNode = TryCast(node, MethodStatementSyntax)
- If methodNode IsNot Nothing Then
- Return Await ConvertMethodToAsync(document, semanticModel, methodNode, cancellationToken).ConfigureAwait(False)
- End If
-
- Dim lambdaNode = TryCast(node, LambdaHeaderSyntax)
- If lambdaNode IsNot Nothing Then
- Return lambdaNode.AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword)).WithAdditionalAnnotations(Formatter.Annotation)
- End If
-
- Return Nothing
- End Function
-
- Protected Overrides Function AddAsyncKeyword(node As SyntaxNode) As SyntaxNode
- Dim methodNode = TryCast(node, MethodStatementSyntax)
- If methodNode Is Nothing Then
- Return Nothing
- End If
- ' Visual Basic includes newlines in the trivia for MethodStatementSyntax nodes. If we are
- ' inserting into the beginning of method statement, we will need to move the trivia.
- Dim token = methodNode.ChildTokens().FirstOrDefault()
- Dim keyword = methodNode.DeclarationKeyword
- If keyword = token Then
- Dim trivia = token.LeadingTrivia
- methodNode = methodNode.ReplaceToken(token, token.WithLeadingTrivia())
- Return methodNode.AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword).WithLeadingTrivia(trivia)).WithAdditionalAnnotations(Formatter.Annotation)
- End If
- Return methodNode.AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword)).WithAdditionalAnnotations(Formatter.Annotation)
- End Function
-
- Protected Overrides Function AddAsyncKeywordAndTaskReturnType(node As SyntaxNode, existingReturnType As ITypeSymbol, taskTypeSymbol As INamedTypeSymbol) As SyntaxNode
- Dim methodNode = TryCast(node, MethodStatementSyntax)
- If methodNode Is Nothing Then
- Return Nothing
- End If
- If taskTypeSymbol Is Nothing Then
- Return Nothing
- End If
-
- Dim returnType = taskTypeSymbol.Construct(existingReturnType).GenerateTypeSyntax()
- Return AddAsyncKeyword(methodNode.WithAsClause(methodNode.AsClause.WithType(returnType)))
- End Function
-
- Protected Overrides Function DoesConversionExist(compilation As Compilation, source As ITypeSymbol, destination As ITypeSymbol) As Boolean
- Return compilation.ClassifyConversion(source, destination).Exists
- End Function
- End Class
-End Namespace
diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb
index 92fa5c237e9e2..d302b40c25f18 100644
--- a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb
+++ b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb
@@ -15,7 +15,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
Friend Class VisualBasicAddAwaitCodeFixProvider
- Inherits AbstractAddAsyncAwaitCodeFixProvider
+ Inherits AbstractAddAwaitCodeFixProvider
Friend Const BC30311 As String = "BC30311" ' error BC30311: Value of type 'X' cannot be converted to 'Y'.
Friend Const BC37055 As String = "BC37055" ' error BC37055: Since this is an async method, the return expression must be of type 'blah' rather than 'baz'
@@ -29,11 +29,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
End Get
End Property
- Protected Overrides Function GetDescription(diagnostic As Diagnostic, node As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As String
- Return VBFeaturesResources.Insert_Await
+ Protected Overrides Async Function GetDescriptionAndNodeAsync(root As SyntaxNode, oldNode As SyntaxNode, semanticModel As SemanticModel, diagnostic As Diagnostic, document As Document, cancellationToken As CancellationToken) As Task(Of DescriptionAndNode)
+ Dim newRoot = Await GetNewRootAsync(
+ root, oldNode, semanticModel, diagnostic, document, cancellationToken).ConfigureAwait(False)
+ If newRoot Is Nothing Then
+ Return Nothing
+ End If
+
+ Return New DescriptionAndNode(VBFeaturesResources.Insert_Await, newRoot)
End Function
- Protected Overrides Function GetNewRoot(root As SyntaxNode, oldNode As SyntaxNode, semanticModel As SemanticModel, diagnostic As Diagnostic, document As Document, cancellationToken As CancellationToken) As Task(Of SyntaxNode)
+ Private Function GetNewRootAsync(root As SyntaxNode, oldNode As SyntaxNode, semanticModel As SemanticModel, diagnostic As Diagnostic, document As Document, cancellationToken As CancellationToken) As Task(Of SyntaxNode)
Dim expression = TryCast(oldNode, ExpressionSyntax)
If expression Is Nothing Then
Return SpecializedTasks.Default(Of SyntaxNode)()
diff --git a/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb b/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb
new file mode 100644
index 0000000000000..544cd0330c0d8
--- /dev/null
+++ b/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb
@@ -0,0 +1,133 @@
+' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+Imports System.Collections.Immutable
+Imports System.Composition
+Imports Microsoft.CodeAnalysis.CodeFixes
+Imports Microsoft.CodeAnalysis.MakeMethodAsynchronous
+Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
+
+Namespace Microsoft.CodeAnalysis.VisualBasic.MakeMethodAsynchronous
+
+ Friend Class VisualBasicMakeMethodAsynchronousCodeFixProvider
+ Inherits AbstractMakeMethodAsynchronousCodeFixProvider
+
+ Friend Const BC36937 As String = "BC36937" ' error BC36937: 'Await' can only be used when contained within a method or lambda expression marked with the 'Async' modifier.
+ Friend Const BC37057 As String = "BC37057" ' error BC37057: 'Await' can only be used within an Async method. Consider marking this method with the 'Async' modifier and changing its return type to 'Task'.
+ Friend Const BC37058 As String = "BC37058" ' error BC37058: 'Await' can only be used within an Async method. Consider marking this method with the 'Async' modifier and changing its return type to 'Task'.
+ Friend Const BC37059 As String = "BC37059" ' error BC37059: 'Await' can only be used within an Async lambda expression. Consider marking this expression with the 'Async' modifier and changing its return type to 'Task'.
+
+ Private Shared ReadOnly s_diagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(
+ BC36937, BC37057, BC37058, BC37059)
+
+ Private Shared ReadOnly s_asyncToken As SyntaxToken = SyntaxFactory.Token(SyntaxKind.AsyncKeyword)
+
+ Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String)
+ Get
+ Return s_diagnosticIds
+ End Get
+ End Property
+
+ Protected Overrides Function IsMethodOrAnonymousFunction(node As SyntaxNode) As Boolean
+ Return node.IsKind(SyntaxKind.FunctionBlock) OrElse
+ node.IsKind(SyntaxKind.SubBlock) OrElse
+ node.IsKind(SyntaxKind.MultiLineFunctionLambdaExpression) OrElse
+ node.IsKind(SyntaxKind.MultiLineSubLambdaExpression) OrElse
+ node.IsKind(SyntaxKind.SingleLineFunctionLambdaExpression) OrElse
+ node.IsKind(SyntaxKind.SingleLineSubLambdaExpression)
+ End Function
+
+ Protected Overrides Function AddAsyncTokenAndFixReturnType(
+ keepVoid As Boolean, methodSymbolOpt As IMethodSymbol, node As SyntaxNode,
+ taskType As INamedTypeSymbol, taskOfTType As INamedTypeSymbol) As SyntaxNode
+
+ If node.IsKind(SyntaxKind.SingleLineSubLambdaExpression) OrElse
+ node.IsKind(SyntaxKind.SingleLineFunctionLambdaExpression) Then
+
+ Return FixSingleLineLambdaExpression(DirectCast(node, SingleLineLambdaExpressionSyntax))
+ ElseIf node.IsKind(SyntaxKind.MultiLineSubLambdaExpression) OrElse
+ node.IsKind(SyntaxKind.MultiLineFunctionLambdaExpression) Then
+
+ Return FixMultiLineLambdaExpression(DirectCast(node, MultiLineLambdaExpressionSyntax))
+ ElseIf node.IsKind(SyntaxKind.SubBlock) Then
+ Return FixSubBlock(keepVoid, DirectCast(node, MethodBlockSyntax), taskType)
+ Else
+ Return FixFunctionBlock(methodSymbolOpt, DirectCast(node, MethodBlockSyntax), taskType, taskOfTType)
+ End If
+ End Function
+
+ Private Function FixFunctionBlock(methodSymbol As IMethodSymbol, node As MethodBlockSyntax,
+ taskType As INamedTypeSymbol, taskOfTType As INamedTypeSymbol) As SyntaxNode
+
+ Dim functionStatement = node.SubOrFunctionStatement
+ Dim newFunctionStatement = AddAsyncKeyword(functionStatement)
+
+ If Not IsTaskLike(methodSymbol.ReturnType, taskType, taskOfTType) Then
+ ' if the current return type is not already task-list, then wrap it in Task(of ...)
+ Dim returnType = taskOfTType.Construct(methodSymbol.ReturnType).GenerateTypeSyntax()
+ newFunctionStatement = newFunctionStatement.WithAsClause(
+ newFunctionStatement.AsClause.WithType(returnType))
+ End If
+
+ Return node.WithSubOrFunctionStatement(newFunctionStatement)
+ End Function
+
+ Private Function FixSubBlock(
+ keepVoid As Boolean, node As MethodBlockSyntax, taskType As INamedTypeSymbol) As SyntaxNode
+
+ If keepVoid Then
+ ' User wants to keep this a void method, so keep this as a sub.
+ Dim newSubStatement = AddAsyncKeyword(node.SubOrFunctionStatement)
+ Return node.WithSubOrFunctionStatement(newSubStatement)
+ End If
+
+ ' Have to convert this sub into a func.
+ Dim asClause = SyntaxFactory.SimpleAsClause(taskType.GenerateTypeSyntax())
+
+ Dim subStatement = node.SubOrFunctionStatement
+ Dim functionStatement = SyntaxFactory.FunctionStatement(
+ subStatement.AttributeLists,
+ subStatement.Modifiers.Add(s_asyncToken),
+ SyntaxFactory.Token(SyntaxKind.FunctionKeyword).WithTriviaFrom(subStatement.SubOrFunctionKeyword),
+ subStatement.Identifier,
+ subStatement.TypeParameterList,
+ subStatement.ParameterList,
+ asClause,
+ subStatement.HandlesClause,
+ subStatement.ImplementsClause)
+
+ Dim endFunctionStatement = SyntaxFactory.EndFunctionStatement(
+ node.EndSubOrFunctionStatement.EndKeyword,
+ SyntaxFactory.Token(SyntaxKind.FunctionKeyword).WithTriviaFrom(node.EndSubOrFunctionStatement.BlockKeyword))
+
+ Dim block = SyntaxFactory.FunctionBlock(
+ functionStatement,
+ node.Statements,
+ endFunctionStatement)
+
+ Return block
+ End Function
+
+ Private Shared Function AddAsyncKeyword(subOrFunctionStatement As MethodStatementSyntax) As MethodStatementSyntax
+ Dim modifiers = subOrFunctionStatement.Modifiers
+ Dim newModifiers = modifiers.Add(s_asyncToken)
+ Return subOrFunctionStatement.WithModifiers(newModifiers)
+ End Function
+
+ Private Function FixMultiLineLambdaExpression(node As MultiLineLambdaExpressionSyntax) As SyntaxNode
+ Dim header As LambdaHeaderSyntax = GetNewHeader(node)
+ Return node.WithSubOrFunctionHeader(header).WithLeadingTrivia(node.GetLeadingTrivia())
+ End Function
+
+ Private Function FixSingleLineLambdaExpression(node As SingleLineLambdaExpressionSyntax) As SingleLineLambdaExpressionSyntax
+ Dim header As LambdaHeaderSyntax = GetNewHeader(node)
+ Return node.WithSubOrFunctionHeader(header).WithLeadingTrivia(node.GetLeadingTrivia())
+ End Function
+
+ Private Shared Function GetNewHeader(node As LambdaExpressionSyntax) As LambdaHeaderSyntax
+ Dim header = DirectCast(node.SubOrFunctionHeader, LambdaHeaderSyntax)
+ Dim newModifiers = header.Modifiers.Add(s_asyncToken)
+ Dim newHeader = header.WithModifiers(newModifiers)
+ Return newHeader
+ End Function
+ End Class
+End Namespace
\ No newline at end of file
diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb
index 83bf5f5e22699..e13c9fc4cc479 100644
--- a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb
+++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb
@@ -1520,15 +1520,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources
End Get
End Property
- '''
- ''' Looks up a localized string similar to Make the containing scope 'Async'..
- '''
- Friend ReadOnly Property Make_the_containing_scope_Async() As String
- Get
- Return ResourceManager.GetString("Make_the_containing_scope_Async", resourceCulture)
- End Get
- End Property
-
'''
''' Looks up a localized string similar to Mid statement.
'''
diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx
index 8c80d3c2ce046..91ad0beaaaf19 100644
--- a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx
+++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx
@@ -979,9 +979,6 @@ Sub(<parameterList>) <statement>
Insert 'Await'.
-
- Make the containing scope 'Async'.
-
Make {0} an Async Function.
diff --git a/src/Test/PdbUtilities/project.json b/src/Test/PdbUtilities/project.json
index db4e30afca948..ba4775787d279 100644
--- a/src/Test/PdbUtilities/project.json
+++ b/src/Test/PdbUtilities/project.json
@@ -2,7 +2,7 @@
"supports": {},
"dependencies": {
"System.Collections.Immutable": "1.2.0",
- "System.Reflection.Metadata": "1.4.1-beta-24322-03",
+ "System.Reflection.Metadata": "1.4.1-beta-24410-02",
"Microsoft.DiaSymReader.Native": "1.5.0-beta1",
"Microsoft.DiaSymReader": "1.1.0-beta1-60625-03",
"Microsoft.DiaSymReader.PortablePdb": "1.2.0-beta1-60723-01"
diff --git a/src/Tools/ProcessWatchdog/project.json b/src/Tools/ProcessWatchdog/project.json
index 34b08d994e8de..236fc4a5db5c4 100644
--- a/src/Tools/ProcessWatchdog/project.json
+++ b/src/Tools/ProcessWatchdog/project.json
@@ -2,7 +2,7 @@
"dependencies": {
"CommandLineParser": "2.0.273-beta",
"System.Collections.Immutable": "1.2.0",
- "System.Reflection.Metadata": "1.4.1-beta-24322-03",
+ "System.Reflection.Metadata": "1.4.1-beta-24410-02",
},
"frameworks": {
"net46": {}
diff --git a/src/Tools/SignRoslyn/project.json b/src/Tools/SignRoslyn/project.json
index af9e3987f9d42..79b4d3eb50c8f 100644
--- a/src/Tools/SignRoslyn/project.json
+++ b/src/Tools/SignRoslyn/project.json
@@ -2,7 +2,7 @@
"supports": {},
"dependencies": {
"System.Collections.Immutable": "1.2.0",
- "System.Reflection.Metadata": "1.4.1-beta-24322-03",
+ "System.Reflection.Metadata": "1.4.1-beta-24410-02",
"Newtonsoft.Json": "8.0.3"
},
"frameworks": {
diff --git a/src/Tools/Source/RunTests/project.json b/src/Tools/Source/RunTests/project.json
index 5b28dfcfeff4c..f477a4ce4d62e 100644
--- a/src/Tools/Source/RunTests/project.json
+++ b/src/Tools/Source/RunTests/project.json
@@ -3,7 +3,7 @@
"Newtonsoft.Json": "8.0.3",
"RestSharp": "105.2.3",
"System.Collections.Immutable": "1.2.0",
- "System.Reflection.Metadata": "1.4.1-beta-24322-03",
+ "System.Reflection.Metadata": "1.4.1-beta-24410-02",
},
"frameworks": {
"net46": {}
diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/DetailedErrorInfoDialog.xaml b/src/VisualStudio/Core/Def/Implementation/Workspace/DetailedErrorInfoDialog.xaml
new file mode 100644
index 0000000000000..0381e8f461f0f
--- /dev/null
+++ b/src/VisualStudio/Core/Def/Implementation/Workspace/DetailedErrorInfoDialog.xaml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/DetailedErrorInfoDialog.xaml.cs b/src/VisualStudio/Core/Def/Implementation/Workspace/DetailedErrorInfoDialog.xaml.cs
new file mode 100644
index 0000000000000..98185ce6df516
--- /dev/null
+++ b/src/VisualStudio/Core/Def/Implementation/Workspace/DetailedErrorInfoDialog.xaml.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Forms;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Microsoft.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio.Shell;
+
+namespace Microsoft.VisualStudio.LanguageServices.Implementation
+{
+ internal partial class DetailedErrorInfoDialog : DialogWindow
+ {
+ private readonly string errorInfo;
+
+ internal DetailedErrorInfoDialog(string title, string errorInfo)
+ {
+ InitializeComponent();
+ this.errorInfo = errorInfo;
+ this.Title = title;
+ stackTraceText.AppendText(errorInfo);
+ this.CopyButton.Content = ServicesVSResources.Copy_to_clipboard;
+ this.CloseButton.Content = ServicesVSResources.Close;
+
+ }
+
+ private void CopyMessageToClipBoard(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ System.Windows.Clipboard.SetText(errorInfo);
+ }
+ catch (Exception)
+ {
+ // rdpclip.exe not running in a TS session, ignore
+ }
+ }
+
+ private void CloseWindow(object sender, RoutedEventArgs e)
+ {
+ this.Close();
+ }
+ }
+}
diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.ExceptionFormatting.cs b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.ExceptionFormatting.cs
new file mode 100644
index 0000000000000..bffba9a1c4ac3
--- /dev/null
+++ b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.ExceptionFormatting.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace Microsoft.VisualStudio.LanguageServices.Implementation
+{
+ internal partial class VisualStudioErrorReportingService
+ {
+ private static string GetFormattedExceptionStack(Exception exception)
+ {
+ var aggregate = exception as AggregateException;
+ if (aggregate != null)
+ {
+ return GetStackForAggregateException(exception, aggregate);
+ }
+
+ return GetStackForException(exception, false);
+ }
+
+ private static string GetStackForAggregateException(Exception exception, AggregateException aggregate)
+ {
+ var text = GetStackForException(exception, true);
+ for (int i = 0; i < aggregate.InnerExceptions.Count; i++)
+ {
+ text = string.Format("{0}{1}---> (Inner Exception #{2}) {3}{4}{5}", text,
+ Environment.NewLine, i, GetFormattedExceptionStack(aggregate.InnerExceptions[i]), "<---", Environment.NewLine);
+ }
+
+ return text;
+ }
+
+ private static string GetStackForException(Exception exception, bool includeMessageOnly)
+ {
+ var message = exception.Message;
+ var className = exception.GetType().ToString();
+ var stackText = message.Length <= 0
+ ? className
+ : className + " : " + message;
+ var innerException = exception.InnerException;
+ if (innerException != null)
+ {
+ if (includeMessageOnly)
+ {
+ do
+ {
+ stackText += " ---> " + innerException.Message;
+ innerException = innerException.InnerException;
+ } while (innerException != null);
+ }
+ else
+ {
+ stackText += " ---> " + GetFormattedExceptionStack(innerException) + Environment.NewLine +
+ " " + ServicesVSResources.End_of_inner_exception_stack;
+ }
+ }
+
+ return stackText + Environment.NewLine + GetAsyncStackTrace(exception);
+ }
+
+ private static string GetAsyncStackTrace(Exception exception)
+ {
+ var stackTrace = new StackTrace(exception);
+
+ var stackFrames = stackTrace.GetFrames();
+ if (stackFrames == null)
+ {
+ return string.Empty;
+ }
+
+ var firstFrame = true;
+ var stringBuilder = new StringBuilder();
+
+ foreach (var frame in stackFrames)
+ {
+ var method = frame.GetMethod();
+ var declaringType = method?.DeclaringType;
+ if (declaringType != null && typeof(INotifyCompletion).IsAssignableFrom(declaringType))
+ {
+ continue;
+ }
+
+ if (firstFrame)
+ {
+ firstFrame = false;
+ }
+ else
+ {
+ stringBuilder.Append(Environment.NewLine);
+ }
+
+ stringBuilder.AppendFormat(" at ");
+ var isAsync = FormatMethodName(stringBuilder, declaringType);
+ if (!isAsync)
+ {
+ stringBuilder.Append(method?.Name);
+ var methodInfo = method as MethodInfo;
+ if (methodInfo?.IsGenericMethod == true)
+ {
+ FormatGenericArguments(stringBuilder, methodInfo.GetGenericArguments());
+ }
+ }
+ else if (declaringType?.IsGenericType == true)
+ {
+ FormatGenericArguments(stringBuilder, declaringType.GetGenericArguments());
+ }
+
+ stringBuilder.Append("(");
+ if (isAsync)
+ {
+ stringBuilder.Append(ServicesVSResources.Unknown_parameters);
+ }
+ else
+ {
+ FormatParameters(stringBuilder, method);
+ }
+
+ stringBuilder.Append(")");
+ }
+
+ return stringBuilder.ToString();
+ }
+
+ private static bool FormatMethodName(StringBuilder stringBuilder, Type declaringType)
+ {
+ if (declaringType == null)
+ {
+ return false;
+ }
+
+ var isAsync = false;
+ var fullName = declaringType.FullName.Replace('+', '.');
+ if (typeof(IAsyncStateMachine).GetTypeInfo().IsAssignableFrom(declaringType))
+ {
+ isAsync = true;
+ stringBuilder.Append("async ");
+ var start = fullName.LastIndexOf('<');
+ var end = fullName.LastIndexOf('>');
+ if (start >= 0 && end >= 0)
+ {
+ stringBuilder.Append(fullName.Remove(start, 1).Substring(0, end - 1));
+ }
+ else
+ {
+ stringBuilder.Append(fullName);
+ }
+ }
+ else
+ {
+ stringBuilder.Append(fullName);
+ stringBuilder.Append(".");
+ }
+
+ return isAsync;
+ }
+
+ private static void FormatGenericArguments(StringBuilder stringBuilder, Type[] genericTypeArguments)
+ {
+ if (genericTypeArguments.Length <= 0)
+ {
+ return;
+ }
+
+ stringBuilder.Append("[" + String.Join(",", genericTypeArguments.Select(args => args.Name)) + "]");
+ }
+
+ private static void FormatParameters(StringBuilder stringBuilder, MethodBase method) =>
+ stringBuilder.Append(string.Join(",", method?.GetParameters().Select(t => (t.ParameterType?.Name ?? "") + " " + t.Name) ?? Array.Empty()));
+ }
+}
diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.cs b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.cs
index a1e6929440d56..7cde8a2d7e5dd 100644
--- a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.cs
+++ b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioErrorReportingService.cs
@@ -14,7 +14,7 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
- internal class VisualStudioErrorReportingService : IErrorReportingService
+ internal partial class VisualStudioErrorReportingService : IErrorReportingService
{
private readonly static InfoBarButton s_enableItem = new InfoBarButton(ServicesVSResources.Enable);
private readonly static InfoBarButton s_enableAndIgnoreItem = new InfoBarButton(ServicesVSResources.Enable_and_ignore_future_errors);
@@ -31,20 +31,6 @@ public VisualStudioErrorReportingService(
_listener = listener;
}
- public void ShowErrorInfoForCodeFix(string codefixName, Action OnEnable, Action OnEnableAndIgnore, Action OnClose)
- {
- // We can be called from any thread since errors can occur anywhere, however we can only construct and InfoBar from the UI thread.
- _foregroundNotificationService.RegisterNotification(() =>
- {
- IVsWindowFrame frame;
- IVsInfoBarUIFactory factory;
- if (_workspace.TryGetInfoBarData(out frame, out factory))
- {
- CreateInfoBarForCodeFix(factory, frame, string.Format(ServicesVSResources._0_encountered_an_error_and_has_been_disabled, codefixName), OnClose, OnEnable, OnEnableAndIgnore);
- }
- }, _listener.BeginAsyncOperation("Show InfoBar"));
- }
-
public void ShowErrorInfo(string message, params ErrorReportingUI[] items)
{
// We can be called from any thread since errors can occur anywhere, however we can only construct and InfoBar from the UI thread.
@@ -161,102 +147,16 @@ public void OnClosed(IVsInfoBarUIElement infoBarUIElement)
}
}
- private void CreateInfoBarForCodeFix(IVsInfoBarUIFactory factory, IVsWindowFrame frame, string message, Action onClose, Action onEnable = null, Action onEnableAndIgnore = null)
- {
- object unknown;
- if (ErrorHandler.Failed(frame.GetProperty((int)__VSFPROPID7.VSFPROPID_InfoBarHost, out unknown)))
- {
- return;
- }
-
- var textSpans = new List()
- {
- new InfoBarTextSpan(message)
- };
-
- // create action item list
- var actionItems = new List();
- if (onEnable != null)
- {
- actionItems.Add(s_enableItem);
- }
-
- if (onEnableAndIgnore != null)
- {
- actionItems.Add(s_enableAndIgnoreItem);
- }
-
- var infoBarModel = new InfoBarModel(
- textSpans,
- actionItems.ToArray(),
- KnownMonikers.StatusInformation,
- isCloseButtonVisible: true);
-
- IVsInfoBarUIElement infoBarUI;
- if (!TryCreateInfoBarUI(factory, infoBarModel, out infoBarUI))
- {
- return;
- }
-
- uint? infoBarCookie = null;
- var eventSink = new CodeFixInfoBarEvents(() =>
- {
- onClose();
-
- if (infoBarCookie.HasValue)
- {
- infoBarUI.Unadvise(infoBarCookie.Value);
- }
- }, onEnable, onEnableAndIgnore);
-
- uint cookie;
- infoBarUI.Advise(eventSink, out cookie);
- infoBarCookie = cookie;
-
- IVsInfoBarHost host = (IVsInfoBarHost)unknown;
- host.AddInfoBar(infoBarUI);
- }
-
- private class CodeFixInfoBarEvents : IVsInfoBarUIEvents
- {
- private readonly Action _onClose;
- private readonly Action _onEnable;
- private readonly Action _onEnableAndIgnore;
-
- public CodeFixInfoBarEvents(Action onClose, Action onEnable = null, Action onEnableAndIgnore = null)
- {
- Contract.ThrowIfNull(onClose);
-
- _onClose = onClose;
- _onEnable = onEnable;
- _onEnableAndIgnore = onEnableAndIgnore;
- }
-
- public void OnActionItemClicked(IVsInfoBarUIElement infoBarUIElement, IVsInfoBarActionItem actionItem)
- {
- if (actionItem.Equals(s_enableItem))
- {
- _onEnable?.Invoke();
- }
-
- if (actionItem.Equals(s_enableAndIgnoreItem))
- {
- _onEnableAndIgnore?.Invoke();
- }
-
- infoBarUIElement.Close();
- }
-
- public void OnClosed(IVsInfoBarUIElement infoBarUIElement)
- {
- _onClose();
- }
- }
-
private static bool TryCreateInfoBarUI(IVsInfoBarUIFactory infoBarUIFactory, IVsInfoBar infoBar, out IVsInfoBarUIElement uiElement)
{
uiElement = infoBarUIFactory.CreateInfoBar(infoBar);
return uiElement != null;
}
+
+ public void ShowDetailedErrorInfo(Exception exception)
+ {
+ string errorInfo = GetFormattedExceptionStack(exception);
+ (new DetailedErrorInfoDialog(exception.Message, errorInfo)).ShowModal();
+ }
}
}
diff --git a/src/VisualStudio/Core/Def/PublicAPI.Unshipped.txt b/src/VisualStudio/Core/Def/PublicAPI.Unshipped.txt
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs b/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs
index 92eb0a804a533..824feee5ef3a6 100644
--- a/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs
+++ b/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs
@@ -343,6 +343,15 @@ internal static string Choose_a_Symbol_Specification_and_a_Naming_Style {
}
}
+ ///
+ /// Looks up a localized string similar to Close.
+ ///
+ internal static string Close {
+ get {
+ return ResourceManager.GetString("Close", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Computing remove suppressions fix....
///
@@ -361,6 +370,15 @@ internal static string Computing_suppressions_fix {
}
}
+ ///
+ /// Looks up a localized string similar to Copy to Clipboard.
+ ///
+ internal static string Copy_to_clipboard {
+ get {
+ return ResourceManager.GetString("Copy_to_clipboard", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Could not find location of folder on disk.
///
@@ -523,6 +541,15 @@ internal static string Enable_and_ignore_future_errors {
}
}
+ ///
+ /// Looks up a localized string similar to --- End of inner exception stack trace ---.
+ ///
+ internal static string End_of_inner_exception_stack {
+ get {
+ return ResourceManager.GetString("End_of_inner_exception_stack", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to End position must be >= start position.
///
@@ -786,6 +813,15 @@ internal static string Implements_ {
}
}
+ ///
+ /// Looks up a localized string similar to in {0}:line {1}.
+ ///
+ internal static string in_0_line_1 {
+ get {
+ return ResourceManager.GetString("in_0_line_1", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Inherited By.
///
@@ -1689,6 +1725,15 @@ internal static string Uninstalling_0_failed_Additional_information_colon_1 {
}
}
+ ///
+ /// Looks up a localized string similar to <Unknown Parameters>.
+ ///
+ internal static string Unknown_parameters {
+ get {
+ return ResourceManager.GetString("Unknown_parameters", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Unknown rename type.
///
diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx
index cce13233c5a0d..314de7339f61a 100644
--- a/src/VisualStudio/Core/Def/ServicesVSResources.resx
+++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx
@@ -699,4 +699,19 @@ Additional information: {1}
Prefer predefined type
+
+ Copy to Clipboard
+
+
+ Close
+
+
+ --- End of inner exception stack trace ---
+
+
+ in {0}:line {1}
+
+
+ <Unknown Parameters>
+
\ No newline at end of file
diff --git a/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj b/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj
index 06a13885e1fd6..0b2132cc103ff 100644
--- a/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj
+++ b/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj
@@ -158,9 +158,13 @@
+
+ DetailedErrorInfoDialog.xaml
+
+
@@ -712,6 +716,10 @@
DesignerMSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
@@ -733,7 +741,6 @@
-
diff --git a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
index 880b818825f36..56aa054bb5344 100644
--- a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
+++ b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
@@ -702,6 +702,21 @@ private IEnumerable InferTypeInArrayCreationExpression(
return SpecializedCollections.EmptyEnumerable();
}
+ if (previousToken.HasValue && previousToken.Value.GetPreviousToken().Kind() == SyntaxKind.EqualsToken)
+ {
+ // We parsed an array creation but the token before `new` is `=`.
+ // This could be a case like:
+ //
+ // int[] array;
+ // Program p = new |
+ // array[4] = 4;
+ //
+ // This is similar to the cases described in `InferTypeInObjectCreationExpression`.
+ // Again, all we have to do is back up to before `new`.
+
+ return InferTypes(previousToken.Value.SpanStart);
+ }
+
var outerTypes = InferTypes(arrayCreationExpression);
return outerTypes.Where(o => o is IArrayTypeSymbol);
}
diff --git a/src/Workspaces/Core/Portable/ExtensionManager/IErrorReportingService.cs b/src/Workspaces/Core/Portable/ExtensionManager/IErrorReportingService.cs
index dbbbbb97e5c4f..851f4499b0ab2 100644
--- a/src/Workspaces/Core/Portable/ExtensionManager/IErrorReportingService.cs
+++ b/src/Workspaces/Core/Portable/ExtensionManager/IErrorReportingService.cs
@@ -8,8 +8,8 @@ namespace Microsoft.CodeAnalysis.Extensions
{
internal interface IErrorReportingService : IWorkspaceService
{
- void ShowErrorInfoForCodeFix(string codefixName, Action OnEnable, Action OnEnableAndIgnore, Action OnClose);
void ShowErrorInfo(string message, params ErrorReportingUI[] items);
+ void ShowDetailedErrorInfo(Exception exception);
}
internal struct ErrorReportingUI
diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj
index 257662e16a8d8..3ae8eaf10e82e 100644
--- a/src/Workspaces/Core/Portable/Workspaces.csproj
+++ b/src/Workspaces/Core/Portable/Workspaces.csproj
@@ -251,6 +251,7 @@
+
diff --git a/src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs b/src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs
index b2d66bdde9374..27642ba0ed79a 100644
--- a/src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs
+++ b/src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs
@@ -61,6 +61,15 @@ internal WorkspacesResources() {
}
}
+ ///
+ /// Looks up a localized string similar to '{0}' encountered an error and has been disabled..
+ ///
+ internal static string _0_encountered_an_error_and_has_been_disabled {
+ get {
+ return ResourceManager.GetString("_0_encountered_an_error_and_has_been_disabled", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to '{0}' is already part of the workspace..
///
@@ -530,6 +539,24 @@ internal static string Duplicate_source_file_0_in_project_1 {
}
}
+ ///
+ /// Looks up a localized string similar to Enable.
+ ///
+ internal static string Enable {
+ get {
+ return ResourceManager.GetString("Enable", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Enable and ignore future errors.
+ ///
+ internal static string Enable_and_ignore_future_errors {
+ get {
+ return ResourceManager.GetString("Enable_and_ignore_future_errors", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Exceptions:.
///
@@ -891,6 +918,15 @@ internal static string Service_of_type_0_is_required_to_accomplish_the_task_but_
}
}
+ ///
+ /// Looks up a localized string similar to Show Stack Trace.
+ ///
+ internal static string Show_Stack_Trace {
+ get {
+ return ResourceManager.GetString("Show_Stack_Trace", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Solution file not found: '{0}'.
///
diff --git a/src/Workspaces/Core/Portable/WorkspacesResources.resx b/src/Workspaces/Core/Portable/WorkspacesResources.resx
index 98f4f29f3eb5a..4b6eedf77ae4c 100644
--- a/src/Workspaces/Core/Portable/WorkspacesResources.resx
+++ b/src/Workspaces/Core/Portable/WorkspacesResources.resx
@@ -474,6 +474,18 @@
Options did not come from Workspace
+
+ Enable
+
+
+ Enable and ignore future errors
+
+
+ '{0}' encountered an error and has been disabled.
+
+
+ Show Stack Trace
+
Stream is too long.