From 3816bf8274a594e3da4828a8bb03d1ddd89177d3 Mon Sep 17 00:00:00 2001 From: Lauren Fay Date: Thu, 30 May 2019 13:31:05 -0700 Subject: [PATCH 01/93] Parsing for Parameter Nullchecking (#35826) --- .../Portable/CSharpResources.Designer.cs | 9 + .../CSharp/Portable/CSharpResources.resx | 3 + .../CSharp/Portable/Errors/ErrorCode.cs | 1 + .../Syntax.xml.Internal.Generated.cs | 84 ++- .../Generated/Syntax.xml.Main.Generated.cs | 23 +- .../Generated/Syntax.xml.Syntax.Generated.cs | 39 +- .../CSharp/Portable/Parser/LanguageParser.cs | 134 +++- .../CSharp/Portable/PublicAPI.Unshipped.txt | 4 + .../CSharp/Portable/Syntax/ParameterSyntax.cs | 5 + .../CSharp/Portable/Syntax/Syntax.xml | 3 + .../Portable/xlf/CSharpResources.cs.xlf | 5 + .../Portable/xlf/CSharpResources.de.xlf | 5 + .../Portable/xlf/CSharpResources.es.xlf | 5 + .../Portable/xlf/CSharpResources.fr.xlf | 5 + .../Portable/xlf/CSharpResources.it.xlf | 5 + .../Portable/xlf/CSharpResources.ja.xlf | 5 + .../Portable/xlf/CSharpResources.ko.xlf | 5 + .../Portable/xlf/CSharpResources.pl.xlf | 5 + .../Portable/xlf/CSharpResources.pt-BR.xlf | 5 + .../Portable/xlf/CSharpResources.ru.xlf | 5 + .../Portable/xlf/CSharpResources.tr.xlf | 5 + .../Portable/xlf/CSharpResources.zh-Hans.xlf | 5 + .../Portable/xlf/CSharpResources.zh-Hant.xlf | 5 + .../Generated/Syntax.Test.xml.Generated.cs | 8 +- .../Syntax/Parsing/DeclarationParsingTests.cs | 576 ++++++++++++++++++ .../Parsing/LambdaParameterParsingTests.cs | 551 +++++++++++++++++ 26 files changed, 1445 insertions(+), 60 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index d052b5a007eff..d21d305f8bf12 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -7170,6 +7170,15 @@ internal static string ERR_NamespaceUnexpected { } } + /// + /// Looks up a localized string similar to Space required between '!' and '=' here.. + /// + internal static string ERR_NeedSpaceBetweenExclamationAndEquals { + get { + return ResourceManager.GetString("ERR_NeedSpaceBetweenExclamationAndEquals", resourceCulture); + } + } + /// /// Looks up a localized string similar to Cannot create an array with a negative size. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 4b1bef1957c57..f8c1e2ea074e4 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -5898,4 +5898,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ stackalloc in nested expressions + + Space required between '!' and '=' here. + diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index fb858063b110d..118de8bd3383d 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1717,6 +1717,7 @@ internal enum ErrorCode //ERR_NotDeclaredInBase = 8710, ERR_DefaultInterfaceImplementationInNoPIAType = 8711, + ERR_NeedSpaceBetweenExclamationAndEquals = 8712, #endregion diagnostics introduced for C# 8.0 diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs index 07eb76d20d726..5d0a85b61b098 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs @@ -26227,12 +26227,13 @@ internal sealed partial class ParameterSyntax : CSharpSyntaxNode internal readonly GreenNode modifiers; internal readonly TypeSyntax type; internal readonly SyntaxToken identifier; + internal readonly SyntaxToken exclamationToken; internal readonly EqualsValueClauseSyntax @default; - internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) + internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) : base(kind, diagnostics, annotations) { - this.SlotCount = 5; + this.SlotCount = 6; if (attributeLists != null) { this.AdjustFlagsAndWidth(attributeLists); @@ -26250,6 +26251,11 @@ internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode mo } this.AdjustFlagsAndWidth(identifier); this.identifier = identifier; + if (exclamationToken != null) + { + this.AdjustFlagsAndWidth(exclamationToken); + this.exclamationToken = exclamationToken; + } if (@default != null) { this.AdjustFlagsAndWidth(@default); @@ -26258,11 +26264,11 @@ internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode mo } - internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default, SyntaxFactoryContext context) + internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default, SyntaxFactoryContext context) : base(kind) { this.SetFactoryContext(context); - this.SlotCount = 5; + this.SlotCount = 6; if (attributeLists != null) { this.AdjustFlagsAndWidth(attributeLists); @@ -26280,6 +26286,11 @@ internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode mo } this.AdjustFlagsAndWidth(identifier); this.identifier = identifier; + if (exclamationToken != null) + { + this.AdjustFlagsAndWidth(exclamationToken); + this.exclamationToken = exclamationToken; + } if (@default != null) { this.AdjustFlagsAndWidth(@default); @@ -26288,10 +26299,10 @@ internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode mo } - internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default) : base(kind) { - this.SlotCount = 5; + this.SlotCount = 6; if (attributeLists != null) { this.AdjustFlagsAndWidth(attributeLists); @@ -26309,6 +26320,11 @@ internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode mo } this.AdjustFlagsAndWidth(identifier); this.identifier = identifier; + if (exclamationToken != null) + { + this.AdjustFlagsAndWidth(exclamationToken); + this.exclamationToken = exclamationToken; + } if (@default != null) { this.AdjustFlagsAndWidth(@default); @@ -26323,6 +26339,7 @@ internal ParameterSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode mo public TypeSyntax Type => this.type; /// Gets the identifier. public SyntaxToken Identifier => this.identifier; + public SyntaxToken ExclamationToken => this.exclamationToken; public EqualsValueClauseSyntax Default => this.@default; internal override GreenNode GetSlot(int index) @@ -26333,7 +26350,8 @@ internal override GreenNode GetSlot(int index) case 1: return this.modifiers; case 2: return this.type; case 3: return this.identifier; - case 4: return this.@default; + case 4: return this.exclamationToken; + case 5: return this.@default; default: return null; } } @@ -26344,11 +26362,11 @@ internal override GreenNode GetSlot(int index) public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitParameter(this); - public ParameterSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + public ParameterSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default) { - if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || type != this.Type || identifier != this.Identifier || @default != this.Default) + if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || type != this.Type || identifier != this.Identifier || exclamationToken != this.ExclamationToken || @default != this.Default) { - var newNode = SyntaxFactory.Parameter(attributeLists, modifiers, type, identifier, @default); + var newNode = SyntaxFactory.Parameter(attributeLists, modifiers, type, identifier, exclamationToken, @default); var diags = this.GetDiagnostics(); if (diags != null && diags.Length > 0) newNode = newNode.WithDiagnosticsGreen(diags); @@ -26362,15 +26380,15 @@ public ParameterSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSyntax.Synta } internal override GreenNode SetDiagnostics(DiagnosticInfo[] diagnostics) - => new ParameterSyntax(this.Kind, this.attributeLists, this.modifiers, this.type, this.identifier, this.@default, diagnostics, GetAnnotations()); + => new ParameterSyntax(this.Kind, this.attributeLists, this.modifiers, this.type, this.identifier, this.exclamationToken, this.@default, diagnostics, GetAnnotations()); internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations) - => new ParameterSyntax(this.Kind, this.attributeLists, this.modifiers, this.type, this.identifier, this.@default, GetDiagnostics(), annotations); + => new ParameterSyntax(this.Kind, this.attributeLists, this.modifiers, this.type, this.identifier, this.exclamationToken, this.@default, GetDiagnostics(), annotations); internal ParameterSyntax(ObjectReader reader) : base(reader) { - this.SlotCount = 5; + this.SlotCount = 6; var attributeLists = (GreenNode)reader.ReadValue(); if (attributeLists != null) { @@ -26395,6 +26413,12 @@ internal ParameterSyntax(ObjectReader reader) AdjustFlagsAndWidth(identifier); this.identifier = identifier; } + var exclamationToken = (SyntaxToken)reader.ReadValue(); + if (exclamationToken != null) + { + AdjustFlagsAndWidth(exclamationToken); + this.exclamationToken = exclamationToken; + } var @default = (EqualsValueClauseSyntax)reader.ReadValue(); if (@default != null) { @@ -26410,6 +26434,7 @@ internal override void WriteTo(ObjectWriter writer) writer.WriteValue(this.modifiers); writer.WriteValue(this.type); writer.WriteValue(this.identifier); + writer.WriteValue(this.exclamationToken); writer.WriteValue(this.@default); } @@ -35077,8 +35102,9 @@ public override CSharpSyntaxNode VisitParameter(ParameterSyntax node) var modifiers = this.VisitList(node.Modifiers); var type = (TypeSyntax)this.Visit(node.Type); var identifier = (SyntaxToken)this.Visit(node.Identifier); + var exclamationToken = (SyntaxToken)this.Visit(node.ExclamationToken); var @default = (EqualsValueClauseSyntax)this.Visit(node.Default); - return node.Update(attributeLists, modifiers, type, identifier, @default); + return node.Update(attributeLists, modifiers, type, identifier, exclamationToken, @default); } public override CSharpSyntaxNode VisitIncompleteMember(IncompleteMemberSyntax node) @@ -41246,7 +41272,7 @@ public BracketedParameterListSyntax BracketedParameterList(SyntaxToken openBrack return result; } - public ParameterSyntax Parameter(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + public ParameterSyntax Parameter(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default) { #if DEBUG if (identifier == null) @@ -41259,9 +41285,20 @@ public ParameterSyntax Parameter(Microsoft.CodeAnalysis.Syntax.InternalSyntax.Sy default: throw new ArgumentException(nameof(identifier)); } + if (exclamationToken != null) + { + switch (exclamationToken.Kind) + { + case SyntaxKind.ExclamationToken: + case SyntaxKind.None: + break; + default: + throw new ArgumentException(nameof(exclamationToken)); + } + } #endif - return new ParameterSyntax(SyntaxKind.Parameter, attributeLists.Node, modifiers.Node, type, identifier, @default, this.context); + return new ParameterSyntax(SyntaxKind.Parameter, attributeLists.Node, modifiers.Node, type, identifier, exclamationToken, @default, this.context); } public IncompleteMemberSyntax IncompleteMember(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type) @@ -48574,7 +48611,7 @@ public static BracketedParameterListSyntax BracketedParameterList(SyntaxToken op return result; } - public static ParameterSyntax Parameter(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + public static ParameterSyntax Parameter(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default) { #if DEBUG if (identifier == null) @@ -48587,9 +48624,20 @@ public static ParameterSyntax Parameter(Microsoft.CodeAnalysis.Syntax.InternalSy default: throw new ArgumentException(nameof(identifier)); } + if (exclamationToken != null) + { + switch (exclamationToken.Kind) + { + case SyntaxKind.ExclamationToken: + case SyntaxKind.None: + break; + default: + throw new ArgumentException(nameof(exclamationToken)); + } + } #endif - return new ParameterSyntax(SyntaxKind.Parameter, attributeLists.Node, modifiers.Node, type, identifier, @default); + return new ParameterSyntax(SyntaxKind.Parameter, attributeLists.Node, modifiers.Node, type, identifier, exclamationToken, @default); } public static IncompleteMemberSyntax IncompleteMember(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type) diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs index fa9b59c621309..a47cc830d4af9 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs @@ -4085,8 +4085,9 @@ public override SyntaxNode VisitParameter(ParameterSyntax node) var modifiers = this.VisitList(node.Modifiers); var type = (TypeSyntax)this.Visit(node.Type); var identifier = this.VisitToken(node.Identifier); + var exclamationToken = this.VisitToken(node.ExclamationToken); var @default = (EqualsValueClauseSyntax)this.Visit(node.Default); - return node.Update(attributeLists, modifiers, type, identifier, @default); + return node.Update(attributeLists, modifiers, type, identifier, exclamationToken, @default); } public override SyntaxNode VisitIncompleteMember(IncompleteMemberSyntax node) @@ -10022,7 +10023,7 @@ public static BracketedParameterListSyntax BracketedParameterList(SyntaxToken op } /// Creates a new ParameterSyntax instance. - public static ParameterSyntax Parameter(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + public static ParameterSyntax Parameter(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default) { switch (identifier.Kind()) { @@ -10032,14 +10033,28 @@ public static ParameterSyntax Parameter(SyntaxList attribut default: throw new ArgumentException(nameof(identifier)); } - return (ParameterSyntax)Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.SyntaxFactory.Parameter(attributeLists.Node.ToGreenList(), modifiers.Node.ToGreenList(), type == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.TypeSyntax)type.Green, (Syntax.InternalSyntax.SyntaxToken)identifier.Node, @default == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.EqualsValueClauseSyntax)@default.Green).CreateRed(); + switch (exclamationToken.Kind()) + { + case SyntaxKind.ExclamationToken: + case SyntaxKind.None: + break; + default: + throw new ArgumentException(nameof(exclamationToken)); + } + return (ParameterSyntax)Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.SyntaxFactory.Parameter(attributeLists.Node.ToGreenList(), modifiers.Node.ToGreenList(), type == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.TypeSyntax)type.Green, (Syntax.InternalSyntax.SyntaxToken)identifier.Node, (Syntax.InternalSyntax.SyntaxToken)exclamationToken.Node, @default == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.EqualsValueClauseSyntax)@default.Green).CreateRed(); } + /// Creates a new ParameterSyntax instance. + public static ParameterSyntax Parameter(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + { + return SyntaxFactory.Parameter(attributeLists, modifiers, type, identifier, default(SyntaxToken), @default); + } + /// Creates a new ParameterSyntax instance. public static ParameterSyntax Parameter(SyntaxToken identifier) { - return SyntaxFactory.Parameter(default(SyntaxList), default(SyntaxTokenList), default(TypeSyntax), identifier, default(EqualsValueClauseSyntax)); + return SyntaxFactory.Parameter(default(SyntaxList), default(SyntaxTokenList), default(TypeSyntax), identifier, default(SyntaxToken), default(EqualsValueClauseSyntax)); } /// Creates a new IncompleteMemberSyntax instance. diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs index 513588facc211..e520bb5d7e30f 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs @@ -18542,11 +18542,23 @@ public SyntaxToken Identifier get { return new SyntaxToken(this, ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.ParameterSyntax)this.Green).identifier, this.GetChildPosition(3), this.GetChildIndex(3)); } } + public SyntaxToken ExclamationToken + { + get + { + var slot = ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.ParameterSyntax)this.Green).exclamationToken; + if (slot != null) + return new SyntaxToken(this, slot, this.GetChildPosition(4), this.GetChildIndex(4)); + + return default(SyntaxToken); + } + } + public EqualsValueClauseSyntax Default { get { - return this.GetRed(ref this.@default, 4); + return this.GetRed(ref this.@default, 5); } } @@ -18556,7 +18568,7 @@ internal override SyntaxNode GetNodeSlot(int index) { case 0: return this.GetRedAtZero(ref this.attributeLists); case 2: return this.GetRed(ref this.type, 2); - case 4: return this.GetRed(ref this.@default, 4); + case 5: return this.GetRed(ref this.@default, 5); default: return null; } } @@ -18566,7 +18578,7 @@ internal override SyntaxNode GetCachedSlot(int index) { case 0: return this.attributeLists; case 2: return this.type; - case 4: return this.@default; + case 5: return this.@default; default: return null; } } @@ -18581,11 +18593,11 @@ public override void Accept(CSharpSyntaxVisitor visitor) visitor.VisitParameter(this); } - public ParameterSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + public ParameterSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, SyntaxToken exclamationToken, EqualsValueClauseSyntax @default) { - if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || type != this.Type || identifier != this.Identifier || @default != this.Default) + if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || type != this.Type || identifier != this.Identifier || exclamationToken != this.ExclamationToken || @default != this.Default) { - var newNode = SyntaxFactory.Parameter(attributeLists, modifiers, type, identifier, @default); + var newNode = SyntaxFactory.Parameter(attributeLists, modifiers, type, identifier, exclamationToken, @default); var annotations = this.GetAnnotations(); if (annotations != null && annotations.Length > 0) return newNode.WithAnnotations(annotations); @@ -18597,27 +18609,32 @@ public ParameterSyntax Update(SyntaxList attributeLists, Sy public ParameterSyntax WithAttributeLists(SyntaxList attributeLists) { - return this.Update(attributeLists, this.Modifiers, this.Type, this.Identifier, this.Default); + return this.Update(attributeLists, this.Modifiers, this.Type, this.Identifier, this.ExclamationToken, this.Default); } public ParameterSyntax WithModifiers(SyntaxTokenList modifiers) { - return this.Update(this.AttributeLists, modifiers, this.Type, this.Identifier, this.Default); + return this.Update(this.AttributeLists, modifiers, this.Type, this.Identifier, this.ExclamationToken, this.Default); } public ParameterSyntax WithType(TypeSyntax type) { - return this.Update(this.AttributeLists, this.Modifiers, type, this.Identifier, this.Default); + return this.Update(this.AttributeLists, this.Modifiers, type, this.Identifier, this.ExclamationToken, this.Default); } public ParameterSyntax WithIdentifier(SyntaxToken identifier) { - return this.Update(this.AttributeLists, this.Modifiers, this.Type, identifier, this.Default); + return this.Update(this.AttributeLists, this.Modifiers, this.Type, identifier, this.ExclamationToken, this.Default); + } + + public ParameterSyntax WithExclamationToken(SyntaxToken exclamationToken) + { + return this.Update(this.AttributeLists, this.Modifiers, this.Type, this.Identifier, exclamationToken, this.Default); } public ParameterSyntax WithDefault(EqualsValueClauseSyntax @default) { - return this.Update(this.AttributeLists, this.Modifiers, this.Type, this.Identifier, @default); + return this.Update(this.AttributeLists, this.Modifiers, this.Type, this.Identifier, this.ExclamationToken, @default); } public ParameterSyntax AddAttributeLists(params AttributeListSyntax[] items) diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 96e247bbcc502..43a8cfb1033bc 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -3838,17 +3838,31 @@ private ParameterSyntax ParseParameter( type = null; name = this.EatToken(SyntaxKind.ArgListKeyword); } - - EqualsValueClauseSyntax def = null; + SyntaxToken exclamation = null; + SyntaxToken equals = null; + if (this.CurrentToken.Kind == SyntaxKind.ExclamationToken) + { + exclamation = this.EatToken(SyntaxKind.ExclamationToken); + } + else if (this.CurrentToken.Kind == SyntaxKind.ExclamationEqualsToken) + { + var notEq = this.EatToken(SyntaxKind.ExclamationEqualsToken); + equals = ConvertToMissingWithTrailingTrivia(notEq, SyntaxKind.EqualsToken); + equals = AddError(equals, ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals); + exclamation = SyntaxFactory.MissingToken(SyntaxKind.ExclamationToken); + } if (this.CurrentToken.Kind == SyntaxKind.EqualsToken) { - var equals = this.EatToken(SyntaxKind.EqualsToken); + equals = this.EatToken(SyntaxKind.EqualsToken); + } + EqualsValueClauseSyntax def = null; + if (!(equals is null)) + { var value = this.ParseExpressionCore(); def = _syntaxFactory.EqualsValueClause(equals, value: value); def = CheckFeatureAvailability(def, MessageID.IDS_FeatureOptionalParameter); } - - return _syntaxFactory.Parameter(attributes, modifiers.ToList(), type, name, def); + return _syntaxFactory.Parameter(attributes, modifiers.ToList(), type, name, exclamation, def); } private static bool IsParameterModifier(SyntaxKind kind) @@ -9539,11 +9553,23 @@ private bool ScanDesignator() private bool IsPossibleLambdaExpression(Precedence precedence) { - if (precedence <= Precedence.Lambda && this.PeekToken(1).Kind == SyntaxKind.EqualsGreaterThanToken) + if (precedence <= Precedence.Lambda) { - return true; + SyntaxKind token1 = this.PeekToken(1).Kind; + if (token1 == SyntaxKind.EqualsGreaterThanToken) + { + return true; + } + if (token1 == SyntaxKind.ExclamationToken && this.PeekToken(2).Kind == SyntaxKind.EqualsGreaterThanToken) + { + return true; + } + // Broken case but error will be added in lambda function. + if (token1 == SyntaxKind.ExclamationEqualsToken && this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken) + { + return true; + } } - if (ScanAsyncLambda(precedence)) { return true; @@ -10002,11 +10028,8 @@ private bool ScanParenthesizedImplicitlyTypedLambda(Precedence precedence) { return false; } - // case 1: ( x , - if (this.PeekToken(1).Kind == SyntaxKind.IdentifierToken - && (!this.IsInQuery || !IsTokenQueryContextualKeyword(this.PeekToken(1))) - && this.PeekToken(2).Kind == SyntaxKind.CommaToken) + if (isParenVarCommaSyntax()) { // Make sure it really looks like a lambda, not just a tuple int curTk = 3; @@ -10030,11 +10053,21 @@ private bool ScanParenthesizedImplicitlyTypedLambda(Precedence precedence) } // case 2: ( x ) => - if (IsTrueIdentifier(this.PeekToken(1)) - && this.PeekToken(2).Kind == SyntaxKind.CloseParenToken - && this.PeekToken(3).Kind == SyntaxKind.EqualsGreaterThanToken) + if (IsTrueIdentifier(this.PeekToken(1))) { - return true; + // allow for a) => or a!) => + var skipIndex = 2; + if (PeekToken(skipIndex).Kind == SyntaxKind.ExclamationToken) + { + skipIndex++; + } + + // Must have: ) => + if (this.PeekToken(skipIndex + 1).Kind == SyntaxKind.CloseParenToken + && this.PeekToken(skipIndex + 2).Kind == SyntaxKind.EqualsGreaterThanToken) + { + return true; + } } // case 3: ( ) => @@ -10053,6 +10086,32 @@ private bool ScanParenthesizedImplicitlyTypedLambda(Precedence precedence) } return false; + + bool isParenVarCommaSyntax() + { + var next = this.PeekToken(1); + + // Ensure next token is a variable + if (next.Kind == SyntaxKind.IdentifierToken) + { + if (!this.IsInQuery || !IsTokenQueryContextualKeyword(next)) + { + // Variable must be directly followed by a comma if not followed by exclamation + var afterKind = this.PeekToken(2).Kind; + // ( x , [...] + if (afterKind == SyntaxKind.CommaToken) + { + return true; + } + // ( x! , [...] + if (afterKind == SyntaxKind.ExclamationToken && this.PeekToken(3).Kind == SyntaxKind.CommaToken) + { + return true; + } + } + } + return false; + } } private bool ScanExplicitlyTypedLambda(Precedence precedence) @@ -10122,7 +10181,10 @@ private bool ScanExplicitlyTypedLambda(Precedence precedence) // eat the identifier this.EatToken(); } - + if (this.CurrentToken.Kind == SyntaxKind.ExclamationToken) + { + this.EatToken(); + } switch (this.CurrentToken.Kind) { case SyntaxKind.EndOfFileToken: @@ -10133,7 +10195,6 @@ private bool ScanExplicitlyTypedLambda(Precedence precedence) { return true; } - continue; case SyntaxKind.CloseParenToken: @@ -11041,12 +11102,34 @@ private LambdaExpressionSyntax ParseLambdaExpression(SyntaxToken asyncToken) else { var name = this.ParseIdentifierToken(); - var arrow = this.EatToken(SyntaxKind.EqualsGreaterThanToken); - arrow = CheckFeatureAvailability(arrow, MessageID.IDS_FeatureLambda); - + SyntaxToken arrow, exclamation; + // Case x! => + if (this.CurrentToken.Kind == SyntaxKind.ExclamationToken) + { + exclamation = this.EatToken(SyntaxKind.ExclamationToken); + arrow = this.EatToken(SyntaxKind.EqualsGreaterThanToken); + arrow = CheckFeatureAvailability(arrow, MessageID.IDS_FeatureLambda); + } + // Case x!=> + else if (this.CurrentToken.Kind == SyntaxKind.ExclamationEqualsToken && this.PeekToken(1).Kind == SyntaxKind.GreaterThanToken) + { + var notEq = this.EatToken(SyntaxKind.ExclamationEqualsToken); + arrow = ConvertToMissingWithTrailingTrivia(notEq, SyntaxKind.EqualsGreaterThanToken); + arrow = AddError(arrow, ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals); + var gt = this.EatToken(SyntaxKind.GreaterThanToken); + arrow = AddTrailingSkippedSyntax(arrow, gt); + exclamation = SyntaxFactory.MissingToken(SyntaxKind.ExclamationToken); + } + // Case x=>, x => + else + { + arrow = this.EatToken(SyntaxKind.EqualsGreaterThanToken); + arrow = CheckFeatureAvailability(arrow, MessageID.IDS_FeatureLambda); + exclamation = null; + } var parameter = _syntaxFactory.Parameter( default(SyntaxList), default(SyntaxList), - type: null, identifier: name, @default: null); + type: null, identifier: name, exclamation, @default: null); var body = ParseLambdaBody(); return _syntaxFactory.SimpleLambdaExpression(asyncToken, parameter, arrow, body); @@ -11170,7 +11253,9 @@ private ParameterSyntax ParseLambdaParameter() } SyntaxToken paramName = this.ParseIdentifierToken(); - var parameter = _syntaxFactory.Parameter(default(SyntaxList), modifiers.ToList(), paramType, paramName, null); + // PROTOTYPE : null checking; lang version check needed + var exclamation = this.CurrentToken.Kind == SyntaxKind.ExclamationToken ? this.EatToken(SyntaxKind.ExclamationToken) : null; + var parameter = _syntaxFactory.Parameter(default(SyntaxList), modifiers.ToList(), paramType, paramName, exclamation, null); _pool.Free(modifiers); return parameter; } @@ -11209,7 +11294,8 @@ private bool ShouldParseLambdaParameterType(bool hasModifier) if (peek1.Kind != SyntaxKind.CommaToken && peek1.Kind != SyntaxKind.CloseParenToken && peek1.Kind != SyntaxKind.EqualsGreaterThanToken && - peek1.Kind != SyntaxKind.OpenBraceToken) + peek1.Kind != SyntaxKind.OpenBraceToken && + peek1.Kind != SyntaxKind.ExclamationToken) { return true; } diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index c3b4455295baa..3fa95246cab34 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -4,6 +4,9 @@ *REMOVED*static Microsoft.CodeAnalysis.CSharp.LanguageVersionFacts.TryParse(this string version, out Microsoft.CodeAnalysis.CSharp.LanguageVersion result) -> bool *REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(Microsoft.CodeAnalysis.Text.SourceText text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree *REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(string text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Text.Encoding encoding = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree +Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.ExclamationToken.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.WithExclamationToken(Microsoft.CodeAnalysis.SyntaxToken exclamationToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax abstract Microsoft.CodeAnalysis.CSharp.Syntax.CommonForEachStatementSyntax.AwaitKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind outputKind, bool reportSuppressedDiagnostics = false, string moduleName = null, string mainTypeName = null, string scriptClassName = null, System.Collections.Generic.IEnumerable usings = null, Microsoft.CodeAnalysis.OptimizationLevel optimizationLevel = Microsoft.CodeAnalysis.OptimizationLevel.Debug, bool checkOverflow = false, bool allowUnsafe = false, string cryptoKeyContainer = null, string cryptoKeyFile = null, System.Collections.Immutable.ImmutableArray cryptoPublicKey = default(System.Collections.Immutable.ImmutableArray), bool? delaySign = null, Microsoft.CodeAnalysis.Platform platform = Microsoft.CodeAnalysis.Platform.AnyCpu, Microsoft.CodeAnalysis.ReportDiagnostic generalDiagnosticOption = Microsoft.CodeAnalysis.ReportDiagnostic.Default, int warningLevel = 4, System.Collections.Generic.IEnumerable> specificDiagnosticOptions = null, bool concurrentBuild = true, bool deterministic = false, Microsoft.CodeAnalysis.XmlReferenceResolver xmlReferenceResolver = null, Microsoft.CodeAnalysis.SourceReferenceResolver sourceReferenceResolver = null, Microsoft.CodeAnalysis.MetadataReferenceResolver metadataReferenceResolver = null, Microsoft.CodeAnalysis.AssemblyIdentityComparer assemblyIdentityComparer = null, Microsoft.CodeAnalysis.StrongNameProvider strongNameProvider = null, bool publicSign = false, Microsoft.CodeAnalysis.MetadataImportOptions metadataImportOptions = Microsoft.CodeAnalysis.MetadataImportOptions.Public, Microsoft.CodeAnalysis.CSharp.NullableContextOptions nullableContextOptions = Microsoft.CodeAnalysis.CSharp.NullableContextOptions.Disable) -> void Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind outputKind, bool reportSuppressedDiagnostics, string moduleName, string mainTypeName, string scriptClassName, System.Collections.Generic.IEnumerable usings, Microsoft.CodeAnalysis.OptimizationLevel optimizationLevel, bool checkOverflow, bool allowUnsafe, string cryptoKeyContainer, string cryptoKeyFile, System.Collections.Immutable.ImmutableArray cryptoPublicKey, bool? delaySign, Microsoft.CodeAnalysis.Platform platform, Microsoft.CodeAnalysis.ReportDiagnostic generalDiagnosticOption, int warningLevel, System.Collections.Generic.IEnumerable> specificDiagnosticOptions, bool concurrentBuild, bool deterministic, Microsoft.CodeAnalysis.XmlReferenceResolver xmlReferenceResolver, Microsoft.CodeAnalysis.SourceReferenceResolver sourceReferenceResolver, Microsoft.CodeAnalysis.MetadataReferenceResolver metadataReferenceResolver, Microsoft.CodeAnalysis.AssemblyIdentityComparer assemblyIdentityComparer, Microsoft.CodeAnalysis.StrongNameProvider strongNameProvider, bool publicSign, Microsoft.CodeAnalysis.MetadataImportOptions metadataImportOptions) -> void @@ -283,6 +286,7 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachVariableStatement(Micr static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalDeclarationStatement(Microsoft.CodeAnalysis.SyntaxToken awaitKeyword, Microsoft.CodeAnalysis.SyntaxToken usingKeyword, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.NullableDirectiveTrivia(Microsoft.CodeAnalysis.SyntaxToken hashToken, Microsoft.CodeAnalysis.SyntaxToken nullableKeyword, Microsoft.CodeAnalysis.SyntaxToken settingToken, Microsoft.CodeAnalysis.SyntaxToken endOfDirectiveToken, bool isActive) -> Microsoft.CodeAnalysis.CSharp.Syntax.NullableDirectiveTriviaSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.NullableDirectiveTrivia(Microsoft.CodeAnalysis.SyntaxToken settingToken, bool isActive) -> Microsoft.CodeAnalysis.CSharp.Syntax.NullableDirectiveTriviaSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Parameter(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseMemberDeclaration(string text, int offset = 0, Microsoft.CodeAnalysis.ParseOptions options = null, bool consumeFullText = true) -> Microsoft.CodeAnalysis.CSharp.Syntax.MemberDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(Microsoft.CodeAnalysis.Text.SourceText text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Collections.Immutable.ImmutableDictionary diagnosticOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(Microsoft.CodeAnalysis.Text.SourceText text, Microsoft.CodeAnalysis.ParseOptions options, string path, System.Threading.CancellationToken cancellationToken) -> Microsoft.CodeAnalysis.SyntaxTree diff --git a/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs index cf6eeed50e3ab..edee92685369c 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs @@ -15,5 +15,10 @@ internal bool IsArgList return this.Type == null && this.Identifier.ContextualKind() == SyntaxKind.ArgListKeyword; } } + + public ParameterSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax @default) + { + return Update(attributeLists, modifiers, type, identifier, exclamationToken: default, @default); + } } } diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index 9f1656181bd98..13531662e7029 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -3787,6 +3787,9 @@ + + + diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 758e6d79b9662..85f42045fa8f1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Omezení new() nejde používat s omezením unmanaged. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 05234c0c6a874..3da1b80d3a736 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Die new()-Einschränkung kann nicht mit der unmanaged-Einschränkung verwendet werden. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index ee0b831d705cb..c58126d4308d0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint La restricción "new()" no se puede utilizar con la restricción "unmanaged" diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 9658fadd93e4a..a61570d0c9bb7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint La contrainte 'new()' ne peut pas être utilisée avec la contrainte 'unmanaged' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index f99a9902c4427..89d95f581f49c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Non è possibile usare il vincolo 'new()' con il vincolo 'unmanaged' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index eba847bf5990c..8bf288579043b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint new()' 制約は 'unmanaged' 制約と一緒には使用できません diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index ba62f093b932d..a3951b0d3ec47 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint new()' 제약 조건은 'unmanaged' 제약 조건과 함께 사용할 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 9ca5c86059c31..a9c110dec77ca 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Ograniczenie „new()” nie może być używane z ograniczeniem „unmanaged” diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index a3622bc33d2dc..17ce1d21359e4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint A restrição 'new()' não pode ser usada com a restrição 'unmanaged' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 39b04fc1eacc2..7cea09f06c33c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Ограничение "new()" невозможно использовать вместе с ограничением "unmanaged" diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index bcd05d9fa274d..6dce79f3ffdd7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint 'new()' kısıtlaması, 'unmanaged' kısıtlamasıyla kullanılamaz diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index ec3a1b77a8a97..9051858f686b4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -287,6 +287,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint "new()" 约束不能与 "unmanaged" 约束一起使用 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index aff8d3b603a22..2798912f5ee39 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -262,6 +262,11 @@ The attribute [EnumeratorCancellation] cannot be used on multiple parameters + + Space required between '!' and '=' here. + Space required between '!' and '=' here. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint new()' 條件約束不能和 'unmanaged' 條件約束一起使用 diff --git a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs index 9915d3dc88fca..468f936db5429 100644 --- a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs +++ b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs @@ -525,7 +525,7 @@ private static Syntax.InternalSyntax.BracketedParameterListSyntax GenerateBracke => InternalSyntaxFactory.BracketedParameterList(InternalSyntaxFactory.Token(SyntaxKind.OpenBracketToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.CloseBracketToken)); private static Syntax.InternalSyntax.ParameterSyntax GenerateParameter() - => InternalSyntaxFactory.Parameter(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), null, InternalSyntaxFactory.Identifier("Identifier"), null); + => InternalSyntaxFactory.Parameter(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), null, InternalSyntaxFactory.Identifier("Identifier"), null, null); private static Syntax.InternalSyntax.IncompleteMemberSyntax GenerateIncompleteMember() => InternalSyntaxFactory.IncompleteMember(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), null); @@ -2828,6 +2828,7 @@ public void TestParameterFactoryAndProperties() Assert.NotNull(node.Modifiers); Assert.Null(node.Type); Assert.Equal(SyntaxKind.IdentifierToken, node.Identifier.Kind); + Assert.Null(node.ExclamationToken); Assert.Null(node.Default); AttachAndCheckDiagnostics(node); @@ -9498,7 +9499,7 @@ private static BracketedParameterListSyntax GenerateBracketedParameterList() => SyntaxFactory.BracketedParameterList(SyntaxFactory.Token(SyntaxKind.OpenBracketToken), new SeparatedSyntaxList(), SyntaxFactory.Token(SyntaxKind.CloseBracketToken)); private static ParameterSyntax GenerateParameter() - => SyntaxFactory.Parameter(new SyntaxList(), new SyntaxTokenList(), default(TypeSyntax), SyntaxFactory.Identifier("Identifier"), default(EqualsValueClauseSyntax)); + => SyntaxFactory.Parameter(new SyntaxList(), new SyntaxTokenList(), default(TypeSyntax), SyntaxFactory.Identifier("Identifier"), default(SyntaxToken), default(EqualsValueClauseSyntax)); private static IncompleteMemberSyntax GenerateIncompleteMember() => SyntaxFactory.IncompleteMember(new SyntaxList(), new SyntaxTokenList(), default(TypeSyntax)); @@ -11801,8 +11802,9 @@ public void TestParameterFactoryAndProperties() Assert.NotNull(node.Modifiers); Assert.Null(node.Type); Assert.Equal(SyntaxKind.IdentifierToken, node.Identifier.Kind()); + Assert.Equal(SyntaxKind.None, node.ExclamationToken.Kind()); Assert.Null(node.Default); - var newNode = node.WithAttributeLists(node.AttributeLists).WithModifiers(node.Modifiers).WithType(node.Type).WithIdentifier(node.Identifier).WithDefault(node.Default); + var newNode = node.WithAttributeLists(node.AttributeLists).WithModifiers(node.Modifiers).WithType(node.Type).WithIdentifier(node.Identifier).WithExclamationToken(node.ExclamationToken).WithDefault(node.Default); Assert.Equal(node, newNode); } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs index 1522282190ccc..b08b705a6d2d6 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs @@ -7191,5 +7191,581 @@ class C where T : struct? {} } EOF(); } + + [Fact] + public void TestMethodDeclarationNullValidation() + { + UsingStatement(@"void M(string name!) { }"); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestOptParamMethodDeclarationWithNullValidation() + { + UsingStatement(@"void M(string name! = null) { }"); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestOptParamMethodDeclarationWithNullValidationNoSpaces() + { + UsingStatement(@"void M(string name!=null) { }", expectedErrors: new DiagnosticDescription[] + { + // (1,19): error CS8712: Space required between explanation-point and equals-sign here. + // void M(string name!=null) { } + Diagnostic(ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals, "!=").WithLocation(1, 19) + }); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestNullCheckedArgList() + { + UsingStatement(@"void M(__arglist!) { }"); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.ArgListKeyword); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + + [Fact] + public void TestNullCheckedArgWithLeadingSpace() + { + UsingStatement(@"void M(string name !=null) { }", expectedErrors: new DiagnosticDescription[] + { + // (1,20): error CS8712: Space required between explanation-point and equals-sign here. + // void M(string name !=null) { } + Diagnostic(ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals, "!=").WithLocation(1, 20) + }); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestNullCheckedArgWithLeadingNewLine() + { + UsingStatement(@"void M(string name +!=null) { }", expectedErrors: new DiagnosticDescription[] + { + // (2,1): error CS8712: Space required between '!' and '=' here. + // !=null) { } + Diagnostic(ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals, "!=").WithLocation(2, 1) + }); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestNullCheckedArgWithTrailingSpace() + { + UsingStatement(@"void M(string name!= null) { }", expectedErrors: new DiagnosticDescription[] + { + // (1,19): error CS8712: Space required between explanation-point and equals-sign here. + // void M(string name!= null) { } + Diagnostic(ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals, "!=").WithLocation(1, 19) + }); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestNullCheckedArgWithTrailingNewLine() + { + UsingStatement(@"void M(string name!= +null) { }", expectedErrors: new DiagnosticDescription[] + { + // (1,19): error CS8712: Space required between '!' and '=' here. + // void M(string name!= + Diagnostic(ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals, "!=").WithLocation(1, 19) + }); + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken, "name"); + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + + [Fact] + public void TestNullCheckedMethod() + { + UsingTree(@" +class C +{ + public void M(string x!) { } +}"); + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.MethodDeclaration); + { + N(SyntaxKind.PublicKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + } + } + } + + [Fact] + public void TestNullCheckedConstructor() + { + UsingTree(@" +class C +{ + public C(string x!) { } +}"); + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.ConstructorDeclaration); + { + N(SyntaxKind.PublicKeyword); + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + } + } + } + + + [Fact] + public void TestNullCheckedOperator() + { + UsingTree(@" +class Box +{ + public static int operator+ (Box b!, Box c) + { + return 2; + } +}"); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.OperatorDeclaration); + { + N(SyntaxKind.PublicKeyword); + N(SyntaxKind.StaticKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.OperatorKeyword); + N(SyntaxKind.PlusToken); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.ReturnStatement); + { + N(SyntaxKind.ReturnKeyword); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken); + } + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.EndOfFileToken); + } + + [Fact] + public void TestAnonymousDelegateNullChecking() + { + // PROTOTYPE : During semantics, make sure this causes an error + UsingTree(@" +delegate void Del(int x!); +Del d = delegate(int k!) { /* ... */ };"); + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.DelegateDeclaration); + { + N(SyntaxKind.DelegateKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.VariableDeclarator); + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.AnonymousMethodExpression); + { + N(SyntaxKind.DelegateKeyword); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + } + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.SemicolonToken); + } + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs index 0421f125b178f..813245a496fda 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.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 Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -580,5 +582,554 @@ public void HangingLambdaParsing_Bug14167() EOF(); } + [Fact] + public void TestLambdaWithNullValidation() + { + UsingDeclaration("Func func1 = x! => x + \"1\";"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.SimpleLambdaExpression); + { + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.AddExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.PlusToken); + N(SyntaxKind.StringLiteralExpression); + { + N(SyntaxKind.StringLiteralToken); + } + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestLambdaWithNullValidationParams() + { + UsingDeclaration("Func func1 = (x!, y) => x == y;"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.BoolKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "y"); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.EqualsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.EqualsEqualsToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestNullCheckedSingleParamInParens() + { + UsingDeclaration("Func func1 = (x!) => x;"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestNullCheckedSingleParamNoSpaces() + { + UsingDeclaration("Func func1 = x!=>x;", expectedErrors: new DiagnosticDescription[] + { + // (1,25): error CS8712: Space required between explanation-point and equals-sign here. + // Func func1 = x!=>x; + Diagnostic(ErrorCode.ERR_NeedSpaceBetweenExclamationAndEquals, "!=").WithLocation(1, 25) + }); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.SimpleLambdaExpression); + { + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestNullCheckedTypedSingleParamInParen() + { + UsingDeclaration("Func func1 = (int x!) => x;"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestNullCheckedTypedManyParams() + { + UsingDeclaration("Func func1 = (int x!, int y) => x;"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken, "y"); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestManyNullCheckedTypedParams() + { + UsingDeclaration("Func func1 = (int x!, int y!) => x;"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.IdentifierToken, "y"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestNullCheckedNoParams() + { + UsingDeclaration("Func func1 = (!) => 42;", expectedErrors: new DiagnosticDescription[] + { + // (1,21): error CS1525: Invalid expression term ')' + // Func func1 = (!) => 42; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(1, 21), + // (1,23): error CS1003: Syntax error, ',' expected + // Func func1 = (!) => 42; + Diagnostic(ErrorCode.ERR_SyntaxError, "=>").WithArguments(",", "=>").WithLocation(1, 23) + }); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedExpression); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.LogicalNotExpression); + { + N(SyntaxKind.ExclamationToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken); + } + } + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.SemicolonToken); + } + } + + [Fact] + public void TestNullCheckedDiscard() + { + UsingDeclaration("Func func1 = (_!) => 42;"); + N(SyntaxKind.FieldDeclaration); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.GenericName); + N(SyntaxKind.IdentifierToken, "Func"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "func1"); + } + N(SyntaxKind.EqualsValueClause); + { + N(SyntaxKind.EqualsToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "_"); + N(SyntaxKind.ExclamationToken); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + } } } From 650a8d77c691d8064241fac4baee9a9d9618c6d9 Mon Sep 17 00:00:00 2001 From: Lauren Fay Date: Fri, 31 May 2019 09:07:26 -0700 Subject: [PATCH 02/93] Merge master with param-nullchecking (#36070) --- docs/Language Feature Status.md | 1 + docs/README.md | 2 +- .../DefaultInterfaceImplementation.md | 36 + docs/ide/README.md | 124 + eng/Version.Details.xml | 4 +- eng/Versions.props | 5 +- eng/common/PublishToPackageFeed.proj | 1 + eng/common/build.ps1 | 8 + eng/common/build.sh | 27 +- eng/common/cross/arm/sources.list.vivid | 11 - eng/common/cross/arm/sources.list.wily | 11 - eng/common/cross/arm64/sources.list.buster | 11 + eng/common/cross/arm64/sources.list.stretch | 12 + eng/common/cross/arm64/sources.list.vivid | 11 - eng/common/cross/arm64/sources.list.wily | 11 - eng/common/cross/build-rootfs.sh | 67 +- eng/common/cross/x86/sources.list.vivid | 11 - eng/common/cross/x86/sources.list.wily | 11 - eng/common/darc-init.ps1 | 11 +- eng/common/darc-init.sh | 15 +- eng/common/dotnet-install.cmd | 2 + eng/common/dotnet-install.ps1 | 27 + eng/common/dotnet-install.sh | 49 + eng/common/init-tools-native.ps1 | 6 +- eng/common/init-tools-native.sh | 12 +- eng/common/templates/job/job.yml | 3 + eng/common/templates/steps/send-to-helix.yml | 3 + eng/common/tools.ps1 | 70 +- eng/common/tools.sh | 166 +- eng/config/PublishData.json | 9 + eng/targets/PackageProject.targets | 2 +- global.json | 2 +- .../CSharpDeclarationComputer.cs | 5 +- .../Portable/Binder/Binder.ValueChecks.cs | 18 +- .../Portable/Binder/DecisionDagBuilder.cs | 87 +- .../Conversions/ConversionKindExtensions.cs | 1 + .../Portable/CSharpResources.Designer.cs | 18 +- .../CSharp/Portable/CSharpResources.resx | 6 +- .../CSharp/Portable/CodeGen/EmitExpression.cs | 11 +- .../CSharp/Portable/Errors/ErrorCode.cs | 6 +- .../Portable/FlowAnalysis/NullableWalker.cs | 33 +- .../Syntax.xml.Internal.Generated.cs | 107 +- .../Generated/Syntax.xml.Main.Generated.cs | 23 +- .../Generated/Syntax.xml.Syntax.Generated.cs | 40 +- .../LocalRewriter/LocalRewriter_StackAlloc.cs | 3 +- .../Portable/Lowering/SpillSequenceSpiller.cs | 8 + .../CSharp/Portable/Parser/LanguageParser.cs | 67 +- .../CSharp/Portable/Parser/SyntaxParser.cs | 7 + .../CSharp/Portable/PublicAPI.Unshipped.txt | 6 + .../ParameterWellKnownAttributeData.cs | 72 +- .../Portable/Symbols/ExtraAnnotations.cs | 2 +- .../Symbols/FlowAnalysisAnnotations.cs | 48 +- .../Symbols/MemberSymbolExtensions.cs | 2 +- .../Symbols/Metadata/PE/PEMethodSymbol.cs | 15 +- .../Symbols/Metadata/PE/PEParameterSymbol.cs | 119 +- .../Portable/Symbols/Source/ModifierUtils.cs | 12 +- .../Source/SourceComplexParameterSymbol.cs | 78 +- .../Source/SourceCustomEventAccessorSymbol.cs | 48 +- .../Symbols/Source/SourceCustomEventSymbol.cs | 121 +- .../Source/SourceEventAccessorSymbol.cs | 49 +- .../Symbols/Source/SourceEventSymbol.cs | 12 +- .../Source/SourceFieldLikeEventSymbol.cs | 8 +- .../Source/SourceMemberContainerSymbol.cs | 10 +- .../Source/SourceMemberMethodSymbol.cs | 11 +- .../Source/SourceOrdinaryMethodSymbol.cs | 17 +- .../Source/SourcePropertyAccessorSymbol.cs | 8 + .../Symbols/Source/SourcePropertySymbol.cs | 23 +- .../Portable/Symbols/SymbolExtensions.cs | 2 +- ...l.cs => SynthesizedEventAccessorSymbol.cs} | 27 +- .../CSharp/Portable/Symbols/TypeSymbol.cs | 15 +- .../Portable/Syntax/EventDeclarationSyntax.cs | 21 + .../CSharp/Portable/Syntax/Syntax.xml | 5 +- .../CSharp/Portable/Syntax/SyntaxFactory.cs | 12 + .../Portable/xlf/CSharpResources.cs.xlf | 12 +- .../Portable/xlf/CSharpResources.de.xlf | 12 +- .../Portable/xlf/CSharpResources.es.xlf | 12 +- .../Portable/xlf/CSharpResources.fr.xlf | 12 +- .../Portable/xlf/CSharpResources.it.xlf | 12 +- .../Portable/xlf/CSharpResources.ja.xlf | 12 +- .../Portable/xlf/CSharpResources.ko.xlf | 12 +- .../Portable/xlf/CSharpResources.pl.xlf | 12 +- .../Portable/xlf/CSharpResources.pt-BR.xlf | 14 +- .../Portable/xlf/CSharpResources.ru.xlf | 12 +- .../Portable/xlf/CSharpResources.tr.xlf | 12 +- .../Portable/xlf/CSharpResources.zh-Hans.xlf | 12 +- .../Portable/xlf/CSharpResources.zh-Hant.xlf | 12 +- .../CodeGenStackAllocInitializerTests.cs | 42 + .../CSharp/Test/Emit/CodeGen/CodeGenTests.cs | 361 +- .../CSharp/Test/Emit/CodeGen/PatternTests.cs | 211 + .../Test/Semantic/Semantics/BindingTests.cs | 2 +- .../Semantics/NullableReferenceTypesTests.cs | 1072 +- .../Semantic/Semantics/RefEscapingTests.cs | 175 + .../Compilation/GetSemanticInfoTests.cs | 31 + .../DefaultInterfaceImplementationTests.cs | 10180 +++++++++++++++- .../Test/Symbol/Symbols/Source/EventTests.cs | 5 +- .../Symbol/Symbols/Source/PropertyTests.cs | 4 +- .../Test/Symbol/Symbols/SymbolErrorTests.cs | 40 +- .../Generated/Syntax.Test.xml.Generated.cs | 12 +- .../Syntax/Parsing/DeclarationParsingTests.cs | 12 +- .../Syntax/Parsing/ParserErrorMessageTests.cs | 7 +- .../Microsoft.Build.Tasks.CodeAnalysis.csproj | 1 + .../Microsoft.Managed.EditorConfig.targets | 11 +- .../Core/MSBuildTask/xlf/ErrorString.tr.xlf | 3 +- .../InternalUtilities/EnumUtilties.cs | 15 + .../Core/Portable/MetadataReader/PEModule.cs | 16 + .../Attributes/AttributeDescription.cs | 18 +- .../Core/Portable/Symbols/TypedConstant.cs | 15 +- .../Test/Utilities/CSharp/CSharpTestBase.cs | 55 +- .../Portable/xlf/VBResources.tr.xlf | 4 +- .../CSharpReplCommandCompletionProvider.cs | 6 + .../LoadDirectiveCompletionProvider.cs | 6 + .../ReferenceDirectiveCompletionProvider.cs | 6 + ...harpSendToInteractiveSubmissionProvider.cs | 5 + .../CloseBlockCommentCommandHandler.cs | 5 + .../CSharpDirectiveTriviaBraceMatcher.cs | 6 + .../CSharpEmbeddedLanguageBraceMatcher.cs | 5 + .../LessThanGreaterThanBraceMatcher.cs | 2 + .../OpenCloseBraceBraceMatcher.cs | 2 + .../OpenCloseBracketBraceMatcher.cs | 2 + .../OpenCloseParenBraceMatcher.cs | 2 + .../StringLiteralBraceMatcher.cs | 6 + .../CSharpChangeSignatureCommandHandler.cs | 4 + .../CSharpDecompiledSourceServiceFactory.cs | 5 + ...pEmbeddedLanguageEditorFeaturesProvider.cs | 1 + .../CSharpEndConstructGenerationService.cs | 5 + ...nterpolatedVerbatimStringCommandHandler.cs | 5 + .../CSharpEditorFormattingService.cs | 7 +- .../SmartTokenFormatterCommandHandler.cs | 4 +- .../Indentation/WhitespaceExtensions.cs | 15 - .../CSharp/GoToBase/CSharpGoToBaseService.cs | 4 + .../CSharpGoToDefinitionSymbolService.cs | 5 + .../AsyncAwaitHighlighter.cs | 6 + .../CheckedExpressionHighlighter.cs | 6 + .../CheckedStatementHighlighter.cs | 6 + .../ConditionalPreprocessorHighlighter.cs | 6 + .../IfStatementHighlighter.cs | 6 + .../LockStatementHighlighter.cs | 6 + .../KeywordHighlighters/LoopHighlighter.cs | 6 + .../KeywordHighlighters/RegionHighlighter.cs | 6 + .../ReturnStatementHighlighter.cs | 6 + .../SwitchStatementHighlighter.cs | 6 + .../TryStatementHighlighter.cs | 6 + .../UnsafeStatementHighlighter.cs | 6 + .../UsingStatementHighlighter.cs | 6 + .../YieldStatementHighlighter.cs | 6 + .../CSharpLineSeparatorService.cs | 5 + ...MisplacedUsingDirectivesCodeFixProvider.cs | 5 + .../CSharpNavigationBarItemService.cs | 5 + ...RenameTrackingLanguageHeuristicsService.cs | 5 + ...ingLiteralCommandHandler.StringSplitter.cs | 7 +- .../SplitStringLiteralOptions.cs | 5 + .../TextStructureNavigatorProvider.cs | 2 +- .../CSharpBinaryExpressionWrapper.cs | 2 +- .../CSharpWrappingCodeRefactoringProvider.cs | 1 + ...bstractCSharpSeparatedSyntaxListWrapper.cs | 3 +- .../AddUsing/AddUsingTests_NuGet.cs | 18 +- .../ConvertLinqQueryToForEachTests.cs | 174 + .../DeclarationNameCompletionProviderTests.cs | 174 + .../ConvertForToForEachTests.cs | 141 + ...tSwitchStatementToExpressionFixAllTests.cs | 203 + ...ConvertSwitchStatementToExpressionTests.cs | 628 + .../DiagnosticAnalyzerDriverTests.cs | 2 +- .../DisposableFieldsShouldBeDisposedTests.cs | 1433 +++ .../DisposeObjectsBeforeLosingScopeTests.cs | 5045 ++++++++ .../Helpers/DummyLanguageService.cs | 5 + .../Indentation/CSharpFormatterTestsBase.cs | 3 +- .../SmartIndenterEnterOnTokenTests.cs | 4 +- .../Indentation/SmartIndenterTests.cs | 4 +- .../SmartTokenFormatterFormatRangeTests.cs | 3 +- .../GenerateVariable/GenerateVariableTests.cs | 168 +- .../PullMemberUp/CSharpPullMemberUpTests.cs | 7 +- .../RemoveUnusedValueAssignmentTests.cs | 136 + ...ullCheckForCastAndEqualityOperatorTests.cs | 7 +- .../UseIsNullCheckForReferenceEqualsTests.cs | 82 +- .../UseSimpleUsingStatementTests.cs | 289 + .../CSharpTest/Workspaces/WorkspaceTests.cs | 189 +- .../ClassificationTypeFormatDefinitions.cs | 3 +- .../ClassificationTypeFormatDefinitions.cs | 165 +- .../Core.Wpf/ConflictTagDefinition.cs | 1 + .../UnnecessaryCodeFormatDefinition.cs | 3 +- .../ActiveStatementTagFormatDefinition.cs | 1 + ...ditAndContinueErrorTypeFormatDefinition.cs | 1 + .../RenameConflictTagDefinition.cs | 1 + ...meFieldBackgroundAndBorderTagDefinition.cs | 1 + .../HighlightTags/RenameFixupTagDefinition.cs | 1 + .../Taggers/ClassificationTypeDefinitions.cs | 3 +- ...ractiveDocumentNavigationServiceFactory.cs | 2 +- ...eractiveScriptEnvironmentServiceFactory.cs | 5 + .../InteractiveSupportsFeatureService.cs | 10 + .../DefaultNavigateToPreviewServiceFactory.cs | 5 + .../EditorNotificationServiceFactory.cs | 5 + .../Core.Wpf/Preview/PreviewFactoryService.cs | 188 +- .../Core.Wpf/PreviewWarningTagDefinition.cs | 1 + .../DefinitionHighlightTagDefinition.cs | 1 + .../WrittenReferenceHighlightTagDefinition.cs | 1 + .../RenameTrackingTagDefinition.cs | 1 + .../FixAll/FixAllGetFixesService.cs | 5 + .../SuggestedActions/SuggestedAction.cs | 21 +- .../SymbolSearchUpdateEngine.Update.cs | 21 +- .../SymbolSearch/SymbolSearchUpdateEngine.cs | 2 +- .../SymbolSearchUpdateEngineFactory.cs | 24 +- .../Tags/DefaultImageMonikerService.cs | 6 + .../FindReferencesCommandHandler.cs | 2 +- .../IDefinitionsAndReferencesFactory.cs | 5 + .../GoToDefinitionCommandHandler.cs | 5 + .../CodeActionEditHandlerService.cs | 45 +- .../ICodeActionEditHandlerService.cs | 2 +- ...CommentUncommentSelectionCommandHandler.cs | 2 +- .../ActiveStatementTrackingService.cs | 3 +- .../ActiveStatementTrackingServiceFactory.cs | 5 + ...stractSmartTokenFormatterCommandHandler.cs | 4 +- .../InfoBar/EditorInfoBarService.cs | 5 + .../AsyncCompletion/CommitManager.cs | 2 +- .../AsyncCompletion/CompletionSource.cs | 9 +- .../AsyncCompletion/RecentItemsManager.cs | 5 + .../QuickInfo/QuickInfoSourceProvider.cs | 5 + .../InteractiveCommandCompletionService.cs | 5 + .../MetadataAsSourceFileService.cs | 1 + .../SymbolMappingServiceFactory.cs | 5 + .../OrganizeDocumentCommandHandler.cs | 47 +- .../Peek/PeekableItemFactory.cs | 2 +- ...enameTrackingCancellationCommandHandler.cs | 5 + .../IBlankLineIndentationService.cs | 23 - .../SmartIndent/IIndentationService.cs | 9 + .../Implementation/SmartIndent/SmartIndent.cs | 34 +- .../SmartIndent/SmartIndentProvider.cs | 5 + .../Implementation/SolutionChangeSummary.cs | 6 +- .../TextBufferAssociatedViewService.cs | 5 + .../TodoComment/TodoCommentOptions.cs | 5 + .../EditorErrorReportingServiceFactory.cs | 5 + .../Workspaces/ProjectCacheServiceFactory.cs | 5 + .../ModernCommands/SortImportsCommandArgs.cs | 21 + .../Core/Options/BraceCompletionOptions.cs | 5 + .../Core/Options/CompletionOptions.cs | 5 + .../Core/Options/ExtensionManagerOptions.cs | 5 + .../Core/Options/NavigationBarOptions.cs | 5 + .../Core/Options/SignatureHelpOptions.cs | 5 + ...DefaultTextBufferSupportsFeatureService.cs | 5 + .../Extensions/SmartIndentExtensions.cs | 4 +- .../Shared/Options/ComponentOnOffOptions.cs | 5 + .../Shared/Options/FeatureOnOffOptions.cs | 10 +- .../Options/InternalFeatureOnOffOptions.cs | 5 + .../PerformanceFunctionIdOptionsProvider.cs | 5 + .../Core/Shared/Preview/PreviewWorkspace.cs | 17 + .../Shared/Utilities/ClassificationTypeMap.cs | 2 +- .../Core/Undo/DefaultSourceTextUndoService.cs | 5 + .../Core/Undo/NoOpGlobalUndoServiceFactory.cs | 5 + .../Core/Wrapping/AbstractWrapper.cs | 6 +- .../AbstractBinaryExpressionWrapper.cs | 5 +- .../AbstractSeparatedSyntaxListWrapper.cs | 4 +- .../DiagnosticDataSerializerTests.cs | 5 + ...ditorConfigDocumentOptionsProviderTests.cs | 5 + .../SolutionCrawler/WorkCoordinatorTests.cs | 31 +- .../Classification/ClassificationTests.vb | 4 + .../Test2/CodeFixes/CodeFixServiceTests.vb | 8 + .../CSharpCompletionCommandHandlerTests.vb | 311 +- ...isualBasicCompletionCommandHandlerTests.vb | 5 + .../TestChangeSignatureOptionsService.cs | 5 + .../AbstractCompletionProviderTests.cs | 1 + .../Diagnostics/AbstractUserDiagnosticTest.cs | 2 +- .../TestGenerateTypeOptionsService.cs | 5 + .../TestProjectManagementService.cs | 5 + .../TestExtractInterfaceOptions.cs | 5 + .../Formatting/CoreFormatterTestsBase.cs | 4 +- .../InProcRemoteHostClientFactory.cs | 10 + .../TestMoveToNamespaceOptionsService.cs | 5 + .../Preview/MockPreviewPaneService.cs | 5 + .../Remote/InProcRemostHostClient.cs | 3 +- .../MockPreviewDialogService.cs | 5 + .../StubVsEditorAdaptersFactoryService.cs | 5 + .../TestExperimentationService.cs | 5 + .../TestUtilities/TestExportProvider.cs | 4 +- .../TestExtensionErrorHandler.cs | 5 + .../TestUtilities/TestObscuringTipManager.cs | 5 + .../TestUtilities/TestWaitIndicator.cs | 1 + .../Workspaces/MefTestWorkspace.cs | 1 + .../NoCompilationLanguageServiceFactory.cs | 5 + ...eActionOperationFactoryWorkspaceService.cs | 5 + ...TestFormattingRuleFactoryServiceFactory.cs | 1 + .../Workspaces/TestHostProject.cs | 37 +- ...eActionOperationFactoryWorkspaceService.cs | 5 + .../TestUtilities/Workspaces/TestWorkspace.cs | 54 +- .../Workspaces/TestWorkspace_Create.cs | 2 + .../TestWorkspace_XmlConsumption.cs | 43 +- .../Intellisense/IntelliSenseTestState.vb | 4 + .../MockDocumentNavigationServiceFactory.vb | 4 + .../MockSymbolNavigationServiceFactory.vb | 4 + .../MockDocumentNavigationServiceProvider.vb | 4 + .../MockSymbolNavigationServiceProvider.vb | 4 + .../AutomaticLineEnderCommandHandler.vb | 2 +- .../InterpolatedStringBraceMatcher.vb | 5 + .../StringLiteralBraceMatcher.vb | 5 + .../VisualBasicDirectiveTriviaBraceMatcher.vb | 5 + ...VisualBasicEmbeddedLanguageBraceMatcher.vb | 5 + ...isualBasicChangeSignatureCommandHandler.vb | 4 + ...cEmbeddedLanguageEditorFeaturesProvider.vb | 1 + .../SmartTokenFormatterCommandHandler.vb | 6 +- .../GoToBase/VisualBasicGoToBaseService.vb | 4 + .../VisualBasicGoToDefinitionSymbolService.vb | 4 + .../AccessorDeclarationHighlighter.vb | 5 + .../ConditionalPreprocessorHighlighter.vb | 5 + .../ConstructorDeclarationHighlighter.vb | 5 + .../DoLoopBlockHighlighter.vb | 5 + .../EnumBlockHighlighter.vb | 5 + .../EventBlockHighlighter.vb | 5 + .../EventDeclarationHighlighter.vb | 5 + .../ForLoopBlockHighlighter.vb | 5 + .../MethodDeclarationHighlighter.vb | 5 + .../MultiLineIfBlockHighlighter.vb | 5 + .../MultiLineLambdaExpressionHighlighter.vb | 5 + .../NamespaceBlockHighlighter.vb | 5 + .../OperatorDeclarationHighlighter.vb | 5 + .../PropertyBlockHighlighter.vb | 5 + .../PropertyDeclarationHighlighter.vb | 5 + .../KeywordHighlighters/RegionHighlighter.vb | 5 + .../SelectBlockHighlighter.vb | 5 + .../SingleLineIfBlockHighlighter.vb | 5 + .../SyncLockBlockHighlighter.vb | 5 + .../TryBlockHighlighter.vb | 5 + .../TypeBlockHighlighter.vb | 5 + .../UsingBlockHighlighter.vb | 5 + .../WhileBlockHighlighter.vb | 5 + .../WithBlockHighlighter.vb | 5 + .../XmlCDataHighlighter.vb | 5 + .../XmlCommentHighlighter.vb | 5 + .../XmlDocumentPrologueHighlighter.vb | 5 + .../XmlElementHighlighter.vb | 5 + .../XmlEmbeddedExpressionHighlighter.vb | 5 + .../XmlProcessingInstructionHighlighter.vb | 5 + .../LineCommit/CommitCommandHandler.vb | 2 +- .../VisualBasic/LineCommit/CommitFormatter.vb | 4 + .../VisualBasicLineSeparatorService.vb | 4 + ...RenameTrackingLanguageHeuristicsService.vb | 4 + .../TextStructureNavigatorProvider.vb | 2 +- .../VisualBasicBinaryExpressionWrapper.vb | 2 +- ...ctVisualBasicSeparatedSyntaxListWrapper.vb | 2 +- ...ualBasicWrappingCodeRefactoringProvider.vb | 1 + .../DiagnosticAnalyzerDriverTests.vb | 2 +- .../GenerateVariable/GenerateVariableTests.vb | 149 +- .../DisposableFieldsShouldBeDisposedTests.vb | 1255 ++ .../DisposeObjectsBeforeLosingScopeTests.vb | 2830 +++++ .../SmartTokenFormatter_FormatTokenTests.vb | 3 +- .../Debugger/Engine/DkmException.cs | 1 + ...ddAccessibilityModifiersCodeFixProvider.cs | 5 + ...dAnonymousTypeMemberNameCodeFixProvider.cs | 5 + .../CSharpAddBracesCodeFixProvider.cs | 5 + ...arpAddFileBannerCodeRefactoringProvider.cs | 5 + .../CSharpAddImportCodeFixProvider.cs | 1 + .../CSharpAddImportFeatureService.cs | 5 + .../CSharpAddMissingImportsFeatureService.cs | 5 + ...SharpAddMissingReferenceCodeFixProvider.cs | 1 + ...harpAddObsoleteAttributeCodeFixProvider.cs | 1 + ...CSharpAddSpecificPackageCodeFixProvider.cs | 5 + .../CSharpAddParameterCodeFixProvider.cs | 5 + ...CSharpAliasAmbiguousTypeCodeFixProvider.cs | 5 + .../CSharpFeaturesResources.Designer.cs | 29 +- .../Portable/CSharpFeaturesResources.resx | 9 + .../CSharpChangeSignatureService.cs | 5 + .../Async/CSharpAddAwaitCodeFixProvider.cs | 5 + ...harpConvertToAsyncMethodCodeFixProvider.cs | 5 + ...sionInInterpolatedStringCodeFixProvider.cs | 5 + .../CSharpFixReturnTypeCodeFixProvider.cs | 1 + .../GenerateEnumMemberCodeFixProvider.cs | 5 + .../GenerateConversionCodeFixProvider.cs | 5 + ...enerateDeconstructMethodCodeFixProvider.cs | 5 + .../GenerateMethodCodeFixProvider.cs | 5 + .../GenerateTypeCodeFixProvider.cs | 5 + .../HideBase/HideBaseCodeFixProvider.cs | 5 + .../Iterator/CSharpAddYieldCodeFixProvider.cs | 5 + ...SharpChangeToIEnumerableCodeFixProvider.cs | 5 + ...akeStatementAsynchronousCodeFixProvider.cs | 5 + .../CSharpDeclareAsNullableCodeFixProvider.cs | 5 + .../RemoveUnnecessaryCastCodeFixProvider.cs | 5 + .../CSharpSuppressionCodeFixProvider.cs | 5 + ...terpolatedVerbatimStringCodeFixProvider.cs | 5 + .../CSharpCodeLensDisplayInfoService.cs | 5 + .../AddAwaitCodeRefactoringProvider.cs | 5 + ...FunctionToMethodCodeRefactoringProvider.cs | 5 + .../InlineTemporaryCodeRefactoringProvider.cs | 5 + .../MoveType/CSharpMoveTypeService.cs | 4 + .../CSharpChangeNamespaceService.cs | 5 + ...arpSyncNamespaceCodeRefactoringProvider.cs | 5 + .../UseExplicitTypeCodeRefactoringProvider.cs | 5 + .../UseImplicitTypeCodeRefactoringProvider.cs | 5 + .../CSharpCommentSelectionService.cs | 5 + .../Completion/CSharpCompletionService.cs | 5 + .../PropertySubPatternCompletionProvider.cs | 2 +- .../CSharpSuggestionModeCompletionProvider.cs | 11 - ...arpResolveConflictMarkerCodeFixProvider.cs | 1 + ...ymousTypeToClassCodeRefactoringProvider.cs | 5 + ...vertAnonymousTypeToTupleCodeFixProvider.cs | 5 + ...tyToFullPropertyCodeRefactoringProvider.cs | 5 + ...vertForEachToForCodeRefactoringProvider.cs | 5 + ...vertForToForEachCodeRefactoringProvider.cs | 5 + ...onvertIfToSwitchCodeRefactoringProvider.cs | 5 + ...CSharpConvertLinqQueryToForEachProvider.cs | 5 + ...CSharpConvertForEachToLinqQueryProvider.cs | 5 + ...rtNumericLiteralCodeRefactoringProvider.cs | 5 + ...entToExpressionCodeFixProvider.Rewriter.cs | 282 + ...tchStatementToExpressionCodeFixProvider.cs | 91 + ...ertSwitchStatementToExpressionConstants.cs | 11 + ...ToExpressionDiagnosticAnalyzer.Analyzer.cs | 192 + ...StatementToExpressionDiagnosticAnalyzer.cs | 79 + ...ToInterpolatedStringRefactoringProvider.cs | 5 + ...ToInterpolatedStringRefactoringProvider.cs | 5 + ...ertTupleToStructCodeRefactoringProvider.cs | 5 + .../CSharpDesignerAttributeService.cs | 5 + .../CSharpAnalyzerDriverService.cs | 5 + .../CSharpDocumentHighlightsService.cs | 5 + ...rpDocumentationCommentFormattingService.cs | 4 + ...CSharpAddDocCommentNodesCodeFixProvider.cs | 5 + ...harpRemoveDocCommentNodeCodeFixProvider.cs | 5 + .../EditAndContinue/BreakpointSpans.cs | 2 +- .../CSharpEditAndContinueAnalyzer.cs | 4 + .../CSharpEmbeddedLanguageFeaturesProvider.cs | 1 + .../CSharpEncapsulateFieldService.cs | 5 + .../CSharpExtractInterfaceService.cs | 5 + .../CSharpSyntaxTriviaServiceFactory.cs | 5 + .../CSharpFullyQualifyCodeFixProvider.cs | 5 + .../CSharpGenerateConstructorService.cs | 5 + .../GenerateConstructorCodeFixProvider.cs | 5 + ...harpGenerateEqualsAndGetHashCodeService.cs | 5 + ...SharpGenerateDefaultConstructorsService.cs | 5 + .../CSharpGenerateEnumMemberService.cs | 5 + .../CSharpGenerateConversionService.cs | 5 + .../CSharpGenerateDeconstructMethodService.cs | 5 + .../CSharpGenerateMethodService.cs | 5 + .../CSharpGenerateVariableService.cs | 5 + .../GenerateType/CSharpGenerateTypeService.cs | 5 + .../CSharpGenerateVariableCodeFixProvider.cs | 5 + ...rpImplementAbstractClassCodeFixProvider.cs | 1 + .../CSharpImplementAbstractClassService.cs | 5 + ...CSharpImplementInterfaceCodeFixProvider.cs | 5 + .../CSharpImplementInterfaceService.cs | 5 + ...ddParameterCheckCodeRefactoringProvider.cs | 5 + ...berFromParameterCodeRefactoringProvider.cs | 5 + .../CSharpInlineDeclarationCodeFixProvider.cs | 5 + ...ceUsingStatementCodeRefactoringProvider.cs | 5 + .../CSharpIntroduceVariableService.cs | 5 + ...nvertConditionalCodeRefactoringProvider.cs | 5 + .../CSharpInvertIfCodeRefactoringProvider.cs | 5 + ...arpInvertLogicalCodeRefactoringProvider.cs | 5 + ...ateWithConditionalAccessCodeFixProvider.cs | 5 + .../CSharpAnonymousTypeDisplayService.cs | 5 + .../CSharpSymbolDisplayServiceFactory.cs | 5 + .../CSharpMakeFieldReadonlyCodeFixProvider.cs | 5 + .../MakeLocalFunctionStaticCodeFixProvider.cs | 5 + ...rpMakeMethodAsynchronousCodeFixProvider.cs | 5 + ...arpMakeMethodSynchronousCodeFixProvider.cs | 5 + .../MakeRefStructCodeFixProvider.cs | 5 + ...MakeStructFieldsWritableCodeFixProvider.cs | 5 + .../CSharpMetadataAsSourceServiceFactory.cs | 5 + ...harpMoveDeclarationNearReferenceService.cs | 5 + .../CSharpMoveToNamespaceService.cs | 5 + ...NameTupleElementCodeRefactoringProvider.cs | 5 + .../CSharpNavigateToSearchService.cs | 4 + .../CSharpOrderModifiersCodeFixProvider.cs | 1 + .../CSharpOrganizeImportsService.cs | 8 + .../Organizers/ClassDeclarationOrganizer.cs | 5 + .../ConstructorDeclarationOrganizer.cs | 5 + .../DestructorDeclarationOrganizer.cs | 5 + .../Organizers/EnumDeclarationOrganizer.cs | 5 + .../Organizers/EventDeclarationOrganizer.cs | 8 +- .../EventFieldDeclarationOrganizer.cs | 5 + .../Organizers/FieldDeclarationOrganizer.cs | 5 + .../Organizers/IndexerDeclarationOrganizer.cs | 5 + .../InterfaceDeclarationOrganizer.cs | 5 + .../Organizers/MethodDeclarationOrganizer.cs | 5 + .../OperatorDeclarationOrganizer.cs | 5 + .../PropertyDeclarationOrganizer.cs | 5 + .../Organizers/StructDeclarationOrganizer.cs | 5 + ...SharpQualifyMemberAccessCodeFixProvider.cs | 5 + .../QuickInfo/CSharpQuickInfoSevice.cs | 5 + .../CSharpSemanticQuickInfoProvider.cs | 5 + .../CSharpSyntacticQuickInfoProvider.cs | 5 + ...RemoveUnnecessaryImportsCodeFixProvider.cs | 5 + .../CSharpRemoveUnnecessaryImportsService.cs | 4 + .../CSharpUnnecessaryImportsService.cs | 4 + ...veUnnecessaryParenthesesCodeFixProvider.cs | 5 + ...arpRemoveUnreachableCodeCodeFixProvider.cs | 5 + ...emoveUnusedLocalFunctionCodeFixProvider.cs | 5 + ...SharpRemoveUnusedMembersCodeFixProvider.cs | 5 + ...CSharpRemoveUnusedValuesCodeFixProvider.cs | 5 + ...harpRemoveUnusedVariableCodeFixProvider.cs | 5 + ...arpReplaceDefaultLiteralCodeFixProvider.cs | 5 + ...scardDeclarationsWithAssignmentsService.cs | 5 + ...mmentTextWithTagCodeRefactoringProvider.cs | 5 + .../CSharpReplaceMethodWithPropertyService.cs | 5 + ...CSharpReplacePropertyWithMethodsService.cs | 5 + .../AttributeSignatureHelpProvider.cs | 5 + ...tructorInitializerSignatureHelpProvider.cs | 5 + ...ntAccessExpressionSignatureHelpProvider.cs | 5 + ...mePartiallyWrittenSignatureHelpProvider.cs | 5 + .../GenericNameSignatureHelpProvider.cs | 5 + ...vocationExpressionSignatureHelpProvider.cs | 5 + ...CreationExpressionSignatureHelpProvider.cs | 5 + .../TupleConstructionSignatureHelpProvider.cs | 5 + .../CSharpSimplifyThisOrMeCodeFixProvider.cs | 5 + .../SimplifyTypeNamesCodeFixProvider.cs | 1 + .../CSharpDocumentDifferenceService.cs | 4 + .../CSharpSpellcheckCodeFixProvider.cs | 5 + .../CSharpIfLikeStatementGenerator.cs | 5 + ...tiveIfStatementsCodeRefactoringProvider.cs | 5 + ...stedIfStatementsCodeRefactoringProvider.cs | 5 + ...tiveIfStatementsCodeRefactoringProvider.cs | 4 + ...stedIfStatementsCodeRefactoringProvider.cs | 4 + .../Structure/CSharpBlockStructureService.cs | 5 + .../EventDeclarationStructureProvider.cs | 3 +- ...pTodoCommentIncrementalAnalyzerProvider.cs | 5 + .../UseExplicitTypeCodeFixProvider.cs | 5 + .../UseImplicitTypeCodeFixProvider.cs | 5 + .../CSharpUnsealClassCodeFixProvider.cs | 5 + ...dateProjectToAllowUnsafeCodeFixProvider.cs | 5 + .../CSharpUpgradeProjectCodeFixProvider.cs | 5 + .../CSharpUseAutoPropertyCodeFixProvider.cs | 5 + ...UseCollectionInitializerCodeFixProvider.cs | 5 + ...arpUseCompoundAssignmentCodeFixProvider.cs | 1 + ...ionForAssignmentCodeRefactoringProvider.cs | 5 + ...ressionForReturnCodeRefactoringProvider.cs | 5 + .../CSharpUseDeconstructionCodeFixProvider.cs | 5 + .../CSharpUseDefaultLiteralCodeFixProvider.cs | 5 + .../UseExplicitTypeForConstCodeFixProvider.cs | 5 + .../UseExpressionBodyCodeFixProvider.cs | 1 + ...seExpressionBodyCodeRefactoringProvider.cs | 1 + ...eExpressionBodyForLambdaCodeFixProvider.cs | 5 + ...ionBodyForLambdaCodeRefactoringProvider.cs | 1 + .../CSharpUseIndexOperatorCodeFixProvider.cs | 5 + .../CSharpUseRangeOperatorCodeFixProvider.cs | 5 + ...arpUseInferredMemberNameCodeFixProvider.cs | 5 + ...rCastAndEqualityOperatorCodeFixProvider.cs | 16 +- ...lCheckForReferenceEqualsCodeFixProvider.cs | 28 +- .../CSharpUseLocalFunctionCodeFixProvider.cs | 5 + ...seNamedArgumentsCodeRefactoringProvider.cs | 1 + ...CSharpUseNullPropagationCodeFixProvider.cs | 4 + ...harpUseObjectInitializerCodeFixProvider.cs | 5 + .../CSharpAsAndNullCheckCodeFixProvider.cs | 5 + .../CSharpIsAndCastCheckCodeFixProvider.cs | 5 + ...sAndCastCheckWithoutNameCodeFixProvider.cs | 1 + .../UseSimpleUsingStatementCodeFixProvider.cs | 5 + ...eSimpleUsingStatementDiagnosticAnalyzer.cs | 48 +- .../xlf/CSharpFeaturesResources.cs.xlf | 15 + .../xlf/CSharpFeaturesResources.de.xlf | 15 + .../xlf/CSharpFeaturesResources.es.xlf | 15 + .../xlf/CSharpFeaturesResources.fr.xlf | 15 + .../xlf/CSharpFeaturesResources.it.xlf | 15 + .../xlf/CSharpFeaturesResources.ja.xlf | 15 + .../xlf/CSharpFeaturesResources.ko.xlf | 15 + .../xlf/CSharpFeaturesResources.pl.xlf | 15 + .../xlf/CSharpFeaturesResources.pt-BR.xlf | 15 + .../xlf/CSharpFeaturesResources.ru.xlf | 15 + .../xlf/CSharpFeaturesResources.tr.xlf | 15 + .../xlf/CSharpFeaturesResources.zh-Hans.xlf | 15 + .../xlf/CSharpFeaturesResources.zh-Hant.xlf | 15 + ...etersFromMembersCodeRefactoringProvider.cs | 5 + .../AbstractAddParameterCodeFixProvider.cs | 310 +- .../AddParameter/AddParameterService.cs | 329 + .../AddParameter/IAddParameterService.cs | 29 + .../AddRequiredParenthesesCodeFixProvider.cs | 5 + ...tChangeSignatureCodeRefactoringProvider.cs | 5 + .../NamingStyle/NamingStyleCodeFixProvider.cs | 5 + .../CodeLensReferencesServiceFactory.cs | 5 + .../AbstractCodeQualityDiagnosticAnalyzer.cs | 2 + ...actExtractMethodCodeRefactoringProvider.cs | 5 + .../MoveTypeCodeRefactoringProvider.cs | 5 + .../ServicesLayerCodeActionHelpersService.cs | 5 + .../CompletionHelperServiceFactory.cs | 5 + .../Completion/CompletionOptionsProvider.cs | 5 + ...mendationServiceBasedCompletionProvider.cs | 6 +- .../AbstractSymbolCompletionProvider.cs | 14 +- .../Providers/TypeImportCompletionService.cs | 5 + .../Diagnostics/Analyzers/IDEDiagnosticIds.cs | 6 + .../InternalDiagnosticsOptionsProvider.cs | 5 + ...ieldsShouldBeDisposedDiagnosticAnalyzer.cs | 275 + .../DisposeAnalysis/DisposeAnalysisHelper.cs | 322 + ...ectsBeforeLosingScopeDiagnosticAnalyzer.cs | 219 + .../EncapsulateFieldRefactoringProvider.cs | 5 + ...ExtractInterfaceCodeRefactoringProvider.cs | 5 + .../ExtractMethodOptionsProvider.cs | 5 + .../Portable/FeaturesResources.Designer.cs | 91 + .../Core/Portable/FeaturesResources.resx | 31 + .../Formatting/FormattingCodeFixProvider.cs | 5 + ...uctorFromMembersCodeRefactoringProvider.cs | 1 + ...aultConstructorsCodeRefactoringProvider.cs | 5 + ...hCodeFromMembersCodeRefactoringProvider.cs | 1 + ...ableService.GenerateParameterCodeAction.cs | 53 + .../AbstractGenerateVariableService.State.cs | 10 + .../AbstractGenerateVariableService.cs | 35 +- ...enerateOverridesCodeRefactoringProvider.cs | 1 + .../ImplementTypeOptionsProvider.cs | 5 + ...mbolTreeInfoIncrementalAnalyzerProvider.cs | 5 + ...ntaxTreeInfoIncrementalAnalyzerProvider.cs | 5 + ...ntroduceVariableCodeRefactoringProvider.cs | 5 + .../Microsoft.CodeAnalysis.Features.csproj | 1 + ...ionNearReferenceCodeRefactoringProvider.cs | 5 + .../MoveToNamespaceCodeActionProvider.cs | 5 + ...DefaultDocumentNavigationServiceFactory.cs | 5 + .../DefaultSymbolNavigationServiceFactory.cs | 5 + .../Navigation/NavigationOptionsProvider.cs | 5 + .../SemanticChangeNotificationService.cs | 5 + .../IOrganizeImportsService.cs | 2 + .../PopulateSwitchCodeFixProvider.cs | 5 + .../PreferFrameworkTypeCodeFixProvider.cs | 5 + .../Portable/PullMemberUp/MembersPuller.cs | 20 +- ...thodWithPropertyCodeRefactoringProvider.cs | 5 + ...pertyWithMethodsCodeRefactoringProvider.cs | 5 + .../Shared/IDocumentSupportsFeatureService.cs | 5 + .../ServiceComponentOnOffOptionsProvider.cs | 5 + .../ServiceFeatureOnOffOptionsProvider.cs | 5 + .../InternalSolutionCrawlerOptionsProvider.cs | 5 + .../SolutionCrawler/SolutionCrawlerService.cs | 5 + .../SymbolMappingServiceFactory.cs | 5 + .../UseCoalesceExpressionCodeFixProvider.cs | 5 + ...sceExpressionForNullableCodeFixProvider.cs | 5 + .../UseExplicitTupleNameCodeFixProvider.cs | 5 + ...IsNullForReferenceEqualsCodeFixProvider.cs | 4 +- .../UseThrowExpressionCodeFixProvider.cs | 5 + .../ValidateFormatStringOption.cs | 5 + .../Portable/xlf/FeaturesResources.cs.xlf | 50 + .../Portable/xlf/FeaturesResources.de.xlf | 50 + .../Portable/xlf/FeaturesResources.es.xlf | 50 + .../Portable/xlf/FeaturesResources.fr.xlf | 50 + .../Portable/xlf/FeaturesResources.it.xlf | 50 + .../Portable/xlf/FeaturesResources.ja.xlf | 50 + .../Portable/xlf/FeaturesResources.ko.xlf | 50 + .../Portable/xlf/FeaturesResources.pl.xlf | 50 + .../Portable/xlf/FeaturesResources.pt-BR.xlf | 50 + .../Portable/xlf/FeaturesResources.ru.xlf | 50 + .../Portable/xlf/FeaturesResources.tr.xlf | 50 + .../xlf/FeaturesResources.zh-Hans.xlf | 50 + .../xlf/FeaturesResources.zh-Hant.xlf | 50 + ...ddAccessibilityModifiersCodeFixProvider.vb | 4 + ...dAnonymousTypeMemberNameCodeFixProvider.vb | 4 + ...sicAddFileBannerCodeRefactoringProvider.vb | 4 + .../VisualBasicAddImportCodeFixProvider.vb | 1 + .../VisualBasicAddImportFeatureService.vb | 4 + ...ualBasicAddMissingImportsFeatureService.vb | 4 + ...asicAddObsoleteAttributeCodeFixProvider.vb | 1 + ...lBasicAddSpecificPackageCodeFixProvider.vb | 4 + .../VisualBasicAddParameterCodeFixProvider.vb | 4 + ...lBasicAliasAmbiguousTypeCodeFixProvider.vb | 4 + .../VisualBasicChangeSignatureService.vb | 4 + ...BasicAddMissingReferenceCodeFixProvider.vb | 1 + .../VisualBasicAddAwaitCodeFixProvider.vb | 4 + ...icConvertToAsyncFunctionCodeFixProvider.vb | 4 + ...rrectNextControlVariableCodeFixProvider.vb | 4 + .../GenerateEndConstructCodeFixProvider.vb | 4 + .../GenerateEnumMemberCodeFixProvider.vb | 4 + .../GenerateEventCodeFixProvider.vb | 4 + .../GenerateConversionCodeFixProvider.vb | 4 + ...erateParameterizedMemberCodeFixProvider.vb | 4 + .../GenerateTypeCodeFixProvider.vb | 4 + .../IncorrectExitContinueCodeFixProvider.vb | 4 + ...orrectFunctionReturnTypeCodeFixProvider.vb | 4 + .../InsertMissingCastCodeFixProvider.vb | 4 + ...VisualBasicChangeToYieldCodeFixProvider.vb | 4 + ...alBasicConvertToIteratorCodeFixProvider.vb | 4 + .../MoveToTopOfFileCodeFixProvider.vb | 4 + .../OverloadBaseCodeFixProvider.vb | 4 + .../RemoveUnnecessaryCastCodeFixProvider.vb | 4 + .../VisualBasicSuppressionCodeFixProvider.vb | 4 + .../CodeLens/VisualBasicDisplayInfoService.vb | 4 + .../AddAwaitCodeRefactoringProvider.vb | 4 + .../InlineTemporaryCodeRefactoringProvider.vb | 4 + .../MoveType/VisualBasicMoveTypeService.vb | 3 + .../VisualBasicChangeNamespaceService.vb | 4 + .../VisualBasicCommentSelectionService.vb | 4 + .../VisualBasicCompletionService.vb | 4 + ...sicResolveConflictMarkerCodeFixProvider.vb | 1 + ...ymousTypeToClassCodeRefactoringProvider.vb | 4 + ...vertAnonymousTypeToTupleCodeFixProvider.vb | 4 + ...lBasicConvertAutoPropertyToFullProperty.vb | 4 + ...vertForEachToForCodeRefactoringProvider.vb | 4 + ...vertForToForEachCodeRefactoringProvider.vb | 4 + ...onvertIfToSwitchCodeRefactoringProvider.vb | 4 + ...rtNumericLiteralCodeRefactoringProvider.vb | 4 + ...ToInterpolatedStringRefactoringProvider.vb | 4 + ...ToInterpolatedStringRefactoringProvider.vb | 4 + ...ertTupleToStructCodeRefactoringProvider.vb | 4 + .../BasicDesignerAttributeService.vb | 4 + .../VisualBasicAnalyzerDriverService.vb | 4 + .../VisualBasicDocumentHighlightsService.vb | 3 + ...asicRemoveDocCommentNodeCodeFixProvider.vb | 4 + ...icDocumentationCommentFormattingService.vb | 3 + .../VisualBasicEditAndContinueAnalyzer.vb | 4 + ...alBasicEmbeddedLanguageFeaturesProvider.vb | 1 + .../VisualBasicEncapsulateFieldService.vb | 4 + .../VisualBasicExtractInterfaceService.vb | 4 + .../VisualBasicExtractMethodService.vb | 4 + .../VisualBasicSyntaxTriviaServiceFactory.vb | 4 + .../VisualBasicFullyQualifyCodeFixProvider.vb | 4 + .../GenerateConstructorCodeFixProvider.vb | 4 + .../VisualBasicGenerateConstructorService.vb | 4 + ...BasicGenericEqualsAndGetHashCodeService.vb | 4 + ...BasicGenerateDefaultConstructorsService.vb | 4 + .../VisualBasicGenerateEnumMemberService.vb | 4 + .../VisualBasicGenerateConversionService.vb | 4 + .../VisualBasicGenerateMethodService.vb | 4 + .../VisualBasicGenerateVariableService.vb | 4 + .../VisualBasicGenerateTypeService.vb | 4 + ...ualBasicGenerateVariableCodeFixProvider.vb | 4 + ...icImplementAbstractClassCodeFixProvider.vb | 1 + ...isualBasicImplementAbstractClassService.vb | 4 + ...lBasicImplementInterfaceCodeFixProvider.vb | 4 + .../VisualBasicImplementInterfaceService.vb | 4 + ...ddParameterCheckCodeRefactoringProvider.vb | 4 + ...berFromParameterCodeRefactoringProvider.vb | 4 + ...ceUsingStatementCodeRefactoringProvider.vb | 4 + .../VisualBasicIntroduceVariableService.vb | 4 + ...nvertConditionalCodeRefactoringProvider.vb | 4 + ...vertIfCodeRefactoringProvider.MultiLine.vb | 4 + ...ertIfCodeRefactoringProvider.SingleLine.vb | 4 + ...sicInvertLogicalCodeRefactoringProvider.vb | 4 + .../VisualBasicAnonymousTypeDisplayService.vb | 4 + .../VisualBasicSymbolDisplayServiceFactory.vb | 4 + ...alBasicMakeFieldReadonlyCodeFixProvider.vb | 4 + ...icMakeMethodAsynchronousCodeFixProvider.vb | 4 + ...sicMakeMethodSynchronousCodeFixProvider.vb | 4 + ...sualBasicMetadataAsSourceServiceFactory.vb | 4 + ...asicMoveDeclarationNearReferenceService.vb | 4 + ...NameTupleElementCodeRefactoringProvider.vb | 4 + .../VisualBasicNavigateToSearchService.vb | 4 + ...isualBasicOrderModifiersCodeFixProvider.vb | 1 + .../VisualBasicOrganizeImportsService.vb | 10 + .../Organizers/TypeBlockOrganizer.vb | 4 + ...BasicQualifyMemberAccessCodeFixProvider.vb | 4 + .../QuickInfo/VisualBasicQuickInfoService.vb | 4 + .../VisualBasicSemanticQuickInfoProvider.vb | 4 + ...RemoveUnnecessaryImportsCodeFixProvider.vb | 4 + ...ualBasicRemoveUnnecessaryImportsService.vb | 3 + .../VisualBasicUnnecessaryImportsService.vb | 3 + ...veUnnecessaryParenthesesCodeFixProvider.vb | 4 + ...BasicRemoveUnusedMembersCodeFixProvider.vb | 4 + ...lBasicRemoveUnusedValuesCodeFixProvider.vb | 4 + ...asicRemoveUnusedVariableCodeFixProvider.vb | 4 + ...mmentTextWithTagCodeRefactoringProvider.vb | 4 + ...alBasicReplaceMethodWithPropertyService.vb | 4 + .../VisualBasicReplacePropertyWithMethods.vb | 4 + .../AddRemoveHandlerSignatureHelpProvider.vb | 4 + .../AttributeSignatureHelpProvider.vb | 4 + .../CastExpressionSignatureHelpProvider.vb | 4 + ...ditionalExpressionSignatureHelpProvider.vb | 8 + ...unctionAggregationSignatureHelpProvider.vb | 4 + .../GenericNameSignatureHelpProvider.vb | 4 + .../GetTypeExpressionSignatureHelpProvider.vb | 4 + ...amespaceExpressionSignatureHelpProvider.vb | 4 + ...vocationExpressionSignatureHelpProvider.vb | 4 + .../MidAssignmentSignatureHelpProvider.vb | 4 + .../NameOfExpressionSignatureHelpProvider.vb | 4 + ...CreationExpressionSignatureHelpProvider.vb | 4 + ...inedCastExpressionSignatureHelpProvider.vb | 4 + ...aiseEventStatementSignatureHelpProvider.vb | 4 + ...ualBasicSimplifyThisOrMeCodeFixProvider.vb | 4 + .../SimplifyTypeNamesCodeFixProvider.vb | 1 + .../VisualBasicDocumentDifferenceService.vb | 3 + .../VisualBasicSpellCheckCodeFixProvider.vb | 4 + .../VisualBasicIfLikeStatementGenerator.vb | 4 + ...tiveIfStatementsCodeRefactoringProvider.vb | 4 + ...stedIfStatementsCodeRefactoringProvider.vb | 4 + ...tiveIfStatementsCodeRefactoringProvider.vb | 4 + ...stedIfStatementsCodeRefactoringProvider.vb | 4 + .../VisualBasicBlockStructureProvider.vb | 4 + ...cTodoCommentIncrementalAnalyzerProvider.vb | 4 + .../VisualBasicUnsealClassCodeFixProvider.vb | 4 + ...sualBasicUseAutoPropertyCodeFixProvider.vb | 4 + ...UseCollectionInitializerCodeFixProvider.vb | 4 + ...sicUseCompoundAssignmentCodeFixProvider.vb | 1 + ...ionForAssignmentCodeRefactoringProvider.vb | 4 + ...ressionForReturnCodeRefactoringProvider.vb | 4 + ...sicUseInferredMemberNameCodeFixProvider.vb | 4 + ...lCheckForReferenceEqualsCodeFixProvider.vb | 6 +- ...seNamedArgumentsCodeRefactoringProvider.vb | 1 + ...lBasicUseNullPropagationCodeFixProvider.vb | 3 + ...asicUseObjectInitializerCodeFixProvider.vb | 4 + .../Portable/VBFeaturesResources.Designer.vb | 11 +- .../Portable/VBFeaturesResources.resx | 3 + .../Portable/xlf/VBFeaturesResources.cs.xlf | 5 + .../Portable/xlf/VBFeaturesResources.de.xlf | 5 + .../Portable/xlf/VBFeaturesResources.es.xlf | 5 + .../Portable/xlf/VBFeaturesResources.fr.xlf | 5 + .../Portable/xlf/VBFeaturesResources.it.xlf | 5 + .../Portable/xlf/VBFeaturesResources.ja.xlf | 5 + .../Portable/xlf/VBFeaturesResources.ko.xlf | 361 +- .../Portable/xlf/VBFeaturesResources.pl.xlf | 5 + .../xlf/VBFeaturesResources.pt-BR.xlf | 5 + .../Portable/xlf/VBFeaturesResources.ru.xlf | 5 + .../Portable/xlf/VBFeaturesResources.tr.xlf | 5 + .../xlf/VBFeaturesResources.zh-Hans.xlf | 5 + .../xlf/VBFeaturesResources.zh-Hant.xlf | 5 + .../HostTest/InteractiveHostTests.cs | 4 +- .../VS.ExternalAPIs.Roslyn.Package.csproj | 1 + src/Scripting/CSharpTest.Desktop/CsiTests.cs | 2 +- .../CSharpTest/CommandLineRunnerTests.cs | 14 +- .../ObjectFormatter/CommonObjectFormatter.cs | 5 +- .../DevDivInsertionFiles.csproj | 9 +- .../Portable/Compilation/Exceptions.cs | 14 + .../Diagnostics/DiagnosticDescription.cs | 1 + .../Diagnostics/ThrowingDiagnosticAnalyzer.cs | 11 + .../Portable/Roslyn.Test.Utilities.csproj | 1 + src/Test/Utilities/Portable/Traits/Traits.cs | 2 + ...ronousOperationListenerProviderAccessor.cs | 27 + ...ronousOperationListenerProviderAccessor.cs | 12 + ...ft.CodeAnalysis.ExternalAccess.Apex.csproj | 1 + .../FSharpSynchronousIndentationService.cs | 17 +- ....CodeAnalysis.ExternalAccess.FSharp.csproj | 1 + ...lysis.ExternalAccess.Xamarin.Remote.csproj | 4 + .../CSharp/Impl/CSharpVSResources.Designer.cs | 9 + .../CSharp/Impl/CSharpVSResources.resx | 3 + ...pCodeModelNavigationPointServiceFactory.cs | 6 +- .../CSharpCodeModelServiceFactory.cs | 2 +- .../CSharpBreakpointResolutionService.cs | 5 + .../CSharpLanguageDebugInfoService.cs | 5 + .../CSharpProximityExpressionsService.cs | 5 + .../EventHookup/EventHookupSessionManager.cs | 2 +- .../CSharpHelpContextService.cs | 5 + .../ObjectBrowser/CSharpLibraryService.cs | 1 + .../CSharpSyncClassViewCommandHandler.cs | 2 +- .../CSharp/Impl/Options/AutomationObject.cs | 6 + .../FormattingOptionPageControl.xaml.cs | 3 +- .../Impl/Options/Formatting/StyleViewModel.cs | 31 + .../CSharpProgressionLanguageService.cs | 5 + .../CSharpEntryPointFinderService.cs | 5 + .../CSharpProjectShim.ICSInputSet.cs | 7 +- ...CSharpCompilationOptionsChangingService.cs | 5 + .../CSharpParseOptionsChangingService.cs | 5 + ...AdditionalFormattingRuleLanguageService.cs | 5 + .../CSharp/Impl/xlf/CSharpVSResources.cs.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.de.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.es.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.fr.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.it.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.ja.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.ko.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.pl.xlf | 5 + .../Impl/xlf/CSharpVSResources.pt-BR.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.ru.xlf | 5 + .../CSharp/Impl/xlf/CSharpVSResources.tr.xlf | 5 + .../Impl/xlf/CSharpVSResources.zh-Hans.xlf | 5 + .../Impl/xlf/CSharpVSResources.zh-Hant.xlf | 5 + .../CSharp/Test/Watson/WatsonTests.cs | 4 +- src/VisualStudio/Core/Def/Commands.vsct | 14 + .../Experimentation/ExperimentationOptions.cs | 5 + .../Core/Def/HACK_ThemeColorFixer.cs | 2 +- .../Core/Def/ID.CSharpCommands.cs | 1 + .../RemoteCodeLensReferencesService.cs | 5 + .../Def/Implementation/CommandBindings.cs | 4 + .../ContainedLanguageRefactorNotifyService.cs | 5 + .../DebuggeeModuleMetadataProvider.cs | 1 + .../VisualStudioActiveStatementProvider.cs | 5 + .../EnhancedColorExperiment.cs | 2 +- ...encesTableControlEventProcessorProvider.cs | 5 + .../FindReferences/FindUsagesOptions.cs | 5 + ...indUsagesValueUsageInfoColumnDefinition.cs | 5 + ...StudioGenerateTypeOptionsServiceFactory.cs | 5 + .../Def/Implementation/Log/LoggerOptions.cs | 5 + .../Log/VisualStudioErrorLogger.cs | 5 + ...sualStudioMoveToNamespaceOptionsService.cs | 5 + ...alStudioNavigateToPreviewServiceFactory.cs | 5 + .../Def/Implementation/Preview/FileChange.cs | 3 +- .../Implementation/Preview/PreviewEngine.cs | 9 + .../PreviewUpdater.PreviewDialogWorkspace.cs | 48 +- .../Preview/Tagging/PreviewTaggerProvider.cs | 5 + .../Implementation/Preview/TopLevelChange.cs | 54 +- .../DefaultProjectInfoServiceFactory.cs | 5 + .../Legacy/SolutionEventsBatchScopeCreator.cs | 1 + ...sualStudioAnalyzerAssemblyLoaderService.cs | 5 + ...MetadataReferenceProviderServiceFactory.cs | 5 + ...cellaneousFilesScriptEnvironmentService.cs | 5 + .../ProjectSystem/VisualStudioProject.cs | 5 + .../ProjectSystem/VisualStudioWorkspace.cs | 7 +- ...eImpl.AddAnalyzerConfigDocumentUndoUnit.cs | 24 + ...sualStudioWorkspaceImpl.OpenFileTracker.cs | 8 +- ...pl.RemoveAnalyzerConfigDocumentUndoUnit.cs | 26 + .../VisualStudioWorkspaceImpl.cs | 110 +- .../Implementation/Remote/JsonRpcClient.cs | 9 +- .../Remote/JsonRpcMessageHandler.cs | 32 - .../Remote/RemotableDataJsonRpcEx.cs | 4 +- .../Remote/RemoteHostClientFactory.cs | 5 + .../Remote/RemoteHostOptions.cs | 5 + .../Remote/RemoteSolutionPopulatorProvider.cs | 5 + .../Remote/ServiceHubRemoteHostClient.cs | 6 +- ...udioSymbolSearchService.ProgressService.cs | 13 +- ...osticTableControlEventProcessorProvider.cs | 5 + ...oListTableControlEventProcessorProvider.cs | 5 + .../SuppressionStateColumnDefinition.cs | 5 + ...oListTableControlEventProcessorProvider.cs | 5 + .../Implementation/Venus/ContainedDocument.cs | 5 + .../VirtualMemoryNotificationListener.cs | 2 +- .../VisualStudioSupportsFeatureService.cs | 10 + .../Implementation/Watson/WatsonExtensions.cs | 2 +- ...eActionOperationFactoryWorkspaceService.cs | 5 + ...lStudioDocumentNavigationServiceFactory.cs | 2 +- ...udioFormattingRuleFactoryServiceFactory.cs | 1 + .../VisualStudioNavigationOptionsProvider.cs | 5 + ...ualStudioProjectCacheHostServiceFactory.cs | 5 + ...ualStudioSymbolNavigationServiceFactory.cs | 2 +- ...sualStudioWorkspaceStatusServiceFactory.cs | 1 + .../Implementation/WorkspaceCacheService.cs | 5 + src/VisualStudio/Core/Def/RoslynPackage.cs | 2 +- ...ualStudioSymbolSearchService.LogService.cs | 5 +- .../VisualStudioSymbolSearchService.cs | 2 +- ...ectTelemetryIncrementalAnalyzerProvider.cs | 5 + .../Def/Telemetry/ProjectTypeLookupService.cs | 5 + .../Core/Def/xlf/Commands.vsct.cs.xlf | 10 + .../Core/Def/xlf/Commands.vsct.de.xlf | 10 + .../Core/Def/xlf/Commands.vsct.es.xlf | 10 + .../Core/Def/xlf/Commands.vsct.fr.xlf | 10 + .../Core/Def/xlf/Commands.vsct.it.xlf | 10 + .../Core/Def/xlf/Commands.vsct.ja.xlf | 10 + .../Core/Def/xlf/Commands.vsct.ko.xlf | 10 + .../Core/Def/xlf/Commands.vsct.pl.xlf | 10 + .../Core/Def/xlf/Commands.vsct.pt-BR.xlf | 10 + .../Core/Def/xlf/Commands.vsct.ru.xlf | 10 + .../Core/Def/xlf/Commands.vsct.tr.xlf | 10 + .../Core/Def/xlf/Commands.vsct.zh-Hans.xlf | 10 + .../Core/Def/xlf/Commands.vsct.zh-Hant.xlf | 10 + ...dio.LanguageServices.Implementation.csproj | 1 + .../ProjectSystem/CPS/CPSCodeModelFactory.cs | 5 + .../Core/Impl/RoslynVisualStudioWorkspace.cs | 4 +- .../AnalyzerItem/AnalyzerItemProvider.cs | 5 + .../AnalyzerReferenceManager.cs | 2 +- .../Mocks/InProcRemoteHostClientFactory.cs | 5 + .../RemoteHostClientServiceFactoryTests.cs | 14 +- .../TestCSharpSnippetInfoService.vb | 2 +- .../TestVisualBasicSnippetInfoService.vb | 2 +- .../CSharpEditorConfigGeneratorTests.vb | 2 + .../SnippetCompletionProviderTests.vb | 4 + .../SymbolSearchUpdateEngineTests.vb | 38 +- .../Core/Test/Venus/ContainedDocumentTests.vb | 13 + .../Venus/DocumentService_IntegrationTests.vb | 4 + .../TestSetup/TestExtensionErrorHandler.cs | 5 + .../InProcess/TextViewWindow_InProc.cs | 16 +- .../TextViewWindow_OutOfProc.Verifier.cs | 31 +- .../OutOfProcess/TextViewWindow_OutOfProc.cs | 2 +- .../Remote/RemoteHostClientFactory.cs | 5 + .../Remote/RemoteHostClientFactoryOptions.cs | 5 + src/VisualStudio/Setup/AssemblyRedirects.cs | 2 + .../Setup/Roslyn.VisualStudio.Setup.csproj | 2 + ...cCodeModelNavigationPointServiceFactory.vb | 4 + .../VisualBasicCodeModelServiceFactory.vb | 2 +- .../Debugging/ProximityExpressionsGetter.vb | 4 + .../Debugging/VisualBasicBreakpointService.vb | 4 + .../VisualBasicLanguageDebugInfoService.vb | 4 + .../Help/VisualBasicHelpContextService.vb | 4 + .../VisualBasicLibraryService.vb | 1 + .../VisualBasicSyncClassViewCommandHandler.vb | 2 +- .../VisualBasicProgressionLanguageService.vb | 4 + .../VisualBasicEntryPointFinderService.vb | 4 + ...lBasicCompilationOptionsChangingService.vb | 4 + .../VisualBasicParseOptionsChangingService.vb | 4 + ...AdditionalFormattingRuleLanguageService.vb | 4 + .../ProjectionSpanTagDefinition.cs | 1 + .../VenusMargin/ProjectionSpanTagger.cs | 5 + ...lRemoveUnnecessaryUsingsCodeFixProvider.cs | 5 + .../XamlOrganizeImportsService.cs | 8 + ....VisualStudio.LanguageServices.Xaml.csproj | 1 + .../Xaml/Impl/Resources.Designer.cs | 11 +- src/VisualStudio/Xaml/Impl/Resources.resx | 3 + .../Xaml/Impl/xlf/Resources.cs.xlf | 5 + .../Xaml/Impl/xlf/Resources.de.xlf | 5 + .../Xaml/Impl/xlf/Resources.es.xlf | 5 + .../Xaml/Impl/xlf/Resources.fr.xlf | 5 + .../Xaml/Impl/xlf/Resources.it.xlf | 5 + .../Xaml/Impl/xlf/Resources.ja.xlf | 5 + .../Xaml/Impl/xlf/Resources.ko.xlf | 5 + .../Xaml/Impl/xlf/Resources.pl.xlf | 5 + .../Xaml/Impl/xlf/Resources.pt-BR.xlf | 5 + .../Xaml/Impl/xlf/Resources.ru.xlf | 5 + .../Xaml/Impl/xlf/Resources.tr.xlf | 5 + .../Xaml/Impl/xlf/Resources.zh-Hans.xlf | 5 + .../Xaml/Impl/xlf/Resources.zh-Hant.xlf | 5 + .../AddImports/CSharpAddImportsService.cs | 5 + .../CSharpCaseCorrectionService.cs | 5 + .../CSharpClassificationService.cs | 5 + .../CSharpSyntaxClassificationService.cs | 5 + .../CSharpCodeCleanerServiceFactory.cs | 5 + .../CSharpCodeGenerationServiceFactory.cs | 5 + .../CodeGeneration/CSharpSyntaxGenerator.cs | 5 + .../CodeStyle/CSharpCodeStyleOptions.cs | 14 +- .../CSharpCodeStyleOptionsProvider.cs | 5 + .../CSharpDiagnosticPropertiesService.cs | 5 + .../Portable/Editing/CSharpImportAdder.cs | 5 + .../CSharpEmbeddedLanguagesProvider.cs | 1 + .../VirtualChars/CSharpVirtualCharService.cs | 5 + .../CSharpOptionsSerializationService.cs | 5 + .../ContextQuery/CSharpSyntaxContext.cs | 11 +- .../ContextQuery/SyntaxTokenExtensions.cs | 13 +- .../CSharpDeclaredSymbolInfoFactoryService.cs | 5 + .../CSharpFormattingOptionsProvider.cs | 5 + .../Formatting/CSharpFormattingService.cs | 4 + .../CSharpGeneratedCodeRecognitionService.cs | 4 + .../CSharpIndentationService.Indenter.cs | 6 +- .../Indentation/CSharpIndentationService.cs | 17 +- .../Indentation/CSharpSmartTokenFormatter.cs} | 9 +- .../CSharpCommandLineParserService.cs | 5 + .../CSharpCompilationFactoryService.cs | 5 + .../CSharpPrecedenceService.cs | 5 + .../CSharpSemanticFactsService.cs | 24 + .../CSharpSemanticFactsServiceFactory.cs | 5 + .../CSharpSymbolDeclarationService.cs | 5 + .../CSharpSyntaxFactsServiceFactory.cs | 5 + .../CSharpSyntaxKindsService.cs | 5 + .../CSharpSyntaxTreeFactoryService.cs | 7 +- .../CSharpTypeInferenceService.cs | 5 + ...FileMergeConflictCommentAdditionService.cs | 5 + .../CSharpRecommendationService.cs | 5 + .../CSharpRenameRewriterLanguageService.cs | 4 + .../CSharpSimplificationService.cs | 1 + .../SimpleAnalyzerAssemblyLoaderService.cs | 5 + .../CSharp/CSharpProjectFileLoaderFactory.cs | 5 + .../VisualBasicProjectFileLoaderFactory.cs | 5 + .../Operations/ApplyChangesOperation.cs | 3 +- .../CodeStyle/CodeStyleOptionsProvider.cs | 5 + .../Editing/GenerationOptionsProvider.cs | 5 + .../RegularExpressionsOptions.cs | 5 + ...topReferenceSerializationServiceFactory.cs | 5 + .../SimpleAnalyzerAssemblyLoaderService.cs | 5 + .../ReferenceSerializationServiceFactory.cs | 5 + .../Execution/SerializerServiceFactory.cs | 5 + .../SolutionSynchronizationService.cs | 5 + .../Experiments/IExperimentationService.cs | 6 + .../ServicesLayerExtensionManager.cs | 5 + .../Extensions/OperationExtensions.cs | 76 + .../Portable/Formatting/FormattingOptions.cs | 3 + .../Formatting/FormattingOptionsProvider.cs | 5 + ...aultFormattingRuleFactoryServiceFactory.cs | 1 + ...ractIndentationService.AbstractIndenter.cs | 3 +- .../AbstractIndentationService.cs | 6 +- .../Indentation/IIndentationService.cs | 69 + .../Indentation/ISmartTokenFormatter.cs | 2 +- .../AbstractSemanticFactsService.cs | 22 +- .../ISemanticFactsService.cs | 5 +- .../DefaultDocumentTextDifferencingService.cs | 5 + .../Core/Portable/Log/WorkspaceErrorLogger.cs | 5 + .../Microsoft.CodeAnalysis.Workspaces.csproj | 1 + ...torConfigDocumentOptionsProviderFactory.cs | 5 + .../Core/Portable/PublicAPI.Unshipped.txt | 26 + .../DefaultRemoteHostClientServiceFactory.cs | 5 + .../SemanticModelWorkspaceServiceFactory.cs | 5 + .../Extensions/ContextQuery/SyntaxContext.cs | 4 + .../Extensions/ICompilationExtensions.cs | 3 + .../Shared/Extensions/ISolutionExtensions.cs | 29 +- .../Extensions/ITypeSymbolExtensions.cs | 5 + .../Extensions/SemanticModelExtensions.cs | 20 +- .../Extensions/TextDocumentExtensions.cs | 27 +- .../Portable/Shared/RuntimeOptionsProvider.cs | 5 + .../IAsynchronousOperationListenerProvider.cs | 1 + .../SimplificationOptionProvider.cs | 5 + ...NullSolutionCrawlerRegisterationService.cs | 5 + .../SolutionSize/SolutionSizeTracker.cs | 5 + .../SymbolSearch/ISymbolSearchLogService.cs | 5 +- .../ISymbolSearchProgressService.cs | 22 +- .../SymbolSearch/ISymbolSearchService.cs | 5 + .../SymbolSearchOptionsProvider.cs | 5 + .../TemporaryStorageServiceFactory.cs | 5 + .../Core/Portable/Workspace/AdhocWorkspace.cs | 28 + .../Portable/Workspace/ApplyChangesKind.cs | 5 +- .../Core/Portable/Workspace/FileTextLoader.cs | 5 + .../Caching/ProjectCacheServiceFactory.cs | 5 + .../DocumentationProviderServiceFactory.cs | 5 + .../HostContext/ProjectTypeLookupService.cs | 5 + .../FrameworkAssemblyPathResolverFactory.cs | 5 + .../Host/Metadata/MetadataServiceFactory.cs | 5 + .../IPersistentStorageLocationService.cs | 5 + .../PersistentStorageOptionsProvider.cs | 5 + .../PersistentStorageServiceFactory.cs | 5 + .../Host/Status/WorkspaceStatusService.cs | 5 + .../WorkspaceTaskSchedulerFactory.cs | 5 + .../TrivialTemporaryStorageService.cs | 5 + .../Host/TextFactory/TextFactoryService.cs | 5 + .../Workspace/Solution/AdditionalDocument.cs | 15 + ...Document.cs => AdditionalTextWithState.cs} | 16 +- .../Solution/AnalyzerConfigDocument.cs | 6 +- .../Solution/AnalyzerConfigDocumentState.cs | 5 + .../Portable/Workspace/Solution/Document.cs | 2 +- .../Portable/Workspace/Solution/Project.cs | 30 +- .../Workspace/Solution/ProjectChanges.cs | 36 + .../Workspace/Solution/ProjectInfo.cs | 7 +- .../Workspace/Solution/ProjectState.cs | 2 +- .../Portable/Workspace/Solution/Solution.cs | 104 +- .../Workspace/Solution/SolutionState.cs | 23 + .../Workspace/Solution/TextDocument.cs | 6 +- .../Workspace/Solution/TextDocumentKind.cs | 25 + .../Core/Portable/Workspace/Workspace.cs | 114 +- .../Portable/Workspace/Workspace_Editor.cs | 135 +- .../Portable/WorkspacesResources.Designer.cs | 27 + .../Core/Portable/WorkspacesResources.resx | 9 + .../Portable/xlf/WorkspacesResources.cs.xlf | 15 + .../Portable/xlf/WorkspacesResources.de.xlf | 15 + .../Portable/xlf/WorkspacesResources.es.xlf | 15 + .../Portable/xlf/WorkspacesResources.fr.xlf | 15 + .../Portable/xlf/WorkspacesResources.it.xlf | 15 + .../Portable/xlf/WorkspacesResources.ja.xlf | 15 + .../Portable/xlf/WorkspacesResources.ko.xlf | 15 + .../Portable/xlf/WorkspacesResources.pl.xlf | 15 + .../xlf/WorkspacesResources.pt-BR.xlf | 15 + .../Portable/xlf/WorkspacesResources.ru.xlf | 15 + .../Portable/xlf/WorkspacesResources.tr.xlf | 17 +- .../xlf/WorkspacesResources.zh-Hans.xlf | 15 + .../xlf/WorkspacesResources.zh-Hant.xlf | 15 + .../Execution/SnapshotSerializationTests.cs | 5 + .../TestPersistenceService.cs | 5 + .../TestProjectCacheService.cs | 5 + .../TestTemporaryStorageService.cs | 5 + .../CoreTest/SolutionTests/SolutionTests.cs | 8 + .../WorkspaceTests/AdhocWorkspaceTests.cs | 44 +- .../DynamicFileInfoProviderMefTests.cs | 5 + .../Diagnostics/PerformanceTrackerService.cs | 1 + .../ProjectCacheHostServiceFactory.cs | 5 + .../RemoteDocumentDifferenceService.cs | 8 + ...emoteGlobalOperationNotificationService.cs | 1 + .../Remote/Core/Services/SolutionCreator.cs | 26 +- .../RemotePersistentStorageLocationService.cs | 5 + ...odeAnalysis.Remote.Razor.ServiceHub.csproj | 3 - ...soft.CodeAnalysis.Remote.ServiceHub.csproj | 3 - .../Services/CodeAnalysisService_AddImport.cs | 6 +- .../Services/CodeAnalysisService_CodeLens.cs | 32 +- .../CodeAnalysisService_DesignerAttributes.cs | 8 +- .../CodeAnalysisService_Diagnostics.cs | 20 +- .../CodeAnalysisService_DocumentHighlights.cs | 6 +- .../CodeAnalysisService_NavigateTo.cs | 12 +- .../CodeAnalysisService_SymbolFinder.cs | 51 +- .../CodeAnalysisService_TodoComments.cs | 8 +- .../ServiceHub/Services/RemoteHostService.cs | 47 +- .../RemoteSymbolSearchUpdateEngine.cs | 41 +- .../SnapshotService.JsonRpcAssetSource.cs | 10 +- .../Remote/ServiceHub/Shared/Extensions.cs | 20 + .../Shared/ServiceHubServiceBase.cs | 167 +- .../VisualBasicAddImportsService.vb | 4 + ...VisualBasicCaseCorrectionServiceFactory.vb | 4 + .../VisualBasicSyntaxClassificationService.vb | 4 + .../VisualBasicClassificationService.vb | 4 + .../AddMissingTokensCodeCleanupProvider.vb | 4 + .../CaseCorrectionCodeCleanupProvider.vb | 4 + .../FixIncorrectTokensCodeCleanupProvider.vb | 4 + ...ModifiersOrOperatorsCodeCleanupProvider.vb | 4 + .../ReduceTokensCodeCleanupProvider.vb | 4 + ...saryLineContinuationCodeCleanupProvider.vb | 4 + .../VisualBasicCodeCleanerServiceFactory.vb | 4 + ...VisualBasicCodeGenerationServiceFactory.vb | 4 + .../VisualBasicSyntaxGenerator.vb | 4 + .../VisualBasicCodeStyleOptionsProvider.vb | 4 + .../VisualBasicDiagnosticPropertiesService.vb | 4 + .../Editing/VisualBasicImportAdder.vb | 4 + .../VisualBasicEmbeddedLanguagesProvider.vb | 1 + .../VisualBasicVirtualCharService.vb | 4 + .../VisualBasicOptionsSerializationService.vb | 4 + .../ContextQuery/VisualBasicSyntaxContext.vb | 1 + ...alBasicDeclaredSymbolInfoFactoryService.vb | 4 + .../FindSymbols/VisualBasicReferenceFinder.vb | 4 + .../VisualBasicFormattingService.vb | 3 + ...ualBasicGeneratedCodeRecognitionService.vb | 4 + .../Indentation/SpecialFormattingOperation.vb | 3 +- .../VisualBasicIndentationService.Indenter.vb | 4 +- .../VisualBasicIndentationService.vb | 8 +- .../VisualBasicSmartTokenFormatter.vb} | 6 +- .../VisualBasicCommandLineParserService.vb | 4 + .../VisualBasicCompilationFactoryService.vb | 4 + .../VisualBasicPrecedenceService.vb | 4 + .../VisualBasicSemanticFactsService.vb | 7 +- .../VisualBasicSymbolDeclarationService.vb | 4 + .../VisualBasicSyntaxFactsService.vb | 4 + .../VisualBasicSyntaxKindsService.vb | 4 + .../VisualBasicSyntaxTreeFactoryService.vb | 4 + .../VisualBasicTypeInferenceService.vb | 4 + ...FileMergeConflictCommentAdditionService.vb | 4 + .../VisualBasicRecommendationService.vb | 4 + ...sicRenameRewriterLanguageServiceFactory.vb | 4 + .../VisualBasicSimplificationService.vb | 1 + 1168 files changed, 35427 insertions(+), 2881 deletions(-) create mode 100644 docs/ide/README.md delete mode 100644 eng/common/cross/arm/sources.list.vivid delete mode 100644 eng/common/cross/arm/sources.list.wily create mode 100644 eng/common/cross/arm64/sources.list.buster create mode 100644 eng/common/cross/arm64/sources.list.stretch delete mode 100644 eng/common/cross/arm64/sources.list.vivid delete mode 100644 eng/common/cross/arm64/sources.list.wily delete mode 100644 eng/common/cross/x86/sources.list.vivid delete mode 100644 eng/common/cross/x86/sources.list.wily create mode 100644 eng/common/dotnet-install.cmd create mode 100644 eng/common/dotnet-install.ps1 create mode 100644 eng/common/dotnet-install.sh rename src/Compilers/CSharp/Portable/Symbols/Synthesized/{SynthesizedFieldLikeEventAccessorSymbol.cs => SynthesizedEventAccessorSymbol.cs} (78%) create mode 100644 src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs delete mode 100644 src/EditorFeatures/CSharp/Formatting/Indentation/WhitespaceExtensions.cs create mode 100644 src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs create mode 100644 src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs create mode 100644 src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.cs create mode 100644 src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.cs delete mode 100644 src/EditorFeatures/Core/Implementation/SmartIndent/IBlankLineIndentationService.cs create mode 100644 src/EditorFeatures/Core/ModernCommands/SortImportsCommandArgs.cs create mode 100644 src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.vb create mode 100644 src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb create mode 100644 src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.Rewriter.cs create mode 100644 src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs create mode 100644 src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionConstants.cs create mode 100644 src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.Analyzer.cs create mode 100644 src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.cs create mode 100644 src/Features/Core/Portable/AddParameter/AddParameterService.cs create mode 100644 src/Features/Core/Portable/AddParameter/IAddParameterService.cs create mode 100644 src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs create mode 100644 src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs create mode 100644 src/Features/Core/Portable/DisposeAnalysis/DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer.cs create mode 100644 src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateParameterCodeAction.cs create mode 100644 src/Tools/ExternalAccess/Apex/ApexAsynchronousOperationListenerProviderAccessor.cs create mode 100644 src/Tools/ExternalAccess/Apex/IApexAsynchronousOperationListenerProviderAccessor.cs create mode 100644 src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.AddAnalyzerConfigDocumentUndoUnit.cs create mode 100644 src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.RemoveAnalyzerConfigDocumentUndoUnit.cs delete mode 100644 src/VisualStudio/Core/Def/Implementation/Remote/JsonRpcMessageHandler.cs create mode 100644 src/VisualStudio/Core/Test/Venus/ContainedDocumentTests.vb rename src/{EditorFeatures/CSharp/Formatting => Workspaces/CSharp/Portable}/Indentation/CSharpIndentationService.Indenter.cs (98%) rename src/{EditorFeatures/CSharp/Formatting => Workspaces/CSharp/Portable}/Indentation/CSharpIndentationService.cs (94%) rename src/{EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatter.cs => Workspaces/CSharp/Portable/Indentation/CSharpSmartTokenFormatter.cs} (96%) rename src/{EditorFeatures/Core/Implementation/SmartIndent => Workspaces/Core/Portable/Indentation}/AbstractIndentationService.AbstractIndenter.cs (98%) rename src/{EditorFeatures/Core/Implementation/SmartIndent => Workspaces/Core/Portable/Indentation}/AbstractIndentationService.cs (96%) create mode 100644 src/Workspaces/Core/Portable/Indentation/IIndentationService.cs rename src/{EditorFeatures/Core/Implementation/Formatting => Workspaces/Core/Portable}/Indentation/ISmartTokenFormatter.cs (85%) create mode 100644 src/Workspaces/Core/Portable/Workspace/Solution/AdditionalDocument.cs rename src/Workspaces/Core/Portable/Workspace/Solution/{AdditionalTextDocument.cs => AdditionalTextWithState.cs} (55%) create mode 100644 src/Workspaces/Core/Portable/Workspace/Solution/TextDocumentKind.cs rename src/{EditorFeatures/VisualBasic/Formatting => Workspaces/VisualBasic/Portable}/Indentation/SpecialFormattingOperation.vb (99%) rename src/{EditorFeatures/VisualBasic/Formatting => Workspaces/VisualBasic/Portable}/Indentation/VisualBasicIndentationService.Indenter.vb (99%) rename src/{EditorFeatures/VisualBasic/Formatting => Workspaces/VisualBasic/Portable}/Indentation/VisualBasicIndentationService.vb (94%) rename src/{EditorFeatures/VisualBasic/Formatting/Indentation/SmartTokenFormatter.vb => Workspaces/VisualBasic/Portable/Indentation/VisualBasicSmartTokenFormatter.vb} (90%) diff --git a/docs/Language Feature Status.md b/docs/Language Feature Status.md index c4009b5eb2f6b..5d5525e3ac9ab 100644 --- a/docs/Language Feature Status.md +++ b/docs/Language Feature Status.md @@ -16,6 +16,7 @@ efforts behind them. | [Generic attributes](https://github.com/dotnet/csharplang/issues/124) | [generic-attributes](https://github.com/dotnet/roslyn/tree/features/generic-attributes) | In Progress | [AviAvni](https://github.com/AviAvni) | [agocke](https://github.com/agocke) | [mattwar](https://github.com/mattwar) | | [Default in deconstruction](https://github.com/dotnet/roslyn/pull/25562) | [decon-default](https://github.com/dotnet/roslyn/tree/features/decon-default) | [Implemented](https://github.com/dotnet/roslyn/issues/25559) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) | | [Relax ordering of `ref` and `partial` modifiers](https://github.com/dotnet/csharplang/issues/946) | [ref-partial](https://github.com/dotnet/roslyn/tree/features/ref-partial) | In Progress | [alrz](https://github.com/alrz) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) | +| [Parameter null-checking](https://github.com/dotnet/csharplang/issues/2145) | [param-nullchecking](https://github.com/dotnet/roslyn/tree/features/param-nullchecking) | [In Progress](https://github.com/dotnet/roslyn/issues/36024) | [fayrose](https://github.com/fayrose) | [agocke](https://github.com/agocked) | [jaredpar](https://github.com/jaredpar) | # C# 8.0 diff --git a/docs/README.md b/docs/README.md index 1ce6c3bc8a4ed..0b5ca7c8e4527 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ README ====== -This file is a placeholder. This directory will contain public documentation. +This file is a placeholder. This directory will contain public documentation. \ No newline at end of file diff --git a/docs/features/DefaultInterfaceImplementation.md b/docs/features/DefaultInterfaceImplementation.md index 25aee100bca21..37ab2c1823dae 100644 --- a/docs/features/DefaultInterfaceImplementation.md +++ b/docs/features/DefaultInterfaceImplementation.md @@ -27,6 +27,42 @@ class Test1 : I1 } ``` +- Re-abstraction of interface implementation in derived interfaces. Types implementing the derived interface are required to supply implementation even when a base interface provides an implementation. +Here is an example: +``` +public interface I1 +{ + void M1() + { + } + + int P1 + { + get => throw null; + set => throw null; + } + + event System.Action E1 + { + add => throw null; + remove => throw null; + } +} + +public interface I2 : I1 +{ + abstract void I1.M1(); + abstract int I1.P1 {get;set;} + abstract event System.Action I1.E1; +} + +class Test1 : I2 // This type must implement all members of I1 +{ +} +``` +In metadata, methods representing re-abstraction have all three flags `abstarct`, `virtual`, `sealed` set and do not have `newslot` flag set. + + - Supplying an implementation along with declaration of a property or an indexer and recognizing that implementation as default implementation for them when a type implements the interface. - Supplying an implementation along with declaration of an event and recognizing that implementation as default implementation for the event when a type implements the interface. diff --git a/docs/ide/README.md b/docs/ide/README.md new file mode 100644 index 0000000000000..525e6613ccb93 --- /dev/null +++ b/docs/ide/README.md @@ -0,0 +1,124 @@ +# Recently added productivity features and links to release notes + +## TOC + * [Dev16](#prod-16) + * [Dev 16.2](#prod-16-2) + * [Dev 16.1](#prod-16-1) + * [Dev16.0](#prod-16-0) + * [Dev15](#prod-15) + * [Dev 15.9](#prod-15-9) + * [Dev 15.8](#prod-15-8) + * [Dev 15.7](#prod-15-7) + * [Dev 15.6](#prod-15-6) + * [Dev 15.5](#prod-15-5) + * [Dev 15.4](#prod-15-4) + +## dev16 + +### 16.2 Preview ([release notes](https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-preview) ) +* [Test Explorer improvements](https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-preview#test-explorer-162P1) + +### 16.1 ([release notes](https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes)) +* There is now experimental intellisense completion for unimported types! You now receive intellisense suggestions for types in dependencies in your project even if you have not yet added the import statement to your file. You must turn this option on in Tools > Options > Text Editor > C# > Intellisense. +* Toggle Single Line Comment/Uncomment is now available through the keyboard shortcut (Ctrl+K,/). This command will add or remove a single line comment depending on whether your selection is already commented. +* You can now export naming styles with the “Generate editorconfig” button located in Tools > Options > Text Editor > C# > Code Style. +* You can now use a new editorconfig code style rule to require or prevent usings inside a namespace. This setting will also be exported when you use the “Generate editorconfig” button located in Tools > Options > Text Editor > C# > Code Style. +* The Find All References “Kind” column now has more filter options and is aware of namespaces and types. +* .NET codefixes and Refactorings + * Split/Merge if + * Wrap binary expressions + * Unseal a class +* A regex completion list can now be accessed through the intellisense menu (Ctrl + space) when inside a regex string. These completions also include an in-line description of what the suggestion does. +* You can now use one-click code cleanup for projects and solutions. You can right-click on projects or the solution in the Solution Explorer and select ‘Run Code Cleanup’. +* You can now use a refactoring dialog to move type to namespace or folder. Place your cursor in the class name and type (Ctrl + .) to open the quick actions and refactorings menu and select ‘Move to namespace.’ This launches a dialog where you can select the target namespace you would like to move the type to. +* Toggle Block Comment/Uncomment (Ctrl+Shift+/) or through Edit > Advanced > Toggle Block Comment. +* There is now a codefix for making readonly struct fields writable. Place your cursor in the struct name, type (Ctrl+.) to open the quick actions and refactorings menu, and select ‘Make readonly fields writable.’ +* The codefix to add a private field from a constructor and vice versa is easier to discover and will show when any portion of the field name is selected. This refactoring now also offers all possible constructors. + +### 16.0 ([release notes](https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.0)) + +* .NET refactorings and codefixes: + * Sync Namespace and Folder Name + * Pull members up refactoring with dialog options + * Wrap/indent/align lists of parameters/arguments + * Convert anonymous type to tuple + * Use expression/block body for lambda + * Invert conditional expressions and logical operations + * Convert to compound assignment + * Automatically close block comment on “/” + * Convert to compound assignment + * Fix Implicitly-typed variables cannot be constant + * Auto-fixer to replace @$" with $@" when typing interpolated verbatim string + * Completion for #nullable enable|disable + * Fix for unused expression values and parameters + * Fix for allowing Extract Interface to remain in the same file + * For cases where "await" is implied but omitted, there is now a compiler warning. + * Convert a local function to a method. + * Convert a tuple to a named-struct. + * Convert an anonymous type to a class. + * Convert an anonymous type to a tuple. + * For a foreach loop to LINQ query or to LINQ method. + * Generate deconstruct method +* Categorize references by Read/Write in Find All References window. +* Add Editorconfig when_multiline option for csharp_prefer_braces. +* New classification colors are available from the .NET Compiler Platform SDK (aka Roslyn). New default colors, similar to the Visual Studio Code colors, are gradually being rolled out. You can adjust these colors in Tools > Options > Environment > Fonts and Colors or turn them off in Environment > Preview Features by unchecking the Use enhanced colors check box. We’d appreciate hearing feedback on how this change affects your workflow. +* Configure [code cleanup](https://docs.microsoft.com/en-us/visualstudio/ide/code-styles-and-code-cleanup) (settings formally a part of Format Document) +* [Format document global tool](https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes#-apply-code-style-preferences) can be run from the command-line + * Use [code metrics](https://docs.microsoft.com/visualstudio/code-quality/code-metrics-values) with .NET Core projects with our added compatibility. + * Export editor settings to an Editorconfig file through **Tools > Options > Text Editor > C# > Code Style** with the button "Generate .editorconfig file from settings". + * Use C# and Visual Basic's new Regex parser support. Regular expressions are now recognized, and language features are enabled on them. Regex strings are either recognized when a string is passed to the Regex constructor or when a string is immediately preceded with a comment containing the string language=regex. The language features included in this release are classification, brace matching, highlight references, and diagnostics. + * You can now use dead code analysis for unused private members with an optional code fix to remove unused member declaration. + * The Find References feature on an accessor now only returns results for that accessor. + * "Using" statements can be added when code is pasted into a file. A code fix appears after pasting recognized code that prompts you to add relevant missing imports. + * You can now use Find All References (Shift-F12) and CodeLens to show results from Razor (.cshtml) files in .NET Core projects. You can then navigate to the identified code in the relevant Razor files. + * You will now receive a warning when running code analysis using FxCop. .NET Compiler analyzers are the recommended way to perform code analysis going forward. Read more on migrating to .NET compiler platform analyzers. + +## dev15 + +### dev15 Summary +* Visual Studio-based code cleanup via Format Document +* Refactorings: InvertIf, add parameter from method callsite, remove unnecessary parentheses, convert if-else assignment, completion for attributes and return to ternary conditional. +* .editorconfig “refresh” such that changes will be automatically applied without file reload +* IOperation APIs RTW +* Portable PDB format to enable cross-platform debugging scenarios + +### 15.9 +None + +### 15.8 ([release notes](https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-v15.8#productivity)) + * Format Document (Ctrl + K, D or Ctrl + E, D) for C# development. + * .NET refactorings and codefixes: + * Invert If + * Add parameter from method callsite + * Remove unnecessary parentheses + * Use ternary conditionals in assignments and return statements + * Go to Enclosing Block (Ctrl + Alt + UpArrow) + * Go to Next/Previous Issue (Alt + PgUp/PgDn) skip to error, squiggle, lightbulb. + * Go to Member (Ctrl + T, M) is now scoped to the file by default + * Multi-caret: Insert carets with Ctrl + Alt + LeftMouseClick. + * Multi-caret: Add a selection and caret at next location that matches current selection with Shift + Alt + Ins. + * Access a contextual navigation menu with Alt + `. + * Visual Studio Code and ReSharper (Visual Studio) keybindings + +### 15.7 ([release notes](https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-v15.7#dotnet_productivity)) +* .NET refactorings and codefixes: + * For-to-foreach, and vice versa. + * Make private fields readonly. + * Toggle between var and the explicit type, regardless of your code style preferences. + * Go To Definition (F12) is now supported for LINQ query clauses and deconstructions. + * Quick Info shows captures on lambdas and local functions, so you can see what variables are in scope. + * Change Signature refactoring (Ctrl+. on signature) works on local functions. + * You can edit .NET Core project files in-place, so opening containing folder, restoring tabs, and other Editor features are fully supported. IDE changes, such as adding a linked file, will be merged with unsaved changes in the editor. + +### 15.6 ([release notes](https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-v15.6#productivity)) + * Navigate to decompiled sources (must enable in Tools > Options > Text Editor > C# > Advanced > Enable navigation to decompiled sources) + * .NET EditorConfig options: dotnet_prefer_inferred_tuple_names + * .NET EditorConfig options: dotnet_prefer_inferred_anonymous_type_member_names + * Ctrl + D to Duplicate text + * Expand Selection command that allows you to successively expand your selection to the next logical block. You can use the shortcuts Shift+Alt+= to expand and Shift+Alt+- to contract the current selection. + +### 15.5 +None + +### 15.4 ([release notes](https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-v15.4#editor)) + * Editor: Control Click Go To Definition diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8d489b28048e4..1d212db2676ce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,9 +3,9 @@ - + https://github.com/dotnet/arcade - ac8d88df02d246d3147338fcfb03b1b93dc84b53 + 86e674361bdcefecbd8199ab62d0b1a6cb25703d diff --git a/eng/Versions.props b/eng/Versions.props index b801f5ad358c9..bf15201fa8bba 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -6,7 +6,7 @@ --> 3.2.0 - beta2 + beta3 true - + diff --git a/global.json b/global.json index b8a97eed5921f..ca5751ec9d077 100644 --- a/global.json +++ b/global.json @@ -7,6 +7,6 @@ "xcopy-msbuild": "16.0.0-alpha" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19230.6" + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19272.13" } } diff --git a/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs b/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs index f5c354f766572..9c9f0bf2213ec 100644 --- a/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs +++ b/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs @@ -129,7 +129,10 @@ private static void ComputeDeclarations( case SyntaxKind.EventDeclaration: { var t = (EventDeclarationSyntax)node; - foreach (var decl in t.AccessorList.Accessors) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + if (t.AccessorList != null) + { + foreach (var decl in t.AccessorList.Accessors) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } var attributes = GetAttributes(t.AttributeLists); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index ae0846d2e8a62..c2ea55f92f01f 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -1322,6 +1322,11 @@ private static bool CheckInvocationArgMixing( uint scopeOfTheContainingExpression, DiagnosticBag diagnostics) { + // SPEC: + // In a method invocation, the following constraints apply: + // - If there is a ref or out argument of a ref struct type (including the receiver), with safe-to-escape E1, then + // - no argument (including the receiver) may have a narrower safe-to-escape than E1. + if (symbol.IsStatic) { // ignore receiver when symbol is static @@ -1333,7 +1338,7 @@ private static bool CheckInvocationArgMixing( // collect all writeable ref-like arguments, including receiver var receiverType = receiverOpt?.Type; - if (receiverType?.IsRefLikeType == true && receiverType?.IsReadOnly == false) + if (receiverType?.IsRefLikeType == true && !isReceiverRefReadOnly(symbol)) { escapeTo = GetValEscape(receiverOpt, scopeOfTheContainingExpression); } @@ -1432,6 +1437,17 @@ private static bool CheckInvocationArgMixing( } return true; + + static bool isReceiverRefReadOnly(Symbol methodOrPropertySymbol) => methodOrPropertySymbol switch + { + MethodSymbol m => m.IsEffectivelyReadOnly, + // TODO: val escape checks should be skipped for property accesses when + // we can determine the only accessors being called are readonly. + // For now we are pessimistic and check escape if any accessor is non-readonly. + // Tracking in https://github.com/dotnet/roslyn/issues/35606 + PropertySymbol p => p.GetMethod?.IsEffectivelyReadOnly != false && p.SetMethod?.IsEffectivelyReadOnly != false, + _ => throw ExceptionUtilities.UnexpectedValue(methodOrPropertySymbol) + }; } /// diff --git a/src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs b/src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs index 46d3524b71bf3..0da8e5da0b4be 100644 --- a/src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs +++ b/src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs @@ -902,7 +902,7 @@ private void CheckConsistentDecision( case BoundDagTypeTest t2: { HashSet useSiteDiagnostics = null; - bool? matches = Binder.ExpressionOfTypeMatchesPatternType(_conversions, t1.Type, t2.Type, ref useSiteDiagnostics, out _); + bool? matches = ExpressionOfTypeMatchesPatternTypeForLearningFromSuccessfulTypeTest(t1.Type, t2.Type, ref useSiteDiagnostics); if (matches == false) { // If T1 could never be T2 @@ -917,7 +917,6 @@ private void CheckConsistentDecision( } // If every T2 is a T1, then failure of T1 implies failure of T2. - matches = Binder.ExpressionOfTypeMatchesPatternType(_conversions, t2.Type, t1.Type, ref useSiteDiagnostics, out _); _diagnostics.Add(syntax, useSiteDiagnostics); if (matches == true) @@ -1007,6 +1006,90 @@ private void CheckConsistentDecision( } } + /// + /// Determine what we can learn from one successful runtime type test about another planned + /// runtime type test for the purpose of building the decision tree. + /// We accomodate a special behavior of the runtime here, which does not match the language rules. + /// A value of type `int[]` is an "instanceof" (i.e. result of the `isinst` instruction) the type + /// `uint[]` and vice versa. It is similarly so for every pair of same-sized numeric types, and + /// arrays of enums are considered to be their underlying type. We need the dag construction to + /// recognize this runtime behavior, so we pretend that matching one of them gives no information + /// on whether the other will be matched. That isn't quite correct (nothing reasonable we do + /// could be), but it comes closest to preserving the existing C#7 behavior without undesirable + /// side-effects, and permits the code-gen strategy to preserve the dynamic semantic equivalence + /// of a switch (on the one hand) and a series of if-then-else statements (on the other). + /// See, for example, https://github.com/dotnet/roslyn/issues/35661 + /// + private bool? ExpressionOfTypeMatchesPatternTypeForLearningFromSuccessfulTypeTest( + TypeSymbol expressionType, + TypeSymbol patternType, + ref HashSet useSiteDiagnostics) + { + bool? result = Binder.ExpressionOfTypeMatchesPatternType(_conversions, expressionType, patternType, ref useSiteDiagnostics, out Conversion conversion); + return (!conversion.Exists && isRuntimeSimilar(expressionType, patternType)) + ? null // runtime and compile-time test behavior differ. Pretend we don't know what happens. + : result; + + static bool isRuntimeSimilar(TypeSymbol expressionType, TypeSymbol patternType) + { + while (expressionType is ArrayTypeSymbol { ElementType: var e1, IsSZArray: var sz1, Rank: var r1 } && + patternType is ArrayTypeSymbol { ElementType: var e2, IsSZArray: var sz2, Rank: var r2 } && + sz1 == sz2 && r1 == r2) + { + e1 = e1.EnumUnderlyingType(); + e2 = e2.EnumUnderlyingType(); + switch (e1.SpecialType, e2.SpecialType) + { + // The following support CLR behavior that is required by + // the CLI specification but violates the C# language behavior. + // See ECMA-335's definition of *array-element-compatible-with*. + case var (s1, s2) when s1 == s2: + case (SpecialType.System_SByte, SpecialType.System_Byte): + case (SpecialType.System_Byte, SpecialType.System_SByte): + case (SpecialType.System_Int16, SpecialType.System_UInt16): + case (SpecialType.System_UInt16, SpecialType.System_Int16): + case (SpecialType.System_Int32, SpecialType.System_UInt32): + case (SpecialType.System_UInt32, SpecialType.System_Int32): + case (SpecialType.System_Int64, SpecialType.System_UInt64): + case (SpecialType.System_UInt64, SpecialType.System_Int64): + case (SpecialType.System_IntPtr, SpecialType.System_UIntPtr): + case (SpecialType.System_UIntPtr, SpecialType.System_IntPtr): + + // The following support behavior of the CLR that violates the CLI + // and C# specifications, but we implement them because that is the + // behavior on 32-bit runtimes. + case (SpecialType.System_Int32, SpecialType.System_IntPtr): + case (SpecialType.System_Int32, SpecialType.System_UIntPtr): + case (SpecialType.System_UInt32, SpecialType.System_IntPtr): + case (SpecialType.System_UInt32, SpecialType.System_UIntPtr): + case (SpecialType.System_IntPtr, SpecialType.System_Int32): + case (SpecialType.System_IntPtr, SpecialType.System_UInt32): + case (SpecialType.System_UIntPtr, SpecialType.System_Int32): + case (SpecialType.System_UIntPtr, SpecialType.System_UInt32): + + // The following support behavior of the CLR that violates the CLI + // and C# specifications, but we implement them because that is the + // behavior on 64-bit runtimes. + case (SpecialType.System_Int64, SpecialType.System_IntPtr): + case (SpecialType.System_Int64, SpecialType.System_UIntPtr): + case (SpecialType.System_UInt64, SpecialType.System_IntPtr): + case (SpecialType.System_UInt64, SpecialType.System_UIntPtr): + case (SpecialType.System_IntPtr, SpecialType.System_Int64): + case (SpecialType.System_IntPtr, SpecialType.System_UInt64): + case (SpecialType.System_UIntPtr, SpecialType.System_Int64): + case (SpecialType.System_UIntPtr, SpecialType.System_UInt64): + return true; + + default: + (expressionType, patternType) = (e1, e2); + break; + } + } + + return false; + } + } + private static ImmutableArray RemoveEvaluation(ImmutableArray cases, BoundDagEvaluation e) { return cases.SelectAsArray((c, eval) => RemoveEvaluation(c, eval), e); diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs index a6b1b2fdee657..b2361704f9255 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs @@ -21,6 +21,7 @@ public static bool IsImplicitConversion(this ConversionKind conversionKind) switch (conversionKind) { case ConversionKind.NoConversion: + case ConversionKind.UnsetConversionKind: return false; case ConversionKind.Identity: diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index d21d305f8bf12..fff53e457a7e4 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -159,6 +159,15 @@ internal static string ERR_AbstractBaseCall { } } + /// + /// Looks up a localized string similar to '{0}': abstract event cannot use event accessor syntax. + /// + internal static string ERR_AbstractEventHasAccessors { + get { + return ResourceManager.GetString("ERR_AbstractEventHasAccessors", resourceCulture); + } + } + /// /// Looks up a localized string similar to '{0}': abstract event cannot have initializer. /// @@ -834,15 +843,6 @@ internal static string ERR_AutoPropertyCannotBeRefReturning { } } - /// - /// Looks up a localized string similar to Instance auto-implemented properties inside interfaces cannot have initializers.. - /// - internal static string ERR_AutoPropertyInitializerInInterface { - get { - return ResourceManager.GetString("ERR_AutoPropertyInitializerInInterface", resourceCulture); - } - } - /// /// Looks up a localized string similar to Auto-implemented properties must have get accessors.. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index f8c1e2ea074e4..ce3a91e057b82 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -534,6 +534,9 @@ '{0}': event property must have both add and remove accessors + + '{0}': abstract event cannot use event accessor syntax + '{0}': event must be of a delegate type @@ -4733,9 +4736,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Auto-implemented properties must override all accessors of the overridden property. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Structs without explicit constructors cannot contain members with initializers. diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs index 640ceceead15d..903edd38c048a 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs @@ -2104,14 +2104,21 @@ private bool TryEmitAssignmentInPlace(BoundAssignmentOperator assignmentOperator return true; } - if (right.Kind == BoundKind.ObjectCreationExpression) + if (right is BoundObjectCreationExpression objCreation) { + // If we are creating a Span from a stackalloc, which is a particular pattern of code + // produced by lowering, we must use the constructor in its standard form because the stack + // is required to contain nothing more than stackalloc's argument. + if (objCreation.Arguments.Length > 0 && objCreation.Arguments[0].Kind == BoundKind.ConvertedStackAllocExpression) + { + return false; + } + // It is desirable to do in-place ctor call if possible. // we could do newobj/stloc, but in-place call // produces the same or better code in current JITs if (PartialCtorResultCannotEscape(left)) { - var objCreation = (BoundObjectCreationExpression)right; var ctor = objCreation.Constructor; // ctor can possibly see its own assignments indirectly if there are ref parameters or __arglist diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 118de8bd3383d..8485a0a8496ed 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1289,7 +1289,8 @@ internal enum ErrorCode // available 8041-8049 ERR_InitializerOnNonAutoProperty = 8050, ERR_AutoPropertyMustHaveGetAccessor = 8051, - ERR_AutoPropertyInitializerInInterface = 8052, + // ERR_AutoPropertyInitializerInInterface = 8052, + // available 8053 ERR_EnumsCantContainDefaultConstructor = 8054, ERR_EncodinglessSyntaxTree = 8055, @@ -1717,7 +1718,8 @@ internal enum ErrorCode //ERR_NotDeclaredInBase = 8710, ERR_DefaultInterfaceImplementationInNoPIAType = 8711, - ERR_NeedSpaceBetweenExclamationAndEquals = 8712, + ERR_AbstractEventHasAccessors = 8712, + ERR_NeedSpaceBetweenExclamationAndEquals = 8713, #endregion diagnostics introduced for C# 8.0 diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index 9f14bfb7b9533..fda0a7daed512 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -1668,8 +1668,8 @@ protected override bool IsEmptyStructType(TypeSymbol type) var members = ((NamedTypeSymbol)type).GetMembersUnordered(); - // EmptyStructTypeCache.IsEmptyStructType() returned true. If there - // are fields, those must be cyclic, so treat the type as empty. + // EmptyStructTypeCache.IsEmptyStructType() returned true. If there are fields, + // at least one of those fields must be cyclic, so treat the type as empty. if (members.Any(m => m.Kind == SymbolKind.Field)) { return true; @@ -2764,7 +2764,7 @@ private TypeWithState VisitCallReceiver(BoundCall node) /// /// For each argument, figure out if its corresponding parameter is annotated with NotNullWhenFalse or - /// EnsuresNotNull. + /// NotNull. /// private static ImmutableArray GetAnnotations(int numArguments, bool expanded, ImmutableArray parameters, ImmutableArray argsToParamsOpt) @@ -4125,7 +4125,18 @@ private void ReportNullabilityMismatchWithTargetDelegate(Location location, Name { var invokeParameter = invoke.Parameters[i]; var methodParameter = method.Parameters[i + methodOffset]; - if (IsNullabilityMismatch(invokeParameter.TypeWithAnnotations, methodParameter.TypeWithAnnotations, requireIdentity: invokeParameter.RefKind != RefKind.None)) + + var sourceParameter = invokeParameter; + var destinationParameter = methodParameter; + + var invokeRefKind = invokeParameter.RefKind; + if (invokeRefKind == RefKind.Out) + { + // out parameters have inverted variance + (sourceParameter, destinationParameter) = (destinationParameter, sourceParameter); + } + + if (IsNullabilityMismatch(sourceParameter.TypeWithAnnotations, destinationParameter.TypeWithAnnotations, requireIdentity: invokeRefKind == RefKind.Ref)) { ReportDiagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, location, new FormattedSymbol(methodParameter, SymbolDisplayFormat.ShortFormat), @@ -5143,8 +5154,17 @@ private void VisitDeconstructionArguments(ArrayBuilder v int valueSlot; if (underlyingConversion.IsIdentity) { - operandType = default; - valueType = VisitOptionalImplicitConversion(rightPart, targetType, useLegacyWarnings: true, trackMembers: true, AssignmentKind.Assignment); + if ((variable.Expression as BoundLocal)?.DeclarationKind == BoundLocalDeclarationKind.WithInferredType) + { + // when the LHS is a var declaration, we can just visit the right part to infer the type + valueType = operandType = VisitRvalueWithState(rightPart); + _variableTypes[variable.Expression.ExpressionSymbol] = operandType.ToTypeWithAnnotations(); + } + else + { + operandType = default; + valueType = VisitOptionalImplicitConversion(rightPart, targetType, useLegacyWarnings: true, trackMembers: true, AssignmentKind.Assignment); + } valueSlot = MakeSlot(rightPart); } else @@ -5260,7 +5280,6 @@ private ImmutableArray GetDeconstructionRightParts(BoundExpress // https://github.com/dotnet/roslyn/issues/33011: Should include conversion.UnderlyingConversions[i]. // For instance, Boxing conversions (see Deconstruction_ImplicitBoxingConversion_02) and // ImplicitNullable conversions (see Deconstruction_ImplicitNullableConversion_02). - VisitRvalue(expr); var fields = tupleType.TupleElements; return fields.SelectAsArray((f, e) => (BoundExpression)new BoundFieldAccess(e.Syntax, e, f, constantValueOpt: null), expr); } diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs index 5d0a85b61b098..771b52ad42b04 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs @@ -25071,11 +25071,12 @@ internal sealed partial class EventDeclarationSyntax : BasePropertyDeclarationSy internal readonly ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier; internal readonly SyntaxToken identifier; internal readonly AccessorListSyntax accessorList; + internal readonly SyntaxToken semicolonToken; - internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) + internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) : base(kind, diagnostics, annotations) { - this.SlotCount = 7; + this.SlotCount = 8; if (attributeLists != null) { this.AdjustFlagsAndWidth(attributeLists); @@ -25097,16 +25098,24 @@ internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, Green } this.AdjustFlagsAndWidth(identifier); this.identifier = identifier; - this.AdjustFlagsAndWidth(accessorList); - this.accessorList = accessorList; + if (accessorList != null) + { + this.AdjustFlagsAndWidth(accessorList); + this.accessorList = accessorList; + } + if (semicolonToken != null) + { + this.AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + } } - internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxFactoryContext context) + internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken, SyntaxFactoryContext context) : base(kind) { this.SetFactoryContext(context); - this.SlotCount = 7; + this.SlotCount = 8; if (attributeLists != null) { this.AdjustFlagsAndWidth(attributeLists); @@ -25128,15 +25137,23 @@ internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, Green } this.AdjustFlagsAndWidth(identifier); this.identifier = identifier; - this.AdjustFlagsAndWidth(accessorList); - this.accessorList = accessorList; + if (accessorList != null) + { + this.AdjustFlagsAndWidth(accessorList); + this.accessorList = accessorList; + } + if (semicolonToken != null) + { + this.AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + } } - internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, GreenNode modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken) : base(kind) { - this.SlotCount = 7; + this.SlotCount = 8; if (attributeLists != null) { this.AdjustFlagsAndWidth(attributeLists); @@ -25158,8 +25175,16 @@ internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, Green } this.AdjustFlagsAndWidth(identifier); this.identifier = identifier; - this.AdjustFlagsAndWidth(accessorList); - this.accessorList = accessorList; + if (accessorList != null) + { + this.AdjustFlagsAndWidth(accessorList); + this.accessorList = accessorList; + } + if (semicolonToken != null) + { + this.AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + } } public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList AttributeLists => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.attributeLists); @@ -25170,6 +25195,7 @@ internal EventDeclarationSyntax(SyntaxKind kind, GreenNode attributeLists, Green /// Gets the identifier. public SyntaxToken Identifier => this.identifier; public override AccessorListSyntax AccessorList => this.accessorList; + public SyntaxToken SemicolonToken => this.semicolonToken; internal override GreenNode GetSlot(int index) { @@ -25182,6 +25208,7 @@ internal override GreenNode GetSlot(int index) case 4: return this.explicitInterfaceSpecifier; case 5: return this.identifier; case 6: return this.accessorList; + case 7: return this.semicolonToken; default: return null; } } @@ -25192,11 +25219,11 @@ internal override GreenNode GetSlot(int index) public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitEventDeclaration(this); - public EventDeclarationSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + public EventDeclarationSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken) { - if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || eventKeyword != this.EventKeyword || type != this.Type || explicitInterfaceSpecifier != this.ExplicitInterfaceSpecifier || identifier != this.Identifier || accessorList != this.AccessorList) + if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || eventKeyword != this.EventKeyword || type != this.Type || explicitInterfaceSpecifier != this.ExplicitInterfaceSpecifier || identifier != this.Identifier || accessorList != this.AccessorList || semicolonToken != this.SemicolonToken) { - var newNode = SyntaxFactory.EventDeclaration(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList); + var newNode = SyntaxFactory.EventDeclaration(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken); var diags = this.GetDiagnostics(); if (diags != null && diags.Length > 0) newNode = newNode.WithDiagnosticsGreen(diags); @@ -25210,15 +25237,15 @@ public EventDeclarationSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSynta } internal override GreenNode SetDiagnostics(DiagnosticInfo[] diagnostics) - => new EventDeclarationSyntax(this.Kind, this.attributeLists, this.modifiers, this.eventKeyword, this.type, this.explicitInterfaceSpecifier, this.identifier, this.accessorList, diagnostics, GetAnnotations()); + => new EventDeclarationSyntax(this.Kind, this.attributeLists, this.modifiers, this.eventKeyword, this.type, this.explicitInterfaceSpecifier, this.identifier, this.accessorList, this.semicolonToken, diagnostics, GetAnnotations()); internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations) - => new EventDeclarationSyntax(this.Kind, this.attributeLists, this.modifiers, this.eventKeyword, this.type, this.explicitInterfaceSpecifier, this.identifier, this.accessorList, GetDiagnostics(), annotations); + => new EventDeclarationSyntax(this.Kind, this.attributeLists, this.modifiers, this.eventKeyword, this.type, this.explicitInterfaceSpecifier, this.identifier, this.accessorList, this.semicolonToken, GetDiagnostics(), annotations); internal EventDeclarationSyntax(ObjectReader reader) : base(reader) { - this.SlotCount = 7; + this.SlotCount = 8; var attributeLists = (GreenNode)reader.ReadValue(); if (attributeLists != null) { @@ -25261,6 +25288,12 @@ internal EventDeclarationSyntax(ObjectReader reader) AdjustFlagsAndWidth(accessorList); this.accessorList = accessorList; } + var semicolonToken = (SyntaxToken)reader.ReadValue(); + if (semicolonToken != null) + { + AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + } } internal override void WriteTo(ObjectWriter writer) @@ -25273,6 +25306,7 @@ internal override void WriteTo(ObjectWriter writer) writer.WriteValue(this.explicitInterfaceSpecifier); writer.WriteValue(this.identifier); writer.WriteValue(this.accessorList); + writer.WriteValue(this.semicolonToken); } static EventDeclarationSyntax() @@ -35044,7 +35078,8 @@ public override CSharpSyntaxNode VisitEventDeclaration(EventDeclarationSyntax no var explicitInterfaceSpecifier = (ExplicitInterfaceSpecifierSyntax)this.Visit(node.ExplicitInterfaceSpecifier); var identifier = (SyntaxToken)this.Visit(node.Identifier); var accessorList = (AccessorListSyntax)this.Visit(node.AccessorList); - return node.Update(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList); + var semicolonToken = (SyntaxToken)this.Visit(node.SemicolonToken); + return node.Update(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken); } public override CSharpSyntaxNode VisitIndexerDeclaration(IndexerDeclarationSyntax node) @@ -41059,7 +41094,7 @@ public ArrowExpressionClauseSyntax ArrowExpressionClause(SyntaxToken arrowToken, return result; } - public EventDeclarationSyntax EventDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + public EventDeclarationSyntax EventDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken) { #if DEBUG if (eventKeyword == null) @@ -41082,11 +41117,20 @@ public EventDeclarationSyntax EventDeclaration(Microsoft.CodeAnalysis.Syntax.Int default: throw new ArgumentException(nameof(identifier)); } - if (accessorList == null) - throw new ArgumentNullException(nameof(accessorList)); + if (semicolonToken != null) + { + switch (semicolonToken.Kind) + { + case SyntaxKind.SemicolonToken: + case SyntaxKind.None: + break; + default: + throw new ArgumentException(nameof(semicolonToken)); + } + } #endif - return new EventDeclarationSyntax(SyntaxKind.EventDeclaration, attributeLists.Node, modifiers.Node, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, this.context); + return new EventDeclarationSyntax(SyntaxKind.EventDeclaration, attributeLists.Node, modifiers.Node, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken, this.context); } public IndexerDeclarationSyntax IndexerDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken thisKeyword, BracketedParameterListSyntax parameterList, AccessorListSyntax accessorList, ArrowExpressionClauseSyntax expressionBody, SyntaxToken semicolonToken) @@ -48398,7 +48442,7 @@ public static ArrowExpressionClauseSyntax ArrowExpressionClause(SyntaxToken arro return result; } - public static EventDeclarationSyntax EventDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + public static EventDeclarationSyntax EventDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken) { #if DEBUG if (eventKeyword == null) @@ -48421,11 +48465,20 @@ public static EventDeclarationSyntax EventDeclaration(Microsoft.CodeAnalysis.Syn default: throw new ArgumentException(nameof(identifier)); } - if (accessorList == null) - throw new ArgumentNullException(nameof(accessorList)); + if (semicolonToken != null) + { + switch (semicolonToken.Kind) + { + case SyntaxKind.SemicolonToken: + case SyntaxKind.None: + break; + default: + throw new ArgumentException(nameof(semicolonToken)); + } + } #endif - return new EventDeclarationSyntax(SyntaxKind.EventDeclaration, attributeLists.Node, modifiers.Node, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList); + return new EventDeclarationSyntax(SyntaxKind.EventDeclaration, attributeLists.Node, modifiers.Node, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken); } public static IndexerDeclarationSyntax IndexerDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken thisKeyword, BracketedParameterListSyntax parameterList, AccessorListSyntax accessorList, ArrowExpressionClauseSyntax expressionBody, SyntaxToken semicolonToken) diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs index a47cc830d4af9..5ce8071d71636 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs @@ -4027,7 +4027,8 @@ public override SyntaxNode VisitEventDeclaration(EventDeclarationSyntax node) var explicitInterfaceSpecifier = (ExplicitInterfaceSpecifierSyntax)this.Visit(node.ExplicitInterfaceSpecifier); var identifier = this.VisitToken(node.Identifier); var accessorList = (AccessorListSyntax)this.Visit(node.AccessorList); - return node.Update(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList); + var semicolonToken = this.VisitToken(node.SemicolonToken); + return node.Update(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken); } public override SyntaxNode VisitIndexerDeclaration(IndexerDeclarationSyntax node) @@ -9793,7 +9794,7 @@ public static ArrowExpressionClauseSyntax ArrowExpressionClause(ExpressionSyntax } /// Creates a new EventDeclarationSyntax instance. - public static EventDeclarationSyntax EventDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + public static EventDeclarationSyntax EventDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken) { switch (eventKeyword.Kind()) { @@ -9811,28 +9812,34 @@ public static EventDeclarationSyntax EventDeclaration(SyntaxList(), modifiers.Node.ToGreenList(), (Syntax.InternalSyntax.SyntaxToken)eventKeyword.Node, type == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.TypeSyntax)type.Green, explicitInterfaceSpecifier == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.ExplicitInterfaceSpecifierSyntax)explicitInterfaceSpecifier.Green, (Syntax.InternalSyntax.SyntaxToken)identifier.Node, accessorList == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.AccessorListSyntax)accessorList.Green).CreateRed(); + switch (semicolonToken.Kind()) + { + case SyntaxKind.SemicolonToken: + case SyntaxKind.None: + break; + default: + throw new ArgumentException(nameof(semicolonToken)); + } + return (EventDeclarationSyntax)Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.SyntaxFactory.EventDeclaration(attributeLists.Node.ToGreenList(), modifiers.Node.ToGreenList(), (Syntax.InternalSyntax.SyntaxToken)eventKeyword.Node, type == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.TypeSyntax)type.Green, explicitInterfaceSpecifier == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.ExplicitInterfaceSpecifierSyntax)explicitInterfaceSpecifier.Green, (Syntax.InternalSyntax.SyntaxToken)identifier.Node, accessorList == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.AccessorListSyntax)accessorList.Green, (Syntax.InternalSyntax.SyntaxToken)semicolonToken.Node).CreateRed(); } /// Creates a new EventDeclarationSyntax instance. public static EventDeclarationSyntax EventDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) { - return SyntaxFactory.EventDeclaration(attributeLists, modifiers, SyntaxFactory.Token(SyntaxKind.EventKeyword), type, explicitInterfaceSpecifier, identifier, accessorList); + return SyntaxFactory.EventDeclaration(attributeLists, modifiers, SyntaxFactory.Token(SyntaxKind.EventKeyword), type, explicitInterfaceSpecifier, identifier, accessorList, default(SyntaxToken)); } /// Creates a new EventDeclarationSyntax instance. public static EventDeclarationSyntax EventDeclaration(TypeSyntax type, SyntaxToken identifier) { - return SyntaxFactory.EventDeclaration(default(SyntaxList), default(SyntaxTokenList), SyntaxFactory.Token(SyntaxKind.EventKeyword), type, default(ExplicitInterfaceSpecifierSyntax), identifier, SyntaxFactory.AccessorList()); + return SyntaxFactory.EventDeclaration(default(SyntaxList), default(SyntaxTokenList), SyntaxFactory.Token(SyntaxKind.EventKeyword), type, default(ExplicitInterfaceSpecifierSyntax), identifier, default(AccessorListSyntax), default(SyntaxToken)); } /// Creates a new EventDeclarationSyntax instance. public static EventDeclarationSyntax EventDeclaration(TypeSyntax type, string identifier) { - return SyntaxFactory.EventDeclaration(default(SyntaxList), default(SyntaxTokenList), SyntaxFactory.Token(SyntaxKind.EventKeyword), type, default(ExplicitInterfaceSpecifierSyntax), SyntaxFactory.Identifier(identifier), SyntaxFactory.AccessorList()); + return SyntaxFactory.EventDeclaration(default(SyntaxList), default(SyntaxTokenList), SyntaxFactory.Token(SyntaxKind.EventKeyword), type, default(ExplicitInterfaceSpecifierSyntax), SyntaxFactory.Identifier(identifier), default(AccessorListSyntax), default(SyntaxToken)); } /// Creates a new IndexerDeclarationSyntax instance. diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs index e520bb5d7e30f..800434c40f748 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs @@ -17706,6 +17706,18 @@ public override AccessorListSyntax AccessorList } } + public SyntaxToken SemicolonToken + { + get + { + var slot = ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.EventDeclarationSyntax)this.Green).semicolonToken; + if (slot != null) + return new SyntaxToken(this, slot, this.GetChildPosition(7), this.GetChildIndex(7)); + + return default(SyntaxToken); + } + } + internal override SyntaxNode GetNodeSlot(int index) { switch (index) @@ -17739,11 +17751,11 @@ public override void Accept(CSharpSyntaxVisitor visitor) visitor.VisitEventDeclaration(this); } - public EventDeclarationSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + public EventDeclarationSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, SyntaxToken semicolonToken) { - if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || eventKeyword != this.EventKeyword || type != this.Type || explicitInterfaceSpecifier != this.ExplicitInterfaceSpecifier || identifier != this.Identifier || accessorList != this.AccessorList) + if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || eventKeyword != this.EventKeyword || type != this.Type || explicitInterfaceSpecifier != this.ExplicitInterfaceSpecifier || identifier != this.Identifier || accessorList != this.AccessorList || semicolonToken != this.SemicolonToken) { - var newNode = SyntaxFactory.EventDeclaration(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList); + var newNode = SyntaxFactory.EventDeclaration(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken); var annotations = this.GetAnnotations(); if (annotations != null && annotations.Length > 0) return newNode.WithAnnotations(annotations); @@ -17756,41 +17768,46 @@ public EventDeclarationSyntax Update(SyntaxList attributeLi internal override BasePropertyDeclarationSyntax WithAttributeListsCore(SyntaxList attributeLists) => WithAttributeLists(attributeLists); public new EventDeclarationSyntax WithAttributeLists(SyntaxList attributeLists) { - return this.Update(attributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList); + return this.Update(attributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList, this.SemicolonToken); } internal override BasePropertyDeclarationSyntax WithModifiersCore(SyntaxTokenList modifiers) => WithModifiers(modifiers); public new EventDeclarationSyntax WithModifiers(SyntaxTokenList modifiers) { - return this.Update(this.AttributeLists, modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList); + return this.Update(this.AttributeLists, modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList, this.SemicolonToken); } public EventDeclarationSyntax WithEventKeyword(SyntaxToken eventKeyword) { - return this.Update(this.AttributeLists, this.Modifiers, eventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList); + return this.Update(this.AttributeLists, this.Modifiers, eventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList, this.SemicolonToken); } internal override BasePropertyDeclarationSyntax WithTypeCore(TypeSyntax type) => WithType(type); public new EventDeclarationSyntax WithType(TypeSyntax type) { - return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList); + return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList, this.SemicolonToken); } internal override BasePropertyDeclarationSyntax WithExplicitInterfaceSpecifierCore(ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier) => WithExplicitInterfaceSpecifier(explicitInterfaceSpecifier); public new EventDeclarationSyntax WithExplicitInterfaceSpecifier(ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier) { - return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, explicitInterfaceSpecifier, this.Identifier, this.AccessorList); + return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, explicitInterfaceSpecifier, this.Identifier, this.AccessorList, this.SemicolonToken); } public EventDeclarationSyntax WithIdentifier(SyntaxToken identifier) { - return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, identifier, this.AccessorList); + return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, identifier, this.AccessorList, this.SemicolonToken); } internal override BasePropertyDeclarationSyntax WithAccessorListCore(AccessorListSyntax accessorList) => WithAccessorList(accessorList); public new EventDeclarationSyntax WithAccessorList(AccessorListSyntax accessorList) { - return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, accessorList); + return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, accessorList, this.SemicolonToken); + } + + public EventDeclarationSyntax WithSemicolonToken(SyntaxToken semicolonToken) + { + return this.Update(this.AttributeLists, this.Modifiers, this.EventKeyword, this.Type, this.ExplicitInterfaceSpecifier, this.Identifier, this.AccessorList, semicolonToken); } internal override BasePropertyDeclarationSyntax AddAttributeListsCore(params AttributeListSyntax[] items) => AddAttributeLists(items); @@ -17808,7 +17825,8 @@ public EventDeclarationSyntax WithIdentifier(SyntaxToken identifier) public new EventDeclarationSyntax AddAccessorListAccessors(params AccessorDeclarationSyntax[] items) { - return this.WithAccessorList(this.AccessorList.WithAccessors(this.AccessorList.Accessors.AddRange(items))); + var accessorList = this.AccessorList ?? SyntaxFactory.AccessorList(); + return this.WithAccessorList(accessorList.WithAccessors(accessorList.Accessors.AddRange(items))); } } diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StackAlloc.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StackAlloc.cs index e6d4c5ed95df0..de8717001b4f7 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StackAlloc.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StackAlloc.cs @@ -46,7 +46,8 @@ public override BoundNode VisitStackAllocArrayCreation(BoundStackAllocArrayCreat var locals = ArrayBuilder.GetInstance(); var countTemp = CaptureExpressionInTempIfNeeded(rewrittenCount, sideEffects, locals, SynthesizedLocalKind.Spill); var stackSize = RewriteStackAllocCountToSize(countTemp, elementType); - stackAllocNode = new BoundConvertedStackAllocExpression(stackAllocNode.Syntax, elementType, stackSize, initializerOpt, spanType); + stackAllocNode = new BoundConvertedStackAllocExpression( + stackAllocNode.Syntax, elementType, stackSize, initializerOpt, _compilation.CreatePointerTypeSymbol(elementType)); BoundExpression constructorCall; if (TryGetWellKnownTypeMember(stackAllocNode.Syntax, WellKnownMember.System_Span_T__ctor, out MethodSymbol spanConstructor)) diff --git a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs index dd60cbb1cd5d0..ddaa54eccac52 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs @@ -630,6 +630,14 @@ public override BoundNode VisitArrayInitialization(BoundArrayInitialization node return UpdateExpression(builder, node.Update(initializers)); } + public override BoundNode VisitConvertedStackAllocExpression(BoundConvertedStackAllocExpression node) + { + BoundSpillSequenceBuilder builder = null; + BoundExpression count = VisitExpression(ref builder, node.Count); + var initializerOpt = (BoundArrayInitialization)VisitExpression(ref builder, node.InitializerOpt); + return UpdateExpression(builder, node.Update(node.ElementType, count, initializerOpt, node.Type)); + } + public override BoundNode VisitArrayLength(BoundArrayLength node) { BoundSpillSequenceBuilder builder = null; diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 43a8cfb1033bc..688064f569fca 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -411,11 +411,7 @@ private NamespaceDeclarationSyntax ParseNamespaceDeclarationCore() this.ParseNamespaceBody(ref openBrace, ref body, ref initialBadNodes, SyntaxKind.NamespaceDeclaration); var closeBrace = this.EatToken(SyntaxKind.CloseBraceToken); - SyntaxToken semicolon = null; - if (this.CurrentToken.Kind == SyntaxKind.SemicolonToken) - { - semicolon = this.EatToken(); - } + var semicolon = this.TryEatToken(SyntaxKind.SemicolonToken); Debug.Assert(initialBadNodes == null); // init bad nodes should have been attached to open brace... return _syntaxFactory.NamespaceDeclaration(namespaceToken, name, openBrace, body.Externs, body.Usings, body.Members, closeBrace, semicolon); @@ -808,12 +804,7 @@ private UsingDirectiveSyntax ParseUsingDirective() Debug.Assert(this.CurrentToken.Kind == SyntaxKind.UsingKeyword); var usingToken = this.EatToken(SyntaxKind.UsingKeyword); - - var staticToken = default(SyntaxToken); - if (this.CurrentToken.Kind == SyntaxKind.StaticKeyword) - { - staticToken = this.EatToken(SyntaxKind.StaticKeyword); - } + var staticToken = this.TryEatToken(SyntaxKind.StaticKeyword); var alias = this.IsNamedAssignment() ? ParseNameEquals() : null; @@ -1587,12 +1578,7 @@ private TypeDeclarationSyntax ParseClassOrStructOrInterfaceDeclaration(SyntaxLis closeBrace = this.EatToken(SyntaxKind.CloseBraceToken); } - SyntaxToken semicolon = null; - if (this.CurrentToken.Kind == SyntaxKind.SemicolonToken) - { - semicolon = this.EatToken(); - } - + var semicolon = TryEatToken(SyntaxKind.SemicolonToken); switch (classOrStructOrInterface.Kind) { case SyntaxKind.ClassKeyword: @@ -1911,11 +1897,7 @@ private TypeParameterConstraintSyntax ParseTypeParameterConstraint() return _syntaxFactory.ClassOrStructConstraint(SyntaxKind.StructConstraint, structToken, questionToken); case SyntaxKind.ClassKeyword: var classToken = this.EatToken(); - - if (this.CurrentToken.Kind == SyntaxKind.QuestionToken) - { - questionToken = this.EatToken(); - } + questionToken = this.TryEatToken(SyntaxKind.QuestionToken); return _syntaxFactory.ClassOrStructConstraint(SyntaxKind.ClassConstraint, classToken, questionToken); default: @@ -3461,12 +3443,6 @@ private AccessorDeclarationSyntax ParseAccessorDeclaration(bool isEvent) else if (currentTokenIsSemicolon) { semicolon = EatAccessorSemicolon(); - - if (accessorKind == SyntaxKind.AddAccessorDeclaration || - accessorKind == SyntaxKind.RemoveAccessorDeclaration) - { - semicolon = this.AddError(semicolon, ErrorCode.ERR_AddRemoveMustHaveBody); - } } else { @@ -3990,7 +3966,7 @@ private EventDeclarationSyntax ParseEventDeclarationWithAccessors( // If we got an explicitInterfaceOpt but not an identifier, then we're in the special // case for ERR_ExplicitEventFieldImpl (see ParseMemberName for details). - if (explicitInterfaceOpt != null && this.CurrentToken.Kind != SyntaxKind.OpenBraceToken) + if (explicitInterfaceOpt != null && this.CurrentToken.Kind != SyntaxKind.OpenBraceToken && this.CurrentToken.Kind != SyntaxKind.SemicolonToken) { Debug.Assert(typeParameterList == null, "Exit condition of ParseMemberName in this scenario"); @@ -4010,7 +3986,8 @@ private EventDeclarationSyntax ParseEventDeclarationWithAccessors( type, explicitInterfaceOpt, //already has an appropriate error attached missingIdentifier, - missingAccessorList); + missingAccessorList, + semicolonToken: null); } SyntaxToken identifier; @@ -4043,7 +4020,17 @@ private EventDeclarationSyntax ParseEventDeclarationWithAccessors( identifier = this.AddError(identifier, ErrorCode.ERR_UnexpectedGenericName); } - var accessorList = this.ParseAccessorList(isEvent: true); + AccessorListSyntax accessorList = null; + SyntaxToken semicolon = null; + + if (explicitInterfaceOpt != null && this.CurrentToken.Kind == SyntaxKind.SemicolonToken) + { + semicolon = this.EatToken(SyntaxKind.SemicolonToken); + } + else + { + accessorList = this.ParseAccessorList(isEvent: true); + } var decl = _syntaxFactory.EventDeclaration( attributes, @@ -4052,7 +4039,8 @@ private EventDeclarationSyntax ParseEventDeclarationWithAccessors( type, explicitInterfaceOpt, identifier, - accessorList); + accessorList, + semicolon); decl = EatUnexpectedTrailingSemicolon(decl); @@ -4744,12 +4732,7 @@ private EnumDeclarationSyntax ParseEnumDeclaration(SyntaxListBuilder private StatementSyntax ParseLocalDeclarationStatement(SyntaxToken awaitKeywordOpt = default) { - var usingKeyword = this.CurrentToken.Kind == SyntaxKind.UsingKeyword ? this.EatToken() : null; + var usingKeyword = TryEatToken(SyntaxKind.UsingKeyword); if (usingKeyword != null) { usingKeyword = CheckFeatureAvailability(usingKeyword, MessageID.IDS_FeatureUsingDeclarations); diff --git a/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs b/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs index 5fadeff18c6fe..73d759e377f64 100644 --- a/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs @@ -439,6 +439,13 @@ protected SyntaxToken EatToken() return ct; } + /// + /// Returns and consumes the current token if it has the requested . + /// Otherwise, returns . + /// + protected SyntaxToken TryEatToken(SyntaxKind kind) + => this.CurrentToken.Kind == kind ? this.EatToken() : null; + private void MoveToNextToken() { _prevTokenTrailingTrivia = _currentToken.GetTrailingTrivia(); diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index 3fa95246cab34..4ce2e58b871b5 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -4,6 +4,10 @@ *REMOVED*static Microsoft.CodeAnalysis.CSharp.LanguageVersionFacts.TryParse(this string version, out Microsoft.CodeAnalysis.CSharp.LanguageVersion result) -> bool *REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(Microsoft.CodeAnalysis.Text.SourceText text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree *REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(string text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Text.Encoding encoding = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree +Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax.SemicolonToken.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken eventKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.AccessorListSyntax accessorList, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken eventKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.ExclamationToken.get -> Microsoft.CodeAnalysis.SyntaxToken Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.WithExclamationToken(Microsoft.CodeAnalysis.SyntaxToken exclamationToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax @@ -281,6 +285,8 @@ static Microsoft.CodeAnalysis.CSharp.SymbolDisplay.ToMinimalDisplayString(Micros static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ClassOrStructConstraint(Microsoft.CodeAnalysis.CSharp.SyntaxKind kind, Microsoft.CodeAnalysis.SyntaxToken classOrStructKeyword, Microsoft.CodeAnalysis.SyntaxToken questionToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ClassOrStructConstraintSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DiscardPattern() -> Microsoft.CodeAnalysis.CSharp.Syntax.DiscardPatternSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DiscardPattern(Microsoft.CodeAnalysis.SyntaxToken underscoreToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DiscardPatternSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.EventDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken eventKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.AccessorListSyntax accessorList, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.EventDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken eventKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachStatement(Microsoft.CodeAnalysis.SyntaxToken awaitKeyword, Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachVariableStatement(Microsoft.CodeAnalysis.SyntaxToken awaitKeyword, Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variable, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalDeclarationStatement(Microsoft.CodeAnalysis.SyntaxToken awaitKeyword, Microsoft.CodeAnalysis.SyntaxToken usingKeyword, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax diff --git a/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/ParameterWellKnownAttributeData.cs b/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/ParameterWellKnownAttributeData.cs index 97148a914a0a9..0f8daecf1ebb1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/ParameterWellKnownAttributeData.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/ParameterWellKnownAttributeData.cs @@ -7,50 +7,98 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols /// internal sealed class ParameterWellKnownAttributeData : CommonParameterWellKnownAttributeData { - private bool _hasNotNullWhenTrueAttribute; - public bool HasNotNullWhenTrueAttribute + private bool _hasAllowNullAttribute; + public bool HasAllowNullAttribute { get { VerifySealed(expected: true); - return _hasNotNullWhenTrueAttribute; + return _hasAllowNullAttribute; } set { VerifySealed(expected: false); - _hasNotNullWhenTrueAttribute = value; + _hasAllowNullAttribute = value; SetDataStored(); } } - private bool _hasNotNullWhenFalseAttribute; - public bool HasNotNullWhenFalseAttribute + private bool _hasDisallowNullAttribute; + public bool HasDisallowNullAttribute { get { VerifySealed(expected: true); - return _hasNotNullWhenFalseAttribute; + return _hasDisallowNullAttribute; } set { VerifySealed(expected: false); - _hasNotNullWhenFalseAttribute = value; + _hasDisallowNullAttribute = value; SetDataStored(); } } - private bool _hasEnsuresNotNullAttribute; - public bool HasEnsuresNotNullAttribute + private bool _hasMaybeNullAttribute; + public bool HasMaybeNullAttribute { get { VerifySealed(expected: true); - return _hasEnsuresNotNullAttribute; + return _hasMaybeNullAttribute; } set { VerifySealed(expected: false); - _hasEnsuresNotNullAttribute = value; + _hasMaybeNullAttribute = value; + SetDataStored(); + } + } + + private bool? _maybeNullWhenAttribute; + public bool? MaybeNullWhenAttribute + { + get + { + VerifySealed(expected: true); + return _maybeNullWhenAttribute; + } + set + { + VerifySealed(expected: false); + _maybeNullWhenAttribute = value; + SetDataStored(); + } + } + + private bool _hasNotNullAttribute; + public bool HasNotNullAttribute + { + get + { + VerifySealed(expected: true); + return _hasNotNullAttribute; + } + set + { + VerifySealed(expected: false); + _hasNotNullAttribute = value; + SetDataStored(); + } + } + + private bool? _notNullWhenAttribute; + public bool? NotNullWhenAttribute + { + get + { + VerifySealed(expected: true); + return _notNullWhenAttribute; + } + set + { + VerifySealed(expected: false); + _notNullWhenAttribute = value; SetDataStored(); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs index 8a035e42efcca..a865e1223d5e5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ExtraAnnotations.cs @@ -39,7 +39,7 @@ internal static class ExtraAnnotations { { "System.Boolean System.String.IsNullOrEmpty(System.String)", Array(default, NotNullWhenFalse) }, { "System.Boolean System.String.IsNullOrWhiteSpace(System.String)", Array(default, NotNullWhenFalse) }, - { "System.Boolean System.String.Contains(System.String)", Array(default, EnsuresNotNull) }, + { "System.Boolean System.String.Contains(System.String)", Array(default, NotNull) }, { "System.Void System.Diagnostics.Debug.Assert(System.Boolean)", Array(default, AssertsTrue) }, { "System.Void System.Diagnostics.Debug.Assert(System.Boolean, System.String)", Array(default, AssertsTrue, default) }, { "System.Void System.Diagnostics.Debug.Assert(System.Boolean, System.String, System.String)", Array(default, AssertsTrue, default, default) }, diff --git a/src/Compilers/CSharp/Portable/Symbols/FlowAnalysisAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/FlowAnalysisAnnotations.cs index f4b2b7ce120fc..ead654670cc3f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/FlowAnalysisAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/FlowAnalysisAnnotations.cs @@ -1,7 +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; -using static Microsoft.CodeAnalysis.CSharp.Symbols.FlowAnalysisAnnotations; namespace Microsoft.CodeAnalysis.CSharp.Symbols { @@ -9,42 +8,15 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols internal enum FlowAnalysisAnnotations { None = 0, - NotNullWhenTrue = 1 << 0, - NotNullWhenFalse = 1 << 1, - EnsuresNotNull = NotNullWhenTrue | NotNullWhenFalse, - AssertsTrue = 1 << 2, - AssertsFalse = 1 << 3, - } - - internal static class FlowAnalysisAnnotationsFacts - { - /// - /// For EnsuresNotNull, you should set NotNullWhenTrue and NotNullWhenFalse. - /// - internal static FlowAnalysisAnnotations Create(bool notNullWhenTrue, bool notNullWhenFalse, bool assertsTrue, bool assertsFalse) - { - FlowAnalysisAnnotations value = None; - if (notNullWhenFalse) - { - value |= NotNullWhenFalse; - } - - if (notNullWhenTrue) - { - value |= NotNullWhenTrue; - } - - if (assertsTrue) - { - value |= AssertsTrue; - } - - if (assertsFalse) - { - value |= AssertsFalse; - } - - return value; - } + AllowNull = 1 << 0, + DisallowNull = 1 << 1, + MaybeNullWhenTrue = 1 << 2, + MaybeNullWhenFalse = 1 << 3, + MaybeNull = MaybeNullWhenTrue | MaybeNullWhenFalse, + NotNullWhenTrue = 1 << 4, + NotNullWhenFalse = 1 << 5, + NotNull = NotNullWhenTrue | NotNullWhenFalse, + AssertsTrue = 1 << 6, + AssertsFalse = 1 << 7, } } diff --git a/src/Compilers/CSharp/Portable/Symbols/MemberSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/MemberSymbolExtensions.cs index 528f48f885882..bc5e7be5e1366 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MemberSymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MemberSymbolExtensions.cs @@ -144,7 +144,7 @@ bool isImplementableAndNotPublic(MethodSymbol accessor) public static bool IsImplementable(this MethodSymbol methodOpt) { - return (object)methodOpt != null && (methodOpt.IsAbstract || methodOpt.IsVirtual); + return (object)methodOpt != null && !methodOpt.IsSealed && (methodOpt.IsAbstract || methodOpt.IsVirtual); } public static bool IsAccessor(this MethodSymbol methodSymbol) diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index 5e7f1ec8782ad..c9cc9cc1f8fc2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -118,9 +118,7 @@ static PackedFlags() // 1) Verify that the range of method kinds doesn't fall outside the bounds of the // method kind mask. - var methodKinds = EnumUtilities.GetValues(); - var maxMethodKind = (int)System.Linq.Enumerable.Aggregate(methodKinds, (m1, m2) => m1 | m2); - Debug.Assert((maxMethodKind & MethodKindMask) == maxMethodKind); + Debug.Assert(EnumUtilities.ContainsAllValues(MethodKindMask)); } #endif @@ -429,14 +427,18 @@ public override int Arity // error if it is overridden - it emits a virtual method without the newslot // modifier as for a normal override. It is not clear how the runtime rules // interpret this overriding method since the overridden method is invalid. - public override bool IsSealed => this.IsMetadataFinal && !this.IsAbstract && this.IsOverride; //slowest check last + public override bool IsSealed => this.IsMetadataFinal && + (this._containingType.IsInterface ? + this.IsAbstract && this.IsMetadataVirtual() && !this.IsMetadataNewSlot() : + !this.IsAbstract && this.IsOverride); //slowest check last public override bool HidesBaseMethodsByName => !HasFlag(MethodAttributes.HideBySig); // Has to be metadata virtual and cannot be a destructor. Cannot be either abstract or override. // Final is a little special - if a method has the virtual, newslot, and final attr // (and is not an explicit override) then we treat it as non-virtual for C# purposes. - public override bool IsVirtual => this.IsMetadataVirtual() && !this.IsDestructor && !this.IsMetadataFinal && !this.IsAbstract && !this.IsOverride; + public override bool IsVirtual => this.IsMetadataVirtual() && !this.IsDestructor && !this.IsMetadataFinal && !this.IsAbstract && + (this._containingType.IsInterface ? this.IsMetadataNewSlot() : !this.IsOverride); // Has to be metadata virtual and cannot be a destructor. // Must either lack the newslot flag or be an explicit override (i.e. via the MethodImpl table). @@ -450,8 +452,9 @@ public override int Arity // This means that a virtual method without NewSlot flag in a type that doesn't have a base // is a new virtual method and doesn't override anything. public override bool IsOverride => + !this._containingType.IsInterface && this.IsMetadataVirtual() && !this.IsDestructor && - ((!this.IsMetadataNewSlot() && (object)_containingType.BaseTypeNoUseSiteDiagnostics != null) || this.IsExplicitClassOverride); + ((!this.IsMetadataNewSlot() && (object)_containingType.BaseTypeNoUseSiteDiagnostics != null) || this.IsExplicitClassOverride); public override bool IsStatic => HasFlag(MethodAttributes.Static); diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs index 02c047a7acc33..8126f1de7823c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; -using System.Linq; using System.Reflection; using System.Reflection.Metadata; using System.Runtime.InteropServices; @@ -31,31 +30,31 @@ private enum WellKnownAttributeFlags IsCallerFilePath = 0x1 << 5, IsCallerLineNumber = 0x1 << 6, IsCallerMemberName = 0x1 << 7, - NotNullWhenTrue = 0x1 << 8, - NotNullWhenFalse = 0x1 << 9, - AssertsTrue = 0x1 << 10, - AssertsFalse = 0x1 << 11, } private struct PackedFlags { // Layout: - // |.....|n|rr|cccccccccccc|vvvvvvvvvvvv| + // |...|fffffffff|n|rr|cccccccc|vvvvvvvv| // - // v = decoded well known attribute values. 12 bits. - // c = completion states for well known attributes. 1 if given attribute has been decoded, 0 otherwise. 12 bits. + // v = decoded well known attribute values. 8 bits. + // c = completion states for well known attributes. 1 if given attribute has been decoded, 0 otherwise. 8 bits. // r = RefKind. 2 bits. // n = hasNameInMetadata. 1 bit. + // f = FlowAnalysisAnnotations. 9 bits (8 value bits + 1 completion bit). private const int WellKnownAttributeDataOffset = 0; - private const int WellKnownAttributeCompletionFlagOffset = 12; - private const int RefKindOffset = 24; + private const int WellKnownAttributeCompletionFlagOffset = 8; + private const int RefKindOffset = 16; + private const int FlowAnalysisAnnotationsOffset = 20; private const int RefKindMask = 0x3; - private const int WellKnownAttributeDataMask = 0xFFF; + private const int WellKnownAttributeDataMask = 0xFF; private const int WellKnownAttributeCompletionFlagMask = WellKnownAttributeDataMask; + private const int FlowAnalysisAnnotationsMask = 0xFF; - private const int HasNameInMetadataBit = 0x1 << 26; + private const int HasNameInMetadataBit = 0x1 << 18; + private const int FlowAnalysisAnnotationsCompletionBit = 0x1 << 19; private const int AllWellKnownAttributesCompleteNoData = WellKnownAttributeCompletionFlagMask << WellKnownAttributeCompletionFlagOffset; @@ -79,15 +78,13 @@ static PackedFlags() // 1) Verify that the range of well known attributes doesn't fall outside the bounds of // the attribute completion and data mask. - var attributeFlags = EnumUtilities.GetValues(); - var maxAttributeFlag = (int)System.Linq.Enumerable.Aggregate(attributeFlags, (f1, f2) => f1 | f2); - Debug.Assert((maxAttributeFlag & WellKnownAttributeDataMask) == maxAttributeFlag); + Debug.Assert(EnumUtilities.ContainsAllValues(WellKnownAttributeDataMask)); // 2) Verify that the range of ref kinds doesn't fall outside the bounds of // the ref kind mask. - var refKinds = EnumUtilities.GetValues(); - var maxRefKind = (int)System.Linq.Enumerable.Aggregate(refKinds, (r1, r2) => r1 | r2); - Debug.Assert((maxRefKind & RefKindMask) == maxRefKind); + Debug.Assert(EnumUtilities.ContainsAllValues(RefKindMask)); + + Debug.Assert(EnumUtilities.ContainsAllValues(FlowAnalysisAnnotationsMask)); } #endif @@ -120,6 +117,21 @@ public bool TryGetWellKnownAttribute(WellKnownAttributeFlags flag, out bool valu value = (theBits & ((int)flag << WellKnownAttributeDataOffset)) != 0; return (theBits & ((int)flag << WellKnownAttributeCompletionFlagOffset)) != 0; } + + public bool SetFlowAnalysisAnnotations(FlowAnalysisAnnotations value) + { + int bitsToSet = FlowAnalysisAnnotationsCompletionBit | (((int)value & FlowAnalysisAnnotationsMask) << FlowAnalysisAnnotationsOffset); + return ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); + } + + public bool TryGetFlowAnalysisAnnotations(out FlowAnalysisAnnotations value) + { + int theBits = _bits; // Read this.bits once to ensure the consistency of the value and completion flags. + value = (FlowAnalysisAnnotations)((theBits >> FlowAnalysisAnnotationsOffset) & FlowAnalysisAnnotationsMask); + var result = (theBits & FlowAnalysisAnnotationsCompletionBit) != 0; + Debug.Assert(value == 0 || result); + return result; + } } private readonly Symbol _containingSymbol; @@ -644,50 +656,41 @@ internal override FlowAnalysisAnnotations FlowAnalysisAnnotations { get { - const WellKnownAttributeFlags notNullWhenTrue = WellKnownAttributeFlags.NotNullWhenTrue; - const WellKnownAttributeFlags notNullWhenFalse = WellKnownAttributeFlags.NotNullWhenFalse; - const WellKnownAttributeFlags assertsTrue = WellKnownAttributeFlags.AssertsTrue; - const WellKnownAttributeFlags assertsFalse = WellKnownAttributeFlags.AssertsFalse; - - if (!_packedFlags.TryGetWellKnownAttribute(notNullWhenTrue, out bool hasNotNullWhenTrue) || - !_packedFlags.TryGetWellKnownAttribute(notNullWhenFalse, out bool hasNotNullWhenFalse) || - !_packedFlags.TryGetWellKnownAttribute(assertsTrue, out bool hasAssertsTrue) || - !_packedFlags.TryGetWellKnownAttribute(assertsFalse, out bool hasAssertsFalse)) + FlowAnalysisAnnotations value; + if (!_packedFlags.TryGetFlowAnalysisAnnotations(out value)) { - FlowAnalysisAnnotations? annotations = TryGetExtraAttributeAnnotations(); - - if (annotations.HasValue) - { - // External annotations win, if any is present on the member - hasNotNullWhenTrue = (annotations & FlowAnalysisAnnotations.NotNullWhenTrue) != 0; - hasNotNullWhenFalse = (annotations & FlowAnalysisAnnotations.NotNullWhenFalse) != 0; - hasAssertsTrue = (annotations & FlowAnalysisAnnotations.AssertsTrue) != 0; - hasAssertsFalse = (annotations & FlowAnalysisAnnotations.AssertsFalse) != 0; - } - else - { - bool hasEnsuresNotNull = _moduleSymbol.Module.HasAttribute(_handle, AttributeDescription.EnsuresNotNullAttribute); - hasNotNullWhenTrue = hasEnsuresNotNull || _moduleSymbol.Module.HasAttribute(_handle, AttributeDescription.NotNullWhenTrueAttribute); - hasNotNullWhenFalse = hasEnsuresNotNull || _moduleSymbol.Module.HasAttribute(_handle, AttributeDescription.NotNullWhenFalseAttribute); - hasAssertsTrue = _moduleSymbol.Module.HasAttribute(_handle, AttributeDescription.AssertsTrueAttribute); - hasAssertsFalse = _moduleSymbol.Module.HasAttribute(_handle, AttributeDescription.AssertsFalseAttribute); - } - - _packedFlags.SetWellKnownAttribute(notNullWhenTrue, hasNotNullWhenTrue); - _packedFlags.SetWellKnownAttribute(notNullWhenFalse, hasNotNullWhenFalse); - _packedFlags.SetWellKnownAttribute(assertsTrue, hasAssertsTrue); - _packedFlags.SetWellKnownAttribute(assertsFalse, hasAssertsFalse); - - if (annotations.HasValue) - { - return annotations.Value; - } + // External annotations win, if any is present on the member + value = TryGetExtraAttributeAnnotations() ?? DecodeFlowAnalysisAttributes(_moduleSymbol.Module, _handle); + _packedFlags.SetFlowAnalysisAnnotations(value); } + return value; + } + } - return FlowAnalysisAnnotationsFacts.Create( - notNullWhenTrue: hasNotNullWhenTrue, notNullWhenFalse: hasNotNullWhenFalse, - assertsTrue: hasAssertsTrue, assertsFalse: hasAssertsFalse); + private static FlowAnalysisAnnotations DecodeFlowAnalysisAttributes(PEModule module, ParameterHandle handle) + { + FlowAnalysisAnnotations annotations = FlowAnalysisAnnotations.None; + if (module.HasAttribute(handle, AttributeDescription.AllowNullAttribute)) annotations |= FlowAnalysisAnnotations.AllowNull; + if (module.HasAttribute(handle, AttributeDescription.DisallowNullAttribute)) annotations |= FlowAnalysisAnnotations.DisallowNull; + if (module.HasAttribute(handle, AttributeDescription.MaybeNullAttribute)) + { + annotations |= FlowAnalysisAnnotations.MaybeNull; + } + else if (module.HasMaybeNullWhenOrNotNullWhenAttribute(handle, AttributeDescription.MaybeNullWhenAttribute, out bool when)) + { + annotations |= (when ? FlowAnalysisAnnotations.MaybeNullWhenTrue : FlowAnalysisAnnotations.MaybeNullWhenFalse); + } + if (module.HasAttribute(handle, AttributeDescription.NotNullAttribute)) + { + annotations |= FlowAnalysisAnnotations.NotNull; + } + else if (module.HasMaybeNullWhenOrNotNullWhenAttribute(handle, AttributeDescription.NotNullWhenAttribute, out bool when)) + { + annotations |= (when ? FlowAnalysisAnnotations.NotNullWhenTrue : FlowAnalysisAnnotations.NotNullWhenFalse); } + if (module.HasAttribute(handle, AttributeDescription.AssertsTrueAttribute)) annotations |= FlowAnalysisAnnotations.AssertsTrue; + if (module.HasAttribute(handle, AttributeDescription.AssertsFalseAttribute)) annotations |= FlowAnalysisAnnotations.AssertsFalse; + return annotations; } public override TypeWithAnnotations TypeWithAnnotations diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs index 0b1096d8ae9b4..87a47b0c58aa9 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs @@ -122,9 +122,17 @@ internal static void ReportDefaultInterfaceImplementationModifiers( internal static DeclarationModifiers AdjustModifiersForAnInterfaceMember(DeclarationModifiers mods, bool hasBody, bool isExplicitInterfaceImplementation) { - if ((mods & (DeclarationModifiers.Static | DeclarationModifiers.Private | DeclarationModifiers.Partial | DeclarationModifiers.Virtual | DeclarationModifiers.Abstract)) == 0 && - !isExplicitInterfaceImplementation) + if (isExplicitInterfaceImplementation) { + if ((mods & DeclarationModifiers.Abstract) != 0) + { + mods |= DeclarationModifiers.Sealed; + } + } + else if ((mods & (DeclarationModifiers.Static | DeclarationModifiers.Private | DeclarationModifiers.Partial | DeclarationModifiers.Virtual | DeclarationModifiers.Abstract)) == 0) + { + Debug.Assert(!isExplicitInterfaceImplementation); + if (hasBody || (mods & (DeclarationModifiers.Extern | DeclarationModifiers.Sealed)) != 0) { if ((mods & DeclarationModifiers.Sealed) == 0) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs index 9790ebac65193..dac4060584617 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs @@ -137,16 +137,46 @@ internal override FlowAnalysisAnnotations FlowAnalysisAnnotations // https://github.com/dotnet/roslyn/issues/30078: Make sure this is covered by test return annotations.Value; } + return DecodeFlowAnalysisAttributes(GetDecodedWellKnownAttributeData()); + } + } - ParameterWellKnownAttributeData attributeData = GetDecodedWellKnownAttributeData(); - bool hasEnsuresNotNull = attributeData?.HasEnsuresNotNullAttribute == true; - - return FlowAnalysisAnnotationsFacts.Create( - notNullWhenTrue: hasEnsuresNotNull || attributeData?.HasNotNullWhenTrueAttribute == true, - notNullWhenFalse: hasEnsuresNotNull || attributeData?.HasNotNullWhenFalseAttribute == true, - assertsTrue: attributeData?.HasAssertsTrueAttribute == true, - assertsFalse: attributeData?.HasAssertsFalseAttribute == true); + private static FlowAnalysisAnnotations DecodeFlowAnalysisAttributes(ParameterWellKnownAttributeData attributeData) + { + if (attributeData == null) + { + return FlowAnalysisAnnotations.None; + } + FlowAnalysisAnnotations annotations = FlowAnalysisAnnotations.None; + if (attributeData.HasAllowNullAttribute) annotations |= FlowAnalysisAnnotations.AllowNull; + if (attributeData.HasDisallowNullAttribute) annotations |= FlowAnalysisAnnotations.DisallowNull; + if (attributeData.HasMaybeNullAttribute) + { + annotations |= FlowAnalysisAnnotations.MaybeNull; + } + else + { + bool? value = attributeData.MaybeNullWhenAttribute; + if (value.HasValue) + { + annotations |= (value.GetValueOrDefault() ? FlowAnalysisAnnotations.MaybeNullWhenTrue : FlowAnalysisAnnotations.MaybeNullWhenFalse); + } + } + if (attributeData.HasNotNullAttribute) + { + annotations |= FlowAnalysisAnnotations.NotNull; } + else + { + bool? value = attributeData.NotNullWhenAttribute; + if (value.HasValue) + { + annotations |= (value.GetValueOrDefault() ? FlowAnalysisAnnotations.NotNullWhenTrue : FlowAnalysisAnnotations.NotNullWhenFalse); + } + } + if (attributeData.HasAssertsTrueAttribute) annotations |= FlowAnalysisAnnotations.AssertsTrue; + if (attributeData.HasAssertsFalseAttribute) annotations |= FlowAnalysisAnnotations.AssertsFalse; + return annotations; } internal bool HasEnumeratorCancellationAttribute @@ -640,17 +670,29 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu // NullableAttribute should not be set explicitly. arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location); } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NotNullWhenTrueAttribute)) + else if (attribute.IsTargetAttribute(this, AttributeDescription.AllowNullAttribute)) + { + arguments.GetOrCreateData().HasAllowNullAttribute = true; + } + else if (attribute.IsTargetAttribute(this, AttributeDescription.DisallowNullAttribute)) { - arguments.GetOrCreateData().HasNotNullWhenTrueAttribute = true; + arguments.GetOrCreateData().HasDisallowNullAttribute = true; } - else if (attribute.IsTargetAttribute(this, AttributeDescription.NotNullWhenFalseAttribute)) + else if (attribute.IsTargetAttribute(this, AttributeDescription.MaybeNullAttribute)) { - arguments.GetOrCreateData().HasNotNullWhenFalseAttribute = true; + arguments.GetOrCreateData().HasMaybeNullAttribute = true; } - else if (attribute.IsTargetAttribute(this, AttributeDescription.EnsuresNotNullAttribute)) + else if (attribute.IsTargetAttribute(this, AttributeDescription.MaybeNullWhenAttribute)) { - arguments.GetOrCreateData().HasEnsuresNotNullAttribute = true; + arguments.GetOrCreateData().MaybeNullWhenAttribute = DecodeMaybeNullWhenOrNotNullWhenAttribute(AttributeDescription.MaybeNullWhenAttribute, attribute, arguments.Diagnostics); + } + else if (attribute.IsTargetAttribute(this, AttributeDescription.NotNullAttribute)) + { + arguments.GetOrCreateData().HasNotNullAttribute = true; + } + else if (attribute.IsTargetAttribute(this, AttributeDescription.NotNullWhenAttribute)) + { + arguments.GetOrCreateData().NotNullWhenAttribute = DecodeMaybeNullWhenOrNotNullWhenAttribute(AttributeDescription.NotNullWhenAttribute, attribute, arguments.Diagnostics); } else if (attribute.IsTargetAttribute(this, AttributeDescription.AssertsTrueAttribute)) { @@ -667,6 +709,14 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu } } + private static bool? DecodeMaybeNullWhenOrNotNullWhenAttribute(AttributeDescription description, CSharpAttributeData attribute, DiagnosticBag diagnostics) + { + var arguments = attribute.CommonConstructorArguments; + return arguments.Length == 1 && arguments[0].TryDecodeValue(SpecialType.System_Boolean, out bool value) ? + (bool?)value : + null; + } + private void DecodeDefaultParameterValueAttribute(AttributeDescription description, ref DecodeWellKnownAttributeArguments arguments) { var attribute = arguments.Attribute; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs index 9e98ae1e5505a..5d56331f3e6ef 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs @@ -18,9 +18,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols /// internal sealed class SourceCustomEventAccessorSymbol : SourceEventAccessorSymbol { - private readonly ImmutableArray _explicitInterfaceImplementations; - private readonly string _name; - internal SourceCustomEventAccessorSymbol( SourceEventSymbol @event, AccessorDeclarationSyntax syntax, @@ -29,38 +26,11 @@ internal SourceCustomEventAccessorSymbol( DiagnosticBag diagnostics) : base(@event, syntax.GetReference(), - ImmutableArray.Create(syntax.Keyword.GetLocation())) + ImmutableArray.Create(syntax.Keyword.GetLocation()), explicitlyImplementedEventOpt, aliasQualifierOpt, isAdder: syntax.Kind() == SyntaxKind.AddAccessorDeclaration) { Debug.Assert(syntax != null); Debug.Assert(syntax.Kind() == SyntaxKind.AddAccessorDeclaration || syntax.Kind() == SyntaxKind.RemoveAccessorDeclaration); - bool isAdder = syntax.Kind() == SyntaxKind.AddAccessorDeclaration; - - string name; - ImmutableArray explicitInterfaceImplementations; - if ((object)explicitlyImplementedEventOpt == null) - { - name = SourceEventSymbol.GetAccessorName(@event.Name, isAdder); - explicitInterfaceImplementations = ImmutableArray.Empty; - } - else - { - MethodSymbol implementedAccessor = isAdder ? explicitlyImplementedEventOpt.AddMethod : explicitlyImplementedEventOpt.RemoveMethod; - string accessorName = (object)implementedAccessor != null ? implementedAccessor.Name : SourceEventSymbol.GetAccessorName(explicitlyImplementedEventOpt.Name, isAdder); - - name = ExplicitInterfaceHelpers.GetMemberName(accessorName, explicitlyImplementedEventOpt.ContainingType, aliasQualifierOpt); - explicitInterfaceImplementations = (object)implementedAccessor == null ? ImmutableArray.Empty : ImmutableArray.Create(implementedAccessor); - } - - _explicitInterfaceImplementations = explicitInterfaceImplementations; - _name = name; - this.MakeFlags( - isAdder ? MethodKind.EventAdd : MethodKind.EventRemove, - @event.Modifiers, - returnsVoid: false, // until we learn otherwise (in LazyMethodChecks). - isExtensionMethod: false, - isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any()); - CheckFeatureAvailabilityAndRuntimeSupport(syntax, this.Location, hasBody: true, diagnostics: diagnostics); if (syntax.Body != null || syntax.ExpressionBody != null) @@ -69,16 +39,10 @@ internal SourceCustomEventAccessorSymbol( { diagnostics.Add(ErrorCode.ERR_ExternHasBody, this.Location, this); } - else if (IsAbstract && !IsExtern) - { - diagnostics.Add(ErrorCode.ERR_AbstractHasBody, this.Location, this); - } // Do not report error for IsAbstract && IsExtern. Dev10 reports CS0180 only // in that case ("member cannot be both extern and abstract"). } - _name = GetOverriddenAccessorName(@event, isAdder) ?? _name; - if (syntax.Modifiers.Count > 0) { diagnostics.Add(ErrorCode.ERR_NoModifiersOnAccessor, syntax.Modifiers[0].GetLocation()); @@ -102,21 +66,11 @@ public override Accessibility DeclaredAccessibility } } - public override ImmutableArray ExplicitInterfaceImplementations - { - get { return _explicitInterfaceImplementations; } - } - internal override OneOrMany> GetAttributeDeclarations() { return OneOrMany.Create(GetSyntax().AttributeLists); } - public override string Name - { - get { return _name; } - } - public override bool IsImplicitlyDeclared { get { return false; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs index 23a43c3d72172..d6bee39c9c2f8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs @@ -15,8 +15,8 @@ internal sealed class SourceCustomEventSymbol : SourceEventSymbol { private readonly TypeWithAnnotations _type; private readonly string _name; - private readonly SourceCustomEventAccessorSymbol _addMethod; - private readonly SourceCustomEventAccessorSymbol _removeMethod; + private readonly SourceEventAccessorSymbol _addMethod; + private readonly SourceEventAccessorSymbol _removeMethod; private readonly TypeSymbol _explicitInterfaceType; private readonly ImmutableArray _explicitInterfaceImplementations; @@ -72,51 +72,92 @@ internal SourceCustomEventSymbol(SourceMemberContainerTypeSymbol containingType, AccessorDeclarationSyntax addSyntax = null; AccessorDeclarationSyntax removeSyntax = null; - foreach (AccessorDeclarationSyntax accessor in syntax.AccessorList.Accessors) + + if (syntax.AccessorList != null) { - switch (accessor.Kind()) + foreach (AccessorDeclarationSyntax accessor in syntax.AccessorList.Accessors) + { + bool checkBody = false; + + switch (accessor.Kind()) + { + case SyntaxKind.AddAccessorDeclaration: + if (addSyntax == null) + { + addSyntax = accessor; + checkBody = true; + } + else + { + diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation()); + } + break; + case SyntaxKind.RemoveAccessorDeclaration: + if (removeSyntax == null) + { + removeSyntax = accessor; + checkBody = true; + } + else + { + diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation()); + } + break; + case SyntaxKind.GetAccessorDeclaration: + case SyntaxKind.SetAccessorDeclaration: + diagnostics.Add(ErrorCode.ERR_AddOrRemoveExpected, accessor.Keyword.GetLocation()); + break; + + case SyntaxKind.UnknownAccessorDeclaration: + // Don't need to handle UnknownAccessorDeclaration. An error will have + // already been produced for it in the parser. + break; + + default: + throw ExceptionUtilities.UnexpectedValue(accessor.Kind()); + } + + if (checkBody && !IsAbstract && accessor.Body == null && accessor.ExpressionBody == null && accessor.SemicolonToken.Kind() == SyntaxKind.SemicolonToken) + { + diagnostics.Add(ErrorCode.ERR_AddRemoveMustHaveBody, accessor.SemicolonToken.GetLocation()); + } + } + + if (IsAbstract) + { + if (!syntax.AccessorList.OpenBraceToken.IsMissing) + { + diagnostics.Add(ErrorCode.ERR_AbstractEventHasAccessors, syntax.AccessorList.OpenBraceToken.GetLocation(), this); + } + } + else if ((addSyntax == null || removeSyntax == null) && (!syntax.AccessorList.OpenBraceToken.IsMissing || !isExplicitInterfaceImplementation)) { - case SyntaxKind.AddAccessorDeclaration: - if (addSyntax == null) - { - addSyntax = accessor; - } - else - { - diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation()); - } - break; - case SyntaxKind.RemoveAccessorDeclaration: - if (removeSyntax == null) - { - removeSyntax = accessor; - } - else - { - diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation()); - } - break; - case SyntaxKind.GetAccessorDeclaration: - case SyntaxKind.SetAccessorDeclaration: - diagnostics.Add(ErrorCode.ERR_AddOrRemoveExpected, accessor.Keyword.GetLocation()); - break; - - case SyntaxKind.UnknownAccessorDeclaration: - // Don't need to handle UnknownAccessorDeclaration. An error will have - // already been produced for it in the parser. - break; - - default: - throw ExceptionUtilities.UnexpectedValue(accessor.Kind()); + diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this); } } + else if (isExplicitInterfaceImplementation && !IsAbstract) + { + diagnostics.Add(ErrorCode.ERR_ExplicitEventFieldImpl, this.Locations[0]); + } - _addMethod = CreateAccessorSymbol(addSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics); - _removeMethod = CreateAccessorSymbol(removeSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics); + if (isExplicitInterfaceImplementation && IsAbstract && syntax.AccessorList == null) + { + Debug.Assert(containingType.IsInterface); - if (addSyntax == null || removeSyntax == null) + Binder.CheckFeatureAvailability(syntax, MessageID.IDS_DefaultInterfaceImplementation, diagnostics, this.Locations[0]); + + if (!ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation) + { + diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, this.Locations[0]); + } + + _addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true, explicitlyImplementedEvent, aliasQualifierOpt); + _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, explicitlyImplementedEvent, aliasQualifierOpt); + } + else { - diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this); + _addMethod = CreateAccessorSymbol(addSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics); + _removeMethod = CreateAccessorSymbol(removeSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics); } _explicitInterfaceImplementations = diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs index 59f58de05ce84..983312b3339e3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs @@ -15,6 +15,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols internal abstract class SourceEventAccessorSymbol : SourceMemberMethodSymbol { private readonly SourceEventSymbol _event; + private readonly string _name; + private readonly ImmutableArray _explicitInterfaceImplementations; private ImmutableArray _lazyParameters; private TypeWithAnnotations _lazyReturnType; @@ -22,10 +24,55 @@ internal abstract class SourceEventAccessorSymbol : SourceMemberMethodSymbol public SourceEventAccessorSymbol( SourceEventSymbol @event, SyntaxReference syntaxReference, - ImmutableArray locations) + ImmutableArray locations, + EventSymbol explicitlyImplementedEventOpt, + string aliasQualifierOpt, + bool isAdder) : base(@event.containingType, syntaxReference, locations) { _event = @event; + + string name; + ImmutableArray explicitInterfaceImplementations; + if ((object)explicitlyImplementedEventOpt == null) + { + name = SourceEventSymbol.GetAccessorName(@event.Name, isAdder); + explicitInterfaceImplementations = ImmutableArray.Empty; + } + else + { + MethodSymbol implementedAccessor = isAdder ? explicitlyImplementedEventOpt.AddMethod : explicitlyImplementedEventOpt.RemoveMethod; + string accessorName = (object)implementedAccessor != null ? implementedAccessor.Name : SourceEventSymbol.GetAccessorName(explicitlyImplementedEventOpt.Name, isAdder); + + name = ExplicitInterfaceHelpers.GetMemberName(accessorName, explicitlyImplementedEventOpt.ContainingType, aliasQualifierOpt); + explicitInterfaceImplementations = (object)implementedAccessor == null ? ImmutableArray.Empty : ImmutableArray.Create(implementedAccessor); + } + + _explicitInterfaceImplementations = explicitInterfaceImplementations; + + this.MakeFlags( + isAdder ? MethodKind.EventAdd : MethodKind.EventRemove, + @event.Modifiers, + returnsVoid: false, // until we learn otherwise (in LazyMethodChecks). + isExtensionMethod: false, + isMetadataVirtualIgnoringModifiers: @event.IsExplicitInterfaceImplementation); + + _name = GetOverriddenAccessorName(@event, isAdder) ?? name; + } + + public override string Name + { + get { return _name; } + } + + internal override bool IsExplicitInterfaceImplementation + { + get { return _event.IsExplicitInterfaceImplementation; } + } + + public override ImmutableArray ExplicitInterfaceImplementations + { + get { return _explicitInterfaceImplementations; } } public SourceEventSymbol AssociatedEvent diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs index d7c7de354f2cc..7b70cba326ba6 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs @@ -456,6 +456,11 @@ private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, bool expli DeclarationModifiers.AccessibilityMask; } } + else if (isInterface) + { + Debug.Assert(explicitInterfaceImplementation); + allowedModifiers |= DeclarationModifiers.Abstract; + } if (this.ContainingType.IsStructType()) { @@ -489,8 +494,9 @@ protected void CheckModifiersAndType(DiagnosticBag diagnostics) { Location location = this.Locations[0]; HashSet useSiteDiagnostics = null; + bool isExplicitInterfaceImplementationInInterface = ContainingType.IsInterface && IsExplicitInterfaceImplementation; - if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || IsAbstract || IsOverride)) + if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || (IsAbstract && !isExplicitInterfaceImplementationInInterface) || IsOverride)) { diagnostics.Add(ErrorCode.ERR_VirtualPrivate, location, this); } @@ -514,7 +520,7 @@ protected void CheckModifiersAndType(DiagnosticBag diagnostics) // A member '{0}' marked as override cannot be marked as new or virtual diagnostics.Add(ErrorCode.ERR_OverrideNotNew, location, this); } - else if (IsSealed && !IsOverride) + else if (IsSealed && !IsOverride && !(isExplicitInterfaceImplementationInInterface && IsAbstract)) { // '{0}' cannot be sealed because it is not an override diagnostics.Add(ErrorCode.ERR_SealedNonOverride, location, this); @@ -533,7 +539,7 @@ protected void CheckModifiersAndType(DiagnosticBag diagnostics) { diagnostics.Add(ErrorCode.ERR_AbstractAndExtern, location, this); } - else if (IsAbstract && IsSealed) + else if (IsAbstract && IsSealed && !isExplicitInterfaceImplementationInInterface) { diagnostics.Add(ErrorCode.ERR_AbstractAndSealed, location, this); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs index 7bdd6b17f456f..03c72f02bf68b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs @@ -20,8 +20,8 @@ internal sealed class SourceFieldLikeEventSymbol : SourceEventSymbol private readonly string _name; private readonly TypeWithAnnotations _type; private readonly SourceEventFieldSymbol _associatedField; - private readonly SynthesizedFieldLikeEventAccessorSymbol _addMethod; - private readonly SynthesizedFieldLikeEventAccessorSymbol _removeMethod; + private readonly SynthesizedEventAccessorSymbol _addMethod; + private readonly SynthesizedEventAccessorSymbol _removeMethod; internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, SyntaxTokenList modifiers, VariableDeclaratorSyntax declaratorSyntax, DiagnosticBag diagnostics) : base(containingType, declaratorSyntax, modifiers, isFieldLike: true, interfaceSpecifierSyntaxOpt: null, @@ -100,8 +100,8 @@ internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingTy } // Accessors will assume that Type is available. - _addMethod = new SynthesizedFieldLikeEventAccessorSymbol(this, isAdder: true); - _removeMethod = new SynthesizedFieldLikeEventAccessorSymbol(this, isAdder: false); + _addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true); + _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false); if (declarationSyntax.Variables[0] == declaratorSyntax) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 7f3e64a754cdb..495dfe26c126f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -8,8 +8,6 @@ using System.Runtime.InteropServices; using System.Threading; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Collections; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; @@ -109,15 +107,11 @@ static Flags() // 1) Verify that the range of special types doesn't fall outside the bounds of the // special type mask. - var specialTypes = EnumUtilities.GetValues(); - var maxSpecialType = (int)specialTypes.Aggregate((s1, s2) => s1 | s2); - Debug.Assert((maxSpecialType & SpecialTypeMask) == maxSpecialType); + Debug.Assert(EnumUtilities.ContainsAllValues(SpecialTypeMask)); // 2) Verify that the range of declaration modifiers doesn't fall outside the bounds of // the declaration modifier mask. - var declarationModifiers = EnumUtilities.GetValues(); - var maxDeclarationModifier = (int)declarationModifiers.Aggregate((d1, d2) => d1 | d2); - Debug.Assert((maxDeclarationModifier & DeclarationModifiersMask) == maxDeclarationModifier); + Debug.Assert(EnumUtilities.ContainsAllValues(DeclarationModifiersMask)); } #endif diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index ff2569ed2f682..c604a1e1a0653 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -5,7 +5,6 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Globalization; -using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Emit; @@ -85,15 +84,11 @@ static Flags() // 1) Verify that the range of method kinds doesn't fall outside the bounds of the // method kind mask. - var methodKinds = EnumUtilities.GetValues(); - var maxMethodKind = (int)methodKinds.Aggregate((m1, m2) => m1 | m2); - Debug.Assert((maxMethodKind & MethodKindMask) == maxMethodKind); + Debug.Assert(EnumUtilities.ContainsAllValues(MethodKindMask)); // 2) Verify that the range of declaration modifiers doesn't fall outside the bounds of // the declaration modifier mask. - var declarationModifiers = EnumUtilities.GetValues(); - var maxDeclarationModifier = (int)declarationModifiers.Aggregate((d1, d2) => d1 | d2); - Debug.Assert((maxDeclarationModifier & DeclarationModifiersMask) == maxDeclarationModifier); + Debug.Assert(EnumUtilities.ContainsAllValues(DeclarationModifiersMask)); } #endif @@ -1719,7 +1714,7 @@ protected void CheckFeatureAvailabilityAndRuntimeSupport(SyntaxNode declarationS Binder.CheckFeatureAvailability(declarationSyntax, MessageID.IDS_DefaultInterfaceImplementation, diagnostics, location); } - if ((hasBody || IsExtern) && !ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation) + if ((hasBody || IsExplicitInterfaceImplementation || IsExtern) && !ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation) { diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, location); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs index 35f9fcd788de5..d029e1501328c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs @@ -447,7 +447,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB } } - CheckModifiers(_hasAnyBody, location, diagnostics); + CheckModifiers(syntax.ExplicitInterfaceSpecifier != null, _hasAnyBody, location, diagnostics); return; @@ -866,6 +866,11 @@ private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, MethodKind DeclarationModifiers.AccessibilityMask; } } + else if (isInterface) + { + Debug.Assert(isExplicitInterfaceImplementation); + allowedModifiers |= DeclarationModifiers.Abstract; + } allowedModifiers |= DeclarationModifiers.Extern | DeclarationModifiers.Async; @@ -971,7 +976,7 @@ private ImmutableArray MakeTypeParameters(MethodDeclaration return result.ToImmutableAndFree(); } - private void CheckModifiers(bool hasBody, Location location, DiagnosticBag diagnostics) + private void CheckModifiers(bool isExplicitInterfaceImplementation, bool hasBody, Location location, DiagnosticBag diagnostics) { const DeclarationModifiers partialMethodInvalidModifierMask = (DeclarationModifiers.AccessibilityMask & ~DeclarationModifiers.Private) | DeclarationModifiers.Virtual | @@ -981,6 +986,8 @@ private void CheckModifiers(bool hasBody, Location location, DiagnosticBag diagn DeclarationModifiers.Sealed | DeclarationModifiers.Extern; + bool isExplicitInterfaceImplementationInInterface = isExplicitInterfaceImplementation && ContainingType.IsInterface; + if (IsPartial && !ReturnsVoid) { diagnostics.Add(ErrorCode.ERR_PartialMethodMustReturnVoid, location); @@ -989,7 +996,7 @@ private void CheckModifiers(bool hasBody, Location location, DiagnosticBag diagn { diagnostics.Add(ErrorCode.ERR_PartialMethodInvalidModifier, location); } - else if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || IsAbstract || IsOverride)) + else if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || (IsAbstract && !isExplicitInterfaceImplementationInInterface) || IsOverride)) { diagnostics.Add(ErrorCode.ERR_VirtualPrivate, location, this); } @@ -1003,7 +1010,7 @@ private void CheckModifiers(bool hasBody, Location location, DiagnosticBag diagn // A member '{0}' marked as override cannot be marked as new or virtual diagnostics.Add(ErrorCode.ERR_OverrideNotNew, location, this); } - else if (IsSealed && !IsOverride) + else if (IsSealed && !IsOverride && !(isExplicitInterfaceImplementationInInterface && IsAbstract)) { // '{0}' cannot be sealed because it is not an override diagnostics.Add(ErrorCode.ERR_SealedNonOverride, location, this); @@ -1022,7 +1029,7 @@ private void CheckModifiers(bool hasBody, Location location, DiagnosticBag diagn { diagnostics.Add(ErrorCode.ERR_AbstractAndExtern, location, this); } - else if (IsAbstract && IsSealed) + else if (IsAbstract && IsSealed && !isExplicitInterfaceImplementationInInterface) { diagnostics.Add(ErrorCode.ERR_AbstractAndSealed, location, this); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs index bfb9370dacd9f..0a746c63e8852 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs @@ -561,6 +561,14 @@ internal CSharpSyntaxNode GetSyntax() return (CSharpSyntaxNode)syntaxReferenceOpt.GetSyntax(); } + internal override bool IsExplicitInterfaceImplementation + { + get + { + return _property.IsExplicitInterfaceImplementation; + } + } + public override ImmutableArray ExplicitInterfaceImplementations { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs index 7cf31f264dcc2..38b95d6f51250 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs @@ -100,7 +100,7 @@ private SourcePropertySymbol( diagnostics, out modifierErrors); this.CheckAccessibility(location, diagnostics, isExplicitInterfaceImplementation); - this.CheckModifiers(location, isIndexer, diagnostics); + this.CheckModifiers(isExplicitInterfaceImplementation, location, isIndexer, diagnostics); isAutoProperty = isAutoProperty && (!(containingType.IsInterface && !IsStatic) && !IsAbstract && !IsExtern && !isIndexer && hasAccessorList); @@ -481,11 +481,7 @@ private void CheckInitializer( Location location, DiagnosticBag diagnostics) { - if (_containingType.IsInterface && !IsStatic) - { - diagnostics.Add(ErrorCode.ERR_AutoPropertyInitializerInInterface, location, this); - } - else if (!isAutoProperty) + if (!isAutoProperty) { diagnostics.Add(ErrorCode.ERR_InitializerOnNonAutoProperty, location, this); } @@ -872,6 +868,11 @@ private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, bool isExp DeclarationModifiers.AccessibilityMask; } } + else if (isInterface) + { + Debug.Assert(isExplicitInterfaceImplementation); + allowedModifiers |= DeclarationModifiers.Abstract; + } if (ContainingType.IsStructType()) { @@ -944,9 +945,11 @@ private static ImmutableArray MakeParameters( return parameters; } - private void CheckModifiers(Location location, bool isIndexer, DiagnosticBag diagnostics) + private void CheckModifiers(bool isExplicitInterfaceImplementation, Location location, bool isIndexer, DiagnosticBag diagnostics) { - if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || IsAbstract || IsOverride)) + bool isExplicitInterfaceImplementationInInterface = isExplicitInterfaceImplementation && ContainingType.IsInterface; + + if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || (IsAbstract && !isExplicitInterfaceImplementationInInterface) || IsOverride)) { diagnostics.Add(ErrorCode.ERR_VirtualPrivate, location, this); } @@ -965,7 +968,7 @@ private void CheckModifiers(Location location, bool isIndexer, DiagnosticBag dia // A member '{0}' marked as override cannot be marked as new or virtual diagnostics.Add(ErrorCode.ERR_OverrideNotNew, location, this); } - else if (IsSealed && !IsOverride) + else if (IsSealed && !IsOverride && !(IsAbstract && isExplicitInterfaceImplementationInInterface)) { // '{0}' cannot be sealed because it is not an override diagnostics.Add(ErrorCode.ERR_SealedNonOverride, location, this); @@ -984,7 +987,7 @@ private void CheckModifiers(Location location, bool isIndexer, DiagnosticBag dia { diagnostics.Add(ErrorCode.ERR_AbstractAndExtern, location, this); } - else if (IsAbstract && IsSealed) + else if (IsAbstract && IsSealed && !isExplicitInterfaceImplementationInInterface) { diagnostics.Add(ErrorCode.ERR_AbstractAndSealed, location, this); } diff --git a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs index a461466b78dc2..c360392f273e1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs @@ -398,7 +398,7 @@ internal static void GetTypeOrReturnType(this Symbol symbol, out RefKind refKind internal static bool IsImplementableInterfaceMember(this Symbol symbol) { - return !symbol.IsStatic && (symbol.IsAbstract || symbol.IsVirtual) && (symbol.ContainingType?.IsInterface ?? false); + return !symbol.IsStatic && !symbol.IsSealed && (symbol.IsAbstract || symbol.IsVirtual) && (symbol.ContainingType?.IsInterface ?? false); } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldLikeEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs similarity index 78% rename from src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldLikeEventAccessorSymbol.cs rename to src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs index 03a92699ddd32..bdfed0484c84e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldLikeEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs @@ -11,35 +11,20 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols { /// - /// Event accessor that has been synthesized for a field-like event declared in source. + /// Event accessor that has been synthesized for a field-like event declared in source, + /// or for an event re-abstraction in an interface. /// /// - /// Associated with . + /// Associated with and . /// - internal sealed class SynthesizedFieldLikeEventAccessorSymbol : SourceEventAccessorSymbol + internal sealed class SynthesizedEventAccessorSymbol : SourceEventAccessorSymbol { // Since we don't have a syntax reference, we'll have to use another object for locking. private readonly object _methodChecksLockObject = new object(); - private readonly string _name; - - internal SynthesizedFieldLikeEventAccessorSymbol(SourceFieldLikeEventSymbol @event, bool isAdder) - : base(@event, null, @event.Locations) - { - this.MakeFlags( - isAdder ? MethodKind.EventAdd : MethodKind.EventRemove, - @event.Modifiers, - returnsVoid: false, // until we learn otherwise (in LazyMethodChecks). - isExtensionMethod: false, - isMetadataVirtualIgnoringModifiers: false); - - _name = GetOverriddenAccessorName(@event, isAdder) ?? - SourceEventSymbol.GetAccessorName(@event.Name, isAdder); - } - - public override string Name + internal SynthesizedEventAccessorSymbol(SourceEventSymbol @event, bool isAdder, EventSymbol explicitlyImplementedEventOpt = null, string aliasQualifierOpt = null) + : base(@event, null, @event.Locations, explicitlyImplementedEventOpt, aliasQualifierOpt, isAdder) { - get { return _name; } } public override bool IsImplicitlyDeclared diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs index 56946e6fb1dc6..621360fc12d38 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs @@ -1059,7 +1059,16 @@ private static Symbol FindMostSpecificImplementation(Symbol interfaceMember, Nam ref useSiteDiagnostics, out var _, out var _); case 1: - return implementingMember.Single(); + { + Symbol result = implementingMember.Single(); + + if (result.IsAbstract) + { + return null; + } + + return result; + } default: return null; } @@ -1164,6 +1173,10 @@ private static Symbol FindMostSpecificImplementationInBases( { case 1: result = methodSet.Single(); + if (result.IsAbstract) + { + result = null; + } break; default: result = null; diff --git a/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs new file mode 100644 index 0000000000000..7ebcef51fdbcf --- /dev/null +++ b/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs @@ -0,0 +1,21 @@ +// 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 Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.ComponentModel; + +namespace Microsoft.CodeAnalysis.CSharp.Syntax +{ + public partial class EventDeclarationSyntax + { + public EventDeclarationSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + { + return Update(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken: default); + } + + public EventDeclarationSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, SyntaxToken semicolonToken) + { + return Update(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList: null, semicolonToken); + } + } +} diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index 13531662e7029..50bec3f94fc31 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -3641,7 +3641,10 @@ - + + + + diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs index a225238e9364b..bd12910f5df15 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs @@ -2519,6 +2519,18 @@ public static PragmaWarningDirectiveTriviaSyntax PragmaWarningDirectiveTrivia(Sy return PragmaWarningDirectiveTrivia(hashToken, pragmaKeyword, warningKeyword, disableOrRestoreKeyword, nullableKeyword, errorCodes: default, endOfDirectiveToken, isActive); } + /// Creates a new EventDeclarationSyntax instance. + public static EventDeclarationSyntax EventDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList) + { + return EventDeclaration(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList, semicolonToken: default); + } + + /// Creates a new EventDeclarationSyntax instance. + public static EventDeclarationSyntax EventDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken eventKeyword, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, SyntaxToken semicolonToken) + { + return EventDeclaration(attributeLists, modifiers, eventKeyword, type, explicitInterfaceSpecifier, identifier, accessorList: null, semicolonToken); + } + // BACK COMPAT OVERLOAD DO NOT MODIFY [EditorBrowsable(EditorBrowsableState.Never)] public static SyntaxTree ParseSyntaxTree( diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 85f42045fa8f1..029a798eb12f3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -12,6 +12,11 @@ Konstruovaný obecný typ nejde vytvořit z jiného než obecného typu. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Pokud chcete pro interpolovaný doslovný řetězec použít @$ místo $@, použijte verzi jazyka {0} nebo vyšší. @@ -4673,7 +4678,7 @@ Pokud se taková třída používá jako základní třída a pokud odvozující Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Pro deklarace částečné metody {0} platí omezení parametrů s nekonzistentními typy. + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference Automaticky implementované vlastnosti musí přepsat všechny přistupující objekty přepsané vlastnosti. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Automaticky implementované vlastnosti instance uvnitř rozhraní nemůžou mít inicializátory. - - Structs without explicit constructors cannot contain members with initializers. Struktury bez explicitních konstruktorů nemůžou obsahovat členy s inicializátory. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 3da1b80d3a736..a948d9a75df01 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -12,6 +12,11 @@ Es kann kein konstruierter generischer Typ aus einem nicht generischen Typ erstellt werden. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Um für eine interpolierte ausführliche Zeichenfolge "@$" anstelle von "$@" zu verwenden, benötigen Sie Sprachversion {0} oder höher. @@ -4673,7 +4678,7 @@ Wenn solch eine Klasse als Basisklasse verwendet wird und die ableitende Klasse Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Die Deklarationen der partiellen {0}-Methode enthalten inkonsistente Typparametereinschränkungen. + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ Um die Warnung zu beheben, können Sie stattdessen /reference verwenden (Einbett Automatisch implementierte Eigenschaften müssen alle Accessoren der überschriebenen Eigenschaft überschreiben. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Automatisch implementierte Instanzeigenschaften in Schnittstellen können keine Initialisierer aufweisen. - - Structs without explicit constructors cannot contain members with initializers. Strukturen ohne explizite Konstruktoren können keine Member mit Initialisierern enthalten. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index c58126d4308d0..eff99319e6600 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -12,6 +12,11 @@ No se puede crear un tipo genérico construido a partir de un tipo no genérico. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Para usar "@$" en lugar de "$@" para una cadena textual interpolada, use la versión "{0}" del lenguaje o una posterior. @@ -4675,7 +4680,7 @@ Si se utiliza una clase de este tipo como clase base y si la clase derivada defi Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Las declaraciones de métodos parciales de '{0}' tienen restricciones de parámetros de tipo incoherentes + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8660,11 +8665,6 @@ Para eliminar la advertencia puede usar /reference (establezca la propiedad Embe Las propiedades implementadas automáticamente deben invalidar todos los descriptores de acceso de la propiedad invalidada. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Las propiedades de instancia implementadas automáticamente dentro de interfaces no pueden tener inicializadores. - - Structs without explicit constructors cannot contain members with initializers. Las estructuras sin constructores explícitos no pueden contener miembros con inicializadores. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index a61570d0c9bb7..e2eb691117786 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -12,6 +12,11 @@ Impossible de créer un type générique construit à partir d'un type non générique. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Pour utiliser '@$' au lieu de '$@' pour une chaîne textuelle interpolée, utilisez la version de langage '{0}' ou ultérieure. @@ -4674,7 +4679,7 @@ Si une telle classe est utilisée en tant que classe de base et si la classe dé Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Les déclarations de méthode partielles de '{0}' ont des contraintes de paramètre de type incohérentes + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8659,11 +8664,6 @@ Pour supprimer l'avertissement, vous pouvez utiliser la commande /reference (dé Les propriétés implémentées automatiquement doivent substituer tous les accesseurs de la propriété substituée. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Les propriétés d'instance implémentées automatiquement dans les interfaces ne peuvent pas avoir d'initialiseurs. - - Structs without explicit constructors cannot contain members with initializers. Les structs sans constructeurs explicites ne peuvent pas contenir de membres avec initialiseurs diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 89d95f581f49c..12a0038144e2e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -12,6 +12,11 @@ Non è possibile creare un tipo generico costruito a partire da un tipo non generico. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Per usare '@$' invece di '$@' per una stringa verbatim interpolata, usare la versione '{0}' o versioni successive del linguaggio. @@ -4673,7 +4678,7 @@ Se si usa tale classe come classe base e se la classe di derivazione definisce u Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Le dichiarazioni di metodo parziale di '{0}' contengono vincoli incoerenti per i parametri di tipo + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ Per rimuovere l'avviso, è invece possibile usare /reference (impostare la propr Le proprietà implementate automaticamente devono sostituire tutte le funzioni di accesso della proprietà sostituita. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Le proprietà implementate automaticamente di istanza all'interno di interfacce non possono avere inizializzatori. - - Structs without explicit constructors cannot contain members with initializers. Le struct senza costruttori espliciti non possono contenere membri con inizializzatori. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 8bf288579043b..4d8d1f7802b50 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -12,6 +12,11 @@ 非ジェネリック型から、構築済みジェネリック型を作成できません。 + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 挿入される verbatim 文字列で '$@' の代わりに '@$' を使用するには、言語バージョン '{0}' 以上をご使用ください。 @@ -4673,7 +4678,7 @@ If such a class is used as a base class and if the deriving class defines a dest Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - {0}' の部分メソッド宣言には、矛盾する型パラメーター制約が含まれています。 + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 自動実装プロパティは、オーバーライドされたプロパティのすべてのアクセサーをオーバーライドする必要があります。 - - Instance auto-implemented properties inside interfaces cannot have initializers. - インターフェイス内のインスタンス自動実装プロパティは初期化子を持つことができません。 - - Structs without explicit constructors cannot contain members with initializers. 明示的なコンストラクターがない構造体には、初期化子を持つメンバーを含めることはできません。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index a3951b0d3ec47..2dfa9481a7fc5 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -12,6 +12,11 @@ 제네릭이 아닌 형식에서 생성된 제네릭 형식을 만들 수 없습니다. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 보간된 축자 문자열에 '$@' 대신 '@$'를 사용하려면 언어 버전 '{0}' 이상을 사용하세요. @@ -4673,7 +4678,7 @@ If such a class is used as a base class and if the deriving class defines a dest Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - {0}'의 부분 메서드(Partial Method) 선언에 일관성이 없는 형식 매개 변수 제약 조건이 있습니다. + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 자동 구현 속성은 재정의된 속성의 모든 접근자를 재정의해야 합니다. - - Instance auto-implemented properties inside interfaces cannot have initializers. - 인터페이스 내부에서 인스턴스 자동 구현 속성은 이니셜라이저를 사용할 수 없습니다. - - Structs without explicit constructors cannot contain members with initializers. 명시적 생성자가 없는 구조체는 이니셜라이저를 사용하여 멤버를 포함할 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index a9c110dec77ca..50fe858312cc4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -12,6 +12,11 @@ Nie można utworzyć konstruowanego typu ogólnego z typu nieogólnego. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Aby używać elementu „@$” zamiast elementu „$@” w interpolowanym ciągu dosłownym, użyj wersji języka „{0}” lub wyższej. @@ -4673,7 +4678,7 @@ Jeśli taka klasa zostanie użyta jako klasa bazowa i klasa pochodna definiuje d Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Częściowe deklaracje metody „{0}” mają niespójne ograniczenia parametrów typu + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ Aby usunąć ostrzeżenie, możesz zamiast tego użyć opcji /reference (ustaw w Automatycznie implementowane właściwości muszą przesłaniać wszystkie metody dostępu przesłanianej właściwości. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Właściwości wystąpienia zaimplementowane automatycznie w interfejsach nie mogą mieć inicjatorów. - - Structs without explicit constructors cannot contain members with initializers. Struktury bez jawnych konstruktorów nie mogą zawierać składowych z inicjatorami. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 17ce1d21359e4..5b2932146f331 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -12,6 +12,11 @@ Não é possível criar um tipo genérico construído com base em um tipo não genérico. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Para usar '@$' em vez de '$@' para uma cadeia de caracteres textuais interpolada, use a versão de linguagem '{0}' ou superior. @@ -244,7 +249,7 @@ Method '{0}' with an iterator block must be 'async' to return '{1}' - O método '{0}' com um bloco iterador deve ser 'async' para retornar '\ {1 \}' + Method '{0}' with an iterator block must be 'async' to return '{1}' @@ -4673,7 +4678,7 @@ Se tal classe for usada como uma classe base e se a classe derivada definir um d Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - As declarações de método parcial "{0}" têm restrições de parâmetro de tipo inconsistentes + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ Para incorporar informações de tipo de interoperabilidade para os dois assembl Propriedades autoimplementadas devem substituir todos os acessadores de propriedade substituída. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Propriedades autoimplementadas de instância dentro de interfaces não podem ter inicializadores. - - Structs without explicit constructors cannot contain members with initializers. Estruturas sem construtores explícitos não podem conter membros com inicializadores. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 7cea09f06c33c..7412eba6c91a6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -12,6 +12,11 @@ Не удается создать сконструированный универсальный тип из неуниверсального типа. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Чтобы применять "@$" вместо "$@" для интерполированной строки verbatim, используйте версию языка "{0}" или более позднюю. @@ -4673,7 +4678,7 @@ If such a class is used as a base class and if the deriving class defines a dest Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - Объявления разделяемого метода "{0}" имеют несовместимые ограничения параметров типов. + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8660,11 +8665,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Автоматически реализуемые свойства должны переопределять все методы доступа переопределенного свойства. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Автоматически реализуемые свойства экземпляра в интерфейсах не могут иметь инициализаторы. - - Structs without explicit constructors cannot contain members with initializers. Структуры без явных конструкторов не могут содержать члены с инициализаторами. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 6dce79f3ffdd7..5853b7f1aaaf4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -12,6 +12,11 @@ Oluşturulmuş genel tür, genel olmayan türden oluşturulamaz. + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. İlişkilendirilmiş tam bir dize için '$@' yerine '@$' kullanmak istiyorsanız lütfen '{0}' veya üzeri bir dil sürümü kullanın. @@ -4674,7 +4679,7 @@ Bu sınıf temel sınıf olarak kullanılırsa ve türetilen sınıf bir yıkıc Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - {0}' öğesinin kısmı yöntem bildirimleri tutarsız tür parametresi kısıtlamalarına sahip + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8659,11 +8664,6 @@ Uyarıyı kaldırmak için, /reference kullanabilirsiniz (Birlikte Çalışma T Otomatik uygulanan özellikler geçersiz kılınan özelliğin tüm erişicilerini geçersiz kılmalıdır. - - Instance auto-implemented properties inside interfaces cannot have initializers. - Örnek tarafından arabirimlerin içine otomatik olarak uygulanan özelliklerin başlatıcıları olamaz. - - Structs without explicit constructors cannot contain members with initializers. Açık oluşturucuları olmayan yapı birimleri başlatıcıları olan üyeler içeremez. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 9051858f686b4..35e2d8bdd18f6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -12,6 +12,11 @@ 无法从非泛型类型创建构造泛型类型。 + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 若要对内插逐字字符串使用 “@$” 而不是 “$@”,请使用语言版本“{0}”或更高版本。 @@ -4714,7 +4719,7 @@ If such a class is used as a base class and if the deriving class defines a dest Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - “{0}”的分部方法声明具有不一致的类型参数约束 + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8699,11 +8704,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 自动实现的属性必须覆盖被覆盖属性的所有访问器。 - - Instance auto-implemented properties inside interfaces cannot have initializers. - 接口中实例自动实现的属性不能具有初始值设定项。 - - Structs without explicit constructors cannot contain members with initializers. 没有显式构造函数的结构不能包含具有初始值设定项的成员。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 2798912f5ee39..d93527670291f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -12,6 +12,11 @@ 無法從另一個非泛型型別建立建構的泛型型別。 + + '{0}': abstract event cannot use event accessor syntax + '{0}': abstract event cannot use event accessor syntax + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 若要使用 '@$' 而不是 '$@' 作為插入的逐字字串,請使用 {0} 或更高的語言版本。 @@ -4673,7 +4678,7 @@ If such a class is used as a base class and if the deriving class defines a dest Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' - {0}' 的部分方法宣告出現不一致的類型參數條件約束 + Partial method declarations of '{0}' have inconsistent constraints for type parameter '{1}' @@ -8658,11 +8663,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 自動實作的屬性必須覆寫已覆寫屬性的所有存取子。 - - Instance auto-implemented properties inside interfaces cannot have initializers. - 介面內的執行個體自動實作屬性不可有初始設定式。 - - Structs without explicit constructors cannot contain members with initializers. 沒有明確建構函式的結構,不可包含有初始設定式的成員。 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStackAllocInitializerTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStackAllocInitializerTests.cs index bd698c123984b..02045bd80c0b4 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStackAllocInitializerTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStackAllocInitializerTests.cs @@ -420,6 +420,48 @@ .maxstack 1 IL_000c: call ""byte C.Method(int)"" IL_0011: pop IL_0012: ret +}"); + CompileAndVerify(text, + parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3), + options: TestOptions.UnsafeDebugExe, + expectedOutput: "12", + verify: Verification.Fails).VerifyIL("C.Main", +@"{ + // Code size 44 (0x2c) + .maxstack 4 + .locals init (int* V_0) //p + IL_0000: nop + IL_0001: ldc.i4.s 16 + IL_0003: conv.u + IL_0004: localloc + IL_0006: dup + IL_0007: ldc.i4.s 42 + IL_0009: stind.i4 + IL_000a: dup + IL_000b: ldc.i4.4 + IL_000c: add + IL_000d: ldc.i4.1 + IL_000e: call ""byte C.Method(int)"" + IL_0013: stind.i4 + IL_0014: dup + IL_0015: ldc.i4.2 + IL_0016: conv.i + IL_0017: ldc.i4.4 + IL_0018: mul + IL_0019: add + IL_001a: ldc.i4.s 42 + IL_001c: stind.i4 + IL_001d: dup + IL_001e: ldc.i4.3 + IL_001f: conv.i + IL_0020: ldc.i4.4 + IL_0021: mul + IL_0022: add + IL_0023: ldc.i4.2 + IL_0024: call ""byte C.Method(int)"" + IL_0029: stind.i4 + IL_002a: stloc.0 + IL_002b: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs index 0d02d716a2f25..46bceddedb3c6 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs @@ -16148,7 +16148,7 @@ .maxstack 1 [Fact] public void CorrectOverloadOfStackAllocSpanChosen() { - var comp = CreateCompilationWithMscorlibAndSpan(@" + var source = @" using System; class Test { @@ -16162,15 +16162,18 @@ unsafe public static void Main() var span2 = condition ? new Span(null, 3) : stackalloc int[4]; Console.Write(span2.Length); } -}", TestOptions.UnsafeReleaseExe); +}"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.UnsafeReleaseExe); + CompileAndVerify(comp, expectedOutput: "24", verify: Verification.Fails); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.UnsafeDebugExe); CompileAndVerify(comp, expectedOutput: "24", verify: Verification.Fails); } - [Fact] + [Fact, WorkItem(35764, "https://github.com/dotnet/roslyn/issues/35764")] public void StackAllocExpressionIL() { - var comp = CreateCompilationWithMscorlibAndSpan(@" + var source = @" using System; class Test { @@ -16181,9 +16184,11 @@ public static void Main() x = stackalloc int[0]; Console.Write(x.Length); } -}", TestOptions.ReleaseExe); - - CompileAndVerify(comp, expectedOutput: "330", verify: Verification.Fails).VerifyIL("Test.Main", @" +}"; + var expectedOutput = "330"; + CSharpCompilation comp; + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyIL("Test.Main", @" { // Code size 49 (0x31) .maxstack 2 @@ -16203,13 +16208,41 @@ .locals init (System.Span V_0) //x IL_0026: call ""int System.Span.Length.get"" IL_002b: call ""void System.Console.Write(int)"" IL_0030: ret +}"); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 54 (0x36) + .maxstack 2 + .locals init (System.Span V_0, //x + System.Span V_1) + IL_0000: nop + IL_0001: ldc.i4 0x84 + IL_0006: conv.u + IL_0007: localloc + IL_0009: ldc.i4.s 33 + IL_000b: newobj ""System.Span..ctor(void*, int)"" + IL_0010: stloc.1 + IL_0011: ldloc.1 + IL_0012: stloc.0 + IL_0013: ldloca.s V_0 + IL_0015: call ""int System.Span.Length.get"" + IL_001a: call ""void System.Console.Write(int)"" + IL_001f: nop + IL_0020: ldloca.s V_0 + IL_0022: initobj ""System.Span"" + IL_0028: ldloca.s V_0 + IL_002a: call ""int System.Span.Length.get"" + IL_002f: call ""void System.Console.Write(int)"" + IL_0034: nop + IL_0035: ret }"); } [Fact] public void StackAllocSpanLengthNotEvaluatedTwice() { - var comp = CreateCompilationWithMscorlibAndSpan(@" + var source = @" using System; class Test { @@ -16228,8 +16261,8 @@ public static void Main() Console.Write(x.Length); } } -}", TestOptions.ReleaseExe); - +}"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "12345", verify: Verification.Fails).VerifyIL("Test.Main", @" { // Code size 44 (0x2c) @@ -16261,13 +16294,302 @@ .locals init (int V_0, //i IL_0028: ldc.i4.5 IL_0029: blt.s IL_0004 IL_002b: ret +}"); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "12345", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 56 (0x38) + .maxstack 2 + .locals init (int V_0, //i + System.Span V_1, //x + int V_2, + System.Span V_3, + bool V_4) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_002d + IL_0005: nop + IL_0006: call ""int Test.GetLength()"" + IL_000b: stloc.2 + IL_000c: ldloc.2 + IL_000d: conv.u + IL_000e: ldc.i4.4 + IL_000f: mul.ovf.un + IL_0010: localloc + IL_0012: ldloc.2 + IL_0013: newobj ""System.Span..ctor(void*, int)"" + IL_0018: stloc.3 + IL_0019: ldloc.3 + IL_001a: stloc.1 + IL_001b: ldloca.s V_1 + IL_001d: call ""int System.Span.Length.get"" + IL_0022: call ""void System.Console.Write(int)"" + IL_0027: nop + IL_0028: nop + IL_0029: ldloc.0 + IL_002a: ldc.i4.1 + IL_002b: add + IL_002c: stloc.0 + IL_002d: ldloc.0 + IL_002e: ldc.i4.5 + IL_002f: clt + IL_0031: stloc.s V_4 + IL_0033: ldloc.s V_4 + IL_0035: brtrue.s IL_0005 + IL_0037: ret +}"); + } + + [Fact] + public void NestedStackAlloc_01() + { + var source = @" +using System; +class Test +{ + public static void Main() + { + Console.WriteLine(M(2, stackalloc int[3])); + } + public static int M(int x, Span y) => x * y.Length; +}"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "6", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 25 (0x19) + .maxstack 2 + .locals init (System.Span V_0) + IL_0000: ldc.i4.s 12 + IL_0002: conv.u + IL_0003: localloc + IL_0005: ldc.i4.3 + IL_0006: newobj ""System.Span..ctor(void*, int)"" + IL_000b: stloc.0 + IL_000c: ldc.i4.2 + IL_000d: ldloc.0 + IL_000e: call ""int Test.M(int, System.Span)"" + IL_0013: call ""void System.Console.WriteLine(int)"" + IL_0018: ret +}"); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "6", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 27 (0x1b) + .maxstack 2 + .locals init (System.Span V_0) + IL_0000: nop + IL_0001: ldc.i4.s 12 + IL_0003: conv.u + IL_0004: localloc + IL_0006: ldc.i4.3 + IL_0007: newobj ""System.Span..ctor(void*, int)"" + IL_000c: stloc.0 + IL_000d: ldc.i4.2 + IL_000e: ldloc.0 + IL_000f: call ""int Test.M(int, System.Span)"" + IL_0014: call ""void System.Console.WriteLine(int)"" + IL_0019: nop + IL_001a: ret +}"); + } + + [Fact] + public void NestedStackAlloc_02() + { + var source = @" +using System; +class Test +{ + public static void Main() + { + int z = 2; + Console.WriteLine(M(z, stackalloc int[3])); + } + public static int M(int x, Span y) => x * y.Length; +}"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "6", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 27 (0x1b) + .maxstack 2 + .locals init (int V_0, + System.Span V_1) + IL_0000: ldc.i4.2 + IL_0001: stloc.0 + IL_0002: ldc.i4.s 12 + IL_0004: conv.u + IL_0005: localloc + IL_0007: ldc.i4.3 + IL_0008: newobj ""System.Span..ctor(void*, int)"" + IL_000d: stloc.1 + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: call ""int Test.M(int, System.Span)"" + IL_0015: call ""void System.Console.WriteLine(int)"" + IL_001a: ret +}"); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "6", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 31 (0x1f) + .maxstack 2 + .locals init (int V_0, //z + int V_1, + System.Span V_2) + IL_0000: nop + IL_0001: ldc.i4.2 + IL_0002: stloc.0 + IL_0003: ldloc.0 + IL_0004: stloc.1 + IL_0005: ldc.i4.s 12 + IL_0007: conv.u + IL_0008: localloc + IL_000a: ldc.i4.3 + IL_000b: newobj ""System.Span..ctor(void*, int)"" + IL_0010: stloc.2 + IL_0011: ldloc.1 + IL_0012: ldloc.2 + IL_0013: call ""int Test.M(int, System.Span)"" + IL_0018: call ""void System.Console.WriteLine(int)"" + IL_001d: nop + IL_001e: ret +}"); + } + + [Fact] + public void NestedStackAlloc_03() + { + var source = @" +using System; +class Test +{ + public static void Main() + { + int z = 2; + Console.WriteLine(z * stackalloc int[3] { 1, stackalloc int[2] { 4, 5 }.Length, 3 }.Length); + } + public static int M(int x, Span y) => x * y.Length; +}"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "6", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 70 (0x46) + .maxstack 4 + .locals init (int V_0, + System.Span V_1, + System.Span V_2) + IL_0000: ldc.i4.2 + IL_0001: stloc.0 + IL_0002: ldc.i4.8 + IL_0003: conv.u + IL_0004: localloc + IL_0006: dup + IL_0007: ldc.i4.4 + IL_0008: stind.i4 + IL_0009: dup + IL_000a: ldc.i4.4 + IL_000b: add + IL_000c: ldc.i4.5 + IL_000d: stind.i4 + IL_000e: ldc.i4.2 + IL_000f: newobj ""System.Span..ctor(void*, int)"" + IL_0014: stloc.1 + IL_0015: ldc.i4.s 12 + IL_0017: conv.u + IL_0018: localloc + IL_001a: dup + IL_001b: ldc.i4.1 + IL_001c: stind.i4 + IL_001d: dup + IL_001e: ldc.i4.4 + IL_001f: add + IL_0020: ldloca.s V_1 + IL_0022: call ""int System.Span.Length.get"" + IL_0027: stind.i4 + IL_0028: dup + IL_0029: ldc.i4.2 + IL_002a: conv.i + IL_002b: ldc.i4.4 + IL_002c: mul + IL_002d: add + IL_002e: ldc.i4.3 + IL_002f: stind.i4 + IL_0030: ldc.i4.3 + IL_0031: newobj ""System.Span..ctor(void*, int)"" + IL_0036: stloc.2 + IL_0037: ldloc.0 + IL_0038: ldloca.s V_2 + IL_003a: call ""int System.Span.Length.get"" + IL_003f: mul + IL_0040: call ""void System.Console.WriteLine(int)"" + IL_0045: ret +}"); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "6", verify: Verification.Fails).VerifyIL("Test.Main", @" +{ + // Code size 74 (0x4a) + .maxstack 4 + .locals init (int V_0, //z + int V_1, + System.Span V_2, + System.Span V_3) + IL_0000: nop + IL_0001: ldc.i4.2 + IL_0002: stloc.0 + IL_0003: ldloc.0 + IL_0004: stloc.1 + IL_0005: ldc.i4.8 + IL_0006: conv.u + IL_0007: localloc + IL_0009: dup + IL_000a: ldc.i4.4 + IL_000b: stind.i4 + IL_000c: dup + IL_000d: ldc.i4.4 + IL_000e: add + IL_000f: ldc.i4.5 + IL_0010: stind.i4 + IL_0011: ldc.i4.2 + IL_0012: newobj ""System.Span..ctor(void*, int)"" + IL_0017: stloc.2 + IL_0018: ldc.i4.s 12 + IL_001a: conv.u + IL_001b: localloc + IL_001d: dup + IL_001e: ldc.i4.1 + IL_001f: stind.i4 + IL_0020: dup + IL_0021: ldc.i4.4 + IL_0022: add + IL_0023: ldloca.s V_2 + IL_0025: call ""int System.Span.Length.get"" + IL_002a: stind.i4 + IL_002b: dup + IL_002c: ldc.i4.2 + IL_002d: conv.i + IL_002e: ldc.i4.4 + IL_002f: mul + IL_0030: add + IL_0031: ldc.i4.3 + IL_0032: stind.i4 + IL_0033: ldc.i4.3 + IL_0034: newobj ""System.Span..ctor(void*, int)"" + IL_0039: stloc.3 + IL_003a: ldloc.1 + IL_003b: ldloca.s V_3 + IL_003d: call ""int System.Span.Length.get"" + IL_0042: mul + IL_0043: call ""void System.Console.WriteLine(int)"" + IL_0048: nop + IL_0049: ret }"); } [Fact] public void ImplicitCastOperatorOnStackAllocIsLoweredCorrectly() { - var comp = CreateCompilationWithMscorlibAndSpan(@" + var source = @" using System; unsafe class Test { @@ -16289,15 +16611,18 @@ public static implicit operator Test(double* value) Console.Write(""PointerOpCalled""); return default(Test); } -}", TestOptions.UnsafeReleaseExe); - - CompileAndVerify(comp, expectedOutput: "SpanOpCalled|PointerOpCalled", verify: Verification.Fails); +}"; + var expectedOutput = "SpanOpCalled|PointerOpCalled"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.UnsafeReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.UnsafeDebugExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails); } [Fact] public void ExplicitCastOperatorOnStackAllocIsLoweredCorrectly() { - var comp = CreateCompilationWithMscorlibAndSpan(@" + var source = @" using System; unsafe class Test { @@ -16311,8 +16636,10 @@ public static explicit operator Test(Span value) Console.Write(""SpanOpCalled""); return default(Test); } -}", TestOptions.UnsafeReleaseExe); - +}"; + var comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.UnsafeReleaseExe); + CompileAndVerify(comp, expectedOutput: "SpanOpCalled", verify: Verification.Fails); + comp = CreateCompilationWithMscorlibAndSpan(source, TestOptions.UnsafeDebugExe); CompileAndVerify(comp, expectedOutput: "SpanOpCalled", verify: Verification.Fails); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs index e262112c73fa7..d4f8ecca320a2 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs @@ -2596,5 +2596,216 @@ .locals init (System.ValueType V_0) //o } } } + + [Fact] + public void CompileTimeRuntimeInstanceofMismatch_01() + { + var source = +@"using System; +class Program +{ + static void Main() + { + M(new byte[1]); + M(new sbyte[1]); + M(new Ebyte[1]); + M(new Esbyte[1]); + + M(new short[1]); + M(new ushort[1]); + M(new Eshort[1]); + M(new Eushort[1]); + + M(new int[1]); + M(new uint[1]); + M(new Eint[1]); + M(new Euint[1]); + + M(new int[1][]); + M(new uint[1][]); + M(new Eint[1][]); + M(new Euint[1][]); + + M(new long[1]); + M(new ulong[1]); + M(new Elong[1]); + M(new Eulong[1]); + + M(new IntPtr[1]); + M(new UIntPtr[1]); + + M(new IntPtr[1][]); + M(new UIntPtr[1][]); + } + + static void M(object o) + { + switch (o) + { + case byte[] _ when o.GetType() == typeof(byte[]): + Console.WriteLine(""byte[]""); + break; + case sbyte[] _ when o.GetType() == typeof(sbyte[]): + Console.WriteLine(""sbyte[]""); + break; + case Ebyte[] _ when o.GetType() == typeof(Ebyte[]): + Console.WriteLine(""Ebyte[]""); + break; + case Esbyte[] _ when o.GetType() == typeof(Esbyte[]): + Console.WriteLine(""Esbyte[]""); + break; + + case short[] _ when o.GetType() == typeof(short[]): + Console.WriteLine(""short[]""); + break; + case ushort[] _ when o.GetType() == typeof(ushort[]): + Console.WriteLine(""ushort[]""); + break; + case Eshort[] _ when o.GetType() == typeof(Eshort[]): + Console.WriteLine(""Eshort[]""); + break; + case Eushort[] _ when o.GetType() == typeof(Eushort[]): + Console.WriteLine(""Eushort[]""); + break; + + case int[] _ when o.GetType() == typeof(int[]): + Console.WriteLine(""int[]""); + break; + case uint[] _ when o.GetType() == typeof(uint[]): + Console.WriteLine(""uint[]""); + break; + case Eint[] _ when o.GetType() == typeof(Eint[]): + Console.WriteLine(""Eint[]""); + break; + case Euint[] _ when o.GetType() == typeof(Euint[]): + Console.WriteLine(""Euint[]""); + break; + + case int[][] _ when o.GetType() == typeof(int[][]): + Console.WriteLine(""int[][]""); + break; + case uint[][] _ when o.GetType() == typeof(uint[][]): + Console.WriteLine(""uint[][]""); + break; + case Eint[][] _ when o.GetType() == typeof(Eint[][]): + Console.WriteLine(""Eint[][]""); + break; + case Euint[][] _ when o.GetType() == typeof(Euint[][]): + Console.WriteLine(""Euint[][]""); + break; + + case long[] _ when o.GetType() == typeof(long[]): + Console.WriteLine(""long[]""); + break; + case ulong[] _ when o.GetType() == typeof(ulong[]): + Console.WriteLine(""ulong[]""); + break; + case Elong[] _ when o.GetType() == typeof(Elong[]): + Console.WriteLine(""Elong[]""); + break; + case Eulong[] _ when o.GetType() == typeof(Eulong[]): + Console.WriteLine(""Eulong[]""); + break; + + case IntPtr[] _ when o.GetType() == typeof(IntPtr[]): + Console.WriteLine(""IntPtr[]""); + break; + case UIntPtr[] _ when o.GetType() == typeof(UIntPtr[]): + Console.WriteLine(""UIntPtr[]""); + break; + + case IntPtr[][] _ when o.GetType() == typeof(IntPtr[][]): + Console.WriteLine(""IntPtr[][]""); + break; + case UIntPtr[][] _ when o.GetType() == typeof(UIntPtr[][]): + Console.WriteLine(""UIntPtr[][]""); + break; + + default: + Console.WriteLine(""oops: "" + o.GetType()); + break; + } + } +} +enum Ebyte : byte {} +enum Esbyte : sbyte {} +enum Eshort : short {} +enum Eushort : ushort {} +enum Eint : int {} +enum Euint : uint {} +enum Elong : long {} +enum Eulong : ulong {} +"; + var expectedOutput = +@"byte[] +sbyte[] +Ebyte[] +Esbyte[] +short[] +ushort[] +Eshort[] +Eushort[] +int[] +uint[] +Eint[] +Euint[] +int[][] +uint[][] +Eint[][] +Euint[][] +long[] +ulong[] +Elong[] +Eulong[] +IntPtr[] +UIntPtr[] +IntPtr[][] +UIntPtr[][] +"; + var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe); + compilation.VerifyDiagnostics(); + CompileAndVerify(compilation, expectedOutput: expectedOutput); + compilation = CreateCompilation(source, options: TestOptions.DebugExe); + compilation.VerifyDiagnostics(); + CompileAndVerify(compilation, expectedOutput: expectedOutput); + } + + [Fact] + public void CompileTimeRuntimeInstanceofMismatch_02() + { + var source = +@"using System; +class Program +{ + static void Main() + { + M(new byte[1]); + M(new sbyte[1]); + } + static void M(object o) + { + switch (o) + { + case byte[] _: + Console.WriteLine(""byte[]""); + break; + case sbyte[] _: // not subsumed, even though it will never occur due to CLR behavior + Console.WriteLine(""sbyte[]""); + break; + } + } +} +"; + var expectedOutput = +@"byte[] +byte[] +"; + var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe); + compilation.VerifyDiagnostics(); + CompileAndVerify(compilation, expectedOutput: expectedOutput); + compilation = CreateCompilation(source, options: TestOptions.DebugExe); + compilation.VerifyDiagnostics(); + CompileAndVerify(compilation, expectedOutput: expectedOutput); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs index ecbd91570cf25..5fbb06bba0049 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs @@ -2156,7 +2156,7 @@ public void InterfaceWithPartialMethodExplicitImplementation() { partial void I.M(); }"; - CreateCompilation(source, parseOptions: TestOptions.Regular7).VerifyDiagnostics( + CreateCompilation(source, parseOptions: TestOptions.Regular7, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( // (3,20): error CS0754: A partial method may not explicitly implement an interface method // partial void I.M(); Diagnostic(ErrorCode.ERR_PartialMethodNotExplicit, "M").WithLocation(3, 20), diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 404497ddf40ac..ab87a3dfc3274 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -11587,15 +11587,9 @@ class B2 : IB var compilation = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); compilation.VerifyDiagnostics( - // (34,37): error CS0071: An explicit interface implementation of an event must use event accessor syntax + // (34,38): error CS0071: An explicit interface implementation of an event must use event accessor syntax // event System.Action? IB.E3; // 2 - Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(34, 37), - // (34,40): error CS1519: Invalid token ';' in class, struct, or interface member declaration - // event System.Action? IB.E3; // 2 - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(34, 40), - // (34,38): error CS0065: 'B2.IB.E3': event property must have both add and remove accessors - // event System.Action? IB.E3; // 2 - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E3").WithArguments("B2.IB.E3").WithLocation(34, 38), + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "E3").WithLocation(34, 38), // (30,12): error CS0535: 'B2' does not implement interface member 'IB.E3.remove' // class B2 : IB Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "IB").WithArguments("B2", "IB.E3.remove").WithLocation(30, 12), @@ -17746,9 +17740,9 @@ public void Main(string? s) s.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); // https://github.com/dotnet/roslyn/issues/29855: there should only be one diagnostic c.VerifyDiagnostics( @@ -17779,9 +17773,9 @@ public void Main(string? s) s.ToString(); } } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -17806,9 +17800,9 @@ void M(C? c1) } C? Method() => throw null!; - static bool MyIsNullOrEmpty([NotNullWhenFalse] C? s) => throw null!; + static bool MyIsNullOrEmpty([NotNullWhen(false)] C? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,13): warning CS8602: Dereference of a possibly null reference. @@ -17838,9 +17832,9 @@ public void Main(string? s) s.ToString(); } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (7,13): error CS0103: The name 'Missing' does not exist in the current context @@ -17876,9 +17870,9 @@ public void Main(string? s) s.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); // https://github.com/dotnet/roslyn/issues/29855: there should only be one diagnostic c.VerifyDiagnostics( @@ -17912,9 +17906,9 @@ public void Main(string? s) s.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); // https://github.com/dotnet/roslyn/issues/29855: there should only be one diagnostic c.VerifyDiagnostics( @@ -17934,9 +17928,9 @@ public void NotNullWhenFalse_RequiresBoolReturn() using System.Runtime.CompilerServices; public class C { - public static object MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static object MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); @@ -17961,9 +17955,9 @@ void M(string? s) s.ToString(); // ok } } - public static T MyIsNullOrEmpty([NotNullWhenFalse] string? s, T t) => throw null!; + public static T MyIsNullOrEmpty([NotNullWhen(false)] string? s, T t) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -17995,9 +17989,9 @@ public void Main(string? s) s.ToString(); // ok s2.ToString(); // ok } - public static bool M([NotNullWhenTrue] string? s, out string? s2) => throw null!; + public static bool M([NotNullWhen(true)] string? s, out string? s2) => throw null!; } -", NotNullWhenTrueAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (10,13): warning CS8602: Dereference of a possibly null reference. @@ -18013,7 +18007,7 @@ public void Main(string? s) } [Fact] - public void MethodWithOutNullableParameter_AfterEnsuresNotNull() + public void MethodWithOutNullableParameter_AfterNotNull() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -18035,9 +18029,9 @@ public void Main(string? s) s.ToString(); // ok s2.ToString(); // ok } - public static bool M([EnsuresNotNull] string? s, out string? s2) => throw null!; + public static bool M([NotNull] string? s, out string? s2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (10,13): warning CS8602: Dereference of a possibly null reference. @@ -18050,7 +18044,7 @@ public void Main(string? s) } [Fact] - public void MethodWithOutNullableParameter_AfterEnsuresNotNull_InErrorInvocation() + public void MethodWithOutNullableParameter_AfterNotNull_InErrorInvocation() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -18072,9 +18066,9 @@ public void Main(string? s) s.ToString(); s2.ToString(); } - public static bool M([EnsuresNotNull] string? s, out string? s2) => throw null!; + public static bool M([NotNull] string? s, out string? s2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (7,13): error CS0103: The name 'Missing' does not exist in the current context @@ -19255,7 +19249,7 @@ public void Main(string? key) } [Fact] - public void MethodWithGenericOutParameter_WithEnsuresNotNull() + public void MethodWithGenericOutParameter_WithNotNull() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -19266,9 +19260,9 @@ public void Main(string? key) Copy(key, out var s); // ok s/*T:string!*/.ToString(); // ok } - public static void Copy(T key, [EnsuresNotNull] out T value) => throw null!; + public static void Copy(T key, [NotNull] out T value) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); VerifyOutVar(c, "string!"); // https://github.com/dotnet/roslyn/issues/29856: T is inferred to string! instead of string?, so the `var` gets `string!` c.VerifyTypes(); @@ -19276,7 +19270,7 @@ public void Main(string? key) } [Fact] - public void MethodWithGenericNullableOutParameter_WithEnsuresNotNull() + public void MethodWithGenericNullableOutParameter_WithNotNull() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -19287,9 +19281,9 @@ public void Main(string? key) Copy(key, out var s); // ok s/*T:string!*/.ToString(); // ok } - public static void Copy(T key, [EnsuresNotNull] out T? value) where T : class => throw null!; + public static void Copy(T key, [NotNull] out T? value) where T : class => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); VerifyOutVar(c, "string?"); c.VerifyTypes(); @@ -19539,23 +19533,22 @@ public void Main(string? key) [Fact] [WorkItem(29858, "https://github.com/dotnet/roslyn/issues/29858")] - public void GenericMethod_WithEnsuresNotNullOnReturnType() + public void GenericMethod_WithNotNullOnMethod() { CSharpCompilation c = CreateCompilation(@" using System.Runtime.CompilerServices; public class C { - [EnsuresNotNull] + [NotNull] public static T Copy(T key) => throw null!; } -" + EnsuresNotNullAttributeDefinition); +" + NotNullAttributeDefinition); c.VerifyDiagnostics( - // (5,6): error CS0592: Attribute 'EnsuresNotNull' is not valid on this declaration type. It is only valid on 'parameter' declarations. - // [EnsuresNotNull] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "EnsuresNotNull").WithArguments("EnsuresNotNull", "parameter").WithLocation(5, 6) + // (5,6): error CS0592: Attribute 'NotNull' is not valid on this declaration type. It is only valid on 'property, indexer, field, parameter, return' declarations. + // [NotNull] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "NotNull").WithArguments("NotNull", "property, indexer, field, parameter, return").WithLocation(5, 6) ); - // https://github.com/dotnet/roslyn/issues/29858: Need to confirm if this would be useful } [Fact] @@ -19794,9 +19787,9 @@ public void Main(string key) s.ToString(); // ok } - public static bool TryGetValue(string key, [NotNullWhenTrue] out string? value) => throw null!; + public static bool TryGetValue(string key, [NotNullWhen(true)] out string? value) => throw null!; } -", NotNullWhenTrueAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (13,13): warning CS8602: Dereference of a possibly null reference. @@ -19826,9 +19819,9 @@ public void Main(string? s) s.ToString(); // warn } } - public static bool IsNotNull([NotNullWhenTrue] string? value) => throw null!; + public static bool IsNotNull([NotNullWhen(true)] string? value) => throw null!; } -", NotNullWhenTrueAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (13,13): warning CS8602: Dereference of a possibly null reference. @@ -19840,8 +19833,6 @@ public void Main(string? s) [Fact] public void NotNullWhenTrue_WithNotNullWhenFalse_WithVoidReturn() { - // When both NotNullWhenTrue and NotNullWhenFalse are applied, it's the same as EnsuresNotNull, - // even if the method doesn't return bool. CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; public class C @@ -19851,13 +19842,19 @@ public void Main() M(out string? s); s.ToString(); // ok } - public static void M([NotNullWhenTrue, NotNullWhenFalse] out string? value) => throw null!; + public static void M([NotNullWhen(true), NotNullWhen(false)] out string? value) => throw null!; } -", NotNullWhenTrueAttributeDefinition, NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); - c.VerifyDiagnostics(); + c.VerifyDiagnostics( + // (8,9): warning CS8602: Dereference of a possibly null reference. + // s.ToString(); // ok + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 9), + // (10,46): error CS0579: Duplicate 'NotNullWhen' attribute + // public static void M([NotNullWhen(true), NotNullWhen(false)] out string? value) => throw null!; + Diagnostic(ErrorCode.ERR_DuplicateAttribute, "NotNullWhen").WithArguments("NotNullWhen").WithLocation(10, 46)); - VerifyAnnotationsAndMetadata(c, "C.M", EnsuresNotNull); + VerifyAnnotations(c, "C.M", NotNullWhenTrue); } [Fact] @@ -20339,9 +20336,9 @@ public void Main(string? s) s.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20360,9 +20357,9 @@ public void NotNullWhenFalse_BoolReturn() using System.Runtime.CompilerServices; public class C { - public static object MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static object MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); @@ -20392,9 +20389,9 @@ void Main(string? s, string? s2) s.ToString(); // ok s2.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s, [NotNullWhenFalse] string? s2) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s, [NotNullWhen(false)] string? s2) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20431,9 +20428,9 @@ void Main(string? s, string? s2) s.ToString(); // ok s2.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s, [NotNullWhenTrue] string? s2) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s, [NotNullWhen(true)] string? s2) => throw null!; } -", NotNullWhenFalseAttributeDefinition, NotNullWhenTrueAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20467,9 +20464,9 @@ void Main(string? s, int x) s.ToString(); // ok } - public bool this[[NotNullWhenFalse] string? s, int x] => throw null!; + public bool this[[NotNullWhen(false)] string? s, int x] => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20496,9 +20493,9 @@ void Main(string? s) s.ToString(); // ok } } - static bool Method([NotNullWhenFalse] string? s, string s2) => throw null!; + static bool Method([NotNullWhen(false)] string? s, string s2) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (7,23): warning CS8602: Dereference of a possibly null reference. @@ -20525,9 +20522,9 @@ void Main(string? s) s.ToString(); // warn 2 } } - static bool Method([NotNullWhenFalse] string? s, string? s2) => throw null!; + static bool Method([NotNullWhen(false)] string? s, string? s2) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20558,17 +20555,17 @@ void Main(string? s) s.ToString(); // ok } - static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } " }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( - // (17,34): error CS0246: The type or namespace name 'NotNullWhenFalseAttribute' could not be found (are you missing a using directive or an assembly reference?) - // static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotNullWhenFalse").WithArguments("NotNullWhenFalseAttribute").WithLocation(17, 34), - // (17,34): error CS0246: The type or namespace name 'NotNullWhenFalse' could not be found (are you missing a using directive or an assembly reference?) - // static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotNullWhenFalse").WithArguments("NotNullWhenFalse").WithLocation(17, 34), + // (17,34): error CS0246: The type or namespace name 'NotNullWhenAttribute' could not be found (are you missing a using directive or an assembly reference?) + // static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotNullWhen").WithArguments("NotNullWhenAttribute").WithLocation(17, 34), + // (17,34): error CS0246: The type or namespace name 'NotNullWhen' could not be found (are you missing a using directive or an assembly reference?) + // static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotNullWhen").WithArguments("NotNullWhen").WithLocation(17, 34), // (8,13): warning CS8602: Dereference of a possibly null reference. // s.ToString(); // warn Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 13), @@ -20615,15 +20612,15 @@ void Main(string? s) s.ToString(); // warn 2 } } - public static bool MyIsNullOrEmpty([NotNullWhenFalse(true)] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - public class NotNullWhenFalseAttribute : Attribute + public class NotNullWhenAttribute : Attribute { - public NotNullWhenFalseAttribute(bool bad) { } + public NotNullWhenAttribute(bool when, bool other = false) { } } } " }, options: WithNonNullTypesTrue()); @@ -20658,9 +20655,9 @@ void Main(string? s) s.ToString(); // warn } } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (13,13): warning CS8602: Dereference of a possibly null reference. @@ -20682,9 +20679,9 @@ void Main(string? s) { _ = MyIsNullOrEmpty(null); } - static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } @@ -20707,9 +20704,9 @@ void Main(string? s) s.ToString(); // ok } } - public bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public bool MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20741,9 +20738,9 @@ void Main(string? s) } public static class Extension { - public static bool MyIsNullOrEmpty(this C c, [NotNullWhenFalse] string? s) => throw null!; + public static bool MyIsNullOrEmpty(this C c, [NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20869,7 +20866,7 @@ public class Object } public class String { - public static bool IsNullOrEmpty([NotNullWhenTrue] string? s) => throw null!; + public static bool IsNullOrEmpty([NotNullWhen(true)] string? s) => throw null!; } public struct Void { } public struct Boolean { } @@ -20891,7 +20888,7 @@ public class ObsoleteAttribute : Attribute public ObsoleteAttribute(string message) => throw null!; } } -", NotNullWhenTrueAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -20946,10 +20943,10 @@ namespace System.Diagnostics { public static class Debug { - public static void Assert(bool condition, [EnsuresNotNull] string message) => throw null!; + public static void Assert(bool condition, [NotNull] string message) => throw null!; } } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); @@ -21130,20 +21127,20 @@ public void NotNullWhenFalse_PartialMethod() public partial class C { partial void M1(string? s); - partial void M1([NotNullWhenFalse] string? s) => throw null!; + partial void M1([NotNullWhen(false)] string? s) => throw null!; - partial void M2([NotNullWhenFalse] string? s); + partial void M2([NotNullWhen(false)] string? s); partial void M2(string? s) => throw null!; - partial void M3([NotNullWhenFalse] string? s); - partial void M3([NotNullWhenFalse] string? s) => throw null!; + partial void M3([NotNullWhen(false)] string? s); + partial void M3([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( - // (11,22): error CS0579: Duplicate 'NotNullWhenFalse' attribute - // partial void M3([NotNullWhenFalse] string? s); - Diagnostic(ErrorCode.ERR_DuplicateAttribute, "NotNullWhenFalse").WithArguments("NotNullWhenFalse").WithLocation(11, 22) + // (11,22): error CS0579: Duplicate 'NotNullWhen' attribute + // partial void M3([NotNullWhen(false)] string? s); + Diagnostic(ErrorCode.ERR_DuplicateAttribute, "NotNullWhen").WithArguments("NotNullWhen").WithLocation(11, 22) ); VerifyAnnotations(c, "C.M1", NotNullWhenFalse); @@ -21169,9 +21166,9 @@ void Main(string? s) s.ToString(); // warn 2 } } - public dynamic MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + public dynamic MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,13): warning CS8602: Dereference of a possibly null reference. @@ -21210,8 +21207,8 @@ .param [1] .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void System.Runtime.CompilerServices.NotNullWhenFalseAttribute::.ctor() = ( - 01 00 00 00 + .custom instance void System.Runtime.CompilerServices.NotNullWhenAttribute::.ctor(bool) = ( + 01 00 00 00 00 ) IL_0000: ldnull @@ -21226,14 +21223,14 @@ instance void .ctor () cil managed } } -.class public auto ansi beforefieldinit System.Runtime.CompilerServices.NotNullWhenFalseAttribute +.class public auto ansi beforefieldinit System.Runtime.CompilerServices.NotNullWhenAttribute extends [mscorlib]System.Attribute { .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 00 08 00 00 01 00 54 02 0d 41 6c 6c 6f 77 4d 75 6c 74 69 70 6c 65 00 ) .method public hidebysig specialname rtspecialname - instance void .ctor () cil managed + instance void .ctor (bool when) cil managed { IL_0000: ldnull IL_0001: throw @@ -21281,9 +21278,9 @@ void Main(string? s) MyIsNullOrEmpty(s); s.ToString(); // warn } - object MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null!; + object MyIsNullOrEmpty([NotNullWhen(false)] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -21293,7 +21290,7 @@ void Main(string? s) } [Fact] - public void NotNullWhenFalse_FollowedByEnsuresNotNull() + public void NotNullWhenFalse_FollowedByNotNull() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21312,17 +21309,17 @@ void Main(string? s) s.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s, [EnsuresNotNull] string? s2) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false)] string? s, [NotNull] string? s2) => throw null!; } -", NotNullWhenFalseAttributeDefinition, EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition, NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); - VerifyAnnotationsAndMetadata(c, "C.MyIsNullOrEmpty", NotNullWhenFalse, EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "C.MyIsNullOrEmpty", NotNullWhenFalse, NotNull); } [Fact] - public void NotNullWhenFalse_AndEnsuresNotNull() + public void NotNullWhenFalse_AndNotNull() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21341,17 +21338,17 @@ void Main(string? s) s.ToString(); // ok } - public static bool MyIsNullOrEmpty([NotNullWhenFalse, EnsuresNotNull] string? s) => throw null!; + public static bool MyIsNullOrEmpty([NotNullWhen(false), NotNull] string? s) => throw null!; } -", NotNullWhenFalseAttributeDefinition, EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullWhenAttributeDefinition, NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); - VerifyAnnotationsAndMetadata(c, "C.MyIsNullOrEmpty", EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "C.MyIsNullOrEmpty", NotNull); } [Fact] - public void EnsuresNotNull_Simple() + public void NotNull_Simple() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21362,17 +21359,17 @@ void Main(string? s) ThrowIfNull(42, s); s.ToString(); // ok } - public static void ThrowIfNull(int x, [EnsuresNotNull] string? s) => throw null!; + public static void ThrowIfNull(int x, [NotNull] string? s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); - VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", None, EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", None, NotNull); } [Fact] - public void EnsuresNotNull_Nested() + public void NotNull_Nested() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21383,15 +21380,15 @@ void Main(string? s) ThrowIfNull(s?.ToString()); s.ToString(); // ok } - public static void ThrowIfNull([EnsuresNotNull] string? s) => throw null!; + public static void ThrowIfNull([NotNull] string? s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact, WorkItem(32335, "https://github.com/dotnet/roslyn/issues/32335")] - public void EnsuresNotNull_LearningFromNotNullTest() + public void NotNull_LearningFromNotNullTest() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21404,15 +21401,15 @@ void M(C? c1) } C? Method() => throw null!; - static void ThrowIfNull([EnsuresNotNull] C? c) => throw null!; + static void ThrowIfNull([NotNull] C? c) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_ResettingStateMatters() + public void NotNull_ResettingStateMatters() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21424,9 +21421,9 @@ void Main(string? s, string? s2) s.ToString(); // warn s2.ToString(); // ok } - public static void ThrowIfNull(string? s1, [EnsuresNotNull] string? s2) => throw null!; + public static void ThrowIfNull(string? s1, [NotNull] string? s2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -21436,7 +21433,7 @@ void Main(string? s, string? s2) } [Fact] - public void EnsuresNotNull_ResettingStateMatters_InIndexer() + public void NotNull_ResettingStateMatters_InIndexer() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21448,9 +21445,9 @@ void Main(string? s, string? s2) s.ToString(); // warn s2.ToString(); // ok } - public int this[string? s1, [EnsuresNotNull] string? s2] { get { throw null!; } } + public int this[string? s1, [NotNull] string? s2] { get { throw null!; } } } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -21460,7 +21457,7 @@ void Main(string? s, string? s2) } [Fact] - public void EnsuresNotNull_NoDuplicateDiagnosticsWhenResettingState() + public void NotNull_NoDuplicateDiagnosticsWhenResettingState() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21471,9 +21468,9 @@ void Main(string? s, I i) { ThrowIfNull(i, s); // single warning on conversion failure } - public static void ThrowIfNull(I x, [EnsuresNotNull] string? s) => throw null!; + public static void ThrowIfNull(I x, [NotNull] string? s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,21): warning CS8620: Nullability of reference types in argument of type 'I' doesn't match target type 'I' for parameter 'x' in 'void C.ThrowIfNull(I x, string? s)'. @@ -21483,7 +21480,7 @@ void Main(string? s, I i) } [Fact] - public void EnsuresNotNull_Generic_WithRefType() + public void NotNull_Generic_WithRefType() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21494,15 +21491,15 @@ void Main(string? s) ThrowIfNull(s); s.ToString(); // ok } - public static void ThrowIfNull([EnsuresNotNull] T s) => throw null!; + public static void ThrowIfNull([NotNull] T s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_Generic_WithValueType() + public void NotNull_Generic_WithValueType() { CSharpCompilation c = CreateCompilation(@" using System.Runtime.CompilerServices; @@ -21513,15 +21510,15 @@ void Main(int s) ThrowIfNull(s); s.ToString(); } - public static void ThrowIfNull([EnsuresNotNull] T s) => throw null!; + public static void ThrowIfNull([NotNull] T s) => throw null!; } -" + EnsuresNotNullAttributeDefinition); +" + NotNullAttributeDefinition); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_Generic_WithUnconstrainedGenericType() + public void NotNull_Generic_WithUnconstrainedGenericType() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21532,15 +21529,15 @@ void M(U u) ThrowIfNull(u); u.ToString(); } - public static void ThrowIfNull([EnsuresNotNull] T s) => throw null!; + public static void ThrowIfNull([NotNull] T s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_OnInterface() + public void NotNull_OnInterface() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21554,17 +21551,17 @@ void Main(string? s, Interface i) } public interface Interface { - void ThrowIfNull(int x, [EnsuresNotNull] string? s); + void ThrowIfNull(int x, [NotNull] string? s); } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); - VerifyAnnotationsAndMetadata(c, "Interface.ThrowIfNull", None, EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "Interface.ThrowIfNull", None, NotNull); } [Fact] - public void EnsuresNotNull_OnInterface_ImplementedWithoutAttribute() + public void NotNull_OnInterface_ImplementedWithoutAttribute() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21581,9 +21578,9 @@ void Main(string? s) } public interface Interface { - void ThrowIfNull(int x, [EnsuresNotNull] string? s); + void ThrowIfNull(int x, [NotNull] string? s); } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -21591,12 +21588,12 @@ public interface Interface Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 9) ); - VerifyAnnotationsAndMetadata(c, "Interface.ThrowIfNull", None, EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "Interface.ThrowIfNull", None, NotNull); VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", None, None); } [Fact] - public void EnsuresNotNull_OnInterface_ImplementedWithAttribute() + public void NotNull_OnInterface_ImplementedWithAttribute() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21609,13 +21606,13 @@ void Main(string? s) this.ThrowIfNull(42, s); s.ToString(); // ok } - public void ThrowIfNull(int x, [EnsuresNotNull] string? s) => throw null!; + public void ThrowIfNull(int x, [NotNull] string? s) => throw null!; } public interface Interface { void ThrowIfNull(int x, string? s); } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -21624,15 +21621,15 @@ public interface Interface ); VerifyAnnotationsAndMetadata(c, "Interface.ThrowIfNull", None, None); - VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", None, EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", None, NotNull); } [Fact] - public void EnsuresNotNull_OnDelegate() + public void NotNull_OnDelegate() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; -delegate void D([EnsuresNotNull] object? o); +delegate void D([NotNull] object? o); public class C { void Main(string? s, D d) @@ -21641,33 +21638,33 @@ void Main(string? s, D d) s.ToString(); // ok } } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_WithParams() + public void NotNull_WithParams() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; public class C { - static void EnsuresNotNull([EnsuresNotNull] params object?[]? args) { } + static void NotNull([NotNull] params object?[]? args) { } static void F(object? x, object? y, object[]? a) { - EnsuresNotNull(); + NotNull(); a.ToString(); // warn 1 - EnsuresNotNull(x, y); + NotNull(x, y); x.ToString(); // warn 2 y.ToString(); // warn 3 - EnsuresNotNull(a); + NotNull(a); a.ToString(); // ok } } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (9,9): warning CS8602: Dereference of a possibly null reference. @@ -21683,14 +21680,14 @@ static void F(object? x, object? y, object[]? a) } [Fact] - public void EnsuresNotNull_WithParamsOnFirstParameter() + public void NotNull_WithParamsOnFirstParameter() { CSharpCompilation c = CreateCompilationWithIL(new[] { @" public class D { static void F(object[]? a, object? b, object? c) { - C.EnsuresNotNull(a, b, c); + C.NotNull(a, b, c); a.ToString(); // ok b.ToString(); // warn 1 c.ToString(); // warn 2 @@ -21723,7 +21720,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor ( bool[] .class public auto ansi beforefieldinit C extends [mscorlib]System.Object { - .method public hidebysig static void EnsuresNotNull ( object[] args, object[] args2 ) cil managed + .method public hidebysig static void NotNull ( object[] args, object[] args2 ) cil managed { .param [1] .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = ( @@ -21732,7 +21729,7 @@ 01 00 00 00 .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(bool[]) = ( 01 00 02 00 00 00 01 01 00 00 ) - .custom instance void System.Runtime.CompilerServices.EnsuresNotNullAttribute::.ctor() = ( + .custom instance void System.Runtime.CompilerServices.NotNullAttribute::.ctor() = ( 01 00 00 00 ) .param [2] @@ -21742,7 +21739,7 @@ 01 00 00 00 .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(bool[]) = ( 01 00 02 00 00 00 01 01 00 00 ) - .custom instance void System.Runtime.CompilerServices.EnsuresNotNullAttribute::.ctor() = ( + .custom instance void System.Runtime.CompilerServices.NotNullAttribute::.ctor() = ( 01 00 00 00 ) @@ -21759,7 +21756,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor () cil ma } } -.class public auto ansi beforefieldinit System.Runtime.CompilerServices.EnsuresNotNullAttribute +.class public auto ansi beforefieldinit System.Runtime.CompilerServices.NotNullAttribute extends [mscorlib]System.Attribute { .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( @@ -21787,24 +21784,24 @@ .method public hidebysig specialname rtspecialname instance void .ctor () cil ma } [Fact] - public void EnsuresNotNull_WithNamedArguments() + public void NotNull_WithNamedArguments() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; public class C { - static void EnsuresNotNull1([EnsuresNotNull] object? x = null, object? y = null) { } - static void EnsuresNotNull2(object? x = null, [EnsuresNotNull] object? y = null) { } + static void NotNull1([NotNull] object? x = null, object? y = null) { } + static void NotNull2(object? x = null, [NotNull] object? y = null) { } static void F(object? x) { - EnsuresNotNull1(); - EnsuresNotNull1(y: x); + NotNull1(); + NotNull1(y: x); x.ToString(); // warn - EnsuresNotNull2(y: x); + NotNull2(y: x); x.ToString(); // ok } } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (11,9): warning CS8602: Dereference of a possibly null reference. @@ -21814,25 +21811,25 @@ static void F(object? x) } [Fact] - public void EnsuresNotNull_OnDifferentTypes() + public void NotNull_OnDifferentTypes() { CSharpCompilation c = CreateCompilation(@" using System.Runtime.CompilerServices; public class C { - public static void Bad([EnsuresNotNull] int i) => throw null!; - public static void ThrowIfNull([EnsuresNotNull] T t) => throw null!; + public static void Bad([NotNull] int i) => throw null!; + public static void ThrowIfNull([NotNull] T t) => throw null!; } -" + EnsuresNotNullAttributeDefinition); +" + NotNullAttributeDefinition); c.VerifyDiagnostics(); - VerifyAnnotations(c, "C.Bad", EnsuresNotNull); - VerifyAnnotations(c, "C.ThrowIfNull", EnsuresNotNull); + VerifyAnnotations(c, "C.Bad", NotNull); + VerifyAnnotations(c, "C.ThrowIfNull", NotNull); } [Fact] - public void EnsuresNotNull_GenericMethod() + public void NotNull_GenericMethod() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21844,9 +21841,9 @@ void M(T t) ThrowIfNull(t); t.ToString(); // ok } - public static void ThrowIfNull([EnsuresNotNull] T s) => throw null!; + public static void ThrowIfNull([NotNull] T s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (7,9): warning CS8602: Dereference of a possibly null reference. @@ -21854,16 +21851,16 @@ void M(T t) Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t").WithLocation(7, 9) ); - VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", NotNull); } [Fact] [WorkItem(30079, "https://github.com/dotnet/roslyn/issues/30079")] - public void EnsuresNotNull_BeginInvoke() + public void NotNull_BeginInvoke() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; -public delegate void Delegate([EnsuresNotNull] string? s); +public delegate void Delegate([NotNull] string? s); public class C { void M(Delegate d, string? s) @@ -21873,7 +21870,7 @@ void M(Delegate d, string? s) s.ToString(); // warn 2 } } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,32): warning CS8602: Dereference of a possibly null reference. @@ -21886,7 +21883,7 @@ void M(Delegate d, string? s) } [Fact] - public void EnsuresNotNull_BackEffect() + public void NotNull_BackEffect() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21897,9 +21894,9 @@ void M(string? s1, string? s2) ThrowIfNull(s2 = s1, s1); s2.ToString(); // warn } - public static void ThrowIfNull(string? x1, [EnsuresNotNull] string? x2) => throw null!; + public static void ThrowIfNull(string? x1, [NotNull] string? x2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); // https://github.com/dotnet/roslyn/issues/29865: Should we be able to trace that s2 was assigned a non-null value? c.VerifyDiagnostics( @@ -21911,7 +21908,7 @@ void M(string? s1, string? s2) [Fact] [WorkItem(29916, "https://github.com/dotnet/roslyn/issues/29916")] - public void EnsuresNotNull_InErrorInvocation() + public void NotNull_InErrorInvocation() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21922,9 +21919,9 @@ void M(string? s1, string? s2) Missing(ThrowIfNull(s1, s2 = s1)); s2.ToString(); } - public static void ThrowIfNull([EnsuresNotNull] string? x1, string? x2) => throw null!; + public static void ThrowIfNull([NotNull] string? x1, string? x2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (7,9): error CS0103: The name 'Missing' does not exist in the current context @@ -21934,7 +21931,7 @@ void M(string? s1, string? s2) } [Fact] - public void EnsuresNotNull_ForwardEffect() + public void NotNull_ForwardEffect() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21945,15 +21942,15 @@ void M(string? s1, string? s2) ThrowIfNull(s1, s2 = s1); s2.ToString(); // ok } - public static void ThrowIfNull([EnsuresNotNull] string? x1, string? x2) => throw null!; + public static void ThrowIfNull([NotNull] string? x1, string? x2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_ForwardEffect2() + public void NotNull_ForwardEffect2() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21964,9 +21961,9 @@ void M(string? s1) ThrowIfNull(s1, s1 = null); s1.ToString(); // warn } - public static void ThrowIfNull([EnsuresNotNull] string? x1, string? x2) => throw null!; + public static void ThrowIfNull([NotNull] string? x1, string? x2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -21976,7 +21973,7 @@ void M(string? s1) } [Fact] - public void EnsuresNotNull_ForwardEffect3() + public void NotNull_ForwardEffect3() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -21987,9 +21984,9 @@ void M(string? s1, string? s2) ThrowIfNull(s1 = null, s2 = s1, s1 = """", s1); s2.ToString(); // warn } - public static void ThrowIfNull(string? x1, string? x2, string? x3, [EnsuresNotNull] string? x4) => throw null!; + public static void ThrowIfNull(string? x1, string? x2, string? x3, [NotNull] string? x4) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -22000,7 +21997,7 @@ void M(string? s1, string? s2) [Fact] [WorkItem(29867, "https://github.com/dotnet/roslyn/issues/29867")] - public void EnsuresNotNull_TypeInference() + public void NotNull_TypeInference() { // https://github.com/dotnet/roslyn/issues/29867: This test raises the question of flowing information from annotations into the inferred type CSharpCompilation c = CreateCompilation(new[] { @" @@ -22012,9 +22009,9 @@ void M(string? s1) ThrowIfNull(s1, out var s2); s2/*T:string?*/.ToString(); } - public static void ThrowIfNull([EnsuresNotNull] T x1, out T x2) => throw null!; + public static void ThrowIfNull([NotNull] T x1, out T x2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyTypes(); c.VerifyDiagnostics( @@ -22025,7 +22022,7 @@ void M(string? s1) } [Fact] - public void EnsuresNotNull_ConditionalMethodInReleaseMode() + public void NotNull_ConditionalMethodInReleaseMode() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -22037,15 +22034,15 @@ void Main(string? s) s.ToString(); // ok } [System.Diagnostics.Conditional(""DEBUG"")] - static void ThrowIfNull(int x, [EnsuresNotNull] string? s) => throw null!; + static void ThrowIfNull(int x, [NotNull] string? s) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } [Fact] - public void EnsuresNotNull_SecondArgumentDereferences() + public void NotNull_SecondArgumentDereferences() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -22056,9 +22053,9 @@ void Main(string? s) ThrowIfNull(s, s.ToString()); // warn s.ToString(); // ok } - public static void ThrowIfNull([EnsuresNotNull] string? s, string s2) => throw null!; + public static void ThrowIfNull([NotNull] string? s, string s2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (7,24): warning CS8602: Dereference of a possibly null reference. @@ -22066,11 +22063,11 @@ void Main(string? s) Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(7, 24) ); - VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", EnsuresNotNull, None); + VerifyAnnotationsAndMetadata(c, "C.ThrowIfNull", NotNull, None); } [Fact] - public void EnsuresNotNull_SecondArgumentAssigns() + public void NotNull_SecondArgumentAssigns() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -22081,9 +22078,9 @@ void Main(string? s) ThrowIfNull(s, s = null); s.ToString(); // warn } - static void ThrowIfNull([EnsuresNotNull] string? s, string? s2) => throw null!; + static void ThrowIfNull([NotNull] string? s, string? s2) => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics( // (8,9): warning CS8602: Dereference of a possibly null reference. @@ -22093,7 +22090,7 @@ void Main(string? s) } [Fact] - public void EnsuresNotNull_String_Contains() + public void NotNull_String_Contains() { CSharpCompilation c = CreateCompilation(new[] { @" class C @@ -22108,11 +22105,11 @@ void Main(string? s) c.VerifyDiagnostics(); - VerifyAnnotationsAndMetadata(c, "System.String.Contains", EnsuresNotNull); + VerifyAnnotationsAndMetadata(c, "System.String.Contains", NotNull); } [Fact] - public void EnsuresNotNull_Indexer() + public void NotNull_Indexer() { CSharpCompilation c = CreateCompilation(new[] { @" using System.Runtime.CompilerServices; @@ -22123,9 +22120,9 @@ void Main(string? s) _ = this[42, s]; s.ToString(); // ok } - public int this[int x, [EnsuresNotNull] string? s] => throw null!; + public int this[int x, [NotNull] string? s] => throw null!; } -", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); +", NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); c.VerifyDiagnostics(); } @@ -33658,7 +33655,7 @@ static void Main() public void DelegateCreation_Parameter_01() { var source = -@"delegate void D(T t); +@"delegate void D(T t1); interface I { } interface IIn { } interface IOut { } @@ -33666,42 +33663,43 @@ class C { static void Main() { - _ = new D((object? t) => { }); // 1 - _ = new D((object t) => { }); // 2 - _ = new D>((I t) => { }); // 3 - _ = new D>((I t) => { }); // 4 - _ = new D>((IIn t) => { }); // 5 - _ = new D>((IIn t) => { }); // 6 - _ = new D>((IOut t) => { }); // 7 - _ = new D>((IOut t) => { }); // 8 + // parameter name is different than delegate to ensure that diagnostics refer to the correct names + _ = new D((object? t2) => { }); // 1 + _ = new D((object t2) => { }); // 2 + _ = new D>((I t2) => { }); // 3 + _ = new D>((I t2) => { }); // 4 + _ = new D>((IIn t2) => { }); // 5 + _ = new D>((IIn t2) => { }); // 6 + _ = new D>((IOut t2) => { }); // 7 + _ = new D>((IOut t2) => { }); // 8 } }"; var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (9,39): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D'. - // _ = new D((object? t) => { }); // 1 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D").WithLocation(9, 39), - // (10,39): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D'. - // _ = new D((object t) => { }); // 2 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D").WithLocation(10, 39), - // (11,45): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((I t) => { }); // 3 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(11, 45), - // (12,45): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((I t) => { }); // 4 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(12, 45), - // (13,49): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((IIn t) => { }); // 5 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(13, 49), - // (14,49): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((IIn t) => { }); // 6 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(14, 49), - // (15,51): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((IOut t) => { }); // 7 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(15, 51), - // (16,51): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((IOut t) => { }); // 8 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(16, 51)); + // (10,40): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D'. + // _ = new D((object? t2) => { }); // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D").WithLocation(10, 40), + // (11,40): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D'. + // _ = new D((object t2) => { }); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D").WithLocation(11, 40), + // (12,46): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((I t2) => { }); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(12, 46), + // (13,46): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((I t2) => { }); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(13, 46), + // (14,50): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((IIn t2) => { }); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(14, 50), + // (15,50): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((IIn t2) => { }); // 6 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(15, 50), + // (16,52): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((IOut t2) => { }); // 7 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(16, 52), + // (17,52): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((IOut t2) => { }); // 8 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(17, 52)); } [Fact] @@ -33709,13 +33707,14 @@ static void Main() public void DelegateCreation_Parameter_02() { var source = -@"delegate void D(T t); +@"delegate void D(T t1); interface I { } interface IIn { } interface IOut { } class C { - static void F(T t) { } + // parameter name is different than delegate to ensure that diagnostics refer to the correct names + static void F(T t2) { } static void Main() { _ = new D(F); @@ -33730,21 +33729,21 @@ static void Main() }"; var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (11,28): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F(object t)' doesn't match the target delegate 'D'. + // (12,28): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F(object t2)' doesn't match the target delegate 'D'. // _ = new D(F); // 1 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t", "void C.F(object t)", "D").WithLocation(11, 28), - // (12,30): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(I t)' doesn't match the target delegate 'D>'. + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t2", "void C.F(object t2)", "D").WithLocation(12, 28), + // (13,30): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(I t2)' doesn't match the target delegate 'D>'. // _ = new D>(F>); // 2 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(I t)", "D>").WithLocation(12, 30), - // (13,31): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(I t)' doesn't match the target delegate 'D>'. + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(I t2)", "D>").WithLocation(13, 30), + // (14,31): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(I t2)' doesn't match the target delegate 'D>'. // _ = new D>(F>); // 3 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(I t)", "D>").WithLocation(13, 31), - // (14,32): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(IIn t)' doesn't match the target delegate 'D>'. + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(I t2)", "D>").WithLocation(14, 31), + // (15,32): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(IIn t2)' doesn't match the target delegate 'D>'. // _ = new D>(F>); // 4 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(IIn t)", "D>").WithLocation(14, 32), - // (17,34): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(IOut t)' doesn't match the target delegate 'D>'. + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(IIn t2)", "D>").WithLocation(15, 32), + // (18,34): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(IOut t2)' doesn't match the target delegate 'D>'. // _ = new D>(F>); // 5 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(IOut t)", "D>").WithLocation(17, 34)); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(IOut t2)", "D>").WithLocation(18, 34)); } [Fact] @@ -33752,7 +33751,7 @@ static void Main() public void DelegateCreation_OutParameter_01() { var source = -@"delegate void D(out T t); +@"delegate void D(out T t1); interface I { } interface IIn { } interface IOut { } @@ -33760,42 +33759,43 @@ class C { static void Main() { - _ = new D((out object? t) => t = default!); // 1 - _ = new D((out object t) => t = default!); // 2 - _ = new D>((out I t) => t = default!); // 3 - _ = new D>((out I t) => t = default!); // 4 - _ = new D>((out IIn t) => t = default!); // 5 - _ = new D>((out IIn t) => t = default!); // 6 - _ = new D>((out IOut t) => t = default!); // 7 - _ = new D>((out IOut t) => t = default!); // 8 + // parameter name is different than delegate to ensure that diagnostics refer to the correct names + _ = new D((out object? t2) => t2 = default!); // 1 + _ = new D((out object t2) => t2 = default!); // 2 + _ = new D>((out I t2) => t2 = default!); // 3 + _ = new D>((out I t2) => t2 = default!); // 4 + _ = new D>((out IIn t2) => t2 = default!); // 5 + _ = new D>((out IIn t2) => t2 = default!); // 6 + _ = new D>((out IOut t2) => t2 = default!); // 7 + _ = new D>((out IOut t2) => t2 = default!); // 8 } }"; var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (9,43): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D'. - // _ = new D((out object? t) => t = default!); // 1 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D").WithLocation(9, 43), - // (10,43): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D'. - // _ = new D((out object t) => t = default!); // 2 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D").WithLocation(10, 43), - // (11,49): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((out I t) => t = default!); // 3 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(11, 49), - // (12,49): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((out I t) => t = default!); // 4 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(12, 49), - // (13,53): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((out IIn t) => t = default!); // 5 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(13, 53), - // (14,53): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((out IIn t) => t = default!); // 6 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(14, 53), - // (15,55): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((out IOut t) => t = default!); // 7 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(15, 55), - // (16,55): warning CS8622: Nullability of reference types in type of parameter 't' of 'lambda expression' doesn't match the target delegate 'D>'. - // _ = new D>((out IOut t) => t = default!); // 8 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t", "lambda expression", "D>").WithLocation(16, 55)); + // (10,44): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D'. + // _ = new D((out object? t2) => t2 = default!); // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D").WithLocation(10, 44), + // (11,44): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D'. + // _ = new D((out object t2) => t2 = default!); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D").WithLocation(11, 44), + // (12,50): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((out I t2) => t2 = default!); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(12, 50), + // (13,50): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((out I t2) => t2 = default!); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(13, 50), + // (14,54): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((out IIn t2) => t2 = default!); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(14, 54), + // (15,54): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((out IIn t2) => t2 = default!); // 6 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(15, 54), + // (16,56): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((out IOut t2) => t2 = default!); // 7 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(16, 56), + // (17,56): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((out IOut t2) => t2 = default!); // 8 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(17, 56)); } [Fact] @@ -33803,51 +33803,139 @@ static void Main() public void DelegateCreation_OutParameter_02() { var source = -@"delegate void D(out T t); +@"delegate void D(out T t1); interface I { } interface IIn { } interface IOut { } class C { - static void F(out T t) { t = default!; } + // parameter name is different than delegate to ensure that diagnostics refer to the correct names + static void F(out T t2) { t2 = default!; } static void Main() { _ = new D(F); // 1 - _ = new D(F); // 2 - _ = new D>(F>); // 3 - _ = new D>(F>); // 4 - _ = new D>(F>); // 5 - _ = new D>(F>); // 6 - _ = new D>(F>); // 7 - _ = new D>(F>); // 8 + _ = new D(F); + _ = new D>(F>); // 2 + _ = new D>(F>); // 3 + _ = new D>(F>); + _ = new D>(F>); // 4 + _ = new D>(F>); // 5 + _ = new D>(F>); } }"; var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (10,27): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F(out object? t)' doesn't match the target delegate 'D'. + // (11,27): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F(out object? t2)' doesn't match the target delegate 'D'. // _ = new D(F); // 1 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t", "void C.F(out object? t)", "D").WithLocation(10, 27), - // (11,28): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F(out object t)' doesn't match the target delegate 'D'. - // _ = new D(F); // 2 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t", "void C.F(out object t)", "D").WithLocation(11, 28), - // (12,30): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out I t)' doesn't match the target delegate 'D>'. - // _ = new D>(F>); // 3 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out I t)", "D>").WithLocation(12, 30), - // (13,31): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out I t)' doesn't match the target delegate 'D>'. - // _ = new D>(F>); // 4 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out I t)", "D>").WithLocation(13, 31), - // (14,32): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IIn t)' doesn't match the target delegate 'D>'. - // _ = new D>(F>); // 5 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IIn t)", "D>").WithLocation(14, 32), - // (15,33): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IIn t)' doesn't match the target delegate 'D>'. - // _ = new D>(F>); // 6 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IIn t)", "D>").WithLocation(15, 33), - // (16,33): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IOut t)' doesn't match the target delegate 'D>'. - // _ = new D>(F>); // 7 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IOut t)", "D>").WithLocation(16, 33), - // (17,34): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IOut t)' doesn't match the target delegate 'D>'. - // _ = new D>(F>); // 8 - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IOut t)", "D>").WithLocation(17, 34)); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t2", "void C.F(out object? t2)", "D").WithLocation(11, 27), + // (13,30): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(out I t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(out I t2)", "D>").WithLocation(13, 30), + // (14,31): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(out I t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(out I t2)", "D>").WithLocation(14, 31), + // (16,33): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(out IIn t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(out IIn t2)", "D>").WithLocation(16, 33), + // (17,33): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(out IOut t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(out IOut t2)", "D>").WithLocation(17, 33)); + } + + [Fact] + [WorkItem(32563, "https://github.com/dotnet/roslyn/issues/32563")] + public void DelegateCreation_InParameter_01() + { + var source = +@"delegate void D(in T t1); +interface I { } +interface IIn { } +interface IOut { } +class C +{ + static void Main() + { + // parameter name is different than delegate to ensure that diagnostics refer to the correct names + _ = new D((in object? t2) => { }); // 1 + _ = new D((in object t2) => { }); // 2 + _ = new D>((in I t2) => { }); // 3 + _ = new D>((in I t2) => { }); // 4 + _ = new D>((in IIn t2) => { }); // 5 + _ = new D>((in IIn t2) => { }); // 6 + _ = new D>((in IOut t2) => { }); // 7 + _ = new D>((in IOut t2) => { }); // 8 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (10,43): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D'. + // _ = new D((in object? t2) => { }); // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D").WithLocation(10, 43), + // (11,43): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D'. + // _ = new D((in object t2) => { }); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D").WithLocation(11, 43), + // (12,49): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((in I t2) => { }); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(12, 49), + // (13,49): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((in I t2) => { }); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(13, 49), + // (14,53): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((in IIn t2) => { }); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(14, 53), + // (15,53): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((in IIn t2) => { }); // 6 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(15, 53), + // (16,55): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((in IOut t2) => { }); // 7 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(16, 55), + // (17,55): warning CS8622: Nullability of reference types in type of parameter 't2' of 'lambda expression' doesn't match the target delegate 'D>'. + // _ = new D>((in IOut t2) => { }); // 8 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "=>").WithArguments("t2", "lambda expression", "D>").WithLocation(17, 55)); + } + + [Fact] + [WorkItem(32563, "https://github.com/dotnet/roslyn/issues/32563")] + public void DelegateCreation_InParameter_02() + { + var source = +@"delegate void D(in T t1); +interface I { } +interface IIn { } +interface IOut { } +class C +{ + // parameter name is different than delegate to ensure that diagnostics refer to the correct names + static void F(in T t2) { } + static void Main() + { + _ = new D(F); + _ = new D(F); // 1 + _ = new D>(F>); // 2 + _ = new D>(F>); // 3 + _ = new D>(F>); // 4 + _ = new D>(F>); + _ = new D>(F>); + _ = new D>(F>); // 5 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (12,28): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F(in object t2)' doesn't match the target delegate 'D'. + // _ = new D(F); // 1 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t2", "void C.F(in object t2)", "D").WithLocation(12, 28), + // (13,30): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(in I t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(in I t2)", "D>").WithLocation(13, 30), + // (14,31): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(in I t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 3 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(in I t2)", "D>").WithLocation(14, 31), + // (15,32): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(in IIn t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 4 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(in IIn t2)", "D>").WithLocation(15, 32), + // (18,34): warning CS8622: Nullability of reference types in type of parameter 't2' of 'void C.F>(in IOut t2)' doesn't match the target delegate 'D>'. + // _ = new D>(F>); // 5 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t2", "void C.F>(in IOut t2)", "D>").WithLocation(18, 34)); } [Fact] @@ -34095,32 +34183,66 @@ static void G() } }"; var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); - // https://github.com/dotnet/roslyn/issues/32564: Delegate conversions should allow `b`, `e`, `h` without warning. comp.VerifyDiagnostics( // (10,23): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F(out object? t)' doesn't match the target delegate 'D'. // D a = F; Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t", "void C.F(out object? t)", "D").WithLocation(10, 23), - // (11,24): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F(out object t)' doesn't match the target delegate 'D'. - // D b = F; - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t", "void C.F(out object t)", "D").WithLocation(11, 24), // (12,26): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out I t)' doesn't match the target delegate 'D>'. // D> c = F>; Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out I t)", "D>").WithLocation(12, 26), // (13,27): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out I t)' doesn't match the target delegate 'D>'. // D> d = F>; Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out I t)", "D>").WithLocation(13, 27), - // (14,28): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IIn t)' doesn't match the target delegate 'D>'. - // D> e = F>; - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IIn t)", "D>").WithLocation(14, 28), // (15,29): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IIn t)' doesn't match the target delegate 'D>'. // D> f = F>; Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IIn t)", "D>").WithLocation(15, 29), // (16,29): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IOut t)' doesn't match the target delegate 'D>'. // D> g = F>; - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IOut t)", "D>").WithLocation(16, 29), - // (17,30): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(out IOut t)' doesn't match the target delegate 'D>'. - // D> h = F>; - Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IOut t)", "D>").WithLocation(17, 30) + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(out IOut t)", "D>").WithLocation(16, 29) + ); + } + + [Fact] + [WorkItem(32563, "https://github.com/dotnet/roslyn/issues/32563")] + public void IdentityConversion_DelegateInParameter() + { + var source = +@"delegate void D(in T t); +interface I { } +interface IIn { } +interface IOut { } +class C +{ + static void F(in T t) { } + static void G() + { + D a = F; + D b = F; + D> c = F>; + D> d = F>; + D> e = F>; + D> f = F>; + D> g = F>; + D> h = F>; + } +}"; + var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (11,24): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F(in object t)' doesn't match the target delegate 'D'. + // D b = F; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F").WithArguments("t", "void C.F(in object t)", "D").WithLocation(11, 24), + // (12,26): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(in I t)' doesn't match the target delegate 'D>'. + // D> c = F>; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(in I t)", "D>").WithLocation(12, 26), + // (13,27): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(in I t)' doesn't match the target delegate 'D>'. + // D> d = F>; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(in I t)", "D>").WithLocation(13, 27), + // (14,28): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(in IIn t)' doesn't match the target delegate 'D>'. + // D> e = F>; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(in IIn t)", "D>").WithLocation(14, 28), + // (17,30): warning CS8622: Nullability of reference types in type of parameter 't' of 'void C.F>(in IOut t)' doesn't match the target delegate 'D>'. + // D> h = F>; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate, "F>").WithArguments("t", "void C.F>(in IOut t)", "D>").WithLocation(17, 30) ); } @@ -34710,17 +34832,21 @@ public void DeconstructionTypeInference_01() static void M() { (var x, var y) = ((string?)null, string.Empty); - x.ToString(); + x.ToString(); // 1 y.ToString(); x = null; - y = null; + y = null; // 2 } }"; var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( // (6,9): warning CS8602: Dereference of a possibly null reference. - // x.ToString(); - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(6, 9)); + // x.ToString(); // 1 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(6, 9), + // (9,13): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y = null; // 2 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(9, 13) + ); } [Fact] @@ -34734,17 +34860,21 @@ public void DeconstructionTypeInference_02() static void G() { (var x, var y) = F(); - x.ToString(); + x.ToString(); // 1 y.ToString(); x = null; - y = null; + y = null; // 2 } }"; var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( // (7,9): warning CS8602: Dereference of a possibly null reference. - // x.ToString(); - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(7, 9)); + // x.ToString(); // 1 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(7, 9), + // (10,13): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y = null; // 2 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(10, 13) + ); } [Fact] @@ -88284,7 +88414,7 @@ public void NullableT_NotNullWhenTrue() @"using System.Runtime.CompilerServices; class Program { - static bool F([NotNullWhenTrue]T? t) where T : struct + static bool F([NotNullWhen(true)]T? t) where T : struct { return true; } @@ -88296,7 +88426,7 @@ static void G(T? t) where T : struct _ = t.Value; // 1 } }"; - var comp = CreateCompilation(new[] { source, NotNullWhenTrueAttributeDefinition }, options: WithNonNullTypesTrue()); + var comp = CreateCompilation(new[] { source, NotNullWhenAttributeDefinition }, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( // (13,17): warning CS8629: Nullable value type may be null. // _ = t.Value; // 1 @@ -90379,12 +90509,14 @@ static void F(object? x, object y) } }"; var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); - // https://github.com/dotnet/roslyn/issues/33019: Inferred nullability of implicitly-typed - // deconstruction variables should be recorded in NullableWalker._variableTypes. comp.VerifyDiagnostics( // (6,13): warning CS8600: Converting null literal or possible null value to non-nullable type. // y = null; // 1 - Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(6, 13)); + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(6, 13), + // (10,9): warning CS8602: Dereference of a possibly null reference. + // ay[0].ToString(); // 2 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ay[0]").WithLocation(10, 9) + ); } [Fact] @@ -90577,6 +90709,222 @@ static void F(T x, T? y) ); } + [Fact] + [WorkItem(33019, "https://github.com/dotnet/roslyn/issues/33019")] + public void Deconstruction_34() + { + var source = +@"class Program +{ + static void F(object? x, object y) + { + if (x == null) return; + y = null; // 1 + var t = (new[] { x }, y); + var (ax, ay) = t; + ax[0].ToString(); + ay.ToString(); // 2 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (6,13): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y = null; // 1 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(6, 13), + // (10,9): warning CS8602: Dereference of a possibly null reference. + // ay.ToString(); // 2 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ay").WithLocation(10, 9) + ); + } + + [Fact] + [WorkItem(33019, "https://github.com/dotnet/roslyn/issues/33019")] + public void Deconstruction_35() + { + var source = +@" +using System.Collections.Generic; +class Program +{ + static List MakeList(T a) + { + throw null!; + } + + + static void F(object? x, object y) + { + if (x == null) return; + y = null; // 1 + var t = (new[] { x }, MakeList(y)); + var (ax, ay) = t; + ax[0].ToString(); + ay[0].ToString(); // 2 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (14,13): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y = null; // 1 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(14, 13), + // (18,9): warning CS8602: Dereference of a possibly null reference. + // ay[0].ToString(); // 2 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ay[0]").WithLocation(18, 9) + ); + } + + [Fact] + [WorkItem(33019, "https://github.com/dotnet/roslyn/issues/33019")] + public void Deconstruction_36() + { + var source = +@" +using System.Collections.Generic; +class Program +{ + static List MakeList(T a) where T : object + { + throw null!; + } + + static void F(object? x, object y) + { + if (x == null) return; + y = null; // 1 + var t = (new[] { x }, MakeList(y)); // 2 + var (ax, ay) = t; + ax[0].ToString(); + ay[0].ToString(); // 3 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (13,13): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y = null; // 1 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(13, 13), + // (14,31): warning CS8631: The type 'object?' cannot be used as type parameter 'T' in the generic type or method 'Program.MakeList(T)'. Nullability of type argument 'object?' doesn't match constraint type 'object'. + // var t = (new[] { x }, MakeList(y)); // 2 + Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint, "MakeList").WithArguments("Program.MakeList(T)", "object", "T", "object?").WithLocation(14, 31), + // (17,9): warning CS8602: Dereference of a possibly null reference. + // ay[0].ToString(); + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ay[0]").WithLocation(17, 9) + ); + } + + + [Fact] + [WorkItem(33019, "https://github.com/dotnet/roslyn/issues/33019")] + public void Deconstruction_37() + { + var source = +@" +using System.Collections.Generic; +class Program +{ + static List MakeList(T a) + { + throw null!; + } + + static void F(object? x, object y) + { + if (x == null) return; + y = null; // 1 + var ylist = MakeList(y); + var ylist2 = MakeList(ylist); + var ylist3 = MakeList(ylist2); + ylist3 = null; // 2 + var t = (new[] { x }, MakeList(ylist3)); + var (ax, ay) = t; + ax[0].ToString(); + ay[0].ToString(); // 3 + var ay0 = ay[0]; + if (ay0 == null) return; + ay0[0].ToString(); + ay0[0][0].ToString(); + ay0[0][0][0].ToString(); // 4 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (13,13): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y = null; // 1 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(13, 13), + // (17,18): warning CS8600: Converting null literal or possible null value to non-nullable type. + // ylist3 = null; // 2 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(17, 18), + // (21,9): warning CS8602: Dereference of a possibly null reference. + // ay[0].ToString(); // 3 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ay[0]").WithLocation(21, 9), + // (26,9): warning CS8602: Dereference of a possibly null reference. + // ay0[0][0][0].ToString(); // 4 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ay0[0][0][0]").WithLocation(26, 9) + ); + } + + [Fact] + [WorkItem(33019, "https://github.com/dotnet/roslyn/issues/33019")] + public void Deconstruction_38() + { + var source = +@" +class Program +{ + static void F(object? x1, object y1) + { + var t = (x1, y1); + var (x2, y2) = t; + if (x1 == null) return; + y1 = null; // 1 + var u = (x1, y1); + (x2, y2) = u; // 2 + x2 = null; + y2 = null; // 3 + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (9,14): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y1 = null; // 1 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(9, 14), + // (11,20): warning CS8600: Converting null literal or possible null value to non-nullable type. + // (x2, y2) = u; // 2 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "u").WithLocation(11, 20), + // (13,14): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y2 = null; // 3 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(13, 14) + ); + } + + [Fact] + [WorkItem(33019, "https://github.com/dotnet/roslyn/issues/33019")] + public void Deconstruction_39() + { + var source = +@" +class Program +{ + static void F(object? x1, object y1) + { + if (x1 == null) return; + y1 = null; // 1 + var t = (x1, y1); + var (x2, y2) = (t.Item1, t.Item2); + x2 = null; // 2 + y2 = null; + } +}"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (7,14): warning CS8600: Converting null literal or possible null value to non-nullable type. + // y1 = null; // 1 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(7, 14), + // (10,14): warning CS8600: Converting null literal or possible null value to non-nullable type. + // x2 = null; // 2 + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(10, 14) + ); + } + [Fact] public void Deconstruction_ExtensionMethod_01() { @@ -93427,14 +93775,14 @@ public void CaptureVariablesWhereLambdaAppears_07() class C { - static T F([System.Runtime.CompilerServices.EnsuresNotNull] object? o, params Func[] a) => throw null!; + static T F([System.Runtime.CompilerServices.NotNull] object? o, params Func[] a) => throw null!; static void M(string? x) { F(x = """", () => x = null, () => x.ToString()); } } "; - var comp = CreateCompilation(new[] { source, EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue()); + var comp = CreateCompilation(new[] { source, NotNullAttributeDefinition }, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics(); } @@ -95583,7 +95931,7 @@ class Program } [Fact] - public void AttributeAnnotation_EnsuresNotNull() + public void AttributeAnnotation_NotNull() { var source = @"#pragma warning disable 169 @@ -95596,9 +95944,9 @@ internal A(object x, object y) { } class Program { static object? F; - static object NotNull([EnsuresNotNull]object? o) => throw null!; + static object NotNull([NotNull]object? o) => throw null!; }"; - var comp = CreateCompilation(new[] { EnsuresNotNullAttributeDefinition, source }, options: WithNonNullTypesTrue()); + var comp = CreateCompilation(new[] { NotNullAttributeDefinition, source }, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( // (7,4): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type // [A(NotNull(F), F)] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs index 07202ea61a2db..430334cf23b61 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs @@ -2466,6 +2466,181 @@ public void CopyTo(Span other) ); } + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyRefStruct_Method_RefLikeStructParameter() + { + var csharp = @" +using System; + +public readonly ref struct S +{ + public void M(Span x) { } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + b.M(x); + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics(); + } + + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyMethod_RefLikeStructParameter() + { + var csharp = @" +using System; + +public ref struct S +{ + public readonly void M(Span x) { } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + b.M(x); + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics(); + } + + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyRefStruct_RefLikeProperty() + { + var csharp = @" +using System; + +public readonly ref struct S +{ + public Span P { get => default; set {} } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + b.P = x; + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (11,15): error CS8352: Cannot use local 'x' in this context because it may expose referenced variables outside of their declaration scope + // b.P = x; + Diagnostic(ErrorCode.ERR_EscapeLocal, "x").WithArguments("x").WithLocation(11, 15)); + } + + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyRefLikeProperty_01() + { + var csharp = @" +using System; + +public ref struct S +{ + public readonly Span P { get => default; set {} } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + b.P = x; + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (11,15): error CS8352: Cannot use local 'x' in this context because it may expose referenced variables outside of their declaration scope + // b.P = x; + Diagnostic(ErrorCode.ERR_EscapeLocal, "x").WithArguments("x").WithLocation(11, 15)); + } + + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyRefLikeProperty_02() + { + var csharp = @" +using System; + +public ref struct S +{ + public Span P { get => default; readonly set {} } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + b.P = x; + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (11,15): error CS8352: Cannot use local 'x' in this context because it may expose referenced variables outside of their declaration scope + // b.P = x; + Diagnostic(ErrorCode.ERR_EscapeLocal, "x").WithArguments("x").WithLocation(11, 15)); + } + + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyIndexer_RefLikeStructParameter_01() + { + var csharp = @" +using System; + +public ref struct S +{ + public readonly Span this[Span span] { get => default; set {} } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + _ = b[x]; + b[x] = x; + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (11,13): error CS8347: Cannot use a result of 'S.this[Span]' in this context because it may expose variables referenced by parameter 'span' outside of their declaration scope + // _ = b[x]; + Diagnostic(ErrorCode.ERR_EscapeCall, "b[x]").WithArguments("S.this[System.Span]", "span").WithLocation(11, 13), + // (11,15): error CS8352: Cannot use local 'x' in this context because it may expose referenced variables outside of their declaration scope + // _ = b[x]; + Diagnostic(ErrorCode.ERR_EscapeLocal, "x").WithArguments("x").WithLocation(11, 15)); + } + + [Fact, WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")] + public void ReadOnlyIndexer_RefLikeStructParameter_02() + { + var csharp = @" +using System; +public ref struct S +{ + public Span this[Span span] { get => default; readonly set {} } + + public unsafe static void N(S b) + { + Span x = stackalloc byte[5]; + _ = b[x]; + b[x] = x; + } +} +"; + var comp = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (10,13): error CS8350: This combination of arguments to 'S.this[Span]' is disallowed because it may expose variables referenced by parameter 'span' outside of their declaration scope + // _ = b[x]; + Diagnostic(ErrorCode.ERR_CallArgMixing, "b[x]").WithArguments("S.this[System.Span]", "span").WithLocation(10, 13), + // (10,15): error CS8352: Cannot use local 'x' in this context because it may expose referenced variables outside of their declaration scope + // _ = b[x]; + Diagnostic(ErrorCode.ERR_EscapeLocal, "x").WithArguments("x").WithLocation(10, 15), + // (11,9): error CS8350: This combination of arguments to 'S.this[Span]' is disallowed because it may expose variables referenced by parameter 'span' outside of their declaration scope + // b[x] = x; + Diagnostic(ErrorCode.ERR_CallArgMixing, "b[x]").WithArguments("S.this[System.Span]", "span").WithLocation(11, 9), + // (11,11): error CS8352: Cannot use local 'x' in this context because it may expose referenced variables outside of their declaration scope + // b[x] = x; + Diagnostic(ErrorCode.ERR_EscapeLocal, "x").WithArguments("x").WithLocation(11, 11)); + } + [WorkItem(22197, "https://github.com/dotnet/roslyn/issues/22197")] [Fact()] public void RefTernaryMustMatchValEscapes() diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs index 8d39371bbc350..cab91a5908b77 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs @@ -5916,5 +5916,36 @@ public void GetSpecialType_ThrowsOnGreaterThanCount() Assert.True(exceptionThrown, $"{nameof(comp.GetSpecialType)} did not throw when it should have."); } + + [Fact] + [WorkItem(34984, "https://github.com/dotnet/roslyn/issues/34984")] + public void ConversionIsExplicit_UnsetConversionKind() + { + var source = +@"class C1 +{ +} + +class C2 +{ + public void M() + { + var c = new C1(); + foreach (string item in c.Items) + { + } +}"; + var comp = CreateCompilation(source); + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + + var root = tree.GetRoot(); + var foreachSyntaxNode = root.DescendantNodes().OfType().Single(); + var foreachSymbolInfo = model.GetForEachStatementInfo(foreachSyntaxNode); + + Assert.Equal(Conversion.UnsetConversion, foreachSymbolInfo.CurrentConversion); + Assert.True(foreachSymbolInfo.CurrentConversion.Exists); + Assert.False(foreachSymbolInfo.CurrentConversion.IsImplicit); + } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs index 7e452ef9b7687..ca66edebf2266 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs @@ -2125,12 +2125,6 @@ public interface I1 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( - // (4,16): error CS0073: An add or remove accessor must have a body - // int P1 {add; remove;} => 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 16), - // (4,24): error CS0073: An add or remove accessor must have a body - // int P1 {add; remove;} => 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 24), // (4,13): error CS1014: A get or set accessor expected // int P1 {add; remove;} => 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 13), @@ -2196,21 +2190,15 @@ public interface I1 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( - // (4,16): error CS0073: An add or remove accessor must have a body - // int P1 {add; remove;} = 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 16), - // (4,24): error CS0073: An add or remove accessor must have a body - // int P1 {add; remove;} = 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 24), // (4,13): error CS1014: A get or set accessor expected // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 13), // (4,18): error CS1014: A get or set accessor expected // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "remove").WithLocation(4, 18), - // (4,9): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (4,9): error CS8050: Only auto-implemented properties can have initializers. // int P1 {add; remove;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P1").WithArguments("I1.P1").WithLocation(4, 9), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 9), // (4,9): error CS0548: 'I1.P1': property or indexer must have at least one accessor // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 9) @@ -2239,9 +2227,9 @@ public interface I1 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( - // (4,9): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (4,9): error CS8050: Only auto-implemented properties can have initializers. // int P1 {get; set;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P1").WithArguments("I1.P1").WithLocation(4, 9) + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 9) ); var p1 = compilation1.GetMember("I1.P1"); @@ -3500,12 +3488,6 @@ public interface I1 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( - // (4,25): error CS0073: An add or remove accessor must have a body - // int this[int i] {add; remove;} => 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 25), - // (4,33): error CS0073: An add or remove accessor must have a body - // int this[int i] {add; remove;} => 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 33), // (4,22): error CS1014: A get or set accessor expected // int this[int i] {add; remove;} => 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 22), @@ -3571,12 +3553,6 @@ public interface I1 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( - // (4,25): error CS0073: An add or remove accessor must have a body - // int this[int i] {add; remove;} = 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 25), - // (4,33): error CS0073: An add or remove accessor must have a body - // int this[int i] {add; remove;} = 0; - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(4, 33), // (4,36): error CS1519: Invalid token '=' in class, struct, or interface member declaration // int this[int i] {add; remove;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(4, 36), @@ -8134,15 +8110,18 @@ class Test2 : I1 // (11,25): error CS0238: 'I1.M3()' cannot be sealed because it is not an override // virtual sealed void M3() Diagnostic(ErrorCode.ERR_SealedNonOverride, "M3").WithArguments("I1.M3()").WithLocation(11, 25), - // (26,15): error CS0535: 'Test2' does not implement interface member 'I1.M2()' - // class Test2 : I1 - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M2()").WithLocation(26, 15), // (23,13): error CS0539: 'Test1.M4()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M4() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M4").WithArguments("Test1.M4()").WithLocation(23, 13), // (20,13): error CS0539: 'Test1.M1()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M1() {} - Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("Test1.M1()").WithLocation(20, 13) + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("Test1.M1()").WithLocation(20, 13), + // (21,13): error CS0539: 'Test1.M2()' in explicit interface declaration is not found among members of the interface that can be implemented + // void I1.M2() {} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M2").WithArguments("Test1.M2()").WithLocation(21, 13), + // (22,13): error CS0539: 'Test1.M3()' in explicit interface declaration is not found among members of the interface that can be implemented + // void I1.M3() {} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M3").WithArguments("Test1.M3()").WithLocation(22, 13) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); @@ -8173,7 +8152,7 @@ class Test2 : I1 Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Public, m2.DeclaredAccessibility); - Assert.Same(test1.GetMember("I1.M2"), test1.FindImplementationForInterfaceMember(m2)); + Assert.Null(test1.FindImplementationForInterfaceMember(m2)); Assert.Null(test2.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); @@ -8187,8 +8166,8 @@ class Test2 : I1 Assert.False(m3.IsAsync); Assert.False(m3.IsOverride); Assert.Equal(Accessibility.Public, m3.DeclaredAccessibility); - Assert.Same(test1.GetMember("I1.M3"), test1.FindImplementationForInterfaceMember(m3)); - Assert.Same(m3, test2.FindImplementationForInterfaceMember(m3)); + Assert.Null(test1.FindImplementationForInterfaceMember(m3)); + Assert.Null(test2.FindImplementationForInterfaceMember(m3)); var m4 = i1.GetMember("M4"); @@ -11601,9 +11580,9 @@ public interface I1 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( - // (4,24): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (4,24): error CS8050: Only auto-implemented properties can have initializers. // public virtual int P1 { get; } = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P1").WithArguments("I1.P1").WithLocation(4, 24), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 24), // (4,29): error CS0501: 'I1.P1.get' must declare a body because it is not marked abstract, extern, or partial // public virtual int P1 { get; } = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P1.get").WithLocation(4, 29) @@ -12412,9 +12391,9 @@ class Test1 : I1 // (8,24): error CS0238: 'I1.P3' cannot be sealed because it is not an override // sealed private int P3 Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I1.P3").WithLocation(8, 24), - // (14,17): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (14,17): error CS8050: Only auto-implemented properties can have initializers. // private int P4 {get;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P4").WithArguments("I1.P4").WithLocation(14, 17), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P4").WithArguments("I1.P4").WithLocation(14, 17), // (14,21): error CS0501: 'I1.P4.get' must declare a body because it is not marked abstract, extern, or partial // private int P4 {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P4.get").WithLocation(14, 21), @@ -13777,9 +13756,9 @@ class Test2 : I1, I2, I3 {} "; ValidatePropertyModifiers_14(source1, - // (4,23): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (4,23): error CS8050: Only auto-implemented properties can have initializers. // public sealed int P1 {get;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P1").WithArguments("I1.P1").WithLocation(4, 23), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 23), // (4,27): error CS0501: 'I1.P1.get' must declare a body because it is not marked abstract, extern, or partial // public sealed int P1 {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P1.get").WithLocation(4, 27), @@ -13792,9 +13771,12 @@ class Test2 : I1, I2, I3 // (20,12): error CS0539: 'Test1.P1' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.P1 { get => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("Test1.P1").WithLocation(20, 12), - // (25,19): error CS0535: 'Test2' does not implement interface member 'I2.P2' - // class Test2 : I1, I2, I3 - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I2.P2").WithLocation(25, 19) + // (21,12): error CS0539: 'Test1.P2' in explicit interface declaration is not found among members of the interface that can be implemented + // int I2.P2 { get => throw null; } + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P2").WithArguments("Test1.P2").WithLocation(21, 12), + // (22,12): error CS0539: 'Test1.P3' in explicit interface declaration is not found among members of the interface that can be implemented + // int I3.P3 { set => throw null; } + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test1.P3").WithLocation(22, 12) ); } @@ -13844,7 +13826,7 @@ private void ValidatePropertyModifiers_14(string source1, params DiagnosticDescr Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); - Assert.Same(test1P2, test1.FindImplementationForInterfaceMember(p2)); + Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.Null(test2.FindImplementationForInterfaceMember(p2)); Assert.True(p2get.IsAbstract); @@ -13856,7 +13838,7 @@ private void ValidatePropertyModifiers_14(string source1, params DiagnosticDescr Assert.False(p2get.IsAsync); Assert.False(p2get.IsOverride); Assert.Equal(Accessibility.Public, p2get.DeclaredAccessibility); - Assert.Same(test1P2.GetMethod, test1.FindImplementationForInterfaceMember(p2get)); + Assert.Null(test1.FindImplementationForInterfaceMember(p2get)); Assert.Null(test2.FindImplementationForInterfaceMember(p2get)); var p3 = GetSingleProperty(compilation1, "I3"); @@ -13870,8 +13852,8 @@ private void ValidatePropertyModifiers_14(string source1, params DiagnosticDescr Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); - Assert.Same(test1P3, test1.FindImplementationForInterfaceMember(p3)); - Assert.Same(p3, test2.FindImplementationForInterfaceMember(p3)); + Assert.Null(test1.FindImplementationForInterfaceMember(p3)); + Assert.Null(test2.FindImplementationForInterfaceMember(p3)); Assert.False(p3set.IsAbstract); Assert.True(p3set.IsVirtual); @@ -13882,8 +13864,8 @@ private void ValidatePropertyModifiers_14(string source1, params DiagnosticDescr Assert.False(p3set.IsAsync); Assert.False(p3set.IsOverride); Assert.Equal(Accessibility.Public, p3set.DeclaredAccessibility); - Assert.Same(test1P3.SetMethod, test1.FindImplementationForInterfaceMember(p3set)); - Assert.Same(p3set, test2.FindImplementationForInterfaceMember(p3set)); + Assert.Null(test1.FindImplementationForInterfaceMember(p3set)); + Assert.Null(test2.FindImplementationForInterfaceMember(p3set)); } [Fact] @@ -14037,9 +14019,9 @@ class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 // (44,26): error CS0503: The abstract property 'I8.P8' cannot be marked virtual // abstract virtual int P8 {get;} = 0; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P8").WithArguments("property", "I8.P8").WithLocation(44, 26), - // (44,26): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (44,26): error CS8050: Only auto-implemented properties can have initializers. // abstract virtual int P8 {get;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P8").WithArguments("I8.P8").WithLocation(44, 26), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P8").WithArguments("I8.P8").WithLocation(44, 26), // (90,15): error CS0535: 'Test2' does not implement interface member 'I0.P0' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I0").WithArguments("Test2", "I0.P0").WithLocation(90, 15), @@ -14485,9 +14467,9 @@ class Test2 : I1, I2, I3, I4, I5 // (16,47): error CS0179: 'I4.P4.set' cannot be extern and declare a body // private extern int P4 { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I4.P4.set").WithLocation(16, 47), - // (20,23): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (20,23): error CS8050: Only auto-implemented properties can have initializers. // extern sealed int P5 {get;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P5").WithArguments("I5.P5").WithLocation(20, 23), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P5").WithArguments("I5.P5").WithLocation(20, 23), // (23,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(23, 15), @@ -14717,9 +14699,9 @@ class Test2 : I1, I2, I3, I4, I5 // (20,25): error CS0106: The modifier 'override' is not valid for this item // override sealed int P5 {get;} = 0; Diagnostic(ErrorCode.ERR_BadMemberFlag, "P5").WithArguments("override").WithLocation(20, 25), - // (20,25): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (20,25): error CS8050: Only auto-implemented properties can have initializers. // override sealed int P5 {get;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P5").WithArguments("I5.P5").WithLocation(20, 25), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P5").WithArguments("I5.P5").WithLocation(20, 25), // (20,29): error CS0501: 'I5.P5.get' must declare a body because it is not marked abstract, extern, or partial // override sealed int P5 {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I5.P5.get").WithLocation(20, 29), @@ -20699,9 +20681,12 @@ class Test2 : I1, I2, I3 // (20,12): error CS0539: 'Test1.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.this[int x] { get => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test1.this[int]").WithLocation(20, 12), - // (25,19): error CS0535: 'Test2' does not implement interface member 'I2.this[int]' - // class Test2 : I1, I2, I3 - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I2.this[int]") + // (21,12): error CS0539: 'Test1.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented + // int I2.this[int x] { get => throw null; } + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test1.this[int]").WithLocation(21, 12), + // (22,12): error CS0539: 'Test1.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented + // int I3.this[int x] { set => throw null; } + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test1.this[int]").WithLocation(22, 12) ); } @@ -23380,9 +23365,9 @@ extern event System.Action P11 {add{} remove{}} // (12,34): error CS0106: The modifier 'override' is not valid for this item // override event System.Action P09 {remove{}} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 34), - // (13,39): error CS0500: 'I1.P10.add' cannot declare a body because it is marked abstract + // (13,38): error CS8712: 'I1.P10': abstract event cannot use event accessor syntax // abstract event System.Action P10 {add{}} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I1.P10.add").WithLocation(13, 39), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P10").WithLocation(13, 38), // (14,37): error CS0179: 'I1.P11.add' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "add").WithArguments("I1.P11.add").WithLocation(14, 37), @@ -23747,9 +23732,9 @@ extern event System.Action P11 {add{} remove{}} // (13,39): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_FeatureInPreview, "add").WithArguments("default interface implementation").WithLocation(13, 39), - // (13,39): error CS0500: 'I1.P10.add' cannot declare a body because it is marked abstract + // (13,38): error CS8712: 'I1.P10': abstract event cannot use event accessor syntax // abstract event System.Action P10 {add{}} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I1.P10.add").WithLocation(13, 39), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P10").WithLocation(13, 38), // (14,37): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_FeatureInPreview, "add").WithArguments("default interface implementation").WithLocation(14, 37), @@ -23843,9 +23828,9 @@ extern event System.Action P11 {add{} remove{}} // (13,39): error CS8701: Target runtime doesn't support default interface implementation. // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(13, 39), - // (13,39): error CS0500: 'I1.P10.add' cannot declare a body because it is marked abstract + // (13,38): error CS8712: 'I1.P10': abstract event cannot use event accessor syntax // abstract event System.Action P10 {add{}} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I1.P10.add").WithLocation(13, 39), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P10").WithLocation(13, 38), // (14,37): error CS8701: Target runtime doesn't support default interface implementation. // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(14, 37), @@ -26064,21 +26049,21 @@ class Test2 : I1, I2, I3 // (8,41): error CS0238: 'I2.P2' cannot be sealed because it is not an override // abstract sealed event System.Action P2 {add; remove;} Diagnostic(ErrorCode.ERR_SealedNonOverride, "P2").WithArguments("I2.P2").WithLocation(8, 41), - // (8,48): error CS0073: An add or remove accessor must have a body + // (8,44): error CS8712: 'I2.P2': abstract event cannot use event accessor syntax // abstract sealed event System.Action P2 {add; remove;} - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(8, 48), - // (8,56): error CS0073: An add or remove accessor must have a body - // abstract sealed event System.Action P2 {add; remove;} - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(8, 56), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.P2").WithLocation(8, 44), // (12,40): error CS0238: 'I3.P3' cannot be sealed because it is not an override // virtual sealed event System.Action P3 Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I3.P3").WithLocation(12, 40), // (21,28): error CS0539: 'Test1.P1' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I1.P1 { add => throw null; remove => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("Test1.P1").WithLocation(21, 28), - // (26,19): error CS0535: 'Test2' does not implement interface member 'I2.P2' - // class Test2 : I1, I2, I3 - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I2.P2").WithLocation(26, 19), + // (22,28): error CS0539: 'Test1.P2' in explicit interface declaration is not found among members of the interface that can be implemented + // event System.Action I2.P2 { add => throw null; remove => throw null; } + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P2").WithArguments("Test1.P2").WithLocation(22, 28), + // (23,28): error CS0539: 'Test1.P3' in explicit interface declaration is not found among members of the interface that can be implemented + // event System.Action I3.P3 { add => throw null; remove => throw null; } + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test1.P3").WithLocation(23, 28), // (4,39): warning CS0067: The event 'I1.P1' is never used // public sealed event System.Action P1 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P1").WithArguments("I1.P1").WithLocation(4, 39) @@ -26134,12 +26119,12 @@ void Validate1(MethodSymbol accessor) Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); - Assert.Same(test1P2, test1.FindImplementationForInterfaceMember(p2)); + Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.Null(test2.FindImplementationForInterfaceMember(p2)); - Validate2(p2.AddMethod, test1P2.AddMethod); - Validate2(p2.RemoveMethod, test1P2.RemoveMethod); - void Validate2(MethodSymbol accessor, MethodSymbol implementation) + Validate2(p2.AddMethod); + Validate2(p2.RemoveMethod); + void Validate2(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); @@ -26150,7 +26135,7 @@ void Validate2(MethodSymbol accessor, MethodSymbol implementation) Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); - Assert.Same(implementation, test1.FindImplementationForInterfaceMember(accessor)); + Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } @@ -26164,12 +26149,12 @@ void Validate2(MethodSymbol accessor, MethodSymbol implementation) Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); - Assert.Same(test1P3, test1.FindImplementationForInterfaceMember(p3)); - Assert.Same(p3, test2.FindImplementationForInterfaceMember(p3)); + Assert.Null(test1.FindImplementationForInterfaceMember(p3)); + Assert.Null(test2.FindImplementationForInterfaceMember(p3)); - Validate3(p3.AddMethod, test1P3.AddMethod); - Validate3(p3.RemoveMethod, test1P3.RemoveMethod); - void Validate3(MethodSymbol accessor, MethodSymbol implementation) + Validate3(p3.AddMethod); + Validate3(p3.RemoveMethod); + void Validate3(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); @@ -26180,8 +26165,8 @@ void Validate3(MethodSymbol accessor, MethodSymbol implementation) Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); - Assert.Same(implementation, test1.FindImplementationForInterfaceMember(accessor)); - Assert.Same(accessor, test2.FindImplementationForInterfaceMember(accessor)); + Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); + Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } @@ -26285,78 +26270,54 @@ class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 // (4,42): error CS0503: The abstract event 'I0.P0' cannot be marked virtual // abstract virtual event System.Action P0; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P0").WithArguments("event", "I0.P0").WithLocation(4, 42), - // (8,42): error CS0065: 'I1.P1': event property must have both add and remove accessors - // abstract virtual event System.Action P1 { add { throw null; } } - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(8, 42), // (8,42): error CS0503: The abstract event 'I1.P1' cannot be marked virtual // abstract virtual event System.Action P1 { add { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P1").WithArguments("event", "I1.P1").WithLocation(8, 42), - // (8,47): error CS0500: 'I1.P1.add' cannot declare a body because it is marked abstract + // (8,45): error CS8712: 'I1.P1': abstract event cannot use event accessor syntax // abstract virtual event System.Action P1 { add { throw null; } } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I1.P1.add").WithLocation(8, 47), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P1").WithLocation(8, 45), // (12,42): error CS0503: The abstract event 'I2.P2' cannot be marked virtual // virtual abstract event System.Action P2 Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P2").WithArguments("event", "I2.P2").WithLocation(12, 42), - // (14,9): error CS0500: 'I2.P2.add' cannot declare a body because it is marked abstract - // add { throw null; } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I2.P2.add").WithLocation(14, 9), - // (15,9): error CS0500: 'I2.P2.remove' cannot declare a body because it is marked abstract - // remove { throw null; } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("I2.P2.remove").WithLocation(15, 9), - // (20,42): error CS0065: 'I3.P3': event property must have both add and remove accessors - // abstract virtual event System.Action P3 { remove { throw null; } } - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P3").WithArguments("I3.P3").WithLocation(20, 42), + // (13,5): error CS8712: 'I2.P2': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.P2").WithLocation(13, 5), // (20,42): error CS0503: The abstract event 'I3.P3' cannot be marked virtual // abstract virtual event System.Action P3 { remove { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P3").WithArguments("event", "I3.P3").WithLocation(20, 42), - // (20,47): error CS0500: 'I3.P3.remove' cannot declare a body because it is marked abstract + // (20,45): error CS8712: 'I3.P3': abstract event cannot use event accessor syntax // abstract virtual event System.Action P3 { remove { throw null; } } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("I3.P3.remove").WithLocation(20, 47), - // (24,42): error CS0065: 'I4.P4': event property must have both add and remove accessors - // abstract virtual event System.Action P4 { add => throw null; } - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P4").WithArguments("I4.P4").WithLocation(24, 42), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I3.P3").WithLocation(20, 45), // (24,42): error CS0503: The abstract event 'I4.P4' cannot be marked virtual // abstract virtual event System.Action P4 { add => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P4").WithArguments("event", "I4.P4").WithLocation(24, 42), - // (24,47): error CS0500: 'I4.P4.add' cannot declare a body because it is marked abstract + // (24,45): error CS8712: 'I4.P4': abstract event cannot use event accessor syntax // abstract virtual event System.Action P4 { add => throw null; } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I4.P4.add").WithLocation(24, 47), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I4.P4").WithLocation(24, 45), // (28,42): error CS0503: The abstract event 'I5.P5' cannot be marked virtual // abstract virtual event System.Action P5 Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P5").WithArguments("event", "I5.P5").WithLocation(28, 42), - // (30,9): error CS0500: 'I5.P5.add' cannot declare a body because it is marked abstract - // add => throw null; - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I5.P5.add").WithLocation(30, 9), - // (31,9): error CS0500: 'I5.P5.remove' cannot declare a body because it is marked abstract - // remove => throw null; - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("I5.P5.remove").WithLocation(31, 9), - // (36,42): error CS0065: 'I6.P6': event property must have both add and remove accessors - // abstract virtual event System.Action P6 { remove => throw null; } - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P6").WithArguments("I6.P6").WithLocation(36, 42), + // (29,5): error CS8712: 'I5.P5': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I5.P5").WithLocation(29, 5), // (36,42): error CS0503: The abstract event 'I6.P6' cannot be marked virtual // abstract virtual event System.Action P6 { remove => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P6").WithArguments("event", "I6.P6").WithLocation(36, 42), - // (36,47): error CS0500: 'I6.P6.remove' cannot declare a body because it is marked abstract + // (36,45): error CS8712: 'I6.P6': abstract event cannot use event accessor syntax // abstract virtual event System.Action P6 { remove => throw null; } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("I6.P6.remove").WithLocation(36, 47), - // (40,42): error CS0065: 'I7.P7': event property must have both add and remove accessors - // abstract virtual event System.Action P7 { add; } - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P7").WithArguments("I7.P7").WithLocation(40, 42), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I6.P6").WithLocation(36, 45), // (40,42): error CS0503: The abstract event 'I7.P7' cannot be marked virtual // abstract virtual event System.Action P7 { add; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P7").WithArguments("event", "I7.P7").WithLocation(40, 42), - // (40,50): error CS0073: An add or remove accessor must have a body + // (40,45): error CS8712: 'I7.P7': abstract event cannot use event accessor syntax // abstract virtual event System.Action P7 { add; } - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(40, 50), - // (44,42): error CS0065: 'I8.P8': event property must have both add and remove accessors - // abstract virtual event System.Action P8 { remove; } - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P8").WithArguments("I8.P8").WithLocation(44, 42), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I7.P7").WithLocation(40, 45), // (44,42): error CS0503: The abstract event 'I8.P8' cannot be marked virtual // abstract virtual event System.Action P8 { remove; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P8").WithArguments("event", "I8.P8").WithLocation(44, 42), - // (44,53): error CS0073: An add or remove accessor must have a body + // (44,45): error CS8712: 'I8.P8': abstract event cannot use event accessor syntax // abstract virtual event System.Action P8 { remove; } - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(44, 53), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I8.P8").WithLocation(44, 45), // (54,28): error CS0065: 'Test1.I1.P1': event property must have both add and remove accessors // event System.Action I1.P1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("Test1.I1.P1").WithLocation(54, 28), @@ -27051,24 +27012,18 @@ class Test2 : I1, I2, I3, I4, I5 } "; ValidateEventModifiers_18(source1, - // (4,38): error CS0500: 'I1.P1.add' cannot declare a body because it is marked abstract + // (4,37): error CS8712: 'I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action P1 {add => throw null; remove => throw null;} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I1.P1.add").WithLocation(4, 38), - // (4,57): error CS0500: 'I1.P1.remove' cannot declare a body because it is marked abstract - // abstract event System.Action P1 {add => throw null; remove => throw null;} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("I1.P1.remove").WithLocation(4, 57), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P1").WithLocation(4, 37), // (8,42): error CS0068: 'I2.P2': instance event in interface cannot have initializer // abstract private event System.Action P2 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "P2").WithArguments("I2.P2").WithLocation(8, 42), // (8,42): error CS0621: 'I2.P2': virtual or abstract members cannot be private // abstract private event System.Action P2 = null; Diagnostic(ErrorCode.ERR_VirtualPrivate, "P2").WithArguments("I2.P2").WithLocation(8, 42), - // (16,46): error CS0500: 'I4.P4.add' cannot declare a body because it is marked abstract - // abstract static event System.Action P4 { add {throw null;} remove {throw null;}} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("I4.P4.add").WithLocation(16, 46), - // (16,64): error CS0500: 'I4.P4.remove' cannot declare a body because it is marked abstract + // (16,44): error CS8712: 'I4.P4': abstract event cannot use event accessor syntax // abstract static event System.Action P4 { add {throw null;} remove {throw null;}} - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("I4.P4.remove").WithLocation(16, 64), + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I4.P4").WithLocation(16, 44), // (16,41): error CS0112: A static member 'I4.P4' cannot be marked as override, virtual, or abstract // abstract static event System.Action P4 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P4").WithArguments("I4.P4").WithLocation(16, 41), @@ -29104,6 +29059,11 @@ static void Main() } private static void ValidateMethodImplementationInDerived_01(ModuleSymbol m) + { + ValidateMethodImplementationInDerived_01(m, i4M1IsAbstract: false); + } + + private static void ValidateMethodImplementationInDerived_01(ModuleSymbol m, bool i4M1IsAbstract) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); @@ -29119,33 +29079,33 @@ private static void ValidateMethodImplementationInDerived_01(ModuleSymbol m) Assert.True(i1.IsMetadataAbstract); ValidateExplicitImplementation(i1i2m1); - ValidateExplicitImplementation(i1i4m1); + ValidateExplicitImplementation(i1i4m1, i4M1IsAbstract); Assert.Null(test1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1i4m1)); Assert.Same(i1i2m1, test1.FindImplementationForInterfaceMember(i2m1)); - Assert.Same(i1i4m1, test1.FindImplementationForInterfaceMember(i4m1)); + Assert.Same(i4M1IsAbstract ? null : i1i4m1, test1.FindImplementationForInterfaceMember(i4m1)); Assert.Null(i1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Null(i1.FindImplementationForInterfaceMember(i1i4m1)); Assert.Same(i1i2m1, i1.FindImplementationForInterfaceMember(i2m1)); - Assert.Same(i1i4m1, i1.FindImplementationForInterfaceMember(i4m1)); + Assert.Same(i4M1IsAbstract ? null : i1i4m1, i1.FindImplementationForInterfaceMember(i4m1)); Assert.Null(i2.FindImplementationForInterfaceMember(i2m1)); Assert.Null(i4.FindImplementationForInterfaceMember(i4m1)); Assert.Same(i1i2m1, i3.FindImplementationForInterfaceMember(i2m1)); - Assert.Same(i1i4m1, i3.FindImplementationForInterfaceMember(i4m1)); + Assert.Same(i4M1IsAbstract ? null : i1i4m1, i3.FindImplementationForInterfaceMember(i4m1)); } - private static void ValidateExplicitImplementation(MethodSymbol m1) + private static void ValidateExplicitImplementation(MethodSymbol m1, bool isAbstract = false) { Assert.True(m1.IsMetadataVirtual()); Assert.True(m1.IsMetadataFinal); Assert.False(m1.IsMetadataNewSlot()); - Assert.False(m1.IsAbstract); + Assert.Equal(isAbstract, m1.IsAbstract); Assert.False(m1.IsVirtual); - Assert.False(m1.IsSealed); + Assert.Equal(isAbstract, m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); @@ -29500,15 +29460,18 @@ class Test1 : I1 // (14,28): error CS0106: The modifier 'private' is not valid for this item // private sealed void I2.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private").WithLocation(14, 28), - // (18,32): error CS0106: The modifier 'abstract' is not valid for this item - // protected abstract void I4.M1() - Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("abstract").WithLocation(18, 32), // (18,32): error CS0106: The modifier 'protected' is not valid for this item // protected abstract void I4.M1() - Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(18, 32) + Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(18, 32), + // (18,32): error CS0500: 'I1.I4.M1()' cannot declare a body because it is marked abstract + // protected abstract void I4.M1() + Diagnostic(ErrorCode.ERR_AbstractHasBody, "M1").WithArguments("I1.I4.M1()").WithLocation(18, 32), + // (28,15): error CS0535: 'Test1' does not implement interface member 'I4.M1()' + // class Test1 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.M1()").WithLocation(28, 15) ); - ValidateMethodImplementationInDerived_01(compilation1.SourceModule); + ValidateMethodImplementationInDerived_01(compilation1.SourceModule, i4M1IsAbstract: true); } [Fact] @@ -32130,6 +32093,11 @@ private void ValidatePropertyImplementationInDerived_01(string source1, string s } private static void ValidatePropertyImplementationInDerived_01(ModuleSymbol m) + { + ValidatePropertyImplementationInDerived_01(m, i4M1IsAbstract: false); + } + + private static void ValidatePropertyImplementationInDerived_01(ModuleSymbol m, bool i4M1IsAbstract) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); @@ -32145,24 +32113,24 @@ private static void ValidatePropertyImplementationInDerived_01(ModuleSymbol m) Assert.True(i1.IsMetadataAbstract); ValidateExplicitImplementation(i1i2m1); - ValidateExplicitImplementation(i1i4m1); + ValidateExplicitImplementation(i1i4m1, i4M1IsAbstract); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, test1, i2m1); - VerifyFindImplementationForInterfaceMemberSame(i1i4m1, test1, i4m1); + VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, test1, i4m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i1, i2m1); - VerifyFindImplementationForInterfaceMemberSame(i1i4m1, i1, i4m1); + VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i1, i4m1); VerifyFindImplementationForInterfaceMemberSame(i2m1.IsAbstract ? null : i2m1, i2, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4m1.IsAbstract ? null : i4m1, i4, i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i3, i2m1); - VerifyFindImplementationForInterfaceMemberSame(i1i4m1, i3, i4m1); + VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i3, i4m1); } private static void VerifyFindImplementationForInterfaceMemberSame(PropertySymbol expected, NamedTypeSymbol implementingType, PropertySymbol interfaceProperty) @@ -32203,24 +32171,24 @@ void ValidateAccessor(MethodSymbol accessor, MethodSymbol interfaceAccessor) } } - private static void ValidateExplicitImplementation(PropertySymbol m1) + private static void ValidateExplicitImplementation(PropertySymbol m1, bool isAbstract = false) { - Assert.False(m1.IsAbstract); + Assert.Equal(isAbstract, m1.IsAbstract); Assert.False(m1.IsVirtual); - Assert.False(m1.IsSealed); + Assert.Equal(isAbstract, m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); - ValidateAccessor(m1.GetMethod); - ValidateAccessor(m1.SetMethod); + ValidateAccessor(m1.GetMethod, isAbstract); + ValidateAccessor(m1.SetMethod, isAbstract); - void ValidateAccessor(MethodSymbol accessor) + static void ValidateAccessor(MethodSymbol accessor, bool isAbstract) { if ((object)accessor != null) { - ValidateExplicitImplementation(accessor); + ValidateExplicitImplementation(accessor, isAbstract); } } } @@ -32457,6 +32425,11 @@ class Test1 : I1 } private void ValidatePropertyImplementationInDerived_04(string source1, params DiagnosticDescription[] expected) + { + ValidatePropertyImplementationInDerived_04(source1, i4M1IsAbstract: false, expected); + } + + private void ValidatePropertyImplementationInDerived_04(string source1, bool i4M1IsAbstract, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, @@ -32464,7 +32437,7 @@ private void ValidatePropertyImplementationInDerived_04(string source1, params D Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); - ValidatePropertyImplementationInDerived_01(compilation1.SourceModule); + ValidatePropertyImplementationInDerived_01(compilation1.SourceModule, i4M1IsAbstract); } [Fact] @@ -32604,7 +32577,7 @@ class Test1 : I1 {} "; - ValidatePropertyImplementationInDerived_04(source1, + ValidatePropertyImplementationInDerived_04(source1, i4M1IsAbstract: true, // (14,27): error CS0106: The modifier 'sealed' is not valid for this item // private sealed int I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("sealed").WithLocation(14, 27), @@ -32614,15 +32587,21 @@ class Test1 : I1 // (16,17): error CS0106: The modifier 'private' is not valid for this item // private get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private").WithLocation(16, 17), - // (19,31): error CS0106: The modifier 'abstract' is not valid for this item - // protected abstract int I4.M1 - Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("abstract").WithLocation(19, 31), // (19,31): error CS0106: The modifier 'protected' is not valid for this item // protected abstract int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(19, 31), + // (21,9): error CS0500: 'I1.I4.M1.get' cannot declare a body because it is marked abstract + // get => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.I4.M1.get").WithLocation(21, 9), // (22,19): error CS0106: The modifier 'protected' is not valid for this item // protected set => throw null; - Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected").WithLocation(22, 19) + Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected").WithLocation(22, 19), + // (22,19): error CS0500: 'I1.I4.M1.set' cannot declare a body because it is marked abstract + // protected set => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I1.I4.M1.set").WithLocation(22, 19), + // (30,15): error CS0535: 'Test1' does not implement interface member 'I4.M1' + // class Test1 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.M1").WithLocation(30, 15) ); } @@ -32922,9 +32901,9 @@ class Test2 : I4 // (43,21): error CS0501: 'I4.I3.M3.set' must declare a body because it is not marked abstract, extern, or partial // int I3.M3 {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I4.I3.M3.set").WithLocation(43, 21), - // (44,12): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (44,12): error CS8050: Only auto-implemented properties can have initializers. // int I3.M4 {get; set;} = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "M4").WithArguments("I4.I3.M4").WithLocation(44, 12), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "M4").WithArguments("I4.I3.M4").WithLocation(44, 12), // (44,16): error CS0501: 'I4.I3.M4.get' must declare a body because it is not marked abstract, extern, or partial // int I3.M4 {get; set;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I4.I3.M4.get").WithLocation(44, 16), @@ -34345,6 +34324,11 @@ static void Main() } private static void ValidateEventImplementationInDerived_01(ModuleSymbol m) + { + ValidateEventImplementationInDerived_01(m, i4M1IsAbstract: false); + } + + private static void ValidateEventImplementationInDerived_01(ModuleSymbol m, bool i4M1IsAbstract) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); @@ -34360,24 +34344,24 @@ private static void ValidateEventImplementationInDerived_01(ModuleSymbol m) Assert.True(i1.IsMetadataAbstract); ValidateExplicitImplementation(i1i2m1); - ValidateExplicitImplementation(i1i4m1); + ValidateExplicitImplementation(i1i4m1, i4M1IsAbstract); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, test1, i2m1); - VerifyFindImplementationForInterfaceMemberSame(i1i4m1, test1, i4m1); + VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, test1, i4m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i1, i2m1); - VerifyFindImplementationForInterfaceMemberSame(i1i4m1, i1, i4m1); + VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i1, i4m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i4, i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i3, i2m1); - VerifyFindImplementationForInterfaceMemberSame(i1i4m1, i3, i4m1); + VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i3, i4m1); } private static void VerifyFindImplementationForInterfaceMemberSame(EventSymbol expected, NamedTypeSymbol implementingType, EventSymbol interfaceEvent) @@ -34418,24 +34402,24 @@ void ValidateAccessor(MethodSymbol accessor, MethodSymbol interfaceAccessor) } } - private static void ValidateExplicitImplementation(EventSymbol m1) + private static void ValidateExplicitImplementation(EventSymbol m1, bool isAbstract = false) { - Assert.False(m1.IsAbstract); + Assert.Equal(isAbstract, m1.IsAbstract); Assert.False(m1.IsVirtual); - Assert.False(m1.IsSealed); + Assert.Equal(isAbstract, m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); - ValidateAccessor(m1.AddMethod); - ValidateAccessor(m1.RemoveMethod); + ValidateAccessor(m1.AddMethod, isAbstract); + ValidateAccessor(m1.RemoveMethod, isAbstract); - void ValidateAccessor(MethodSymbol accessor) + static void ValidateAccessor(MethodSymbol accessor, bool isAbstract) { if ((object)accessor != null) { - ValidateExplicitImplementation(accessor); + ValidateExplicitImplementation(accessor, isAbstract); } } } @@ -34814,15 +34798,18 @@ class Test1 : I1 // (14,43): error CS0106: The modifier 'private' is not valid for this item // private sealed event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private").WithLocation(14, 43), - // (19,47): error CS0106: The modifier 'abstract' is not valid for this item - // protected abstract event System.Action I4.M1 - Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("abstract").WithLocation(19, 47), // (19,47): error CS0106: The modifier 'protected' is not valid for this item // protected abstract event System.Action I4.M1 - Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(19, 47) + Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(19, 47), + // (20,5): error CS8712: 'I1.I4.M1': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.I4.M1").WithLocation(20, 5), + // (30,15): error CS0535: 'Test1' does not implement interface member 'I4.M1' + // class Test1 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.M1").WithLocation(30, 15) ); - ValidateEventImplementationInDerived_01(compilation1.SourceModule); + ValidateEventImplementationInDerived_01(compilation1.SourceModule, i4M1IsAbstract: true); } [Fact] @@ -34922,6 +34909,14 @@ public interface I4 : I3 class Test2 : I4 {} + +public interface I5 : I3 +{ + event System.Action I3.M1 +} + +class Test3 : I5 +{} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, @@ -34929,15 +34924,9 @@ class Test2 : I4 targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( - // (30,27): error CS0071: An explicit interface implementation of an event must use event accessor syntax - // event System.Action I3.M1; - Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(30, 27), - // (30,30): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // (30,28): error CS0071: An explicit interface implementation of an event must use event accessor syntax // event System.Action I3.M1; - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(30, 30), - // (30,28): error CS0065: 'I4.I3.M1': event property must have both add and remove accessors - // event System.Action I3.M1; - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "M1").WithArguments("I4.I3.M1").WithLocation(30, 28), + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "M1").WithLocation(30, 28), // (10,28): error CS0065: 'I2.I1.M1': event property must have both add and remove accessors // event System.Action I1.M1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "M1").WithArguments("I2.I1.M1").WithLocation(10, 28), @@ -34955,7 +34944,16 @@ class Test2 : I4 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1.remove").WithLocation(20, 15), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M2.add' // class Test1 : I2 - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M2.add").WithLocation(20, 15) + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M2.add").WithLocation(20, 15), + // (38,27): error CS0071: An explicit interface implementation of an event must use event accessor syntax + // event System.Action I3.M1 + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(38, 27), + // (41,15): error CS0535: 'Test3' does not implement interface member 'I3.M1.remove' + // class Test3 : I5 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test3", "I3.M1.remove").WithLocation(41, 15), + // (41,15): error CS0535: 'Test3' does not implement interface member 'I3.M1.add' + // class Test3 : I5 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test3", "I3.M1.add").WithLocation(41, 15) ); } @@ -36531,7 +36529,7 @@ class Test1 : I1 {} "; - ValidatePropertyImplementationInDerived_04(source1, + ValidatePropertyImplementationInDerived_04(source1, i4M1IsAbstract: true, // (14,27): error CS0106: The modifier 'sealed' is not valid for this item // private sealed int I2.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("sealed").WithLocation(14, 27), @@ -36541,15 +36539,21 @@ class Test1 : I1 // (16,17): error CS0106: The modifier 'private' is not valid for this item // private get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private").WithLocation(16, 17), - // (19,31): error CS0106: The modifier 'abstract' is not valid for this item - // protected abstract int I4.this[int x] - Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(19, 31), // (19,31): error CS0106: The modifier 'protected' is not valid for this item // protected abstract int I4.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("protected").WithLocation(19, 31), + // (21,9): error CS0500: 'I1.I4.this[int].get' cannot declare a body because it is marked abstract + // get => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.I4.this[int].get").WithLocation(21, 9), // (22,19): error CS0106: The modifier 'protected' is not valid for this item // protected set => throw null; - Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected").WithLocation(22, 19) + Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected").WithLocation(22, 19), + // (22,19): error CS0500: 'I1.I4.this[int].set' cannot declare a body because it is marked abstract + // protected set => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I1.I4.this[int].set").WithLocation(22, 19), + // (30,15): error CS0535: 'Test1' does not implement interface member 'I4.this[int]' + // class Test1 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.this[int]").WithLocation(30, 15) ); } @@ -38566,9 +38570,9 @@ public interface I1 // (4,26): error CS0501: 'I1.F1.set' must declare a body because it is not marked abstract, extern, or partial // private int F1 {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.F1.set").WithLocation(4, 26), - // (5,17): error CS8052: Instance auto-implemented properties inside interfaces cannot have initializers. + // (5,17): error CS8050: Only auto-implemented properties can have initializers. // private int F5 {get;} = 5; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "F5").WithArguments("I1.F5").WithLocation(5, 17), + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "F5").WithArguments("I1.F5").WithLocation(5, 17), // (5,21): error CS0501: 'I1.F5.get' must declare a body because it is not marked abstract, extern, or partial // private int F5 {get;} = 5; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.F5.get").WithLocation(5, 21) @@ -44193,5 +44197,9781 @@ interface I3 : I1 ); } + [Fact] + public void MethodReAbstraction_01() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidateMethodReAbstraction_01(source1, source2); + } + + private static void ValidateMethodReAbstraction_01(string source1, string source2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + var expected = new DiagnosticDescription[] + { + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(2, 15) + }; + + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + ValidateReabstraction(i2m1); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + private static void ValidateReabstraction(MethodSymbol m) + { + Assert.True(m.IsMetadataVirtual()); + Assert.True(m.IsMetadataFinal); + Assert.False(m.IsMetadataNewSlot()); + Assert.True(m.IsAbstract); + Assert.False(m.IsVirtual); + Assert.True(m.IsSealed); + Assert.False(m.IsStatic); + Assert.False(m.IsExtern); + Assert.False(m.IsAsync); + Assert.False(m.IsOverride); + Assert.Equal(Accessibility.Private, m.DeclaredAccessibility); + } + + [Fact] + public void MethodReAbstraction_02() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + + ValidateMethodReAbstraction_01(source1, source2); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void MethodReAbstraction_03() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.M1(); + } + + void I1.M1() + { + System.Console.WriteLine(""Test1.M1""); + } +} +"; + ValidateMethodReAbstraction_03(source1, source2); + } + + private void ValidateMethodReAbstraction_03(string source1, string source2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test1.M1" : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test1.M1" : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Equal("void Test1.I1.M1()", test1.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void MethodReAbstraction_04() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.M1(); + } + + void I1.M1() + { + System.Console.WriteLine(""Test1.M1""); + } +} +"; + + ValidateMethodReAbstraction_03(source1, source2); + } + + [Fact] + public void MethodReAbstraction_05() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidateMethodReAbstraction_05(source1, source2); + } + + private static void ValidateMethodReAbstraction_05(string source1, string source2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + var expected = new DiagnosticDescription[] + { + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.M1()").WithLocation(2, 15) + }; + + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I3", i3.Name); + var i1m1 = i3.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i3.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_06() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + + ValidateMethodReAbstraction_05(source1, source2); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void MethodReAbstraction_07() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I2 +{ + void I1.M1() + { + System.Console.WriteLine(""I3.M1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.M1(); + } +} +"; + ValidateMethodReAbstraction_07(source1, source2); + } + + private void ValidateMethodReAbstraction_07(string source1, string source2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I3.M1" : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I3.M1" : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I3", i3.Name); + var i1m1 = i3.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Equal("void I3.I1.M1()", i3.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); + Assert.Equal("void I3.I1.M1()", test1.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void MethodReAbstraction_08() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I2 +{ + void I1.M1() + { + System.Console.WriteLine(""I3.M1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.M1(); + } +} +"; + ValidateMethodReAbstraction_07(source1, source2); + } + + [Fact] + public void MethodReAbstraction_09() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I1 +{ + abstract void I1.M1(); +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidateMethodReAbstraction_09(source1, source2); + } + + private void ValidateMethodReAbstraction_09(string source1, string source2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + var expected = new DiagnosticDescription[] + { + // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15) + }; + + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i1m1 = test1.InterfacesNoUseSiteDiagnostics().First().ContainingNamespace.GetTypeMember("I1").GetMember("M1"); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_10() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + void I1.M1() {} +} + +public interface I3 : I1 +{ + abstract void I1.M1(); +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidateMethodReAbstraction_09(source1, source2); + } + + [Fact] + public void MethodReAbstraction_11() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I1 +{ + void I1.M1() {} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidateMethodReAbstraction_09(source1, source2); + } + + [Fact] + public void MethodReAbstraction_12() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I1 +{ + abstract void I1.M1(); +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + var expected = new DiagnosticDescription[] + { + // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15) + }; + + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I4", i4.Name); + var i1m1 = i4.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i4.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void MethodReAbstraction_13() + { + var source1 = +@" +public interface I1 +{ + void M1() {} +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +public interface I3 : I1 +{ + abstract void I1.M1(); +} + +public interface I4 : I2, I3 +{ + void I1.M1() + { + System.Console.WriteLine(""I4.M1""); + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.M1(); + } +} +"; + + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I4.M1" : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I4.M1" : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I4", i4.Name); + var i1m1 = i4.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Equal("void I4.I1.M1()", i4.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); + Assert.Equal("void I4.I1.M1()", test1.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); + } + } + + [Fact] + public void MethodReAbstraction_14() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract void I1.M1() {} +} + +class Test1 : I2 +{ +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics( + // (9,22): error CS0500: 'I2.I1.M1()' cannot declare a body because it is marked abstract + // abstract void I1.M1() {} + Diagnostic(ErrorCode.ERR_AbstractHasBody, "M1").WithArguments("I2.I1.M1()").WithLocation(9, 22), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) + ); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + ValidateReabstraction(i2m1); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_15() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract extern void I1.M1(); +} + +class Test1 : I2 +{ +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics( + // (9,29): error CS0180: 'I2.I1.M1()' cannot be both extern and abstract + // abstract extern void I1.M1(); + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "M1").WithArguments("I2.I1.M1()").WithLocation(9, 29), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) + ); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + Assert.True(i2m1.IsMetadataVirtual()); + Assert.True(i2m1.IsMetadataFinal); + Assert.False(i2m1.IsMetadataNewSlot()); + Assert.True(i2m1.IsAbstract); + Assert.False(i2m1.IsVirtual); + Assert.True(i2m1.IsSealed); + Assert.False(i2m1.IsStatic); + Assert.True(i2m1.IsExtern); + Assert.False(i2m1.IsAsync); + Assert.False(i2m1.IsOverride); + Assert.Equal(Accessibility.Private, i2m1.DeclaredAccessibility); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_16() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public partial interface I2 : I1 +{ + abstract partial void I1.M1(); +} + +class Test1 : I2 +{ +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics( + // (9,30): error CS0754: A partial method may not explicitly implement an interface method + // abstract partial void I1.M1(); + Diagnostic(ErrorCode.ERR_PartialMethodNotExplicit, "M1").WithLocation(9, 30), + // (9,30): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers + // abstract partial void I1.M1(); + Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M1").WithLocation(9, 30), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) + ); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + ValidateReabstraction(i2m1); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_17() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public partial interface I2 : I1 +{ + abstract async void I1.M1(); +} + +class Test1 : I2 +{ +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics( + // (9,28): error CS1994: The 'async' modifier can only be used in methods that have a body. + // abstract async void I1.M1(); + Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M1").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) + ); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + Assert.True(i2m1.IsMetadataVirtual()); + Assert.True(i2m1.IsMetadataFinal); + Assert.False(i2m1.IsMetadataNewSlot()); + Assert.True(i2m1.IsAbstract); + Assert.False(i2m1.IsVirtual); + Assert.True(i2m1.IsSealed); + Assert.False(i2m1.IsStatic); + Assert.False(i2m1.IsExtern); + Assert.True(i2m1.IsAsync); + Assert.False(i2m1.IsOverride); + Assert.Equal(Accessibility.Private, i2m1.DeclaredAccessibility); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_18() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public partial interface I2 : I1 +{ + abstract public void I1.M1(); +} + +class Test1 : I2 +{ +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics( + // (9,29): error CS0106: The modifier 'public' is not valid for this item + // abstract public void I1.M1(); + Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("public").WithLocation(9, 29), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) + ); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + ValidateReabstraction(i2m1); + + var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_19() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public class C2 : I1 +{ + abstract void I1.M1(); +} +"; + ValidateMethodReAbstraction_19(source1); + } + + private static void ValidateMethodReAbstraction_19(string source1) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics( + // (9,22): error CS0106: The modifier 'abstract' is not valid for this item + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("abstract").WithLocation(9, 22), + // (9,22): error CS0501: 'C2.I1.M1()' must declare a body because it is not marked abstract, extern, or partial + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M1").WithArguments("C2.I1.M1()").WithLocation(9, 22) + ); + + static void validate(ModuleSymbol m) + { + var c2 = m.GlobalNamespace.GetTypeMember("C2"); + var c2m1 = c2.GetMember("I1.M1"); + + Assert.False(c2m1.IsAbstract); + Assert.False(c2m1.IsSealed); + + var i1m1 = c2m1.ExplicitInterfaceImplementations.Single(); + Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); + + Assert.Same(c2m1, c2.FindImplementationForInterfaceMember(i1m1)); + } + } + + [Fact] + public void MethodReAbstraction_20() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public struct C2 : I1 +{ + abstract void I1.M1(); +} +"; + ValidateMethodReAbstraction_19(source1); + } + + [Fact] + public void MethodReAbstraction_21() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +class Test1 : I2 +{ +} +"; + ValidateMethodReAbstraction_21(source1, + // (8,22): error CS0539: 'I2.M1()' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("I2.M1()").WithLocation(8, 22) + ); + } + + private static void ValidateMethodReAbstraction_21(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2m1 = i2.GetMember("I1.M1"); + + ValidateReabstraction(i2m1); + + Assert.Empty(i2m1.ExplicitInterfaceImplementations); + } + } + + [Fact] + public void MethodReAbstraction_22() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract void I1.M1(); +} + +class Test1 : I2 +{ +} +"; + ValidateMethodReAbstraction_21(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,19): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 19), + // (4,19): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 19) + ); + } + + [Fact] + public void MethodReAbstraction_23() + { + var source1 = +@" +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + abstract void I1.M1(); +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,22): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "M1").WithArguments("default interface implementation").WithLocation(9, 22) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,22): error CS8701: Target runtime doesn't support default interface implementation. + // abstract void I1.M1(); + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(9, 22) + ); + } + + [Fact] + public void PropertyReAbstraction_001() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidatePropertyReAbstraction_001(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + ValidateReabstraction(i2p1); + + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + else if (i2p1.GetMethod is object) + { + Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); + } + + if (i1p1.SetMethod is object) + { + Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + else if (i2p1.SetMethod is object) + { + Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); + } + } + } + + private static void ValidateReabstraction(PropertySymbol reabstracting) + { + Assert.True(reabstracting.IsAbstract); + Assert.False(reabstracting.IsVirtual); + Assert.True(reabstracting.IsSealed); + Assert.False(reabstracting.IsStatic); + Assert.False(reabstracting.IsExtern); + Assert.False(reabstracting.IsOverride); + Assert.Equal(Accessibility.Private, reabstracting.DeclaredAccessibility); + + if (reabstracting.GetMethod is object) + { + ValidateReabstraction(reabstracting.GetMethod); + } + + if (reabstracting.SetMethod is object) + { + ValidateReabstraction(reabstracting.SetMethod); + } + } + + [Fact] + public void PropertyReAbstraction_002() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_003() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + i1.P1 = 1; + } + + int I1.P1 + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + set => System.Console.WriteLine(""Test1.set_P1""); + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, +@" +Test1.get_P1 +Test1.set_P1 +"); + } + + private void ValidatePropertyReAbstraction_003(string source1, string source2, string expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var test12p1 = test1.GetMembers().OfType().Single(); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Same(test12p1, test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Same(test12p1.GetMethod, test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + + if (i1p1.SetMethod is object) + { + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Same(test12p1.SetMethod, test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_004() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + i1.P1 = 1; + } + + int I1.P1 + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + set => System.Console.WriteLine(""Test1.set_P1""); + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, +@" +Test1.get_P1 +Test1.set_P1 +"); + } + + [Fact] + public void PropertyReAbstraction_005() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidatePropertyReAbstraction_005(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I3", i3.Name); + + var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Null(i3.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + + if (i1p1.SetMethod is object) + { + Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + } + } + + [Fact] + public void PropertyReAbstraction_006() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_007() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I2 +{ + int I1.P1 + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + set => System.Console.WriteLine(""I3.set_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + i1.P1 = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, +@" +I3.get_P1 +I3.set_P1 +"); + } + + private void ValidatePropertyReAbstraction_007(string source1, string source2, string expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I3", i3.Name); + + var i3p1 = i3.GetMembers().OfType().Single(); + var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Same(i3p1, i3.FindImplementationForInterfaceMember(i1p1)); + Assert.Same(i3p1, test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Same(i3p1.GetMethod, i3.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Same(i3p1.GetMethod, test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + + if (i1p1.SetMethod is object) + { + Assert.Same(i3p1.SetMethod, i3.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Same(i3p1.SetMethod, test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_008() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I2 +{ + int I1.P1 + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + set => System.Console.WriteLine(""I3.set_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + i1.P1 = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, +@" +I3.get_P1 +I3.set_P1 +"); + } + + [Fact] + public void PropertyReAbstraction_009() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidatePropertyReAbstraction_009(string source1, string source2, params DiagnosticDescription[] expected) + { + ValidatePropertyReAbstraction_009(source1, source2, expected, expected); + } + + private static void ValidatePropertyReAbstraction_009(string source1, string source2, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected1); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + var expected = expected1; + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + expected = expected2; + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i1p1 = test1.InterfacesNoUseSiteDiagnostics().First().ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + if (i1p1.GetMethod is object) + { + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + if (i1p1.SetMethod is object) + { + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + } + } + + [Fact] + public void PropertyReAbstraction_010() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + int I1.P1 { get => throw null; set => throw null; } +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_011() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I1 +{ + int I1.P1 { get => throw null; set => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_012() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidatePropertyReAbstraction_012(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidatePropertyReAbstraction_012(string source1, string source2, params DiagnosticDescription[] expected) + { + ValidatePropertyReAbstraction_012(source1, source2, expected, expected); + } + + private static void ValidatePropertyReAbstraction_012(string source1, string source2, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected1); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + var expected = expected1; + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + expected = expected2; + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I4", i4.Name); + var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Null(i4.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + if (i1p1.GetMethod is object) + { + Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + if (i1p1.SetMethod is object) + { + Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_013() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get; set;} +} + +public interface I4 : I2, I3 +{ + int I1.P1 + { + get + { + System.Console.WriteLine(""I4.get_P1""); + return 0; + } + set => System.Console.WriteLine(""I4.set_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + i1.P1 = 1; + } +} +"; + ValidatePropertyReAbstraction_013(source1, source2, +@" +I4.get_P1 +I4.set_P1 +"); + } + + private void ValidatePropertyReAbstraction_013(string source1, string source2, string expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I4", i4.Name); + + var i4p1 = i4.GetMembers().OfType().Single(); + var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Same(i4p1, i4.FindImplementationForInterfaceMember(i1p1)); + Assert.Same(i4p1, test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Same(i4p1.GetMethod, i4.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Same(i4p1.GetMethod, test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + + if (i1p1.SetMethod is object) + { + Assert.Same(i4p1.SetMethod, i4.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Same(i4p1.SetMethod, test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + } + } + + [Fact] + public void PropertyReAbstraction_014() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 + { + get + { + throw null; + } + set + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract + // get + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), + // (15,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract + // set + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(15, 9), + // (22,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(22, 15) + ); + } + + private static void ValidatePropertyReAbstraction_014(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + ValidateReabstraction(i2p1); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + if (i2p1.GetMethod is object) + { + Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); + } + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + else if (i2p1.GetMethod is object) + { + Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); + } + + if (i1p1.SetMethod is object) + { + if (i2p1.SetMethod is object) + { + Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); + } + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + else if (i2p1.SetMethod is object) + { + Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); + } + } + } + + [Fact] + public void PropertyReAbstraction_015() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 + { + get => throw null; + set => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract + // get => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), + // (12,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract + // set => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(12, 9), + // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_016() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + extern abstract int I1.P1 {get; set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_016(source1, + // (9,28): error CS0180: 'I2.I1.P1' cannot be both extern and abstract + // extern abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I2.I1.P1").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + private static void ValidatePropertyReAbstraction_016(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + Assert.True(i2p1.IsAbstract); + Assert.False(i2p1.IsVirtual); + Assert.True(i2p1.IsSealed); + Assert.False(i2p1.IsStatic); + Assert.True(i2p1.IsExtern); + Assert.False(i2p1.IsOverride); + Assert.Equal(Accessibility.Private, i2p1.DeclaredAccessibility); + + var i2p1Get = i2p1.GetMethod; + + if (i2p1Get is object) + { + Assert.True(i2p1Get.IsMetadataVirtual()); + Assert.True(i2p1Get.IsMetadataFinal); + Assert.False(i2p1Get.IsMetadataNewSlot()); + Assert.True(i2p1Get.IsAbstract); + Assert.False(i2p1Get.IsVirtual); + Assert.True(i2p1Get.IsSealed); + Assert.False(i2p1Get.IsStatic); + Assert.True(i2p1Get.IsExtern); + Assert.False(i2p1Get.IsAsync); + Assert.False(i2p1Get.IsOverride); + Assert.Equal(Accessibility.Private, i2p1Get.DeclaredAccessibility); + } + + var i2p1Set = i2p1.SetMethod; + + if (i2p1Set is object) + { + Assert.True(i2p1Set.IsMetadataVirtual()); + Assert.True(i2p1Set.IsMetadataFinal); + Assert.False(i2p1Set.IsMetadataNewSlot()); + Assert.True(i2p1Set.IsAbstract); + Assert.False(i2p1Set.IsVirtual); + Assert.True(i2p1Set.IsSealed); + Assert.False(i2p1Set.IsStatic); + Assert.True(i2p1Set.IsExtern); + Assert.False(i2p1Set.IsAsync); + Assert.False(i2p1Set.IsOverride); + Assert.Equal(Accessibility.Private, i2p1Set.DeclaredAccessibility); + } + + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + else if (i2p1.GetMethod is object) + { + Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); + } + + if (i1p1.SetMethod is object) + { + Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + else if (i2p1.SetMethod is object) + { + Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); + } + } + } + + [Fact] + public void PropertyReAbstraction_017() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract public int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,28): error CS0106: The modifier 'public' is not valid for this item + // abstract public int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_018() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public class C2 : I1 +{ + abstract int I1.P1 { get; set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) + ); + } + + private static void ValidatePropertyReAbstraction_018(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var c2 = m.GlobalNamespace.GetTypeMember("C2"); + var c2p1 = c2.GetMembers().OfType().Single(); + + Assert.False(c2p1.IsAbstract); + Assert.False(c2p1.IsSealed); + + var c2p1Get = c2p1.GetMethod; + + if (c2p1Get is object) + { + Assert.False(c2p1Get.IsAbstract); + Assert.False(c2p1Get.IsSealed); + } + + var c2p1Set = c2p1.SetMethod; + + if (c2p1Set is object) + { + Assert.False(c2p1Set.IsAbstract); + Assert.False(c2p1Set.IsSealed); + } + + var i1p1 = c2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Same(c2p1, c2.FindImplementationForInterfaceMember(i1p1)); + if (i1p1.GetMethod is object) + { + Assert.Same(i1p1.GetMethod, c2p1.GetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Same(c2p1Get, c2.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + else if (c2p1.GetMethod is object) + { + Assert.Empty(c2p1.GetMethod.ExplicitInterfaceImplementations); + } + + if (i1p1.SetMethod is object) + { + Assert.Same(i1p1.SetMethod, c2p1.SetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Same(c2p1Set, c2.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + else if (c2p1.SetMethod is object) + { + Assert.Empty(c2p1.SetMethod.ExplicitInterfaceImplementations); + } + } + } + + [Fact] + public void PropertyReAbstraction_019() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public struct C2 : I1 +{ + abstract int I1.P1 { get; set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) + ); + } + + [Fact] + public void PropertyReAbstraction_020() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.set' + // abstract int I1.P1 { get; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.set").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_021() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.get' + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.get").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_022() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,31): error CS0550: 'I2.I1.P1.set' adds an accessor not found in interface member 'I1.P1' + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.P1.set", "I1.P1").WithLocation(9, 31), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_023() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,26): error CS0550: 'I2.I1.P1.get' adds an accessor not found in interface member 'I1.P1' + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.P1.get", "I1.P1").WithLocation(9, 26), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_024() + { + var source1 = +@" +public interface I1 +{ + int P1 {get => throw null; private set => throw null;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,31): error CS0550: 'I2.I1.P1.set' adds an accessor not found in interface member 'I1.P1' + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.P1.set", "I1.P1").WithLocation(9, 31), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_025() + { + var source1 = +@" +public interface I1 +{ + int P1 {private get => throw null; set => throw null;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,26): error CS0550: 'I2.I1.P1.get' adds an accessor not found in interface member 'I1.P1' + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.P1.get", "I1.P1").WithLocation(9, 26), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_026() + { + var source1 = +@" +public interface I1 +{ + internal int P1 {get => throw null; set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.P1' is inaccessible due to its protection level + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) + ); + } + + private static void ValidatePropertyReAbstraction_026(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) + { + var compilation2 = CreateCompilation(source2, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + references: new[] { reference }, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation2.SourceModule); + compilation2.VerifyDiagnostics(expected); + } + + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + ValidateReabstraction(i2p1); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.GetMethod is object) + { + Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); + } + else if (i2p1.GetMethod is object) + { + Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); + } + + if (i1p1.SetMethod is object) + { + Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); + } + else if (i2p1.SetMethod is object) + { + Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); + } + } + } + + [Fact] + public void PropertyReAbstraction_027() + { + var source1 = +@" +public interface I1 +{ + int P1 {internal get => throw null; set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.P1.get' is inaccessible due to its protection level + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.get").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_028() + { + var source1 = +@" +public interface I1 +{ + int P1 {get => throw null; internal set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.P1.set' is inaccessible due to its protection level + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.set").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) + ); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_029() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.s 65 + IL_0002: ret + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname abstract virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + } // end of method I2::I1.set_F1 + + .property instance char I1.F1() + { + .get instance char I2::I1.get_F1() + .set instance void I2::I1.set_F1(char) + } // end of property I2::I1.F1 +} // end of class I2 +"; + + var source1 = +@" +class Test2 : I2 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); + Assert.Equal("System.Char I2.I1.get_F1()", test2.FindImplementationForInterfaceMember(i1F1.GetMethod).ToTestDisplayString()); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_030() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname abstract virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + IL_0002: ret + } // end of method I2::I1.set_F1 + + .property instance char I1.F1() + { + .get instance char I2::I1.get_F1() + .set instance void I2::I1.set_F1(char) + } // end of property I2::I1.F1 +} // end of class I2 +"; + + var source1 = +@" +class Test2 : I2 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Equal("void I2.I1.set_F1(System.Char value)", test2.FindImplementationForInterfaceMember(i1F1.SetMethod).ToTestDisplayString()); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_031() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.s 65 + IL_0002: ret + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname abstract virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + } // end of method I2::I1.set_F1 + + .property instance char I1.F1() + { + .get instance char I2::I1.get_F1() + .set instance void I2::I1.set_F1(char) + } // end of property I2::I1.F1 +} // end of class I2 + +.class interface public abstract auto ansi I3 + implements I1 +{ + .method private hidebysig specialname abstract virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + } // end of method I3::I1.get_F1 + + .method private hidebysig specialname virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + IL_0002: ret + } // end of method I3::I1.set_F1 + + .property instance char I1.F1() + { + .get instance char I3::I1.get_F1() + .set instance void I3::I1.set_F1(char) + } // end of property I3::I1.F1 +} // end of class I3 +"; + + var source1 = +@" +class Test2 : I2, I3 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS8705: Interface member 'I1.F1' does not have a most specific implementation. Neither 'I2.I1.F1', nor 'I3.I1.F1' are most specific. + // class Test2 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.F1", "I2.I1.F1", "I3.I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_032() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.s 65 + IL_0002: ret + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname abstract virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + } // end of method I2::I1.set_F1 +} // end of class I2 +"; + + var source1 = +@" +class Test2 : I2 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); + Assert.Equal("System.Char I2.I1.get_F1()", test2.FindImplementationForInterfaceMember(i1F1.GetMethod).ToTestDisplayString()); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_033() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname abstract virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + IL_0002: ret + } // end of method I2::I1.set_F1 +} // end of class I2 +"; + + var source1 = +@" +class Test2 : I2 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Equal("void I2.I1.set_F1(System.Char value)", test2.FindImplementationForInterfaceMember(i1F1.SetMethod).ToTestDisplayString()); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_034() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.s 65 + IL_0002: ret + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname abstract virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + } // end of method I2::I1.set_F1 +} // end of class I2 + +.class interface public abstract auto ansi I3 + implements I1 +{ + .method private hidebysig specialname abstract virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + } // end of method I3::I1.get_F1 + + .method private hidebysig specialname virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + IL_0002: ret + } // end of method I3::I1.set_F1 + + .property instance char I1.F1() + { + .get instance char I3::I1.get_F1() + .set instance void I3::I1.set_F1(char) + } // end of property I3::I1.F1 +} // end of class I3 +"; + + var source1 = +@" +class Test2 : I2, I3 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2, I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_035() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.s 65 + IL_0002: ret + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname abstract virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + } // end of method I2::I1.set_F1 + + .property instance char I1.F1() + { + .get instance char I2::I1.get_F1() + .set instance void I2::I1.set_F1(char) + } // end of property I2::I1.F1 +} // end of class I2 + +.class interface public abstract auto ansi I3 + implements I1 +{ + .method private hidebysig specialname abstract virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + } // end of method I3::I1.get_F1 + + .method private hidebysig specialname virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + IL_0002: ret + } // end of method I3::I1.set_F1 +} // end of class I3 +"; + + var source1 = +@" +class Test2 : I2, I3 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2, I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void PropertyReAbstraction_036() + { + var ilSource = @" +.class interface public abstract auto ansi I1 +{ + .method public hidebysig newslot specialname abstract virtual + instance char get_F1() cil managed + { + } // end of method I1::get_F1 + + .method public hidebysig newslot specialname abstract virtual + instance void set_F1(char 'value') cil managed + { + } // end of method I1::set_F1 + + .property instance char F1() + { + .get instance char I1::get_F1() + .set instance void I1::set_F1(char) + } // end of property I1::F1 +} // end of class I1 + +.class interface public abstract auto ansi I2 + implements I1 +{ + .method private hidebysig specialname virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.s 65 + IL_0002: ret + } // end of method I2::I1.get_F1 + + .method private hidebysig specialname abstract virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + } // end of method I2::I1.set_F1 +} // end of class I2 + +.class interface public abstract auto ansi I3 + implements I1 +{ + .method private hidebysig specialname abstract virtual final + instance char I1.get_F1() cil managed + { + .override I1::get_F1 + } // end of method I3::I1.get_F1 + + .method private hidebysig specialname virtual final + instance void I1.set_F1(char 'value') cil managed + { + .override I1::set_F1 + IL_0002: ret + } // end of method I3::I1.set_F1 +} // end of class I3 +"; + + var source1 = +@" +class Test2 : I2, I3 +{ +} +"; + var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' + // class Test2 : I2, I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) + ); + + var i1 = compilation1.GetTypeByMetadataName("I1"); + var i1F1 = i1.GetMember("F1"); + var test2 = compilation1.GetTypeByMetadataName("Test2"); + + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); + Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); + } + + [Fact] + public void PropertyReAbstraction_037() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_038() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_039() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + } + + int I1.P1 + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_040() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + } + + int I1.P1 + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); + } + + [Fact] + public void PropertyReAbstraction_041() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_042() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_043() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I2 +{ + int I1.P1 + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_044() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I2 +{ + int I1.P1 + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); + } + + [Fact] + public void PropertyReAbstraction_045() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_046() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + int I1.P1 { get => throw null; } +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_047() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I1 +{ + int I1.P1 { get => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_048() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidatePropertyReAbstraction_012(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_049() + { + var source1 = +@" +public interface I1 +{ + int P1 { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {get;} +} + +public interface I4 : I2, I3 +{ + int I1.P1 + { + get + { + System.Console.WriteLine(""I4.get_P1""); + return 0; + } + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1.P1; + } +} +"; + ValidatePropertyReAbstraction_013(source1, source2, "I4.get_P1"); + } + + [Fact] + public void PropertyReAbstraction_050() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 + { + get + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract + // get + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), + // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(18, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_051() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 + { + get => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract + // get => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), + // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(15, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_052() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 => throw null; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,27): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract + // abstract int I1.P1 => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "throw null").WithArguments("I2.I1.P1.get").WithLocation(9, 27), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_053() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + extern abstract int I1.P1 {get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_016(source1, + // (9,28): error CS0180: 'I2.I1.P1' cannot be both extern and abstract + // extern abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I2.I1.P1").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_054() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract public int I1.P1 { get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,28): error CS0106: The modifier 'public' is not valid for this item + // abstract public int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_055() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public class C2 : I1 +{ + abstract int I1.P1 { get; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) + ); + } + + [Fact] + public void PropertyReAbstraction_056() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public struct C2 : I1 +{ + abstract int I1.P1 { get; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) + ); + } + + [Fact] + public void PropertyReAbstraction_057() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.set' + // abstract int I1.P1 { get; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.set").WithLocation(9, 21), + // (9,26): error CS0550: 'I2.I1.P1.get' adds an accessor not found in interface member 'I1.P1' + // abstract int I1.P1 { get; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.P1.get", "I1.P1").WithLocation(9, 26), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_058() + { + var source1 = +@" +public interface I1 +{ + internal int P1 {get => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 { get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.P1' is inaccessible due to its protection level + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_059() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_060() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_061() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 = 1; + } + + int I1.P1 + { + set + { + System.Console.WriteLine(""Test1.set_P1""); + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_062() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 = 1; + } + + int I1.P1 + { + set + { + System.Console.WriteLine(""Test1.set_P1""); + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); + } + + [Fact] + public void PropertyReAbstraction_063() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_064() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_065() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I2 +{ + int I1.P1 + { + set + { + System.Console.WriteLine(""I3.set_P1""); + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_066() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I2 +{ + int I1.P1 + { + set + { + System.Console.WriteLine(""I3.set_P1""); + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); + } + + [Fact] + public void PropertyReAbstraction_067() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_068() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + int I1.P1 { set => throw null; } +} + +public interface I3 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_069() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I1 +{ + int I1.P1 { set => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_070() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidatePropertyReAbstraction_012(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void PropertyReAbstraction_071() + { + var source1 = +@" +public interface I1 +{ + int P1 { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I3 : I1 +{ + abstract int I1.P1 {set;} +} + +public interface I4 : I2, I3 +{ + int I1.P1 + { + set + { + System.Console.WriteLine(""I4.set_P1""); + } + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 = 1; + } +} +"; + ValidatePropertyReAbstraction_013(source1, source2, "I4.set_P1"); + } + + [Fact] + public void PropertyReAbstraction_072() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 + { + set + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract + // set + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(11, 9), + // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(18, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_073() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 + { + set => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract + // set => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(11, 9), + // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(15, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_074() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + extern abstract int I1.P1 {set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_016(source1, + // (9,28): error CS0180: 'I2.I1.P1' cannot be both extern and abstract + // extern abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I2.I1.P1").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_075() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract public int I1.P1 { set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,28): error CS0106: The modifier 'public' is not valid for this item + // abstract public int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_076() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public class C2 : I1 +{ + abstract int I1.P1 { set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21), + // (9,26): error CS8051: Auto-implemented properties must have get accessors. + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_AutoPropertyMustHaveGetAccessor, "set").WithArguments("C2.I1.P1.set").WithLocation(9, 26) + ); + } + + [Fact] + public void PropertyReAbstraction_077() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public struct C2 : I1 +{ + abstract int I1.P1 { set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21), + // (9,26): error CS8051: Auto-implemented properties must have get accessors. + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_AutoPropertyMustHaveGetAccessor, "set").WithArguments("C2.I1.P1.set").WithLocation(9, 26) + ); + } + + [Fact] + public void PropertyReAbstraction_078() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.get' + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.get").WithLocation(9, 21), + // (9,26): error CS0550: 'I2.I1.P1.set' adds an accessor not found in interface member 'I1.P1' + // abstract int I1.P1 { set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.P1.set", "I1.P1").WithLocation(9, 26), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_079() + { + var source1 = +@" +public interface I1 +{ + internal int P1 {set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 { set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.P1' is inaccessible due to its protection level + // abstract int I1.P1 { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_080() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; set; } = 0; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS8050: Only auto-implemented properties can have initializers. + // abstract int I1.P1 { get; set; } = 0; + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I2.I1.P1").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_081() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { get; } = 0; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS8050: Only auto-implemented properties can have initializers. + // abstract int I1.P1 { get; } = 0; + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I2.I1.P1").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_082() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 { set; } = 0; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS8050: Only auto-implemented properties can have initializers. + // abstract int I1.P1 { set; } = 0; + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I2.I1.P1").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void PropertyReAbstraction_083() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (8,21): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 21) + ); + } + + private static void ValidatePropertyReAbstraction_083(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + ValidateReabstraction(i2p1); + + Assert.Empty(i2p1.ExplicitInterfaceImplementations); + if (i2p1.GetMethod is object) + { + Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); + } + + if (i2p1.SetMethod is object) + { + Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); + } + } + } + + [Fact] + public void PropertyReAbstraction_084() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), + // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) + ); + } + + [Fact] + public void PropertyReAbstraction_085() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (8,21): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 21) + ); + } + + [Fact] + public void PropertyReAbstraction_086() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract int I1.P1 {get;} + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), + // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract int I1.P1 {get;} + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) + ); + } + + [Fact] + public void PropertyReAbstraction_087() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (8,21): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 21) + ); + } + + [Fact] + public void PropertyReAbstraction_088() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract int I1.P1 {set;} + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), + // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract int I1.P1 {set;} + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) + ); + } + + [Fact] + public void PropertyReAbstraction_089() + { + var source1 = +@" +public interface I1 +{ + int P1 {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get; set;} +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,25): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("default interface implementation").WithLocation(9, 25), + // (9,30): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("default interface implementation").WithLocation(9, 30) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,25): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 25), + // (9,30): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.P1 {get; set;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 30) + ); + } + + [Fact] + public void PropertyReAbstraction_090() + { + var source1 = +@" +public interface I1 +{ + int P1 {get;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {get;} +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,25): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.P1 {get;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("default interface implementation").WithLocation(9, 25) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,25): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.P1 {get;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 25) + ); + } + + [Fact] + public void PropertyReAbstraction_091() + { + var source1 = +@" +public interface I1 +{ + int P1 {set;} +} + +public interface I2 : I1 +{ + abstract int I1.P1 {set;} +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,25): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.P1 {set;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("default interface implementation").WithLocation(9, 25) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,25): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.P1 {set;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 25) + ); + } + + [Fact] + public void EventReAbstraction_001() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidateEventReAbstraction_001(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + ValidateReabstraction(i2p1); + + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Same(i1p1.AddMethod, i2p1.AddMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Same(i1p1.RemoveMethod, i2p1.RemoveMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + private static void ValidateReabstraction(EventSymbol reabstracting) + { + Assert.True(reabstracting.IsAbstract); + Assert.False(reabstracting.IsVirtual); + Assert.True(reabstracting.IsSealed); + Assert.False(reabstracting.IsStatic); + Assert.False(reabstracting.IsExtern); + Assert.False(reabstracting.IsOverride); + Assert.Equal(Accessibility.Private, reabstracting.DeclaredAccessibility); + + if (reabstracting.AddMethod is object) + { + ValidateReabstraction(reabstracting.AddMethod); + } + + if (reabstracting.RemoveMethod is object) + { + ValidateReabstraction(reabstracting.RemoveMethod); + } + } + + [Fact] + public void EventReAbstraction_002() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void EventReAbstraction_003() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 += null; + i1.P1 -= null; + } + + event System.Action I1.P1 + { + add + { + System.Console.WriteLine(""Test1.add_P1""); + } + remove => System.Console.WriteLine(""Test1.remove_P1""); + } +} +"; + ValidateEventReAbstraction_003(source1, source2, +@" +Test1.add_P1 +Test1.remove_P1 +"); + } + + private void ValidateEventReAbstraction_003(string source1, string source2, string expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var test12p1 = test1.GetMembers().OfType().Single(); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Same(test12p1, test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Same(test12p1.AddMethod, test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Same(test12p1.RemoveMethod, test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void EventReAbstraction_004() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 += null; + i1.P1 -= null; + } + + event System.Action I1.P1 + { + add + { + System.Console.WriteLine(""Test1.add_P1""); + } + remove => System.Console.WriteLine(""Test1.remove_P1""); + } +} +"; + ValidateEventReAbstraction_003(source1, source2, +@" +Test1.add_P1 +Test1.remove_P1 +"); + } + + [Fact] + public void EventReAbstraction_005() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidateEventReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidateEventReAbstraction_005(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I3", i3.Name); + + var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Null(i3.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [Fact] + public void EventReAbstraction_006() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidateEventReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void EventReAbstraction_007() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I2 +{ + event System.Action I1.P1 + { + add + { + System.Console.WriteLine(""I3.add_P1""); + } + remove => System.Console.WriteLine(""I3.remove_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 += null; + i1.P1 -= null; + } +} +"; + ValidateEventReAbstraction_007(source1, source2, +@" +I3.add_P1 +I3.remove_P1 +"); + } + + private void ValidateEventReAbstraction_007(string source1, string source2, string expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I3", i3.Name); + + var i3p1 = i3.GetMembers().OfType().Single(); + var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Same(i3p1, i3.FindImplementationForInterfaceMember(i1p1)); + Assert.Same(i3p1, test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Same(i3p1.AddMethod, i3.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Same(i3p1.AddMethod, test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Same(i3p1.RemoveMethod, i3.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Same(i3p1.RemoveMethod, test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void EventReAbstraction_008() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I2 +{ + event System.Action I1.P1 + { + add + { + System.Console.WriteLine(""I3.add_P1""); + } + remove => System.Console.WriteLine(""I3.remove_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 += null; + i1.P1 -= null; + } +} +"; + ValidateEventReAbstraction_007(source1, source2, +@" +I3.add_P1 +I3.remove_P1 +"); + } + + [Fact] + public void EventReAbstraction_009() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidateEventReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidateEventReAbstraction_009(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i1p1 = test1.InterfacesNoUseSiteDiagnostics().First().ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [Fact] + public void EventReAbstraction_010() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + event System.Action I1.P1 { add => throw null; remove => throw null; } +} + +public interface I3 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidateEventReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void EventReAbstraction_011() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I1 +{ + event System.Action I1.P1 { add => throw null; remove => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidateEventReAbstraction_009(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + [Fact] + public void EventReAbstraction_012() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidateEventReAbstraction_012(source1, source2, + // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) + ); + } + + private static void ValidateEventReAbstraction_012(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(expected); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I4", i4.Name); + var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Null(i4.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void EventReAbstraction_013() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 { add => throw null; remove => throw null; } +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I3 : I1 +{ + abstract event System.Action I1.P1; +} + +public interface I4 : I2, I3 +{ + event System.Action I1.P1 + { + add + { + System.Console.WriteLine(""I4.add_P1""); + } + remove => System.Console.WriteLine(""I4.remove_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + i1.P1 += null; + i1.P1 -= null; + } +} +"; + ValidateEventReAbstraction_013(source1, source2, +@" +I4.add_P1 +I4.remove_P1 +"); + } + + private void ValidateEventReAbstraction_013(string source1, string source2, string expected) + { + var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation2.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) + { + var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation3.SourceModule); + compilation3.VerifyDiagnostics(); + + CompileAndVerify(compilation1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, + verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); + } + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I4", i4.Name); + + var i4p1 = i4.GetMembers().OfType().Single(); + var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); + + Assert.Same(i4p1, i4.FindImplementationForInterfaceMember(i1p1)); + Assert.Same(i4p1, test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Same(i4p1.AddMethod, i4.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Same(i4p1.AddMethod, test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Same(i4p1.RemoveMethod, i4.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Same(i4p1.RemoveMethod, test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [Fact] + public void EventReAbstraction_014() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 + { + add + { + throw null; + } + remove + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), + // (22,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(22, 15) + ); + } + + private static void ValidateEventReAbstraction_014(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + ValidateReabstraction(i2p1); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + if (i1p1.AddMethod is object) + { + if (i2p1.AddMethod is object) + { + Assert.Same(i1p1.AddMethod, i2p1.AddMethod.ExplicitInterfaceImplementations.Single()); + } + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + } + else if (i2p1.AddMethod is object) + { + Assert.Empty(i2p1.AddMethod.ExplicitInterfaceImplementations); + } + + if (i1p1.RemoveMethod is object) + { + if (i2p1.RemoveMethod is object) + { + Assert.Same(i1p1.RemoveMethod, i2p1.RemoveMethod.ExplicitInterfaceImplementations.Single()); + } + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + else if (i2p1.RemoveMethod is object) + { + Assert.Empty(i2p1.RemoveMethod.ExplicitInterfaceImplementations); + } + } + } + + [Fact] + public void EventReAbstraction_015() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 + { + add => throw null; + remove => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), + // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) + ); + } + + [Fact] + public void EventReAbstraction_016() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + extern abstract event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,44): error CS0106: The modifier 'extern' is not valid for this item + // extern abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("extern").WithLocation(9, 44), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_017() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract public event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,44): error CS0106: The modifier 'public' is not valid for this item + // abstract public event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 44), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_018() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public class C2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + ValidateEventReAbstraction_018(source1, + // (7,19): error CS0535: 'C2' does not implement interface member 'I1.P1.remove' + // public class C2 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.remove").WithLocation(7, 19), + // (7,19): error CS0535: 'C2' does not implement interface member 'I1.P1.add' + // public class C2 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.add").WithLocation(7, 19), + // (9,37): error CS0071: An explicit interface implementation of an event must use event accessor syntax + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "P1").WithLocation(9, 37), + // (9,37): error CS0106: The modifier 'abstract' is not valid for this item + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) + ); + } + + private static void ValidateEventReAbstraction_018(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var c2 = m.GlobalNamespace.GetTypeMember("C2"); + var c2p1 = c2.GetMembers().OfType().Single(); + + Assert.False(c2p1.IsAbstract); + Assert.False(c2p1.IsSealed); + + var i1p1 = c2p1.ExplicitInterfaceImplementations.Single(); + + Assert.Same(c2p1, c2.FindImplementationForInterfaceMember(i1p1)); + + var c2p1Add = c2p1.AddMethod; + + if (c2p1Add is object) + { + Assert.False(c2p1Add.IsAbstract); + Assert.False(c2p1Add.IsSealed); + + Assert.Same(i1p1.AddMethod, c2p1Add.ExplicitInterfaceImplementations.Single()); + Assert.Same(c2p1Add, c2.FindImplementationForInterfaceMember(i1p1.AddMethod)); + } + else + { + Assert.Null(c2.FindImplementationForInterfaceMember(i1p1.AddMethod)); + } + + var c2p1Remove = c2p1.RemoveMethod; + + if (c2p1Remove is object) + { + Assert.False(c2p1Remove.IsAbstract); + Assert.False(c2p1Remove.IsSealed); + + Assert.Same(i1p1.RemoveMethod, c2p1Remove.ExplicitInterfaceImplementations.Single()); + Assert.Same(c2p1Remove, c2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + else + { + Assert.Null(c2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + } + + [Fact] + public void EventReAbstraction_019() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public class C2 : I1 +{ + abstract event System.Action I1.P1 + { + add => throw null; + remove => throw null; + } +} +"; + ValidateEventReAbstraction_018(source1, + // (9,37): error CS0106: The modifier 'abstract' is not valid for this item + // abstract event System.Action I1.P1 + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) + ); + } + + [Fact] + public void EventReAbstraction_020() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public struct C2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + ValidateEventReAbstraction_018(source1, + // (7,20): error CS0535: 'C2' does not implement interface member 'I1.P1.remove' + // public struct C2 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.remove").WithLocation(7, 20), + // (7,20): error CS0535: 'C2' does not implement interface member 'I1.P1.add' + // public struct C2 : I1 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.add").WithLocation(7, 20), + // (9,37): error CS0071: An explicit interface implementation of an event must use event accessor syntax + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "P1").WithLocation(9, 37), + // (9,37): error CS0106: The modifier 'abstract' is not valid for this item + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) + ); + } + + [Fact] + public void EventReAbstraction_021() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public struct C2 : I1 +{ + abstract event System.Action I1.P1 + { + add => throw null; + remove => throw null; + } +} +"; + ValidateEventReAbstraction_018(source1, + // (9,37): error CS0106: The modifier 'abstract' is not valid for this item + // abstract event System.Action I1.P1 + Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) + ); + } + + [Fact] + public void EventReAbstraction_022() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 { add => throw null; } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 { add => throw null; } + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_023() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 { add; } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 { add; } + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_024() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 { remove => throw null; } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 { remove => throw null; } + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_025() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 { remove; } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 { remove; } + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_026() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 { add; remove; } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 { add; remove; } + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_027() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 {} +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 {} + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_028() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 { add => throw null; remove => throw null; } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // abstract event System.Action I1.P1 { add => throw null; remove => throw null; } + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_029() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 {add => throw null;} +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors + // event System.Action P1 {add => throw null;} + Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_030() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 {add => throw null;} +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 + { + add {} + remove {} + } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors + // event System.Action P1 {add => throw null;} + Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), + // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), + // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) + ); + } + + [Fact] + public void EventReAbstraction_031() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 {remove => throw null;} +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors + // event System.Action P1 {remove => throw null;} + Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_032() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1 {remove => throw null;} +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 + { + add {} + remove {} + } +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors + // event System.Action P1 {remove => throw null;} + Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), + // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax + // { + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), + // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) + ); + } + + [Fact] + public void EventReAbstraction_033() + { + var source1 = +@" +public interface I1 +{ + internal event System.Action P1 {add => throw null; remove => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_033(source1, source2, + // (4,37): error CS0122: 'I1.P1' is inaccessible due to its protection level + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 37), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) + ); + } + + private static void ValidateEventReAbstraction_033(string source1, string source2, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics(); + + foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) + { + var compilation2 = CreateCompilation(source2, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + references: new[] { reference }, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation2.SourceModule); + compilation2.VerifyDiagnostics(expected); + } + + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); + + ValidateReabstraction(i2p1); + + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); + + Assert.Same(i1p1.AddMethod, i2p1.AddMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); + + Assert.Same(i1p1.RemoveMethod, i2p1.RemoveMethod.ExplicitInterfaceImplementations.Single()); + Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); + } + } + + [Fact] + public void EventReAbstraction_034() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_034(source1, + // (8,37): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 37) + ); + } + + private static void ValidateEventReAbstraction_034(string source1, params DiagnosticDescription[] expected) + { + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.NetStandardLatest); + validate(compilation1.SourceModule); + compilation1.VerifyDiagnostics(expected); + + static void validate(ModuleSymbol m) + { + var test1 = m.GlobalNamespace.GetTypeMember("Test1"); + var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); + Assert.Equal("I2", i2.Name); + var i2p1 = i2.GetMembers().OfType().Single(); + + ValidateReabstraction(i2p1); + + Assert.Empty(i2p1.ExplicitInterfaceImplementations); + Assert.Empty(i2p1.AddMethod.ExplicitInterfaceImplementations); + Assert.Empty(i2p1.RemoveMethod.ExplicitInterfaceImplementations); + } + } + + [Fact] + public void EventReAbstraction_035() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_034(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,34): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 34), + // (4,34): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 34) + ); + } + + [Fact] + public void EventReAbstraction_036() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1 +} + +class Test1 : I2 +{ +} +"; + ValidateEventReAbstraction_014(source1, + // (9,36): error CS0071: An explicit interface implementation of an event must use event accessor syntax + // abstract event System.Action I1.P1 + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(9, 36), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) + ); + } + + [Fact] + public void EventReAbstraction_037() + { + var source1 = +@" +public interface I1 +{ + event System.Action P1; +} + +public interface I2 : I1 +{ + abstract event System.Action I1.P1; +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,37): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "P1").WithArguments("default interface implementation").WithLocation(9, 37) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,37): error CS8701: Target runtime doesn't support default interface implementation. + // abstract event System.Action I1.P1; + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P1").WithLocation(9, 37) + ); + } + + [Fact] + public void IndexerReAbstraction_001() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_002() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_003() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + i1[0] = 1; + } + + int I1.this[int i] + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + set => System.Console.WriteLine(""Test1.set_P1""); + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, +@" +Test1.get_P1 +Test1.set_P1 +"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_004() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + i1[0] = 1; + } + + int I1.this[int i] + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + set => System.Console.WriteLine(""Test1.set_P1""); + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, +@" +Test1.get_P1 +Test1.set_P1 +"); + } + + [Fact] + public void IndexerReAbstraction_005() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_006() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_007() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I2 +{ + int I1.this[int i] + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + set => System.Console.WriteLine(""I3.set_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + i1[0] = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, +@" +I3.get_P1 +I3.set_P1 +"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_008() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I2 +{ + int I1.this[int i] + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + set => System.Console.WriteLine(""I3.set_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + i1[0] = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, +@" +I3.get_P1 +I3.set_P1 +"); + } + + [Fact] + public void IndexerReAbstraction_009() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_010() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + int I1.this[int i] { get => throw null; set => throw null; } +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_011() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I1 +{ + int I1.this[int i] { get => throw null; set => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_012() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidatePropertyReAbstraction_012(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_013() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +public interface I4 : I2, I3 +{ + int I1.this[int i] + { + get + { + System.Console.WriteLine(""I4.get_P1""); + return 0; + } + set => System.Console.WriteLine(""I4.set_P1""); + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + i1[0] = 1; + } +} +"; + ValidatePropertyReAbstraction_013(source1, source2, +@" +I4.get_P1 +I4.set_P1 +"); + } + + [Fact] + public void IndexerReAbstraction_014() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] + { + get + { + throw null; + } + set + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract + // get + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), + // (15,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract + // set + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(15, 9), + // (22,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(22, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_015() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] + { + get => throw null; + set => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract + // get => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), + // (12,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract + // set => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(12, 9), + // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(16, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_016() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + extern abstract int I1.this[int i] {get; set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_016(source1, + // (9,28): error CS0180: 'I2.I1.this[int]' cannot be both extern and abstract + // extern abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I2.I1.this[int]").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_017() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract public int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,28): error CS0106: The modifier 'public' is not valid for this item + // abstract public int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_018() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public class C2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), + // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35), + // (9,40): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 40) + ); + } + + [Fact] + public void IndexerReAbstraction_019() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public struct C2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), + // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35), + // (9,40): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 40) + ); + } + + [Fact] + public void IndexerReAbstraction_020() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].set' + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].set").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_021() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].get' + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].get").WithLocation(9, 21), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_022() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,40): error CS0550: 'I2.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.this[int].set", "I1.this[int]").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_023() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,35): error CS0550: 'I2.I1.this[int].get' adds an accessor not found in interface member 'I1.this[int]' + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.this[int].get", "I1.this[int]").WithLocation(9, 35), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_024() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get => throw null; private set => throw null;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,40): error CS0550: 'I2.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.this[int].set", "I1.this[int]").WithLocation(9, 40), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_025() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {private get => throw null; set => throw null;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,35): error CS0550: 'I2.I1.this[int].get' adds an accessor not found in interface member 'I1.this[int]' + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.this[int].get", "I1.this[int]").WithLocation(9, 35), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_026() + { + var source1 = +@" +public interface I1 +{ + internal int this[int i] {get => throw null; set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.this[int]' is inaccessible due to its protection level + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_027() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {internal get => throw null; set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.this[int].get' is inaccessible due to its protection level + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int].get").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_028() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get => throw null; internal set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.this[int].set' is inaccessible due to its protection level + // abstract int I1.this[int i] { get; set; } + Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int].set").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_037() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_038() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_039() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + } + + int I1.this[int i] + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_040() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + } + + int I1.this[int i] + { + get + { + System.Console.WriteLine(""Test1.get_P1""); + return 0; + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); + } + + [Fact] + public void IndexerReAbstraction_041() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_042() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_043() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I2 +{ + int I1.this[int i] + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_044() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I2 +{ + int I1.this[int i] + { + get + { + System.Console.WriteLine(""I3.get_P1""); + return 0; + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); + } + + [Fact] + public void IndexerReAbstraction_045() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_046() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + int I1.this[int i] { get => throw null; } +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_047() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I1 +{ + int I1.this[int i] { get => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_048() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidatePropertyReAbstraction_012(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_049() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { get => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {get;} +} + +public interface I4 : I2, I3 +{ + int I1.this[int i] + { + get + { + System.Console.WriteLine(""I4.get_P1""); + return 0; + } + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + _ = i1[0]; + } +} +"; + ValidatePropertyReAbstraction_013(source1, source2, "I4.get_P1"); + } + + [Fact] + public void IndexerReAbstraction_050() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] + { + get + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract + // get + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), + // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(18, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_051() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] + { + get => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract + // get => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), + // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(15, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_052() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] => throw null; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,36): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract + // abstract int I1.this[int i] => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "throw null").WithArguments("I2.I1.this[int].get").WithLocation(9, 36), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_053() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + extern abstract int I1.this[int i] {get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_016(source1, + // (9,28): error CS0180: 'I2.I1.this[int]' cannot be both extern and abstract + // extern abstract int I1.this[int i] {get;} + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I2.I1.this[int]").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_054() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract public int I1.this[int i] { get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,28): error CS0106: The modifier 'public' is not valid for this item + // abstract public int I1.this[int i] { get;} + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_055() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public class C2 : I1 +{ + abstract int I1.this[int i] { get; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), + // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35) + ); + } + + [Fact] + public void IndexerReAbstraction_056() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public struct C2 : I1 +{ + abstract int I1.this[int i] { get; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), + // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35) + ); + } + + [Fact] + public void IndexerReAbstraction_057() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].set' + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].set").WithLocation(9, 21), + // (9,35): error CS0550: 'I2.I1.this[int].get' adds an accessor not found in interface member 'I1.this[int]' + // abstract int I1.this[int i] { get; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.this[int].get", "I1.this[int]").WithLocation(9, 35), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_058() + { + var source1 = +@" +public interface I1 +{ + internal int this[int i] {get => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] { get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.this[int]' is inaccessible due to its protection level + // abstract int I1.this[int i] { get;} + Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_059() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_060() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_001(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_061() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1[0] = 1; + } + + int I1.this[int i] + { + set + { + System.Console.WriteLine(""Test1.set_P1""); + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_062() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var source2 = +@" +class Test1 : I2 +{ + static void Main() + { + I1 i1 = new Test1(); + i1[0] = 1; + } + + int I1.this[int i] + { + set + { + System.Console.WriteLine(""Test1.set_P1""); + } + } +} +"; + ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); + } + + [Fact] + public void IndexerReAbstraction_063() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_064() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I2 {} +"; + + var source2 = +@" +class Test1 : I3 +{ +} +"; + ValidatePropertyReAbstraction_005(source1, source2, + // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I3 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_065() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I2 +{ + int I1.this[int i] + { + set + { + System.Console.WriteLine(""I3.set_P1""); + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1[0] = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_066() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I2 +{ + int I1.this[int i] + { + set + { + System.Console.WriteLine(""I3.set_P1""); + } + } +} +"; + + var source2 = +@" +class Test1 : I3 +{ + static void Main() + { + I1 i1 = new Test1(); + i1[0] = 1; + } +} +"; + ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); + } + + [Fact] + public void IndexerReAbstraction_067() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_068() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + int I1.this[int i] { set => throw null; } +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_069() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I1 +{ + int I1.this[int i] { set => throw null; } +} +"; + + var source2 = +@" +class Test1 : I2, I3 +{ +} +"; + ValidatePropertyReAbstraction_009(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I2, I3 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_070() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I4 : I2, I3 {} +"; + + var source2 = +@" +class Test1 : I4 +{ +} +"; + ValidatePropertyReAbstraction_012(source1, source2, + new[] { + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) + }, + // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. + // class Test1 : I4 + Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) + ); + } + + [ConditionalFact(typeof(ClrOnly), Reason = ConditionalSkipReason.MonoDefaultInterfaceMethods)] + [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] + public void IndexerReAbstraction_071() + { + var source1 = +@" +public interface I1 +{ + int this[int i] { set => throw null; } +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I3 : I1 +{ + abstract int I1.this[int i] {set;} +} + +public interface I4 : I2, I3 +{ + int I1.this[int i] + { + set + { + System.Console.WriteLine(""I4.set_P1""); + } + } +} +"; + + var source2 = +@" +class Test1 : I4 +{ + static void Main() + { + I1 i1 = new Test1(); + i1[0] = 1; + } +} +"; + ValidatePropertyReAbstraction_013(source1, source2, "I4.set_P1"); + } + + [Fact] + public void IndexerReAbstraction_072() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] + { + set + { + throw null; + } + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract + // set + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(11, 9), + // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(18, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_073() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] + { + set => throw null; + } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (11,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract + // set => throw null; + Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(11, 9), + // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(15, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_074() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + extern abstract int I1.this[int i] {set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_016(source1, + // (9,28): error CS0180: 'I2.I1.this[int]' cannot be both extern and abstract + // extern abstract int I1.this[int i] {set;} + Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I2.I1.this[int]").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_075() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract public int I1.this[int i] { set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,28): error CS0106: The modifier 'public' is not valid for this item + // abstract public int I1.this[int i] { set;} + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(9, 28), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_076() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public class C2 : I1 +{ + abstract int I1.this[int i] { set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), + // (9,35): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 35) + ); + } + + [Fact] + public void IndexerReAbstraction_077() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public struct C2 : I1 +{ + abstract int I1.this[int i] { set; } +} +"; + ValidatePropertyReAbstraction_018(source1, + // (9,21): error CS0106: The modifier 'abstract' is not valid for this item + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), + // (9,35): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 35) + ); + } + + [Fact] + public void IndexerReAbstraction_078() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { set; } +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].get' + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].get").WithLocation(9, 21), + // (9,35): error CS0550: 'I2.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' + // abstract int I1.this[int i] { set; } + Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.this[int].set", "I1.this[int]").WithLocation(9, 35), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_079() + { + var source1 = +@" +public interface I1 +{ + internal int this[int i] {set => throw null;} +} +"; + var source2 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] { set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_026(source1, source2, + // (4,21): error CS0122: 'I1.this[int]' is inaccessible due to its protection level + // abstract int I1.this[int i] { set;} + Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(4, 21), + // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_080() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; set; } = 0; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,47): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // abstract int I1.this[int i] { get; set; } = 0; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(9, 47), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_081() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { get; } = 0; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,42): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // abstract int I1.this[int i] { get; } = 0; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(9, 42), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_082() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] { set; } = 0; +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_014(source1, + // (9,42): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // abstract int I1.this[int i] { set; } = 0; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(9, 42), + // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' + // class Test1 : I2 + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) + ); + } + + [Fact] + public void IndexerReAbstraction_083() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (8,21): error CS0539: 'I2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("I2.this[int]").WithLocation(8, 21) + ); + } + + [Fact] + public void IndexerReAbstraction_084() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), + // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) + ); + } + + [Fact] + public void IndexerReAbstraction_085() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (8,21): error CS0539: 'I2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract int I1.this[int i] {get;} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("I2.this[int]").WithLocation(8, 21) + ); + } + + [Fact] + public void IndexerReAbstraction_086() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract int I1.this[int i] {get;} + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), + // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract int I1.this[int i] {get;} + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) + ); + } + + [Fact] + public void IndexerReAbstraction_087() + { + var source1 = +@" +public interface I1 +{ +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (8,21): error CS0539: 'I2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented + // abstract int I1.this[int i] {set;} + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("I2.this[int]").WithLocation(8, 21) + ); + } + + [Fact] + public void IndexerReAbstraction_088() + { + var source1 = +@" +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} + +class Test1 : I2 +{ +} +"; + ValidatePropertyReAbstraction_083(source1, + // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // public interface I2 : I1 + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), + // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) + // abstract int I1.this[int i] {set;} + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), + // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface + // abstract int I1.this[int i] {set;} + Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) + ); + } + + [Fact] + public void IndexerReAbstraction_089() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get; set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get; set;} +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,34): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("default interface implementation").WithLocation(9, 34), + // (9,39): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("default interface implementation").WithLocation(9, 39) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,34): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 34), + // (9,39): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.this[int i] {get; set;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 39) + ); + } + + [Fact] + public void IndexerReAbstraction_090() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {get;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {get;} +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,34): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.this[int i] {get;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("default interface implementation").WithLocation(9, 34) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,34): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.this[int i] {get;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 34) + ); + } + + [Fact] + public void IndexerReAbstraction_091() + { + var source1 = +@" +public interface I1 +{ + int this[int i] {set;} +} + +public interface I2 : I1 +{ + abstract int I1.this[int i] {set;} +} +"; + + var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular7_3, + targetFramework: TargetFramework.NetStandardLatest); + compilation1.VerifyDiagnostics( + // (9,34): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // abstract int I1.this[int i] {set;} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("default interface implementation").WithLocation(9, 34) + ); + + var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, + parseOptions: TestOptions.Regular, + targetFramework: TargetFramework.DesktopLatestExtended); + compilation2.VerifyDiagnostics( + // (9,34): error CS8701: Target runtime doesn't support default interface implementation. + // abstract int I1.this[int i] {set;} + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 34) + ); + } + } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs index f1b90fd65d408..912321eb67b89 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs @@ -2145,10 +2145,7 @@ public void InvalidEventDeclarations() Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "System.IFormattable").WithArguments(".", "System.IFormattable").WithLocation(1, 21), // (1,41): error CS0539: '.' in explicit interface declaration is not a member of interface // event System.Action System.IFormattable. - Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "").WithArguments(".").WithLocation(1, 41), - // (1,41): error CS0065: '.': event property must have both add and remove accessors - // event System.Action System.IFormattable. - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "").WithArguments(".").WithLocation(1, 41)); + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "").WithArguments(".").WithLocation(1, 41)); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/PropertyTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/PropertyTests.cs index 4159771b18e8e..c81c861c794e7 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/PropertyTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/PropertyTests.cs @@ -262,9 +262,9 @@ public void AutoInitializerInInterface() var comp = CreateCompilation(text, parseOptions: TestOptions.Regular); comp.VerifyDiagnostics( - // (3,9): error CS8035: Auto-implemented properties inside interfaces cannot have initializers. + // (3,9): error CS8050: Only auto-implemented properties can have initializers. // int P { get; } = 0; - Diagnostic(ErrorCode.ERR_AutoPropertyInitializerInInterface, "P").WithArguments("I.P").WithLocation(3, 9)); + Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P").WithArguments("I.P").WithLocation(3, 9)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs index ac66f03f9c7a6..4f1d3edabf817 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs @@ -913,21 +913,15 @@ public interface I1 } "; CreateCompilation(text).VerifyDiagnostics( - // (6,27): error CS0071: An explicit interface implementation of an event must use event accessor syntax + // (6,28): error CS0071: An explicit interface implementation of an event must use event accessor syntax // event System.Action I2.P10; - Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(6, 27), - // (6,31): error CS1519: Invalid token ';' in class, struct, or interface member declaration - // event System.Action I2.P10; - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(6, 31), + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "P10").WithLocation(6, 28), // (6,25): error CS0540: 'I1.P10': containing type does not implement interface 'I2' // event System.Action I2.P10; Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I2").WithArguments("I1.P10", "I2").WithLocation(6, 25), // (6,28): error CS0539: 'I1.P10' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I2.P10; - Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P10").WithArguments("I1.P10").WithLocation(6, 28), - // (6,28): error CS0065: 'I1.P10': event property must have both add and remove accessors - // event System.Action I2.P10; - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P10").WithArguments("I1.P10").WithLocation(6, 28) + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P10").WithArguments("I1.P10").WithLocation(6, 28) ); } @@ -947,18 +941,12 @@ event System.Action I2. // (6,25): error CS0540: 'I1.P10': containing type does not implement interface 'I2' // event System.Action I2. Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I2").WithArguments("I1.P10", "I2").WithLocation(6, 25), - // (6,27): error CS0071: An explicit interface implementation of an event must use event accessor syntax - // event System.Action I2. - Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(6, 27), - // (7,4): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // (7,1): error CS0071: An explicit interface implementation of an event must use event accessor syntax // P10; - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 4), + Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "P10").WithLocation(7, 1), // (7,1): error CS0539: 'I1.P10' in explicit interface declaration is not found among members of the interface that can be implemented // P10; - Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P10").WithArguments("I1.P10").WithLocation(7, 1), - // (7,1): error CS0065: 'I1.P10': event property must have both add and remove accessors - // P10; - Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P10").WithArguments("I1.P10").WithLocation(7, 1) + Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P10").WithArguments("I1.P10").WithLocation(7, 1) ); } @@ -7829,18 +7817,12 @@ public abstract event System.Action E { add { } remove { } } // (8,57): error CS0500: 'clx.P.set' cannot declare a body because it is marked abstract // public abstract object P { get { return null; } set { } } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("NS.clx.P.set").WithLocation(8, 57), - // (9,49): error CS0500: 'clx.E.add' cannot declare a body because it is marked abstract + // (9,47): error CS8712: 'clx.E': abstract event cannot use event accessor syntax // public abstract event System.Action E { add { } remove { } } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("NS.clx.E.add").WithLocation(9, 49), - // (9,57): error CS0500: 'clx.E.remove' cannot declare a body because it is marked abstract - // public abstract event System.Action E { add { } remove { } } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("NS.clx.E.remove").WithLocation(9, 57), - // (10,49): error CS0500: 'clx.X.add' cannot declare a body because it is marked abstract - // public abstract event System.Action X { add => throw null; remove => throw null; } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "add").WithArguments("NS.clx.X.add").WithLocation(10, 49), - // (10,68): error CS0500: 'clx.X.remove' cannot declare a body because it is marked abstract + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("NS.clx.E").WithLocation(9, 47), + // (10,47): error CS8712: 'clx.X': abstract event cannot use event accessor syntax // public abstract event System.Action X { add => throw null; remove => throw null; } - Diagnostic(ErrorCode.ERR_AbstractHasBody, "remove").WithArguments("NS.clx.X.remove").WithLocation(10, 68)); + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("NS.clx.X").WithLocation(10, 47)); var ns = comp.SourceModule.GlobalNamespace.GetMembers("NS").Single() as NamespaceSymbol; // TODO... @@ -9544,7 +9526,7 @@ interface IFace2 : IFace } } "; - CreateCompilation(text, parseOptions: TestOptions.Regular7).VerifyDiagnostics( + CreateCompilation(text, parseOptions: TestOptions.Regular7, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( // (11,20): error CS8652: The feature 'default interface implementation' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // void IFace.F(); // CS0541 Diagnostic(ErrorCode.ERR_FeatureInPreview, "F").WithArguments("default interface implementation").WithLocation(11, 20), diff --git a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs index 468f936db5429..793a0329aedcb 100644 --- a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs +++ b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs @@ -507,7 +507,7 @@ private static Syntax.InternalSyntax.ArrowExpressionClauseSyntax GenerateArrowEx => InternalSyntaxFactory.ArrowExpressionClause(InternalSyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken), GenerateIdentifierName()); private static Syntax.InternalSyntax.EventDeclarationSyntax GenerateEventDeclaration() - => InternalSyntaxFactory.EventDeclaration(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.EventKeyword), GenerateIdentifierName(), null, InternalSyntaxFactory.Identifier("Identifier"), GenerateAccessorList()); + => InternalSyntaxFactory.EventDeclaration(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.EventKeyword), GenerateIdentifierName(), null, InternalSyntaxFactory.Identifier("Identifier"), null, null); private static Syntax.InternalSyntax.IndexerDeclarationSyntax GenerateIndexerDeclaration() => InternalSyntaxFactory.IndexerDeclaration(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), GenerateIdentifierName(), null, InternalSyntaxFactory.Token(SyntaxKind.ThisKeyword), GenerateBracketedParameterList(), null, null, null); @@ -2745,7 +2745,8 @@ public void TestEventDeclarationFactoryAndProperties() Assert.NotNull(node.Type); Assert.Null(node.ExplicitInterfaceSpecifier); Assert.Equal(SyntaxKind.IdentifierToken, node.Identifier.Kind); - Assert.NotNull(node.AccessorList); + Assert.Null(node.AccessorList); + Assert.Null(node.SemicolonToken); AttachAndCheckDiagnostics(node); } @@ -9481,7 +9482,7 @@ private static ArrowExpressionClauseSyntax GenerateArrowExpressionClause() => SyntaxFactory.ArrowExpressionClause(SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken), GenerateIdentifierName()); private static EventDeclarationSyntax GenerateEventDeclaration() - => SyntaxFactory.EventDeclaration(new SyntaxList(), new SyntaxTokenList(), SyntaxFactory.Token(SyntaxKind.EventKeyword), GenerateIdentifierName(), default(ExplicitInterfaceSpecifierSyntax), SyntaxFactory.Identifier("Identifier"), GenerateAccessorList()); + => SyntaxFactory.EventDeclaration(new SyntaxList(), new SyntaxTokenList(), SyntaxFactory.Token(SyntaxKind.EventKeyword), GenerateIdentifierName(), default(ExplicitInterfaceSpecifierSyntax), SyntaxFactory.Identifier("Identifier"), default(AccessorListSyntax), default(SyntaxToken)); private static IndexerDeclarationSyntax GenerateIndexerDeclaration() => SyntaxFactory.IndexerDeclaration(new SyntaxList(), new SyntaxTokenList(), GenerateIdentifierName(), default(ExplicitInterfaceSpecifierSyntax), SyntaxFactory.Token(SyntaxKind.ThisKeyword), GenerateBracketedParameterList(), default(AccessorListSyntax), default(ArrowExpressionClauseSyntax), default(SyntaxToken)); @@ -11719,8 +11720,9 @@ public void TestEventDeclarationFactoryAndProperties() Assert.NotNull(node.Type); Assert.Null(node.ExplicitInterfaceSpecifier); Assert.Equal(SyntaxKind.IdentifierToken, node.Identifier.Kind()); - Assert.NotNull(node.AccessorList); - var newNode = node.WithAttributeLists(node.AttributeLists).WithModifiers(node.Modifiers).WithEventKeyword(node.EventKeyword).WithType(node.Type).WithExplicitInterfaceSpecifier(node.ExplicitInterfaceSpecifier).WithIdentifier(node.Identifier).WithAccessorList(node.AccessorList); + Assert.Null(node.AccessorList); + Assert.Equal(SyntaxKind.None, node.SemicolonToken.Kind()); + var newNode = node.WithAttributeLists(node.AttributeLists).WithModifiers(node.Modifiers).WithEventKeyword(node.EventKeyword).WithType(node.Type).WithExplicitInterfaceSpecifier(node.ExplicitInterfaceSpecifier).WithIdentifier(node.Identifier).WithAccessorList(node.AccessorList).WithSemicolonToken(node.SemicolonToken); Assert.Equal(node, newNode); } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs index b08b705a6d2d6..16eb9f218429c 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs @@ -6040,11 +6040,7 @@ public interface I1 N(SyntaxKind.DotToken); } N(SyntaxKind.IdentifierToken, "P10"); - M(SyntaxKind.AccessorList); - { - M(SyntaxKind.OpenBraceToken); - M(SyntaxKind.CloseBraceToken); - } + N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } @@ -6104,11 +6100,7 @@ event System.Action I2. N(SyntaxKind.DotToken); } N(SyntaxKind.IdentifierToken, "P10"); - M(SyntaxKind.AccessorList); - { - M(SyntaxKind.OpenBraceToken); - M(SyntaxKind.CloseBraceToken); - } + N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index cf657df5e04af..5be24025ce9b0 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -80,12 +80,9 @@ abstract class A // (5,33): error CS0073: An add or remove accessor must have a body // event Action E { add; remove; } Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";"), - // (9,41): error CS0073: An add or remove accessor must have a body + // (9,36): error CS8712: 'A.E': abstract event cannot use event accessor syntax // public abstract event Action E { add; remove; } - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";"), - // (9,49): error CS0073: An add or remove accessor must have a body - // public abstract event Action E { add; remove; } - Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";")); + Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("A.E").WithLocation(9, 36)); } [Fact] diff --git a/src/Compilers/Core/MSBuildTask/Microsoft.Build.Tasks.CodeAnalysis.csproj b/src/Compilers/Core/MSBuildTask/Microsoft.Build.Tasks.CodeAnalysis.csproj index 80f49b3a68c70..0efb1b2363aae 100644 --- a/src/Compilers/Core/MSBuildTask/Microsoft.Build.Tasks.CodeAnalysis.csproj +++ b/src/Compilers/Core/MSBuildTask/Microsoft.Build.Tasks.CodeAnalysis.csproj @@ -8,6 +8,7 @@ en-US $(RoslynPortableTargetFrameworks) true + $(NoWarn);CA1819 diff --git a/src/Compilers/Core/MSBuildTask/Microsoft.Managed.EditorConfig.targets b/src/Compilers/Core/MSBuildTask/Microsoft.Managed.EditorConfig.targets index 2d3a2707dcd65..eef7b463f66af 100644 --- a/src/Compilers/Core/MSBuildTask/Microsoft.Managed.EditorConfig.targets +++ b/src/Compilers/Core/MSBuildTask/Microsoft.Managed.EditorConfig.targets @@ -1,4 +1,4 @@ - + @@ -9,8 +9,11 @@ - + <_AllDirectoriesAbove Include="@(Compile->GetPathsOfAllDirectoriesAbove())" Condition="'$(DiscoverEditorConfigFiles)' != 'false'" /> + + - - \ No newline at end of file + + diff --git a/src/Compilers/Core/MSBuildTask/xlf/ErrorString.tr.xlf b/src/Compilers/Core/MSBuildTask/xlf/ErrorString.tr.xlf index b3a57a1232880..2e5b9b3f7a53b 100644 --- a/src/Compilers/Core/MSBuildTask/xlf/ErrorString.tr.xlf +++ b/src/Compilers/Core/MSBuildTask/xlf/ErrorString.tr.xlf @@ -60,7 +60,8 @@ Failed to check the content hash of the source ref assembly '{0}': {1} {2} - Kaynak ürün kodu derleme '{0}' içerik karma denetlemek başarısız oldu: {1} (2) + Failed to check the content hash of the source ref assembly '{0}': {1} +{2} diff --git a/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs b/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs index 2aaa155653a5d..10b11e0387224 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs @@ -52,5 +52,20 @@ internal static T[] GetValues() where T : struct { return (T[])Enum.GetValues(typeof(T)); } + +#if DEBUG + internal static bool ContainsAllValues(int mask) where T : struct, Enum, IConvertible + { + foreach (T value in GetValues()) + { + int val = value.ToInt32(null); + if ((val & mask) != val) + { + return false; + } + } + return true; + } +#endif } } diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 09e240947f046..cd14db46b1b2d 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1080,6 +1080,22 @@ internal ObsoleteAttributeData TryGetDeprecatedOrExperimentalOrObsoleteAttribute return null; } + internal bool HasMaybeNullWhenOrNotNullWhenAttribute(EntityHandle token, AttributeDescription description, out bool when) + { + Debug.Assert(description.Namespace == "System.Runtime.CompilerServices"); + Debug.Assert(description.Name == "MaybeNullWhenAttribute" || description.Name == "NotNullWhenAttribute"); + + AttributeInfo info = FindTargetAttribute(token, description); + if (info.HasValue && + // MaybeNullWhen(bool), NotNullWhen(bool) + info.SignatureIndex == 0) + { + return TryExtractValueFromAttribute(info.Handle, out when, s_attributeBooleanValueExtractor); + } + when = false; + return false; + } + internal CustomAttributeHandle GetAttributeUsageAttributeHandle(EntityHandle token) { AttributeInfo info = FindTargetAttribute(token, AttributeDescription.AttributeUsageAttribute); diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs index 57a0094d9ad87..90163a74ff3c0 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs @@ -260,9 +260,12 @@ static AttributeDescription() private static readonly byte[][] s_signaturesOfOutAttribute = { s_signature_HasThis_Void }; private static readonly byte[][] s_signaturesOfIsReadOnlyAttribute = { s_signature_HasThis_Void }; private static readonly byte[][] s_signaturesOfIsUnmanagedAttribute = { s_signature_HasThis_Void }; - private static readonly byte[][] s_signaturesOfNotNullWhenTrueAttribute = { s_signature_HasThis_Void }; - private static readonly byte[][] s_signaturesOfNotNullWhenFalseAttribute = { s_signature_HasThis_Void }; - private static readonly byte[][] s_signaturesOfEnsuresNotNullAttribute = { s_signature_HasThis_Void }; + private static readonly byte[][] s_signaturesOfAllowNullAttribute = { s_signature_HasThis_Void }; + private static readonly byte[][] s_signaturesOfDisallowNullAttribute = { s_signature_HasThis_Void }; + private static readonly byte[][] s_signaturesOfMaybeNullAttribute = { s_signature_HasThis_Void }; + private static readonly byte[][] s_signaturesOfMaybeNullWhenAttribute = { s_signature_HasThis_Void_Boolean }; + private static readonly byte[][] s_signaturesOfNotNullAttribute = { s_signature_HasThis_Void }; + private static readonly byte[][] s_signaturesOfNotNullWhenAttribute = { s_signature_HasThis_Void_Boolean }; private static readonly byte[][] s_signaturesOfAssertsTrueAttribute = { s_signature_HasThis_Void }; private static readonly byte[][] s_signaturesOfAssertsFalseAttribute = { s_signature_HasThis_Void }; private static readonly byte[][] s_signaturesOfFixedBufferAttribute = { s_signature_HasThis_Void_Type_Int32 }; @@ -461,9 +464,12 @@ static AttributeDescription() internal static readonly AttributeDescription StructLayoutAttribute = new AttributeDescription("System.Runtime.InteropServices", "StructLayoutAttribute", s_signaturesOfStructLayoutAttribute); internal static readonly AttributeDescription FieldOffsetAttribute = new AttributeDescription("System.Runtime.InteropServices", "FieldOffsetAttribute", s_signaturesOfFieldOffsetAttribute); internal static readonly AttributeDescription FixedBufferAttribute = new AttributeDescription("System.Runtime.CompilerServices", "FixedBufferAttribute", s_signaturesOfFixedBufferAttribute); - internal static readonly AttributeDescription NotNullWhenTrueAttribute = new AttributeDescription("System.Runtime.CompilerServices", "NotNullWhenTrueAttribute", s_signaturesOfNotNullWhenTrueAttribute); - internal static readonly AttributeDescription NotNullWhenFalseAttribute = new AttributeDescription("System.Runtime.CompilerServices", "NotNullWhenFalseAttribute", s_signaturesOfNotNullWhenFalseAttribute); - internal static readonly AttributeDescription EnsuresNotNullAttribute = new AttributeDescription("System.Runtime.CompilerServices", "EnsuresNotNullAttribute", s_signaturesOfEnsuresNotNullAttribute); + internal static readonly AttributeDescription AllowNullAttribute = new AttributeDescription("System.Runtime.CompilerServices", "AllowNullAttribute", s_signaturesOfAllowNullAttribute); + internal static readonly AttributeDescription DisallowNullAttribute = new AttributeDescription("System.Runtime.CompilerServices", "DisallowNullAttribute", s_signaturesOfDisallowNullAttribute); + internal static readonly AttributeDescription MaybeNullAttribute = new AttributeDescription("System.Runtime.CompilerServices", "MaybeNullAttribute", s_signaturesOfMaybeNullAttribute); + internal static readonly AttributeDescription MaybeNullWhenAttribute = new AttributeDescription("System.Runtime.CompilerServices", "MaybeNullWhenAttribute", s_signaturesOfMaybeNullWhenAttribute); + internal static readonly AttributeDescription NotNullAttribute = new AttributeDescription("System.Runtime.CompilerServices", "NotNullAttribute", s_signaturesOfNotNullAttribute); + internal static readonly AttributeDescription NotNullWhenAttribute = new AttributeDescription("System.Runtime.CompilerServices", "NotNullWhenAttribute", s_signaturesOfNotNullWhenAttribute); internal static readonly AttributeDescription AssertsTrueAttribute = new AttributeDescription("System.Runtime.CompilerServices", "AssertsTrueAttribute", s_signaturesOfAssertsTrueAttribute); internal static readonly AttributeDescription AssertsFalseAttribute = new AttributeDescription("System.Runtime.CompilerServices", "AssertsFalseAttribute", s_signaturesOfAssertsFalseAttribute); internal static readonly AttributeDescription MarshalAsAttribute = new AttributeDescription("System.Runtime.InteropServices", "MarshalAsAttribute", s_signaturesOfMarshalAsAttribute); diff --git a/src/Compilers/Core/Portable/Symbols/TypedConstant.cs b/src/Compilers/Core/Portable/Symbols/TypedConstant.cs index af9522f79f2e5..3af7e9b4d3bea 100644 --- a/src/Compilers/Core/Portable/Symbols/TypedConstant.cs +++ b/src/Compilers/Core/Portable/Symbols/TypedConstant.cs @@ -99,19 +99,28 @@ public ImmutableArray Values } internal T DecodeValue(SpecialType specialType) + { + TryDecodeValue(specialType, out T value); + return value; + } + + internal bool TryDecodeValue(SpecialType specialType, out T value) { if (_kind == TypedConstantKind.Error) { - return default(T); + value = default(T); + return false; } if (_type.SpecialType == specialType || (_type.TypeKind == TypeKind.Enum && specialType == SpecialType.System_Enum)) { - return (T)_value; + value = (T)_value; + return true; } // the actual argument type doesn't match the type of the parameter - an error has already been reported by the binder - return default(T); + value = default(T); + return false; } /// diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 167fe31b973b7..2c6b8afd8c2cc 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -17,7 +17,6 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.FlowAnalysis; -using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; @@ -52,38 +51,62 @@ public NullableAttribute(byte[] transformFlags) } "; - protected const string NotNullWhenTrueAttributeDefinition = @" + protected const string AllowNullAttributeDefinition = @" namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Parameter, - AllowMultiple = false)] - public class NotNullWhenTrueAttribute : Attribute + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)] + public sealed class AllowNullAttribute : Attribute + { + } +}"; + + protected const string DisallowNullAttributeDefinition = @" +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)] + public sealed class DisallowNullAttribute : Attribute + { + } +}"; + + protected const string MaybeNullAttributeDefinition = @" +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)] + public sealed class MaybeNullAttribute : Attribute { - public NotNullWhenTrueAttribute() { } } } "; - protected const string NotNullWhenFalseAttributeDefinition = @" + protected const string MaybeNullWhenAttributeDefinition = @" namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Parameter, - AllowMultiple = false)] - public class NotNullWhenFalseAttribute : Attribute + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class MaybeNullWhenAttribute : Attribute { - public NotNullWhenFalseAttribute() { } + public MaybeNullWhenAttribute(bool when) { } } } "; - protected const string EnsuresNotNullAttributeDefinition = @" + protected const string NotNullAttributeDefinition = @" namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Parameter, - AllowMultiple = false)] - public class EnsuresNotNullAttribute : Attribute + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)] + public sealed class NotNullAttribute : Attribute + { + } +} +"; + + protected const string NotNullWhenAttributeDefinition = @" +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class NotNullWhenAttribute : Attribute { - public EnsuresNotNullAttribute() { } + public NotNullWhenAttribute(bool when) { } } } "; diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf index 94e7a079ba40b..7e971d1a3121f 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf @@ -183,7 +183,7 @@ -vbruntime:<file> Compile with the alternate Visual Basic runtime in <file>. - Visual Basic Derleyici Seçenekleri + Visual Basic Derleyici Seçenekleri - ÇIKIŞ DOSYASI - -out:<file> Çıkış dosyası adını belirtir. @@ -331,7 +331,7 @@ veya anycpu (varsayılan) olmalıdır. -preferreduilang Tercih edilen çıkış dilini belirt. -nosdkpath Standart kitaplık bütünleştirilmiş kodlarında varsayılan SDK yolunu - aramayı devre dışı bırakın. + aramayı devre dışı bırakın. -sdkpath:<path> .NET Framework SDK (mscorlib.dll) dizininin konumu. -subsystemversion:<version> Çıkış PE'nin alt sistem sürümünü belirt. diff --git a/src/EditorFeatures/CSharp.Wpf/Completion/CompletionProviders/CSharpReplCommandCompletionProvider.cs b/src/EditorFeatures/CSharp.Wpf/Completion/CompletionProviders/CSharpReplCommandCompletionProvider.cs index bfd24f8ec46c1..5e31f39179002 100644 --- a/src/EditorFeatures/CSharp.Wpf/Completion/CompletionProviders/CSharpReplCommandCompletionProvider.cs +++ b/src/EditorFeatures/CSharp.Wpf/Completion/CompletionProviders/CSharpReplCommandCompletionProvider.cs @@ -1,6 +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.ComponentModel.Composition; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -22,6 +23,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.Completion.CompletionProviders [Order(Before = PredefinedCompletionProviderNames.Keyword)] internal class CSharpReplCommandCompletionProvider : ReplCompletionProvider { + [ImportingConstructor] + public CSharpReplCommandCompletionProvider() + { + } + protected override string GetCompletionString(string commandName) { return commandName; diff --git a/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/LoadDirectiveCompletionProvider.cs b/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/LoadDirectiveCompletionProvider.cs index dfbd9bcf9b6a6..999137d18ad1a 100644 --- a/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/LoadDirectiveCompletionProvider.cs +++ b/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/LoadDirectiveCompletionProvider.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.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.Completion.FileSystem; @@ -15,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.Completion.FileSystem [TextViewRole(PredefinedInteractiveTextViewRoles.InteractiveTextViewRole)] internal sealed class LoadDirectiveCompletionProvider : AbstractLoadDirectiveCompletionProvider { + [ImportingConstructor] + public LoadDirectiveCompletionProvider() + { + } + protected override bool TryGetStringLiteralToken(SyntaxTree tree, int position, out SyntaxToken stringLiteral, CancellationToken cancellationToken) => DirectiveCompletionProviderUtilities.TryGetStringLiteralToken(tree, position, SyntaxKind.LoadDirectiveTrivia, out stringLiteral, cancellationToken); } diff --git a/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/ReferenceDirectiveCompletionProvider.cs b/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/ReferenceDirectiveCompletionProvider.cs index a1b1f14acca27..c54e4806c565a 100644 --- a/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/ReferenceDirectiveCompletionProvider.cs +++ b/src/EditorFeatures/CSharp.Wpf/Completion/FileSystem/ReferenceDirectiveCompletionProvider.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.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.Completion.FileSystem; @@ -16,6 +17,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.Completion.FileSystem [TextViewRole(PredefinedInteractiveTextViewRoles.InteractiveTextViewRole)] internal sealed class ReferenceDirectiveCompletionProvider : AbstractReferenceDirectiveCompletionProvider { + [ImportingConstructor] + public ReferenceDirectiveCompletionProvider() + { + } + protected override bool TryGetStringLiteralToken(SyntaxTree tree, int position, out SyntaxToken stringLiteral, CancellationToken cancellationToken) => DirectiveCompletionProviderUtilities.TryGetStringLiteralToken(tree, position, SyntaxKind.ReferenceDirectiveTrivia, out stringLiteral, cancellationToken); } diff --git a/src/EditorFeatures/CSharp.Wpf/Interactive/CSharpSendToInteractiveSubmissionProvider.cs b/src/EditorFeatures/CSharp.Wpf/Interactive/CSharpSendToInteractiveSubmissionProvider.cs index 44e13e40cbf55..aa1cfd4156650 100644 --- a/src/EditorFeatures/CSharp.Wpf/Interactive/CSharpSendToInteractiveSubmissionProvider.cs +++ b/src/EditorFeatures/CSharp.Wpf/Interactive/CSharpSendToInteractiveSubmissionProvider.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.Interactive internal sealed class CSharpSendToInteractiveSubmissionProvider : AbstractSendToInteractiveSubmissionProvider { + [ImportingConstructor] + public CSharpSendToInteractiveSubmissionProvider() + { + } + protected override bool CanParseSubmission(string code) { ParseOptions options = CSharpParseOptions.Default.WithKind(SourceCodeKind.Script); diff --git a/src/EditorFeatures/CSharp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs b/src/EditorFeatures/CSharp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs index 0f379db1db066..005550e5cf09b 100644 --- a/src/EditorFeatures/CSharp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs +++ b/src/EditorFeatures/CSharp/BlockCommentEditing/CloseBlockCommentCommandHandler.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BlockCommentEditing [Order(After = nameof(BlockCommentEditingCommandHandler))] internal sealed class CloseBlockCommentCommandHandler : VSCommanding.ICommandHandler { + [ImportingConstructor] + public CloseBlockCommentCommandHandler() + { + } + public string DisplayName => EditorFeaturesResources.Block_Comment_Editing; public bool ExecuteCommand(TypeCharCommandArgs args, VSCommanding.CommandExecutionContext executionContext) diff --git a/src/EditorFeatures/CSharp/BraceMatching/CSharpDirectiveTriviaBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/CSharpDirectiveTriviaBraceMatcher.cs index 184b15df7d31f..2003a30a7fd3d 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/CSharpDirectiveTriviaBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/CSharpDirectiveTriviaBraceMatcher.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions; @@ -15,6 +16,11 @@ internal class CSharpDirectiveTriviaBraceMatcher : AbstractDirectiveTriviaBraceM ElseDirectiveTriviaSyntax, EndIfDirectiveTriviaSyntax, RegionDirectiveTriviaSyntax, EndRegionDirectiveTriviaSyntax> { + [ImportingConstructor] + public CSharpDirectiveTriviaBraceMatcher() + { + } + internal override List GetMatchingConditionalDirectives(DirectiveTriviaSyntax directive, CancellationToken cancellationToken) => directive.GetMatchingConditionalDirectives(cancellationToken)?.ToList(); diff --git a/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs index 16c2c9dbf197c..79bb666b8b5c1 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.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.ComponentModel.Composition; using Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching @@ -7,5 +8,9 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching [ExportBraceMatcher(LanguageNames.CSharp)] internal class CSharpEmbeddedLanguageBraceMatcher : AbstractEmbeddedLanguageBraceMatcher { + [ImportingConstructor] + public CSharpEmbeddedLanguageBraceMatcher() + { + } } } diff --git a/src/EditorFeatures/CSharp/BraceMatching/LessThanGreaterThanBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/LessThanGreaterThanBraceMatcher.cs index 0cff74b8c9d08..4f276593abe31 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/LessThanGreaterThanBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/LessThanGreaterThanBraceMatcher.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.ComponentModel.Composition; using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching @@ -7,6 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching [ExportBraceMatcher(LanguageNames.CSharp)] internal class LessThanGreaterThanBraceMatcher : AbstractCSharpBraceMatcher { + [ImportingConstructor] public LessThanGreaterThanBraceMatcher() : base(SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) { diff --git a/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBraceBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBraceBraceMatcher.cs index 96e9cdca58b41..b55d146fef5a6 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBraceBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBraceBraceMatcher.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.ComponentModel.Composition; using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching @@ -7,6 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching [ExportBraceMatcher(LanguageNames.CSharp)] internal class OpenCloseBraceBraceMatcher : AbstractCSharpBraceMatcher { + [ImportingConstructor] public OpenCloseBraceBraceMatcher() : base(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken) { diff --git a/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBracketBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBracketBraceMatcher.cs index 031993260362f..6cb6e13925bc4 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBracketBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/OpenCloseBracketBraceMatcher.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.ComponentModel.Composition; using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching @@ -7,6 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching [ExportBraceMatcher(LanguageNames.CSharp)] internal class OpenCloseBracketBraceMatcher : AbstractCSharpBraceMatcher { + [ImportingConstructor] public OpenCloseBracketBraceMatcher() : base(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken) { diff --git a/src/EditorFeatures/CSharp/BraceMatching/OpenCloseParenBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/OpenCloseParenBraceMatcher.cs index 4d1449143eff2..65951f3eaeae4 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/OpenCloseParenBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/OpenCloseParenBraceMatcher.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.ComponentModel.Composition; using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching @@ -7,6 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching [ExportBraceMatcher(LanguageNames.CSharp)] internal class OpenCloseParenBraceMatcher : AbstractCSharpBraceMatcher { + [ImportingConstructor] public OpenCloseParenBraceMatcher() : base(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken) { diff --git a/src/EditorFeatures/CSharp/BraceMatching/StringLiteralBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/StringLiteralBraceMatcher.cs index 2da2aee06f999..e0040527dc5cb 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/StringLiteralBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/StringLiteralBraceMatcher.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.ComponentModel.Composition; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp; @@ -12,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching [ExportBraceMatcher(LanguageNames.CSharp)] internal class StringLiteralBraceMatcher : IBraceMatcher { + [ImportingConstructor] + public StringLiteralBraceMatcher() + { + } + public async Task FindBracesAsync(Document document, int position, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs b/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs index 7c3674ceb9829..844d4fd35e2dc 100644 --- a/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs @@ -12,5 +12,9 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.ChangeSignature [Name(PredefinedCommandHandlerNames.ChangeSignature)] internal class CSharpChangeSignatureCommandHandler : AbstractChangeSignatureCommandHandler { + [ImportingConstructor] + public CSharpChangeSignatureCommandHandler() + { + } } } diff --git a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs index 197c516c0ffe7..dc8b055c5577d 100644 --- a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs +++ b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.DecompiledSource [ExportLanguageServiceFactory(typeof(IDecompiledSourceService), LanguageNames.CSharp), Shared] internal partial class CSharpDecompiledSourceServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpDecompiledSourceServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices provider) { return new CSharpDecompiledSourceService(provider); diff --git a/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpEmbeddedLanguageEditorFeaturesProvider.cs b/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpEmbeddedLanguageEditorFeaturesProvider.cs index 9f3566dec62eb..4c9e8eceb901e 100644 --- a/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpEmbeddedLanguageEditorFeaturesProvider.cs +++ b/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpEmbeddedLanguageEditorFeaturesProvider.cs @@ -14,6 +14,7 @@ internal class CSharpEmbeddedLanguageEditorFeaturesProvider : AbstractEmbeddedLa { public static IEmbeddedLanguageFeaturesProvider Instance = new CSharpEmbeddedLanguageEditorFeaturesProvider(); + [ImportingConstructor] public CSharpEmbeddedLanguageEditorFeaturesProvider() : base(CSharpEmbeddedLanguagesProvider.Info) { } diff --git a/src/EditorFeatures/CSharp/EndConstruct/CSharpEndConstructGenerationService.cs b/src/EditorFeatures/CSharp/EndConstruct/CSharpEndConstructGenerationService.cs index d9e1c0fa29e2c..9f64afa507e9b 100644 --- a/src/EditorFeatures/CSharp/EndConstruct/CSharpEndConstructGenerationService.cs +++ b/src/EditorFeatures/CSharp/EndConstruct/CSharpEndConstructGenerationService.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.EndConstructGeneration [ExcludeFromCodeCoverage] internal class CSharpEndConstructGenerationService : IEndConstructGenerationService { + [ImportingConstructor] + public CSharpEndConstructGenerationService() + { + } + public bool TryDo( ITextView textView, ITextBuffer subjectBuffer, diff --git a/src/EditorFeatures/CSharp/FixInterpolatedVerbatimString/FixInterpolatedVerbatimStringCommandHandler.cs b/src/EditorFeatures/CSharp/FixInterpolatedVerbatimString/FixInterpolatedVerbatimStringCommandHandler.cs index 653220727825e..c31f12f736c2a 100644 --- a/src/EditorFeatures/CSharp/FixInterpolatedVerbatimString/FixInterpolatedVerbatimStringCommandHandler.cs +++ b/src/EditorFeatures/CSharp/FixInterpolatedVerbatimString/FixInterpolatedVerbatimStringCommandHandler.cs @@ -22,6 +22,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.FixInterpolatedVerbatimString [Name(nameof(FixInterpolatedVerbatimStringCommandHandler))] internal sealed class FixInterpolatedVerbatimStringCommandHandler : IChainedCommandHandler { + [ImportingConstructor] + public FixInterpolatedVerbatimStringCommandHandler() + { + } + public string DisplayName => CSharpEditorResources.Fix_interpolated_verbatim_string; public void ExecuteCommand(TypeCharCommandArgs args, Action nextCommandHandler, CommandExecutionContext executionContext) diff --git a/src/EditorFeatures/CSharp/Formatting/CSharpEditorFormattingService.cs b/src/EditorFeatures/CSharp/Formatting/CSharpEditorFormattingService.cs index a3fa97cced0a0..957e51be1dc7c 100644 --- a/src/EditorFeatures/CSharp/Formatting/CSharpEditorFormattingService.cs +++ b/src/EditorFeatures/CSharp/Formatting/CSharpEditorFormattingService.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Utilities; using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation; @@ -18,6 +19,7 @@ using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -32,6 +34,7 @@ internal partial class CSharpEditorFormattingService : IEditorFormattingService // All the characters that might potentially trigger formatting when typed private readonly char[] _supportedChars = ";{}#nte:)".ToCharArray(); + [ImportingConstructor] public CSharpEditorFormattingService() { } @@ -280,7 +283,7 @@ private async Task> FormatTokenAsync(Document document, Syntax private ISmartTokenFormatter CreateSmartTokenFormatter(OptionSet optionSet, IEnumerable formattingRules, SyntaxNode root) { - return new SmartTokenFormatter(optionSet, formattingRules, (CompilationUnitSyntax)root); + return new CSharpSmartTokenFormatter(optionSet, formattingRules, (CompilationUnitSyntax)root); } private async Task> FormatRangeAsync( @@ -306,7 +309,7 @@ private async Task> FormatRangeAsync( var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - var formatter = new SmartTokenFormatter(options, formattingRules, (CompilationUnitSyntax)root); + var formatter = new CSharpSmartTokenFormatter(options, formattingRules, (CompilationUnitSyntax)root); var changes = formatter.FormatRange(document.Project.Solution.Workspace, tokenRange.Value.Item1, tokenRange.Value.Item2, cancellationToken); return changes; diff --git a/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatterCommandHandler.cs b/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatterCommandHandler.cs index 9969172496812..655903a333617 100644 --- a/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatterCommandHandler.cs +++ b/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatterCommandHandler.cs @@ -5,10 +5,12 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Implementation.Formatting.Indentation; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; +using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; @@ -39,7 +41,7 @@ public SmartTokenFormatterCommandHandler( protected override ISmartTokenFormatter CreateSmartTokenFormatter(OptionSet optionSet, IEnumerable formattingRules, SyntaxNode root) { - return new SmartTokenFormatter(optionSet, formattingRules, (CompilationUnitSyntax)root); + return new CSharpSmartTokenFormatter(optionSet, formattingRules, (CompilationUnitSyntax)root); } protected override bool UseSmartTokenFormatter(SyntaxNode root, TextLine line, IEnumerable formattingRules, OptionSet options, CancellationToken cancellationToken) diff --git a/src/EditorFeatures/CSharp/Formatting/Indentation/WhitespaceExtensions.cs b/src/EditorFeatures/CSharp/Formatting/Indentation/WhitespaceExtensions.cs deleted file mode 100644 index bf7ffc4dc0e3f..0000000000000 --- a/src/EditorFeatures/CSharp/Formatting/Indentation/WhitespaceExtensions.cs +++ /dev/null @@ -1,15 +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. - - -namespace Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation -{ - internal static class WhitespaceExtensions - { -#if false - public static bool IsFirstTokenOnLine(this SyntaxToken token, ITextSnapshot snapshot) - { - return token.IsFirstTokenOnLine(snapshot); - } -#endif - } -} diff --git a/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs b/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs index 8d77ebb343505..ea8ed164244e0 100644 --- a/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs +++ b/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs @@ -9,5 +9,9 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.GoToBase [ExportLanguageService(typeof(IGoToBaseService), LanguageNames.CSharp), Shared] internal class CSharpGoToBaseService : AbstractGoToBaseService { + [ImportingConstructor] + public CSharpGoToBaseService() + { + } } } diff --git a/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionSymbolService.cs b/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionSymbolService.cs index d87c74057b0eb..d0b585d2f7827 100644 --- a/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionSymbolService.cs +++ b/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionSymbolService.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.GoToDefinition [ExportLanguageService(typeof(IGoToDefinitionSymbolService), LanguageNames.CSharp), Shared] internal class CSharpGoToDefinitionSymbolService : AbstractGoToDefinitionSymbolService { + [ImportingConstructor] + public CSharpGoToDefinitionSymbolService() + { + } + protected override ISymbol FindRelatedExplicitlyDeclaredSymbol(ISymbol symbol, Compilation compilation) { return symbol; diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/AsyncAwaitHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/AsyncAwaitHighlighter.cs index 497cd37c7ba26..31f400ff61cc6 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/AsyncAwaitHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/AsyncAwaitHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp; @@ -14,6 +15,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class AsyncAwaitHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public AsyncAwaitHighlighter() + { + } + protected override bool IsHighlightableNode(SyntaxNode node) => node.IsReturnableConstruct(); diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedExpressionHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedExpressionHighlighter.cs index 465d58745e1b7..daf0708b474de 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedExpressionHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedExpressionHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -12,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class CheckedExpressionHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public CheckedExpressionHighlighter() + { + } + protected override IEnumerable GetHighlights( CheckedExpressionSyntax checkedExpressionSyntax, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedStatementHighlighter.cs index 1ed6257bdbb0b..36b840e950bbd 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/CheckedStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting; @@ -11,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class CheckedStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public CheckedStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( CheckedStatementSyntax checkedStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.cs index fb0a0936c414a..ed98b0d8cb360 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -12,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class ConditionalPreprocessorHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public ConditionalPreprocessorHighlighter() + { + } + protected override IEnumerable GetHighlights( DirectiveTriviaSyntax directive, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/IfStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/IfStatementHighlighter.cs index ee5e4980f26bd..35afb0a2fd053 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/IfStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/IfStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; @@ -15,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting [ExportHighlighter(LanguageNames.CSharp)] internal class IfStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public IfStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( IfStatementSyntax ifStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LockStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LockStatementHighlighter.cs index 277e77b9bb66a..cb8e1b47d30ab 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LockStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LockStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting; @@ -11,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class LockStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public LockStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( LockStatementSyntax lockStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs index 41dd960de5cc8..d0d89ac47ca81 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Diagnostics; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions; @@ -13,6 +14,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class LoopHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public LoopHighlighter() + { + } + protected override bool IsHighlightableNode(SyntaxNode node) => node.IsContinuableConstruct(); diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/RegionHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/RegionHighlighter.cs index 3310aeb0c46a6..c60b229acbf8b 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/RegionHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/RegionHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -12,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class RegionHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public RegionHighlighter() + { + } + protected override IEnumerable GetHighlights( DirectiveTriviaSyntax directive, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs index ca398c9280719..5210a91c61e75 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions; @@ -15,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class ReturnStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public ReturnStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( ReturnStatementSyntax returnStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/SwitchStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/SwitchStatementHighlighter.cs index d1d2b92d9f884..eecf36d649a87 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/SwitchStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/SwitchStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Diagnostics; using System.Threading; using Microsoft.CodeAnalysis.CSharp; @@ -14,6 +15,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class SwitchStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public SwitchStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( SwitchStatementSyntax switchStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/TryStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/TryStatementHighlighter.cs index 4736b2634c1f3..716fa36670f3e 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/TryStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/TryStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting; @@ -11,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class TryStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public TryStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( TryStatementSyntax tryStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UnsafeStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UnsafeStatementHighlighter.cs index bd74b8a4e9e1f..83911b37b4ad8 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UnsafeStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UnsafeStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting; @@ -11,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class UnsafeStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public UnsafeStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( UnsafeStatementSyntax unsafeStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UsingStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UsingStatementHighlighter.cs index 284392d87455e..115c354d83d6d 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UsingStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/UsingStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting; @@ -11,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class UsingStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public UsingStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( UsingStatementSyntax usingStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs index 74bb0a9b57047..bb92c209656de 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs @@ -1,6 +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.Collections.Generic; +using System.ComponentModel.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions; @@ -15,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighli [ExportHighlighter(LanguageNames.CSharp)] internal class YieldStatementHighlighter : AbstractKeywordHighlighter { + [ImportingConstructor] + public YieldStatementHighlighter() + { + } + protected override IEnumerable GetHighlights( YieldStatementSyntax yieldStatement, CancellationToken cancellationToken) { diff --git a/src/EditorFeatures/CSharp/LineSeparators/CSharpLineSeparatorService.cs b/src/EditorFeatures/CSharp/LineSeparators/CSharpLineSeparatorService.cs index 5f15208519551..bb31741c89430 100644 --- a/src/EditorFeatures/CSharp/LineSeparators/CSharpLineSeparatorService.cs +++ b/src/EditorFeatures/CSharp/LineSeparators/CSharpLineSeparatorService.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.LineSeparator [ExportLanguageService(typeof(ILineSeparatorService), LanguageNames.CSharp), Shared] internal class CSharpLineSeparatorService : ILineSeparatorService { + [ImportingConstructor] + public CSharpLineSeparatorService() + { + } + /// /// Given a tree returns line separator spans. /// The operation may take fairly long time on a big tree so it is cancellable. diff --git a/src/EditorFeatures/CSharp/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs b/src/EditorFeatures/CSharp/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs index 0565620f14b20..24d0153c10c16 100644 --- a/src/EditorFeatures/CSharp/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs +++ b/src/EditorFeatures/CSharp/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs @@ -36,6 +36,11 @@ internal sealed partial class MisplacedUsingDirectivesCodeFixProvider : CodeFixP { private static readonly SyntaxAnnotation s_usingPlacementCodeFixAnnotation = new SyntaxAnnotation(nameof(s_usingPlacementCodeFixAnnotation)); + [ImportingConstructor] + public MisplacedUsingDirectivesCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.MoveMisplacedUsingDirectivesDiagnosticId); public override FixAllProvider GetFixAllProvider() diff --git a/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs b/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs index 83fec64cea2f3..9f1f656badb15 100644 --- a/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs +++ b/src/EditorFeatures/CSharp/NavigationBar/CSharpNavigationBarItemService.cs @@ -38,6 +38,11 @@ internal class CSharpNavigationBarItemService : AbstractNavigationBarItemService SymbolDisplayParameterOptions.IncludeParamsRefOut, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral); + [ImportingConstructor] + public CSharpNavigationBarItemService() + { + } + public override async Task> GetItemsAsync(Document document, CancellationToken cancellationToken) { var typesInFile = await GetTypesInFileAsync(document, cancellationToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/CSharp/RenameTracking/CSharpRenameTrackingLanguageHeuristicsService.cs b/src/EditorFeatures/CSharp/RenameTracking/CSharpRenameTrackingLanguageHeuristicsService.cs index 05374481fe5bc..21394dfb43250 100644 --- a/src/EditorFeatures/CSharp/RenameTracking/CSharpRenameTrackingLanguageHeuristicsService.cs +++ b/src/EditorFeatures/CSharp/RenameTracking/CSharpRenameTrackingLanguageHeuristicsService.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.RenameTracking [ExportLanguageService(typeof(IRenameTrackingLanguageHeuristicsService), LanguageNames.CSharp), Shared] internal sealed class CSharpRenameTrackingLanguageHeuristicsService : IRenameTrackingLanguageHeuristicsService { + [ImportingConstructor] + public CSharpRenameTrackingLanguageHeuristicsService() + { + } + public bool IsIdentifierValidForRenameTracking(string name) { return name != "var" && name != "dynamic" && name != "_"; diff --git a/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.StringSplitter.cs b/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.StringSplitter.cs index 2c69c027a2659..f33425702ece2 100644 --- a/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.StringSplitter.cs +++ b/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.StringSplitter.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -10,6 +9,8 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.SplitStringLiteral { + using Microsoft.CodeAnalysis.Indentation; + internal partial class SplitStringLiteralCommandHandler { private abstract class StringSplitter @@ -150,7 +151,7 @@ private string GetIndentString(SyntaxNode newRoot) { var newDocument = Document.WithSyntaxRoot(newRoot); - var indentationService = (IBlankLineIndentationService)newDocument.GetLanguageService(); + var indentationService = newDocument.GetLanguageService(); var originalLineNumber = SourceText.Lines.GetLineFromPosition(CursorPosition).LineNumber; var desiredIndentation = indentationService.GetBlankLineIndentation( diff --git a/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralOptions.cs b/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralOptions.cs index 559230fe07c33..3d27cf22fed19 100644 --- a/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralOptions.cs +++ b/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralOptions.cs @@ -17,6 +17,11 @@ internal class SplitStringLiteralOptions [ExportOptionProvider, Shared] internal class SplitStringLiteralOptionsProvider : IOptionProvider { + [ImportingConstructor] + public SplitStringLiteralOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( SplitStringLiteralOptions.Enabled); } diff --git a/src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs b/src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs index 903861f680d85..f6c9ee36acbf5 100644 --- a/src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs +++ b/src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs @@ -17,7 +17,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.TextStructureNavigation internal class TextStructureNavigatorProvider : AbstractTextStructureNavigatorProvider { [ImportingConstructor] - internal TextStructureNavigatorProvider( + public TextStructureNavigatorProvider( ITextStructureNavigatorSelectorService selectorService, IContentTypeRegistryService contentTypeService, IWaitIndicator waitIndicator) diff --git a/src/EditorFeatures/CSharp/Wrapping/BinaryExpression/CSharpBinaryExpressionWrapper.cs b/src/EditorFeatures/CSharp/Wrapping/BinaryExpression/CSharpBinaryExpressionWrapper.cs index 79ea92f7410c5..fa7207af4a405 100644 --- a/src/EditorFeatures/CSharp/Wrapping/BinaryExpression/CSharpBinaryExpressionWrapper.cs +++ b/src/EditorFeatures/CSharp/Wrapping/BinaryExpression/CSharpBinaryExpressionWrapper.cs @@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.Editor.Wrapping.BinaryExpression; namespace Microsoft.CodeAnalysis.Editor.CSharp.Wrapping.BinaryExpression diff --git a/src/EditorFeatures/CSharp/Wrapping/CSharpWrappingCodeRefactoringProvider.cs b/src/EditorFeatures/CSharp/Wrapping/CSharpWrappingCodeRefactoringProvider.cs index 2f10d91699645..20e09ced6ea89 100644 --- a/src/EditorFeatures/CSharp/Wrapping/CSharpWrappingCodeRefactoringProvider.cs +++ b/src/EditorFeatures/CSharp/Wrapping/CSharpWrappingCodeRefactoringProvider.cs @@ -18,6 +18,7 @@ internal class CSharpWrappingCodeRefactoringProvider : AbstractWrappingCodeRefac new CSharpParameterWrapper(), new CSharpBinaryExpressionWrapper()); + [ImportingConstructor] public CSharpWrappingCodeRefactoringProvider() : base(s_wrappers) { diff --git a/src/EditorFeatures/CSharp/Wrapping/SeparatedSyntaxList/AbstractCSharpSeparatedSyntaxListWrapper.cs b/src/EditorFeatures/CSharp/Wrapping/SeparatedSyntaxList/AbstractCSharpSeparatedSyntaxListWrapper.cs index e824e4cbb7d34..acaaaaf8e60a7 100644 --- a/src/EditorFeatures/CSharp/Wrapping/SeparatedSyntaxList/AbstractCSharpSeparatedSyntaxListWrapper.cs +++ b/src/EditorFeatures/CSharp/Wrapping/SeparatedSyntaxList/AbstractCSharpSeparatedSyntaxListWrapper.cs @@ -1,7 +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 Microsoft.CodeAnalysis.Editor; -using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.Editor.Wrapping.SeparatedSyntaxList; namespace Microsoft.CodeAnalysis.CSharp.Editor.Wrapping.SeparatedSyntaxList diff --git a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs index d1de3582dafd5..202302f701f8e 100644 --- a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs +++ b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs @@ -24,10 +24,8 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing public class AddUsingNuGetTests : AbstractAddUsingTests { - const string NugetOrgSource = "nuget.org"; - private static readonly ImmutableArray NugetPackageSources = - ImmutableArray.Create(new PackageSource(NugetOrgSource, "http://nuget.org/")); + ImmutableArray.Create(new PackageSource(SymbolSearchUpdateEngine.NugetOrgSourceName, SymbolSearchUpdateEngine.NugetOrgSourceUri)); protected override TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters) { @@ -63,7 +61,7 @@ public async Task TestSearchPackageSingleName() packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - NugetOrgSource, "NuGetType", 0, It.IsAny())) + SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); await TestInRegularAndScriptAsync( @@ -94,7 +92,7 @@ public async Task TestSearchPackageMultipleNames() packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - NugetOrgSource, "NuGetType", 0, It.IsAny())) + SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); await TestInRegularAndScriptAsync( @@ -123,7 +121,7 @@ public async Task TestMissingIfPackageAlreadyInstalled() packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - NugetOrgSource, "NuGetType", 0, It.IsAny())) + SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); await TestMissingInRegularAndScriptAsync( @@ -149,7 +147,7 @@ public async Task TestOptionsOffered() packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - NugetOrgSource, "NuGetType", 0, It.IsAny())) + SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); var data = new FixProviderData(installerServiceMock.Object, packageServiceMock.Object); @@ -193,7 +191,7 @@ public async Task TestInstallGetsCalledNoVersion() packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - NugetOrgSource, "NuGetType", 0, It.IsAny())) + SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); await TestInRegularAndScriptAsync( @@ -226,7 +224,7 @@ public async Task TestInstallGetsCalledWithVersion() var packageServiceMock = new Mock(MockBehavior.Strict); packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(NugetOrgSource, "NuGetType", 0, It.IsAny())) + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); await TestInRegularAndScriptAsync( @@ -260,7 +258,7 @@ public async Task TestFailedInstallRollsBackFile() var packageServiceMock = new Mock(MockBehavior.Strict); packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) .Returns(Task.FromResult>(new List())); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(NugetOrgSource, "NuGetType", 0, It.IsAny())) + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) .Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); await TestInRegularAndScriptAsync( diff --git a/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs index 0bf1599b2ffaf..2c15e9e53e3b2 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs @@ -1,7 +1,9 @@ // 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.Threading.Tasks; +using ICSharpCode.Decompiler.CSharp; using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; @@ -4182,5 +4184,177 @@ from int n2 in nums } #endregion + + #region Name Generation + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertQueryToForEach)] + public async Task EnumerableFunctionDoesNotUseLocalFunctionName() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + var r = [|from i in c select i+1|]; + + void enumerable() { } + } +}"; + string output = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + IEnumerable enumerable1() + { + foreach (var i in c) + { + yield return i + 1; + } + } + + var r = enumerable1(); + + void enumerable() { } + } +}"; + await TestInRegularAndScriptAsync(source, output); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertQueryToForEach)] + public async Task EnumerableFunctionCanUseLocalFunctionParameterName() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + var r = [|from i in c select i+1|]; + + void M(IEnumerable enumerable) { } + } +}"; + string output = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + IEnumerable enumerable() + { + foreach (var i in c) + { + yield return i + 1; + } + } + + var r = enumerable(); + + void M(IEnumerable enumerable) { } + } +}"; + await TestInRegularAndScriptAsync(source, output); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertQueryToForEach)] + public async Task EnumerableFunctionDoesNotUseLambdaParameterNameWithCSharpLessThan8() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + var r = [|from i in c select i+1|]; + + Action myLambda = enumerable => { }; + } +}"; + string output = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + IEnumerable enumerable1() + { + foreach (var i in c) + { + yield return i + 1; + } + } + + var r = enumerable1(); + + Action myLambda = enumerable => { }; + } +}"; + await TestInRegularAndScriptAsync(source, output, parseOptions: new CSharpParseOptions(CodeAnalysis.CSharp.LanguageVersion.CSharp7_3)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertQueryToForEach)] + public async Task EnumerableFunctionCanUseLambdaParameterNameInCSharp8() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + var r = [|from i in c select i+1|]; + + Action myLambda = enumerable => { }; + } +}"; + string output = @" +using System; +using System.Collections.Generic; +using System.Linq; +class Query +{ + public static void Main(string[] args) + { + List c = new List{ 1, 2, 3, 4, 5, 6, 7 }; + IEnumerable enumerable() + { + foreach (var i in c) + { + yield return i + 1; + } + } + + var r = enumerable(); + + Action myLambda = enumerable => { }; + } +}"; + await TestInRegularAndScriptAsync(source, output, parseOptions: new CSharpParseOptions(CodeAnalysis.CSharp.LanguageVersion.CSharp8)); + } + + #endregion } } diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs index 644ef5d8c8891..ad3fafb54ee3e 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs @@ -1718,6 +1718,180 @@ await VerifyItemExistsAsync(markup, "classB", glyph: (int)Glyph.Local, expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); } + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionDoesNotUseLocalAsLocalFunctionParameter() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + ClassB classB = new ClassB(); + void LocalM1(ClassB $$) { } + } +} +"; + await VerifyItemIsAbsentAsync(markup, "classB"); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionDoesNotUseLocalAsLocalFunctionVariable() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + ClassB classB = new ClassB(); + void LocalM1() + { + ClassB $$ + } + } +} +"; + await VerifyItemIsAbsentAsync(markup, "classB"); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionDoesNotUseLocalInNestedLocalFunction() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + ClassB classB = new ClassB(); + void LocalM1() + { + void LocalM2() + { + ClassB $$ + } + } + } +} +"; + await VerifyItemIsAbsentAsync(markup, "classB"); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionDoesNotUseLocalFunctionParameterInNestedLocalFunction() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + void LocalM1(ClassB classB) + { + void LocalM2() + { + ClassB $$ + } + } + } +} +"; + await VerifyItemIsAbsentAsync(markup, "classB"); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionCanUseLocalFunctionParameterAsParameter() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + void LocalM1(ClassB classB) { } + void LocalM2(ClassB $$) { } + } +} +"; + await VerifyItemExistsAsync(markup, "classB", glyph: (int)Glyph.Parameter, + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionCanUseLocalFunctionVariableAsParameter() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + void LocalM1() + { + ClassB classB + } + void LocalM2(ClassB $$) { } + } +} +"; + await VerifyItemExistsAsync(markup, "classB", glyph: (int)Glyph.Parameter, + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionCanUseLocalFunctionParameterAsVariable() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + void LocalM1(ClassB classB) { } + void LocalM2() + { + ClassB $$ + } + } +} +"; + await VerifyItemExistsAsync(markup, "classB", glyph: (int)Glyph.Local, + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); + } + + [WorkItem(35891, "https://github.com/dotnet/roslyn/issues/35891")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestCompletionCanUseLocalFunctionVariableAsVariable() + { + var markup = @" +class ClassA +{ + class ClassB { } + void M() + { + void LocalM1() + { + ClassB classB + } + void LocalM2() + { + ClassB $$ + } + } +} +"; + await VerifyItemExistsAsync(markup, "classB", glyph: (int)Glyph.Local, + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); + } + private static NamingStylePreferences NamesEndWithSuffixPreferences() { var specificationStyles = new[] diff --git a/src/EditorFeatures/CSharpTest/ConvertForToForEach/ConvertForToForEachTests.cs b/src/EditorFeatures/CSharpTest/ConvertForToForEach/ConvertForToForEachTests.cs index 4439a5334d5e2..5860328d7127f 100644 --- a/src/EditorFeatures/CSharpTest/ConvertForToForEach/ConvertForToForEachTests.cs +++ b/src/EditorFeatures/CSharpTest/ConvertForToForEach/ConvertForToForEachTests.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.ConvertForToForEach; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; @@ -1366,5 +1367,145 @@ void Test(string[][] array) } }"); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertForToForEach)] + public async Task TestDoesNotUseLocalFunctionName() + { + await TestInRegularAndScript1Async( + @"using System; + +class C +{ + void Test(string[] array) + { + [||]for (int i = 0; i < array.Length; i++) + { + Console.WriteLine(array[i]); + } + + void v() { } + } +}", + @"using System; + +class C +{ + void Test(string[] array) + { + foreach (string {|Rename:v1|} in array) + { + Console.WriteLine(v1); + } + + void v() { } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertForToForEach)] + public async Task TestUsesLocalFunctionParameterName() + { + await TestInRegularAndScript1Async( + @"using System; + +class C +{ + void Test(string[] array) + { + [||]for (int i = 0; i < array.Length; i++) + { + Console.WriteLine(array[i]); + } + + void M(string v) + { + } + } +}", + @"using System; + +class C +{ + void Test(string[] array) + { + foreach (string {|Rename:v|} in array) + { + Console.WriteLine(v); + } + + void M(string v) + { + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertForToForEach)] + public async Task TestDoesNotUseLambdaParameterWithCSharpLessThan8() + { + await TestInRegularAndScript1Async( + @"using System; + +class C +{ + void Test(string[] array) + { + [||]for (int i = 0; i < array.Length; i++) + { + Console.WriteLine(array[i]); + } + + Action myLambda = v => { }; + } +}", + @"using System; + +class C +{ + void Test(string[] array) + { + foreach (string {|Rename:v1|} in array) + { + Console.WriteLine(v1); + } + + Action myLambda = v => { }; + } +}", parameters: new TestParameters(new CSharpParseOptions(LanguageVersion.CSharp7_3))); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertForToForEach)] + public async Task TestUsesLambdaParameterNameInCSharp8() + { + await TestInRegularAndScript1Async( + @"using System; + +class C +{ + void Test(string[] array) + { + [||]for (int i = 0; i < array.Length; i++) + { + Console.WriteLine(array[i]); + } + + Action myLambda = v => { }; + } +}", + @"using System; + +class C +{ + void Test(string[] array) + { + foreach (string {|Rename:v|} in array) + { + Console.WriteLine(v); + } + + Action myLambda = v => { }; + } +}", parameters: new TestParameters(new CSharpParseOptions(LanguageVersion.CSharp8))); + } } } diff --git a/src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs b/src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs new file mode 100644 index 0000000000000..9c8446ca8c5cc --- /dev/null +++ b/src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs @@ -0,0 +1,203 @@ +// 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.Threading.Tasks; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertSwitchStatementToExpression +{ + public partial class ConvertSwitchStatementToExpressionTests + { + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestNested_01() + { + await TestInCSharp8( +@"class Program +{ + int M(int i, int j) + { + int r; + {|FixAllInDocument:switch|} (i) + { + case 1: + r = 1; + break; + case 2: + r = 2; + break; + case 3: + r = 3; + break; + default: + r = 4; + break; + } + int x, y; + switch (i) + { + case 1: + x = 1; + y = 1; + break; + case 2: + x = 1; + y = 1; + break; + case 3: + x = 1; + y = 1; + break; + default: + x = 1; + y = 1; + break; + } + switch (i) + { + default: + throw null; + case 1: + switch (j) + { + case 10: + return 10; + case 20: + return 20; + case 30: + return 30; + } + return 0; + case 2: + switch (j) + { + case 10: + return 10; + case 20: + return 20; + case 30: + return 30; + case var _: + return 0; + } + case 3: + switch (j) + { + case 10: + return 10; + case 20: + return 20; + case 30: + return 30; + case var v: + return 0; + } + } + } +}", +@"class Program +{ + int M(int i, int j) + { + var r = i switch + { + 1 => 1, + 2 => 2, + 3 => 3, + _ => 4, + }; + int x, y; + switch (i) + { + case 1: + x = 1; + y = 1; + break; + case 2: + x = 1; + y = 1; + break; + case 3: + x = 1; + y = 1; + break; + default: + x = 1; + y = 1; + break; + } + switch (i) + { + default: + throw null; + case 1: + return j switch + { + 10 => 10, + 20 => 20, + 30 => 30, + _ => 0, + }; + case 2: + return j switch + { + 10 => 10, + 20 => 20, + 30 => 30, + var _ => 0, + }; + case 3: + return j switch + { + 10 => 10, + 20 => 20, + 30 => 30, + var v => 0, + }; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestNested_02() + { + await TestInCSharp8( +@"class Program +{ + System.Action M(int i, int j) + { + {|FixAllInDocument:switch|} (i) + { + default: + return () => + { + switch (j) + { + default: + return 3; + } + }; + } + } +}", +@"class Program +{ + System.Action M(int i, int j) + { + return i switch + { + _ => () => + { + switch (j) + { + default: + return 3; + } + } + , + }; + } +}"); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs b/src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs new file mode 100644 index 0000000000000..4ee5d4d8d6c0c --- /dev/null +++ b/src/EditorFeatures/CSharpTest/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs @@ -0,0 +1,628 @@ +// 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.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.ConvertSwitchStatementToExpression; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertSwitchStatementToExpression +{ + public partial class ConvertSwitchStatementToExpressionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + { + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new ConvertSwitchStatementToExpressionDiagnosticAnalyzer(), new ConvertSwitchStatementToExpressionCodeFixProvider()); + + private Task TestInCSharp8(string actual, string expected) + => TestInRegularAndScriptAsync(actual, expected, parseOptions: TestOptions.Regular8); + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestReturn() + { + await TestInCSharp8( +@"class Program +{ + int M(int i) + { + [||]switch (i) + { + case 1: + return 4; + case 2: + return 5; + case 3: + return 6; + default: + return 7; + } + } +}", +@"class Program +{ + int M(int i) + { + return i switch + { + 1 => 4, + 2 => 5, + 3 => 6, + _ => 7, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestReturnAndThrow() + { + await TestInCSharp8( +@"class Program +{ + int M(int i) + { + [||]switch (i) + { + case 1: + return 4; + default: + throw null; + case 2: + return 5; + case 3: + return 6; + } + } +}", +@"class Program +{ + int M(int i) + { + return i switch + { + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestAssignment_Array() + { + await TestInCSharp8( +@"class Program +{ + int[] array = new int[1]; + + int M(int i) + { + [||]switch (i) + { + case 1: + array[0] = 4; + break; + case 2: + array[0] = 5; + break; + case 3: + array[0] = 6; + break; + default: + array[0] = 7; + break; + } + } +}", +@"class Program +{ + int[] array = new int[1]; + + int M(int i) + { + array[0] = i switch + { + 1 => 4, + 2 => 5, + 3 => 6, + _ => 7, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnDifferentIndexerArgs() + { + await TestMissingAsync( +@"class Program +{ + int[] array = new int[1]; + + int M(int i) + { + [||]switch (i) + { + case 1: + array[1] = 4; + break; + case 2: + array[2] = 5; + break; + case 3: + array[2] = 6; + break; + default: + array[2] = 7; + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnQualifiedName() + { + await TestMissingAsync( +@"class Program +{ + int[] array = new int[1]; + + int M(int i) + { + [||]switch (i) + { + case 1: + this.array[2] = 4; + break; + case 2: + array[2] = 5; + break; + case 3: + array[2] = 6; + break; + default: + array[2] = 7; + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnDefaultBreak_01() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + [||]switch (i) + { + default: + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnDefaultBreak_02() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + [||]switch (i) + { + case _: + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnDefaultBreak_03() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + [||]switch (i) + { + case var _: + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnDefaultBreak_04() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + [||]switch (i) + { + case var x: + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnAllBreak() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + [||]switch (i) + { + case 1: + break; + case 2: + break; + case 3: + break; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestAllThrow() + { + await TestInCSharp8( +@"class Program +{ + void M(int i) + { + [||]switch (i) + { + case 1: + throw null; + default: + throw new Exception(); + } + } +}", +@"class Program +{ + void M(int i) + { + throw i switch + { + 1 => null, + _ => new Exception(), + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestAssignment() + { + await TestInCSharp8( +@"class Program +{ + void M(int i) + { + int j; + [||]switch (i) + { + case 1: + j = 4; + break; + case 2: + j = 5; + break; + case 3: + j = 6; + break; + } + throw null; + } +}", +@"class Program +{ + void M(int i) + { + var j = i switch + { + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnNextStatementMismatch() + { + await TestMissingAsync( +@"class Program +{ + int M(int i) + { + int j = 0; + [||]switch (i) + { + case 1: + j = 4; + break; + case 2: + j = 5; + break; + case 3: + j = 6; + break; + } + return j; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnAssignmentMismatch() + { + await TestMissingAsync( +@"class Program +{ + int M(int i) + { + int j = 0; + [||]switch (i) + { + case 1: + j = 4; + break; + case 2: + j += 5; + break; + } + return j; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestAssignment_Compound() + { + await TestInCSharp8( +@"class Program +{ + void M(int i) + { + int j = 0; + [||]switch (i) + { + case 1: + j += 4; + break; + case 2: + j += 5; + break; + case 3: + j += 6; + break; + } + throw null; + } +}", +@"class Program +{ + void M(int i) + { + int j = 0; + j += i switch + { + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestAssignment_UseBeforeAssignment() + { + await TestInCSharp8( +@"class Program +{ + void M(int i) + { + int j = 123; + M(i); + [||]switch (i) + { + case 1: + j = 4; + break; + case 2: + j = 5; + break; + case 3: + j = 6; + break; + } + throw null; + } +}", +@"class Program +{ + void M(int i) + { + int j = 123; + M(i); + j = i switch + { + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnMultiAssignment() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + int j, k; + [||]switch (i) + { + case 1: + j = 4; + k = 5; + break; + case 2: + j = 6; + k = 7; + break; + case 3: + j = 8; + k = 9; + break; + } + throw null; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingONMultiCaseSection() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + int j; + [||]switch (i) + { + case 1: + case 2: + j = 4; + break; + } + throw null; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnMultiCompoundAssignment() + { + await TestMissingAsync( +@"class Program +{ + void M(int i) + { + int j = 0, k = 0; + [||]switch (i) + { + case 1: + j += 4; + k += 5; + break; + case 2: + j += 6; + k += 7; + break; + case 3: + j += 8; + k += 9; + break; + } + throw null; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestMissingOnGoto() + { + await TestMissingAsync( +@"class Program +{ + int M(int i) + { + [||]switch (i) + { + case 1: + return 0; + case 2: + goto default; + default: + return 2; + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] + public async Task TestTrivia() + { + await TestInCSharp8( +@"class Program +{ + int M(int i) + { + // leading switch + [||]switch (i) // trailing switch + { + // leading label + case 1: + return 4; // trailing body + case 2: + return 5; + case 3: + return 6; + } + + // leading next statement + throw null; // leading next statement + } +}", +@"class Program +{ + int M(int i) + { + // leading switch + return i switch // trailing switch + { + // leading label + 1 => 4, // trailing body + 2 => 5, + 3 => 6, + + // leading next statement + _ => throw null, // leading next statement + }; + } +}"); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs index 0ea83369400ef..6fa96ca02b02b 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs @@ -140,7 +140,7 @@ public async Task AnalyzerOptionsArePassedToAllAnalyzers() var newSln = workspace.CurrentSolution.AddAdditionalDocument(additionalDocId, "add.config", SourceText.From("random text")); currentProject = newSln.Projects.Single(); var additionalDocument = currentProject.GetAdditionalDocument(additionalDocId); - AdditionalText additionalStream = new AdditionalTextDocument(additionalDocument.State); + AdditionalText additionalStream = new AdditionalTextWithState(additionalDocument.State); AnalyzerOptions options = new AnalyzerOptions(ImmutableArray.Create(additionalStream)); var analyzer = new OptionsDiagnosticAnalyzer(expectedOptions: options); diff --git a/src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.cs b/src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.cs new file mode 100644 index 0000000000000..f24f2b2570603 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.cs @@ -0,0 +1,1433 @@ +// 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.Threading.Tasks; +using Microsoft.CodeAnalysis.DisposeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; +using static Roslyn.Test.Utilities.TestHelpers; +using Roslyn.Test.Utilities; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DisposeAnalysis +{ + [Trait(Traits.Feature, Traits.Features.DisposeAnalysis)] + public sealed class DisposableFieldsShouldBeDisposedTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + { + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new DisposableFieldsShouldBeDisposedDiagnosticAnalyzer(), null); + + private Task TestDiagnosticsAsync(string initialMarkup, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, parseOptions: null, expectedDiagnostics); + private Task TestDiagnosticsAsync(string initialMarkup, CSharpParseOptions parseOptions, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, new TestParameters(parseOptions, retainNonFixableDiagnostics: true), expectedDiagnostics); + private Task TestDiagnosticMissingAsync(string initialMarkup, CSharpParseOptions parseOptions = null) + => TestDiagnosticMissingAsync(initialMarkup, new TestParameters(parseOptions, retainNonFixableDiagnostics: true)); + + [Fact] + public async Task DisposableAllocationInConstructor_AssignedDirectly_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private readonly A a;|] + public B() + { + a = new A(); + } + + public void Dispose() + { + a.Dispose(); + } +} +"); + } + + [Fact] + public async Task DisposableAllocationInConstructor_AssignedDirectly_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private readonly A [|a|]; + public B() + { + a = new A(); + } + + public void Dispose() + { + } +} +", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableAllocationInMethod_AssignedDirectly_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public void SomeMethod() + { + a = new A(); + } + + public void Dispose() + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocationInMethod_AssignedDirectly_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|]; + public void SomeMethod() + { + a = new A(); + } + + public void Dispose() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableAllocationInFieldInitializer_AssignedDirectly_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a = new A(); + private readonly A a2 = new A();|] + + public void Dispose() + { + a.Dispose(); + a2.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocationInFieldInitializer_AssignedDirectly_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a = new A(); + private readonly A a2 = new A();|] + + public void Dispose() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "a").WithLocation(13, 15), + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "a2").WithLocation(14, 24)); + } + + [Fact] + public async Task StaticField_NotDisposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private static A a = new A(); + private static readonly A a2 = new A();|] + + public void Dispose() + { + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughLocal_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public void SomeMethod() + { + var l = new A(); + a = l; + } + + public void Dispose() + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughLocal_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|]; + public void SomeMethod() + { + var l = new A(); + a = l; + } + + public void Dispose() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughParameter_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public B(A p) + { + p = new A(); + a = p; + } + + public void Dispose() + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughParameter_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|]; + public B(A p) + { + p = new A(); + a = p; + } + + public void Dispose() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableSymbolWithoutAllocation_AssignedThroughParameter_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public B(A p) + { + a = p; + } + + public void Dispose() + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableSymbolWithoutAllocation_AssignedThroughParameter_NotDisposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public B(A p) + { + a = p; + } + + public void Dispose() + { + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughInstanceInvocation_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public B() + { + a = GetA(); + } + + private A GetA() => new A(); + + public void Dispose() + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughInstanceInvocation_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|]; + public B() + { + a = GetA(); + } + + private A GetA() => new A(); + + public void Dispose() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughStaticCreateInvocation_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a;|] + public B() + { + a = Create(); + } + + private static A Create() => new A(); + + public void Dispose() + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedThroughStaticCreateInvocation_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|]; + public B() + { + a = Create(); + } + + private static A Create() => new A(); + + public void Dispose() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableAllocation_AssignedInDifferentType_DisposedInContainingType_NoDiagnostic() + { + // We don't track disposable field assignments in different type. + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|public A a;|] + public void Dispose() + { + a.Dispose(); + } +} + +class WrapperB +{ + private B b; + public void Create() + { + b.a = new A(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedInDifferentType_DisposedInDifferentNonDisposableType_NoDiagnostic() + { + // We don't track disposable field assignments in different type. + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|public A a;|] + public void Dispose() + { + } +} + +class WrapperB +{ + private B b; + + public void Create() + { + b.a = new A(); + } + + public void Dispose() + { + b.a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedInDifferentType_NotDisposed_NoDiagnostic() + { + // We don't track disposable field assignments in different type. + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|public A a;|] + public void Dispose() + { + } +} + +class Test +{ + public void M(B b) + { + b.a = new A(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_DisposedWithConditionalAccess_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + a?.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedToLocal_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + A l = a; + l.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AssignedToLocal_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|] = new A(); + + public void Dispose() + { + A l = a; + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact] + public async Task DisposableAllocation_IfElseStatement_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a; + private A b;|] + + public B(bool flag) + { + A l = new A(); + if (flag) + { + a = l; + } + else + { + b = l; + } + } + + public void Dispose() + { + A l = null; + if (a != null) + { + l = a; + } + else if (b != null) + { + l = b; + } + + l.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_IfElseStatement_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a; + private A b;|] + + public B(bool flag) + { + A l = new A(); + if (flag) + { + a = l; + } + else + { + b = l; + } + } + + public void Dispose() + { + A l = null; + if (a != null) + { + l = a; + } + else if (b != null) + { + l = b; + } + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "a").WithLocation(13, 15), + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "b").WithLocation(14, 15)); + } + + [Fact] + public async Task DisposableAllocation_EscapedField_NotDisposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + DisposeA(ref this.a); + } + + private static void DisposeA(ref A a) + { + a.Dispose(); + a = null; + } +}"); + } + + [Fact] + public async Task DisposableAllocation_OptimisticPointsToAnalysis_NoDiagnostic() + { + // Invoking an instance method may likely invalidate all the instance field analysis state, i.e. + // reference type fields might be re-assigned to point to different objects in the called method. + // An optimistic points to analysis assumes that the points to values of instance fields don't change on invoking an instance method. + // A pessimistic points to analysis resets all the instance state and assumes the instance field might point to any object, hence has unknown state. + // For dispose analysis, we want to perform an optimistic points to analysis as we assume a disposable field is not likely to be re-assigned to a separate object in helper method invocations in Dispose. + + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + public void PerformSomeCleanup() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + a.PerformSomeCleanup(); + ClearMyState(); + a.Dispose(); + } + + private void ClearMyState() + { + } +}"); + } + + [Fact] + public async Task DisposableAllocation_OptimisticPointsToAnalysis_WithReturn_NoDiagnostic() + { + // Invoking an instance method may likely invalidate all the instance field analysis state, i.e. + // reference type fields might be re-assigned to point to different objects in the called method. + // An optimistic points to analysis assumes that the points to values of instance fields don't change on invoking an instance method. + // A pessimistic points to analysis resets all the instance state and assumes the instance field might point to any object, hence has unknown state. + // For dispose analysis, we want to perform an optimistic points to analysis as we assume a disposable field is not likely to be re-assigned to a separate object in helper method invocations in Dispose. + + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + public void PerformSomeCleanup() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + public bool Disposed; + + public void Dispose() + { + if (Disposed) + { + return; + } + + a.PerformSomeCleanup(); + ClearMyState(); + a.Dispose(); + } + + private void ClearMyState() + { + } +}"); + } + + [Fact] + public async Task DisposableAllocation_IfStatementInDispose_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test : IDisposable +{ + [|private readonly A a = new A();|] + private bool cancelled; + + public void Dispose() + { + if (cancelled) + { + a.GetType(); + } + + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_DisposedinDisposeOverride_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +abstract class Base : IDisposable +{ + public virtual void Dispose() + { + } +} + +class Derived : Base +{ + [|private readonly A a = new A();|] + public override void Dispose() + { + base.Dispose(); + a.Dispose(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_DisposedWithDisposeBoolInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public void Dispose(bool disposed) + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + a.Dispose(true); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_DisposedInsideDisposeBool_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public void Dispose(bool disposed) + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + Dispose(true); + } + + public void Dispose(bool disposed) + { + a.Dispose(disposed); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_DisposedWithDisposeCloseInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public void Close() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + a.Close(); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_AllDisposedMethodsMixed_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public void Dispose(bool disposed) + { + } + + public void Close() + { + } +} + +class B : IDisposable +{ + [|private A a = new A(); + private A a2 = new A(); + private A a3 = new A();|] + + public void Dispose() + { + a.Close(); + } + + public void Dispose(bool disposed) + { + a2.Dispose(); + } + + public void Close() + { + a3.Dispose(true); + } +}"); + } + + [Fact] + public async Task DisposableAllocation_DisposedInsideDisposeClose_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public void Close() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + Close(); + } + + public void Close() + { + a.Close(); + } +}"); + } + + [Fact] + public async Task SystemThreadingTask_SpecialCase_NotDisposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Threading.Tasks; + +public class A: IDisposable +{ + [|private readonly Task t;|] + public A() + { + t = new Task(null); + } + public void Dispose() + { + } +}"); + } + + [Fact, WorkItem(1796, "https://github.com/dotnet/roslyn-analyzers/issues/1796")] + public async Task DisposableAllocation_DisposedWithDisposeAsyncInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Threading.Tasks; + +class A : IDisposable +{ + public void Dispose() => DisposeAsync(); + + public Task DisposeAsync() => Task.CompletedTask; +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + a.DisposeAsync(); + } +}"); + } + + [Fact, WorkItem(1796, "https://github.com/dotnet/roslyn-analyzers/issues/1796")] + public async Task DisposableAllocation_DisposedInsideDisposeCoreAsync_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Threading.Tasks; + +abstract class A : IDisposable +{ + public void Dispose() => DisposeAsync(); + + public Task DisposeAsync() => DisposeCoreAsync(true); + + protected abstract Task DisposeCoreAsync(bool initialized); +} + +class A2 : A +{ + protected override Task DisposeCoreAsync(bool initialized) + { + return Task.CompletedTask; + } +} + +class B : A +{ + [|private A2 a = new A2();|] + + protected override Task DisposeCoreAsync(bool initialized) + { + return a.DisposeAsync(); + } +}"); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DisposableAllocation_DisposedInInvokedMethod_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private A a = new A();|] + + public void Dispose() + { + DisposeHelper(); + } + + private void DisposeHelper() + { + a.Dispose(); + } +}"); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DisposableAllocation_NotDisposedInInvokedMethod_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private A [|a|] = new A(); + + public void Dispose() + { + DisposeHelper(); + } + + private void DisposeHelper() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DisposableAllocation_DisposedInInvokedMethod_DisposableTypeInMetadata_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.IO; + +class B : IDisposable +{ + [|private FileStream a = File.Open("""", FileMode.Create);|] + + public void Dispose() + { + DisposeHelper(); + } + + private void DisposeHelper() + { + a.Dispose(); + } +}"); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DisposableAllocation_NotDisposedInInvokedMethod_DisposableTypeInMetadata_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.IO; + +class B : IDisposable +{ + private FileStream [|a|] = File.Open("""", FileMode.Create); + + public void Dispose() + { + DisposeHelper(); + } + + private void DisposeHelper() + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DisposableAllocation_DisposedInInvokedMethodMultipleLevelsDown_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.IO; + +class B : IDisposable +{ + [|private FileStream a = File.Open("""", FileMode.Create);|] + + public void Dispose() + { + DisposeHelper(); + } + + private void DisposeHelper() + { + Helper.PerformDispose(a); + } +} + +static class Helper +{ + public static void PerformDispose(IDisposable a) + { + a.Dispose(); + } +}"); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DisposableAllocation_NotDisposedInInvokedMethodMultipleLevelsDown_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.IO; + +class B : IDisposable +{ + private FileStream [|a|] = File.Open("""", FileMode.Create); + + public void Dispose() + { + DisposeHelper(); + } + + private void DisposeHelper() + { + Helper.PerformDispose(a); + } +} + +static class Helper +{ + public static void PerformDispose(IDisposable a) + { + } +}", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)); + } + + [Fact, WorkItem(2182, "https://github.com/dotnet/roslyn-analyzers/issues/2182")] + public async Task DisposableAllocation_NonReadOnlyField_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +public sealed class B : IDisposable +{ + public void Dispose() + { + } +} + +public sealed class A : IDisposable +{ + [|private B _b;|] + + public A() + { + _b = new B(); + } + + public void Dispose() + { + if (_b == null) + { + return; + } + + _b.Dispose(); + _b = null; + } +}"); + } + + [Fact, WorkItem(2306, "https://github.com/dotnet/roslyn-analyzers/issues/2306")] + public async Task DisposableAllocationInConstructor_DisposedInGeneratedCodeFile_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + [|private readonly A a;|] + public B() + { + a = new A(); + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("""", """")] + public void Dispose() + { + a.Dispose(); + } +}"); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.cs b/src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.cs new file mode 100644 index 0000000000000..f3e3c8b1c38b5 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.cs @@ -0,0 +1,5045 @@ +// 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.Threading.Tasks; +using Microsoft.CodeAnalysis.DisposeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; +using static Roslyn.Test.Utilities.TestHelpers; +using Roslyn.Test.Utilities; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DisposeAnalysis +{ + [Trait(Traits.Feature, Traits.Features.DisposeAnalysis)] + public sealed class DisposeObjectsBeforeLosingScopeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + { + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer(), null); + + private Task TestDiagnosticsAsync(string initialMarkup, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, parseOptions: null, expectedDiagnostics); + private Task TestDiagnosticsAsync(string initialMarkup, CSharpParseOptions parseOptions, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, new TestParameters(parseOptions, retainNonFixableDiagnostics: true), expectedDiagnostics); + private Task TestDiagnosticMissingAsync(string initialMarkup, CSharpParseOptions parseOptions = null) + => TestDiagnosticMissingAsync(initialMarkup, new TestParameters(parseOptions, retainNonFixableDiagnostics: true)); + + [Fact] + public async Task LocalWithDisposableInitializer_DisposeCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|var a = new A()|]; + a.Dispose(); + } +} +"); + } + + [Fact] + public async Task LocalWithDisposableInitializer_NoDisposeCall_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + var a = [|new A()|]; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)); + } + + [Fact] + public async Task LocalWithDisposableAssignment_DisposeCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|A a; + a = new A(); + a.Dispose(); + + A b = new A(); + a = b; + a.Dispose();|] + } +}"); + } + + [Fact] + public async Task LocalWithDisposableAssignment_NoDisposeCall_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + A a; + a = [|new A()|]; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)); + } + + [Fact] + public async Task ParameterWithDisposableAssignment_DisposeCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A a) + { + [|a = new A(); + a.Dispose();|] + } +}"); + } + + [Fact] + public async Task ParameterWithDisposableAssignment_NoDisposeCall_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A a) + { + a = [|new A()|]; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)); + } + + [Fact] + public async Task OutAndRefParametersWithDisposableAssignment_NoDisposeCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(ref A a1, out A a2) + { + [|a1 = new A(); + a2 = new A();|] + } +}"); + } + + [Fact] + public async Task OutDisposableArgument_NoDisposeCall_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + + } +} + +class Test +{ + void M1(out A param) + { + param = new A(); + } + + void M2(out A param2) + { + M3(out param2); + } + + void M3(out A param3) + { + param3 = new A(); + } + + void Method() + { + [|A a; + M1(out a); + A local = a; + M1(out a); + + M1(out var a2); + + A a3; + M2(out a3)|]; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out a").WithLocation(32, 12), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out a").WithLocation(34, 12), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out var a2").WithLocation(36, 12), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out a3").WithLocation(39, 12)); + } + + [Fact] + public async Task OutDisposableArgument_DisposeCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [| + void M1(out A param) + { + param = new A(); + } + + void M2(out A param2) + { + M3(out param2); + } + + void M3(out A param3) + { + param3 = new A(); + } + + void Method() + { + A a; + M1(out a); + A local = a; + M1(out a); + + M1(out var a2); + + A a3; + M2(out a3); + + local.Dispose(); + a.Dispose(); + a2.Dispose(); + a3.Dispose(); + }|] +}"); + } + + [Fact] + public async Task TryGetSpecialCase_OutDisposableArgument_NoDisposeCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Generic; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class MyCollection +{ + private readonly Dictionary _map; + public MyCollection(Dictionary map) + { + _map = map; + } + + public bool ValueExists(int i) + { + return [|_map.TryGetValue(i, out var value);|] + } +}"); + } + + [Fact, WorkItem(2245, "https://github.com/dotnet/roslyn-analyzers/issues/2245")] + public async Task OutDisposableArgument_StoredIntoField_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + private A _a; + void M(out A param) + { + param = new A(); + } + + void Method() + { + [|M(out _a);|] // This is considered as an escape of interprocedural disposable creation. + } +}"); + } + + [Fact, WorkItem(2245, "https://github.com/dotnet/roslyn-analyzers/issues/2245")] + public async Task OutDisposableArgument_WithinTryXXXInvocation_DisposedOnSuccessPath_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Concurrent; + +public class C +{ + private readonly ConcurrentDictionary _dictionary; + public C(ConcurrentDictionary dictionary) + { + _dictionary = dictionary; + } + + [|public void Remove1(object key) + { + if (_dictionary.TryRemove(key, out IDisposable value)) + { + value.Dispose(); + } + } + + public void Remove2(object key) + { + if (!_dictionary.TryRemove(key, out IDisposable value)) + { + return; + } + + value.Dispose(); + }|] +}"); + } + + [Fact, WorkItem(2245, "https://github.com/dotnet/roslyn-analyzers/issues/2245")] + public async Task OutDisposableArgument_WithinTryXXXInvocation_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.Collections.Concurrent; + +public class C +{ + private readonly ConcurrentDictionary _dictionary; + public C(ConcurrentDictionary dictionary) + { + _dictionary = dictionary; + } + + public void Remove(object key) + { + if (_dictionary.TryRemove(key, [|out IDisposable value|])) + { + // value is not disposed. + } + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)); + } + + [Fact] + public async Task LocalWithMultipleDisposableAssignment_DisposeCallOnSome_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + A a; + [|a = new A(1); + a = new A(2); + a.Dispose(); + a = new A(3);|] + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(17, 13), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(20, 13)); + } + + [Fact] + public async Task FieldWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + public A a; + void M1(Test p) + { + [|p.a = new A(); + + Test l = new Test(); + l.a = new A(); + + this.a = new A();|] + } +}"); + } + + [Fact] + public async Task PropertyWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + public A a { get; set; } + void M1(Test p) + { + [|p.a = new A(); + + Test l = new Test(); + l.a = new A(); + + this.a = new A();|] + } +}"); + } + + [Fact] + public async Task Interprocedural_DisposedInHelper_MethodInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + public A a; + void M1(Test2 t2) + { + [|DisposeHelper(new A()); + t2.DisposeHelper_MethodOnDifferentType(new A()); + DisposeHelper_MultiLevelDown(new A());|] + } + + void DisposeHelper(A a) + { + a.Dispose(); + } + + void DisposeHelper_MultiLevelDown(A a) + { + DisposeHelper(a); + } +} + +class Test2 +{ + public A a; + public void DisposeHelper_MethodOnDifferentType(A a) + { + a.Dispose(); + } +}"); + } + + [Fact] + public async Task Interprocedural_DisposeOwnershipTransfer_MethodInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + public A a; + void M1() + { + [|DisposeOwnershipTransfer(new A()); + var t2 = new Test2(); + t2.DisposeOwnershipTransfer_MethodOnDifferentType(new A()); + DisposeOwnershipTransfer_MultiLevelDown(new A());|] + } + + void DisposeOwnershipTransfer(A a) + { + this.a = a; + } + + void DisposeOwnershipTransfer_MultiLevelDown(A a) + { + DisposeOwnershipTransfer(a); + } +} + +class Test2 +{ + public A a; + public void DisposeOwnershipTransfer_MethodOnDifferentType(A a) + { + this.a = a; + } +}"); + } + + [Fact] + public async Task Interprocedural_NoDisposeOwnershipTransfer_MethodInvocation_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + public A a; + void M1(Test2 t2) + { + [|NoDisposeOwnershipTransfer(new A(1)); + t2.NoDisposeOwnershipTransfer_MethodOnDifferentType(new A(2)); + NoDisposeOwnershipTransfer_MultiLevelDown(new A(3));|] + } + + void NoDisposeOwnershipTransfer(A a) + { + var str = a.ToString(); + var b = a; + } + + void NoDisposeOwnershipTransfer_MultiLevelDown(A a) + { + NoDisposeOwnershipTransfer(a); + } +} + +class Test2 +{ + public A a; + public void NoDisposeOwnershipTransfer_MethodOnDifferentType(A a) + { + var str = a.ToString(); + var b = a; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(17, 36), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(18, 61), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(19, 51)); + } + + [Fact, WorkItem(2136, "https://github.com/dotnet/roslyn-analyzers/issues/2136")] + public async Task Interprocedural_DisposedInHelper_ConstructorInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|new DisposeHelperType(new A()); + DisposeHelper_MultiLevelDown(new A());|] + } + + void DisposeHelper(A a) + { + new DisposeHelperType(a); + } + + void DisposeHelper_MultiLevelDown(A a) + { + DisposeHelper(a); + } +} + +class DisposeHelperType +{ + public DisposeHelperType(A a) + { + a.Dispose(); + } +}"); + } + + [Fact, WorkItem(2136, "https://github.com/dotnet/roslyn-analyzers/issues/2136")] + public async Task Interprocedural_DisposeOwnershipTransfer_ConstructorInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|new DisposableOwnerType(new A()); + DisposeOwnershipTransfer_MultiLevelDown(new A());|] + } + + void DisposeOwnershipTransfer(A a) + { + new DisposableOwnerType(a); + } + + void DisposeOwnershipTransfer_MultiLevelDown(A a) + { + DisposeOwnershipTransfer(a); + } +} + +class DisposableOwnerType +{ + public A a; + public DisposableOwnerType(A a) + { + this.a = a; + } +}"); + } + + [Fact, WorkItem(2136, "https://github.com/dotnet/roslyn-analyzers/issues/2136")] + public async Task Interprocedural_NoDisposeOwnershipTransfer_ConstructorInvocation_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|new NotDisposableOwnerType(new A(1)); + NoDisposeOwnershipTransfer_MultiLevelDown(new A(2));|] + } + + void NoDisposeOwnershipTransfer(A a) + { + new NotDisposableOwnerType(a); + } + + void NoDisposeOwnershipTransfer_MultiLevelDown(A a) + { + NoDisposeOwnershipTransfer(a); + } +} + +class NotDisposableOwnerType +{ + public A a; + public NotDisposableOwnerType(A a) + { + var str = a.ToString(); + var b = a; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(16, 36), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(17, 51)); + } + + [Fact] + public async Task DisposeOwnershipTransfer_AtConstructorInvocation_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" + + + A2 + +using System; + +class Test +{ + DisposableOwnerType M1() + { + [|return new DisposableOwnerType(new A());|] + } +} + + + + +using System; + +public class A : IDisposable +{ + public void Dispose() + { + } +} + +public class DisposableOwnerType +{ + public DisposableOwnerType(A a) + { + } +} + + +"); + } + + [Fact] + public async Task LocalWithDisposableAssignment_DisposeBoolCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + + } + + public void Dispose(bool b) + { + } +} + +class Test +{ + void M1() + { + [|A a; + a = new A(); + a.Dispose(true); + + A b = new A(); + a = b; + a.Dispose(true);|] + } +}"); + } + + [Fact] + public async Task LocalWithDisposableAssignment_CloseCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public void Close() + { + } +} + +class Test +{ + void M1() + { + [|A a; + a = new A(); + a.Close(); + + A b = new A(); + a = b; + a.Close();|] + } +}"); + } + + [Fact, WorkItem(1796, "https://github.com/dotnet/roslyn-analyzers/issues/1796")] + public async Task LocalWithDisposableAssignment_DisposeAsyncCall_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Threading.Tasks; + +class A : IDisposable +{ + public void Dispose() => DisposeAsync(); + + public Task DisposeAsync() => Task.CompletedTask; +} + +class Test +{ + async Task M1() + { + [|A a; + a = new A(); + await a.DisposeAsync(); + + A b = new A(); + a = b; + await a.DisposeAsync();|] + } +}"); + } + + [Fact] + public async Task ArrayElementWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A[] a) + { + [|a[0] = new A();|] // TODO: https://github.com/dotnet/roslyn-analyzers/issues/1577 + } +}"); + } + + [Fact] + public async Task ArrayElementWithDisposableAssignment_ConstantIndex_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A[] a) + { + [|a[0] = new A(); + a[0].Dispose();|] + } +}"); + } + + [Fact] + public async Task ArrayElementWithDisposableAssignment_NonConstantIndex_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A[] a, int i) + { + [|a[i] = new A(); + a[i].Dispose();|] + } +}"); + } + + [Fact] + public async Task ArrayElementWithDisposableAssignment_NonConstantIndex_02_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A[] a, int i, int j) + { + [|a[i] = new A(); + i = j; // Value of i is now unknown + a[i].Dispose();|] // We don't know the points to value of a[i], so don't flag 'new A()' + } +}"); + } + + [Fact] + public async Task ArrayInitializer_ElementWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [| A[] a = new A[] { new A() };|] // TODO: https://github.com/dotnet/roslyn-analyzers/issues/1577 + } +}"); + } + + [Fact] + public async Task ArrayInitializer_ElementWithDisposableAssignment_ConstantIndex_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|A[] a = new A[] { new A() }; + a[0].Dispose();|] + } +}"); + } + + [Fact] + public async Task ArrayInitializer_ElementWithDisposableAssignment_NonConstantIndex_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(int i) + { + [|A[] a = new A[] { new A() }; + a[i].Dispose();|] + } +}"); + } + + [Fact] + internal async Task CollectionInitializer_ElementWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Generic; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|List a = new List() { new A() };|] // TODO: https://github.com/dotnet/roslyn-analyzers/issues/1577 + } +}"); + } + + [Fact] + internal async Task CollectionInitializer_ElementWithDisposableAssignment_ConstantIndex_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Generic; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|List a = new List() { new A() }; + a[0].Dispose();|] + } +}"); + } + + [Fact] + internal async Task CollectionInitializer_ElementWithDisposableAssignment_NonConstantIndex_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Generic; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(int i) + { + [|List a = new List() { new A() }; + a[i].Dispose();|] + } +}"); + } + + [Fact] + internal async Task CollectionAdd_SpecialCases_ElementWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections; +using System.Collections.Generic; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class NonGenericList : ICollection +{ + public void Add(A item) + { + } + + public int Count => throw new NotImplementedException(); + + public object SyncRoot => throw new NotImplementedException(); + + public bool IsSynchronized => throw new NotImplementedException(); + + public void CopyTo(Array array, int index) + { + throw new NotImplementedException(); + } + + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } +} + +class Test +{ + void M1() + { + [|List a = new List(); + a.Add(new A(1)); + + A b = new A(2); + a.Add(b); + + NonGenericList l = new NonGenericList(); + l.Add(new A(3)); + + b = new A(4); + l.Add(b);|] + } +}"); + } + + [Fact] + internal async Task CollectionAdd_IReadOnlyCollection_SpecialCases_ElementWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class MyReadOnlyCollection : IReadOnlyCollection +{ + public void Add(A item) + { + } + + public int Count => throw new NotImplementedException(); + + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } +} + +class Test +{ + void M1() + { + [|var myReadOnlyCollection = new MyReadOnlyCollection(); + myReadOnlyCollection.Add(new A(1)); + A a = new A(2); + myReadOnlyCollection.Add(a); + + var bag = new ConcurrentBag(); + bag.Add(new A(3)); + A a2 = new A(4); + bag.Add(a2);|] + } +}"); + } + + [Fact] + public async Task MemberInitializerWithDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Generic; + +class A : IDisposable +{ + public int X; + public void Dispose() + { + } +} + +class Test +{ + public A a; + void M1() + { + [|var a = new Test { a = { X = 0 } };|] + } +}"); + } + + [Fact] + public async Task StructImplementingIDisposable_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +struct A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|var a = new A();|] + } +}"); + } + + [Fact] + public async Task NonUserDefinedConversions_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : A +{ +} + +class Test +{ + void M1() + { + [|object obj = new A(); // Implicit conversion from A to object + ((A)obj).Dispose(); // Explicit conversion from object to A + + A a = new B(); // Implicit conversion from B to A + a.Dispose();|] + } +}"); + } + + [Fact] + public async Task NonUserDefinedConversions_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : A +{ +} + +class Test +{ + void M1() + { + [|object obj = new A(); // Implicit conversion from A to object + A a = (A)new B();|] // Explicit conversion from B to A + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(19, 22), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new B()").WithLocation(20, 18)); + } + + [Fact] + public async Task UserDefinedConversions_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } + + public static implicit operator A(B value) + { + value.Dispose(); + return null; + } + + public static explicit operator B(A value) + { + value.Dispose(); + return null; + } +} + +class B : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + Test(string s) + { + } + + void M1() + { + [|A a = new B(); // Implicit user defined conversion + B b = (B)new A();|] // Explicit user defined conversion + } +}"); + } + + [Fact] + public async Task LocalWithDisposableAssignment_ByRef_DisposedInCallee_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(); + M2(ref a); + } + + void M2(ref A a) + { + a.Dispose(); + a = null; + }|] +}"); + } + + [Fact] + public async Task LocalWithDisposableAssignment_ByRefEscape_AbstractVirtualMethod_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +public class A : IDisposable +{ + public void Dispose() + { + } +} + +public abstract class Test +{ + void M1() + { + [|A a = new A(); + M2(ref a); + + a = new A(); + M3(ref a);|] + } + + public virtual void M2(ref A a) + { + } + + public abstract void M3(ref A a); +}"); + } + + [Fact] + public async Task LocalWithDisposableAssignment_OutRefKind_NotDisposed_Diagnostic() + { + // Local/parameter passed as out is not considered escaped. + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(); + M2(out a); + } + + void M2(out A a) + { + a = new A(); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(15, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out a").WithLocation(16, 12)); + } + + [Fact] + public async Task LocalWithDefaultOfDisposableAssignment_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1() + { + [|A a = default(A);|] + } +}"); + } + + [Fact] + public async Task NullCoalesce_NoDiagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A a) + { + [|A b = a ?? new A(); + b.Dispose(); + + A c = new A(); + A d = c ?? a; + d.Dispose(); + + a = new A(); + A e = a ?? new A(); + e.Dispose();|] + } +}"); + } + + [Fact] + public async Task NullCoalesce_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(A a) + { + A b = a ?? [|new A()|]; + a.Dispose(); + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(15, 20)); + } + + [Fact] + public async Task WhileLoop_DisposeOnBackEdge_NoDiagnostic() + { + // Need precise CFG to avoid false reports. + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + void M1(bool flag) + { + [|A a = new A(); + while (true) + { + a.Dispose(); + if (flag) + { + break; // All 'A' instances have been disposed on this path, so no diagnostic should be reported. + } + a = new A(); + }|] + } +}"); + } + + [Fact, WorkItem(1648, "https://github.com/dotnet/roslyn-analyzers/issues/1648")] + public async Task WhileLoop_MissingDisposeOnExit_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(1); // Allocated outside the loop and disposed inside a loop is not a recommended pattern and is flagged. + while (true) + { + a.Dispose(); + a = new A(2); // This instance will not be disposed on loop exit. + } + }|] +}", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(1)").WithLocation(16, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(20, 17)); + } + + [Fact] + public async Task WhileLoop_MissingDisposeOnEntry_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + public bool Flag; + [|void M1() + { + A a; + while ((a = new A(1)) != null) // This instance will never be disposed, but is not flagged as there is no feasible loop exit. + { + a = new A(2); + a.Dispose(); + } + } + + void M2(bool flag) + { + A a; + while ((a = new A(3)) != null) // This instance will never be disposed on loop exit. + { + if (Flag) + { + break; + } + a = new A(4); + a.Dispose(); + } + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(28, 21)); + } + + [Fact] + public async Task DoWhileLoop_DisposeOnBackEdge_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1(bool flag) + { + A a = new A(); + do + { + a.Dispose(); + if (flag) + { + break; // All 'A' instances have been disposed on this path, so no diagnostic should be reported. + } + a = new A(); + } while (true); + }|] +}"); + } + + [Fact] + public async Task DoWhileLoop_MissingDisposeOnExit_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(1); + do + { + a.Dispose(); + a = new A(2); // This instance will not be disposed on loop exit. + } while (true); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(20, 17)); + } + + [Fact] + public async Task DoWhileLoop_MissingDisposeOnEntry_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + do + { + a = new A(1); + a.Dispose(); + } while ((a = new A(2)) != null); // This instance will never be disposed, but it is not flagged as there is no feasible loop exit. + } + + void M2() + { + A a = null; + do + { + if (a != null) + { + break; + } + a = new A(3); + a.Dispose(); + } while ((a = new A(4)) != null); // This instance will never be disposed. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(4)").WithLocation(35, 23)); + } + + [Fact] + public async Task ForLoop_DisposeOnBackEdge_MayBeNotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1(bool flag) + { + A a = new A(1); // Allocation outside a loop, dispose inside a loop is not a recommended pattern and should fire diagnostic. + for (int i = 0; i < 10; i++) + { + a.Dispose(); + if (flag) + { + break; // All 'A' instances have been disposed on this path. + } + + a = new A(2); // This can leak on loop exit, and is flagged as a maybe disposed violation. + } + }|] +}", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(1)").WithLocation(16, 15), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(2)").WithLocation(25, 17)); + } + + [Fact] + public async Task ForLoop_MissingDisposeOnExit_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(1); // Allocation outside a loop, dispose inside a loop is not a recommended pattern and should fire diagnostic. + for (int i = 0; i < 10; i++) + { + a.Dispose(); + a = new A(2); // This instance will not be disposed on loop exit. + } + }|] +}", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(1)").WithLocation(16, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(20, 17)); + } + + [Fact] + public async Task ForLoop_MissingDisposeOnEntry_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + int i; + for (i = 0, a = new A(1); i < 10; i++) // This 'A' instance will never be disposed. + { + a = new A(2); + a.Dispose(); + } + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(18, 25)); + } + + [Fact] + public async Task IfStatement_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : A +{ +} + +class Test +{ + [|void M1(A a, string param) + { + A a1 = new A(); + B a2 = new B(); + A b; + if (param != null) + { + a = a1; + b = new B(); + } + else + { + a = a2; + b = new A(); + } + + a.Dispose(); // a points to either a1 or a2. + b.Dispose(); // b points to either instance created in if or else. + }|] +}"); + } + + [Fact] + public async Task IfStatement_02_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : A +{ +} + +class Test +{ + [|void M1(A a, string param, string param2) + { + A a1 = new A(); + B a2 = new B(); + A b; + if (param != null) + { + a = a1; + b = new B(); + + if (param == """") + { + a = new B(); + } + else + { + if (param2 != null) + { + b = new A(); + } + else + { + b = new B(); + } + } + } + else + { + a = a2; + b = new A(); + } + + a.Dispose(); // a points to either a1 or a2 or instance created in 'if(param == """")'. + b.Dispose(); // b points to either instance created in outer if or outer else or innermost if or innermost else. + }|] +}"); + } + + [Fact] + public async Task IfStatement_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public A() { } + public void Dispose() + { + } +} + +class B : A +{ +} + +class C : B +{ +} + +class D : C +{ +} + +class E : D +{ +} + +class Test +{ + [|void M1(A a, string param, string param2) + { + A a1 = new A(1); // Maybe disposed. + B a2 = new B(); // Never disposed. + A b; + if (param != null) + { + a = a1; + b = new C(); // Never disposed. + } + else + { + a = a2; + b = new D(); // Never disposed. + } + + // a points to either a1 or a2. + // b points to either instance created in if or else. + + if (param != null) + { + A c = new A(2); + a = c; + b = a1; + } + else + { + C d = new E(); + b = d; + a = b; + } + + a.Dispose(); // a points to either c or d. + b.Dispose(); // b points to either a1 or d. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new B()").WithLocation(34, 16), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new C()").WithLocation(39, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new D()").WithLocation(44, 17)); + } + + [Fact] + public async Task IfStatement_02_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public A() { } + public void Dispose() + { + } +} + +class B : A +{ +} + +class C : B +{ +} + +class D : C +{ +} + +class E : D +{ +} + +class Test +{ + [|void M1(A a, string param, string param2) + { + A a1 = new B(); // Never disposed + B a2 = new C(); // Never disposed + A b; + if (param != null) + { + a = a1; + b = new A(1); // Maybe disposed + + if (param == """") + { + a = new D(); // Never disposed + } + else + { + if (param2 != null) + { + b = new A(2); // Maybe disposed + } + else + { + b = new A(3); // Maybe disposed + if (param == """") + { + b = new A(4); // Maybe disposed + } + } + + if (param2 == """") + { + b.Dispose(); // b points to one of the three instances of A created above. + b = new A(5); // Always disposed + } + } + } + else + { + a = a2; + b = new A(6); // Maybe disposed + if (param2 != null) + { + a = new A(7); // Always disposed + } + else + { + a = new A(8); // Always disposed + b = new A(9); // Always disposed + } + + a.Dispose(); + } + + b.Dispose(); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new B()").WithLocation(33, 16), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new C()").WithLocation(34, 16), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new D()").WithLocation(43, 21)); + } + + [Fact] + public async Task UsingStatement_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + using (var a = new A()) + { + } + + A b; + using (b = new A()) + { + } + + using (A c = new A(), d = new A()) + { + } + + A e = new A(); + using (e) + { + } + + using (A f = null) + { + } + }|] +}"); + } + + [Fact, WorkItem(2201, "https://github.com/dotnet/roslyn-analyzers/issues/2201")] + public async Task UsingStatementInTryCatch_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System.IO; + +class Test +{ + void M1() + { + try + { + [|using (var ms = new MemoryStream())|] + { + } + } + catch + { + } + } +}"); + } + + [Fact, WorkItem(2201, "https://github.com/dotnet/roslyn-analyzers/issues/2201")] + public async Task NestedTryFinallyInTryCatch_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System.IO; + +class Test +{ + void M1() + { + try + { + [|var ms = new MemoryStream();|] + try + { + } + finally + { + ms?.Dispose(); + } + } + catch + { + } + } +}"); + } + + [Fact] + public async Task ReturnStatement_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Collections.Generic; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|A M1() + { + return new A(); + } + + A M2(A a) + { + a = new A(); + return a; + } + + A M3(A a) + { + a = new A(); + A b = a; + return b; + } + + A M4(A a) => new A(); + + IEnumerable M5() + { + yield return new A(); + }|] +}"); + } + + [Fact] + public async Task ReturnStatement_02_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : I, IDisposable +{ + public void Dispose() + { + } +} + +interface I +{ +} + +class Test +{ + [|I M1() + { + return new A(); + } + + I M2() + { + return new A() as I; + }|] +}"); + } + + [Fact] + public async Task LocalFunctionInvocation_EmptyBody_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + a = new A(); + + void MyLocalFunction() + { + }; + + MyLocalFunction(); // This should not change state of 'a'. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(16, 13)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunctionInvocation_DisposesCapturedValue_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(); + + void MyLocalFunction() + { + a.Dispose(); + }; + + MyLocalFunction(); // This should change state of 'a' to be Disposed. + }|] +}"); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunctionInvocation_CapturedValueAssignedNewDisposable_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + + void MyLocalFunction() + { + a = new A(); + }; + + MyLocalFunction(); // This should change state of 'a' to be NotDisposed and fire a diagnostic. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(19, 17)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunctionInvocation_ChangesCapturedValueContextSensitive_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + + void MyLocalFunction(A b) + { + a = b; + }; + + MyLocalFunction(new A()); // This should change state of 'a' to be NotDisposed and fire a diagnostic. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(22, 25)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreationNotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + void MyLocalFunction() + { + A a = new A(); // This should fire a diagnostic. + }; + + MyLocalFunction(); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(17, 19)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreation_InvokedMultipleTimes_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + void MyLocalFunction(int i) + { + A a = new A(); // This should fire a single diagnostic. + }; + + MyLocalFunction(1); + MyLocalFunction(2); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(17, 19)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreationReturned_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A MyLocalFunction(int i) + { + return new A(); + }; + + var a = MyLocalFunction(1); // This should fire a diagnostic. + var b = MyLocalFunction(2); // This should fire a diagnostic. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "MyLocalFunction(1)").WithLocation(20, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "MyLocalFunction(2)").WithLocation(21, 17)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreationReturned_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A MyLocalFunction() + { + return new A(); + }; + + var a = MyLocalFunction(); + a.Dispose(); + }|] +}"); + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreationAssignedToRefOutParameter_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a1 = null, a2; + MyLocalFunction(ref a1, out a2); // This should fire two diagnostics. + return; + + void MyLocalFunction(ref A param1, out A param2) + { + param1 = new A(); + param2 = new A(); + }; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref a1").WithLocation(16, 25), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out a2").WithLocation(16, 33)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreationAssignedToRefOutParameter_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a1 = null, a2; + MyLocalFunction(ref a1, out a2); + a1.Dispose(); + a2.Dispose(); + return; + + void MyLocalFunction(ref A param1, out A param2) + { + param1 = new A(); + param2 = new A(); + }; + }|] +}"); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreationAssignedToRefOutParameter_MultipleCalls_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a1 = null, a2; + MyLocalFunction(ref /*1*/a1, out /*2*/a2); // This should fire two diagnostics. + MyLocalFunction(ref /*3*/a1, out /*4*/a2); // No diagnostics. + a1.Dispose(); + a2.Dispose(); + return; + + void MyLocalFunction(ref A param1, out A param2) + { + param1 = new A(); + param2 = new A(); + }; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref /*1*/a1").WithLocation(16, 25), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out /*2*/a2").WithLocation(16, 38)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreation_MultipleLevelsBelow_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a1 = null, a2; + MyLocalFunction1(ref /*1*/a1, out /*2*/a2); // This should fire two diagnostics. + return; + + void MyLocalFunction1(ref A param1, out A param2) + { + MyLocalFunction2(ref /*3*/param1, out /*4*/param2); + }; + + void MyLocalFunction2(ref A param3, out A param4) + { + param3 = new A(); + param4 = new A(); + }; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref /*1*/a1").WithLocation(16, 26), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out /*2*/a2").WithLocation(16, 39)); + + // VB has no local functions. + } + + [Fact] + public async Task LocalFunction_DisposableCreation_MultipleLevelsBelow_Nested_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a1 = null, a2; + MyLocalFunction1(ref /*1*/a1, out /*2*/a2); // This should fire two diagnostics. + return; + + void MyLocalFunction1(ref A param1, out A param2) + { + MyLocalFunction2(ref /*3*/param1, out /*4*/param2); + + void MyLocalFunction2(ref A param3, out A param4) + { + param3 = new A(); + param4 = new A(); + }; + }; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref /*1*/a1").WithLocation(16, 26), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out /*2*/a2").WithLocation(16, 39)); + + // VB has no local functions. + } + + [Fact] + public async Task LambdaInvocation_EmptyBody_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + a = new A(); + + System.Action myLambda = () => + { + }; + + myLambda(); // This should not change state of 'a'. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(16, 13)); + } + + [Fact] + public async Task LambdaInvocation_DisposesCapturedValue_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a = new A(); + + System.Action myLambda = () => + { + a.Dispose(); + }; + + myLambda(); // This should change state of 'a' to be Disposed. + }|] +}"); + } + + [Fact] + public async Task LambdaInvocation_CapturedValueAssignedNewDisposable_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + + System.Action myLambda = () => + { + a = new A(); + }; + + myLambda(); // This should change state of 'a' to be NotDisposed and fire a diagnostic. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(19, 17)); + } + + [Fact] + public async Task LambdaInvocation_ChangesCapturedValueContextSensitive_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + + System.Action myLambda = b => + { + a = b; + }; + + myLambda(new A()); // This should change state of 'a' to be NotDisposed and fire a diagnostic. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(22, 18)); + } + + [Fact] + public async Task Lambda_DisposableCreationNotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + System.Action myLambda = () => + { + A a = new A(); // This should fire a diagnostic. + }; + + myLambda(); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(17, 19)); + } + + [Fact] + public async Task Lambda_DisposableCreation_InvokedMultipleTimes_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + System.Action myLambda = () => + { + A a = new A(); // This should fire a single diagnostic. + }; + + myLambda(); + myLambda(); + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(17, 19)); + } + + [Fact] + public async Task Lambda_DisposableCreationReturned_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + System.Func myLambda = () => + { + return new A(); + }; + + var a = myLambda(/*1*/); // This should fire a diagnostic. + var b = myLambda(/*2*/); // This should fire a diagnostic. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "myLambda(/*1*/)").WithLocation(20, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "myLambda(/*2*/)").WithLocation(21, 17)); + } + + [Fact] + public async Task Lambda_DisposableCreationReturned_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + System.Func myLambda = () => + { + return new A(); + }; + + var a = myLambda(); + a.Dispose(); + }|] +}"); + } + + [Fact] + public async Task Lambda_DisposableCreationAssignedToRefOutParameter_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + delegate void MyDelegate(ref A a1, out A a2); + [|void M1() + { + MyDelegate myDelegate = (ref A param1, out A param2) => + { + param1 = new A(); + param2 = new A(); + }; + + A a1 = null, a2; + myDelegate(ref a1, out a2); // This should fire two diagnostics. + return; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref a1").WithLocation(23, 20), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out a2").WithLocation(23, 28)); + } + + [Fact] + public async Task Lambda_DisposableCreationAssignedToRefOutParameter_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + delegate void MyDelegate(ref A a1, out A a2); + [|void M1() + { + MyDelegate myDelegate = (ref A param1, out A param2) => + { + param1 = new A(); + param2 = new A(); + }; + + A a1 = null, a2; + myDelegate(ref a1, out a2); + a1.Dispose(); + a2.Dispose(); + return; + }|] +}"); + } + + [Fact] + public async Task Lambda_DisposableCreationAssignedToRefOutParameter_MultipleCalls_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + delegate void MyDelegate(ref A a1, out A a2); + [|void M1() + { + MyDelegate myDelegate = (ref A param1, out A param2) => + { + param1 = new A(); + param2 = new A(); + }; + + A a1 = null, a2; + myDelegate(ref /*1*/a1, out /*2*/a2); // This should fire two diagnostics. + myDelegate(ref /*3*/a1, out /*4*/a2); // No diagnostics. + a1.Dispose(); + a2.Dispose(); + return; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref /*1*/a1").WithLocation(23, 20), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out /*2*/a2").WithLocation(23, 33)); + } + + [Fact] + public async Task Lambda_DisposableCreation_MultipleLevelsBelow_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + delegate void MyDelegate(ref A a1, out A a2); + [|void M1() + { + MyDelegate myDelegate2 = (ref A param3, out A param4) => + { + param3 = new A(); + param4 = new A(); + }; + + MyDelegate myDelegate1 = (ref A param1, out A param2) => + { + myDelegate2(ref /*3*/param1, out /*4*/param2); + }; + + A a1 = null, a2; + myDelegate1(ref /*1*/a1, out /*2*/a2); // This should fire two diagnostics. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref /*1*/a1").WithLocation(28, 21), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out /*2*/a2").WithLocation(28, 34)); + } + + [Fact] + public async Task Lambda_DisposableCreation_MultipleLevelsBelow_Nested_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + delegate void MyDelegate(ref A a1, out A a2); + [|void M1() + { + MyDelegate myDelegate1 = (ref A param1, out A param2) => + { + MyDelegate myDelegate2 = (ref A param3, out A param4) => + { + param3 = new A(); + param4 = new A(); + }; + + myDelegate2(ref /*3*/param1, out /*4*/param2); + }; + + A a1 = null, a2; + myDelegate1(ref /*1*/a1, out /*2*/a2); // This should fire two diagnostics. + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "ref /*1*/a1").WithLocation(28, 21), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "out /*2*/a2").WithLocation(28, 34)); + } + + [Fact] + public async Task Lambda_InvokedFromInterprocedural_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a1 = new A(); + M2(() => a1.Dispose()); + } + + void M2(Action disposeCallback) => disposeCallback();|] +}"); + } + + [Fact] + internal async Task Lambda_MayBeInvokedFromInterprocedural_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + public bool Flag; + [|void M1() + { + A a1 = new A(1); + M2(() => a1.Dispose()); + + A a2 = new A(2); + if (Flag) + M3(() => a2.Dispose()); + } + + void M2(Action disposeCallback) + { + if (Flag) + disposeCallback(); + } + + void M3(Action disposeCallback) => disposeCallback();|] +}", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(1)").WithLocation(17, 16), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(2)").WithLocation(20, 16)); + } + + [Fact] + public async Task DelegateInvocation_EmptyBody_NoArguments_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + a = new A(); + + System.Action myDelegate = M2; + myDelegate(); // This should not change state of 'a' as it is not passed as argument. + }|] + + void M2() { } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(16, 13)); + } + + [Fact] + public async Task DelegateInvocation_PassedAsArgumentButNotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + a = new A(); + + System.Action myDelegate = M2; + myDelegate(a); // This should not change state of 'a'. + }|] + + void M2(A a) { } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(16, 13)); + } + + [Fact, WorkItem(1813, "https://github.com/dotnet/roslyn-analyzers/issues/1813")] + public async Task DelegateInvocation_DisposesCapturedValue_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + A a; + a = new A(); + + System.Action myDelegate = M2; + myDelegate(a); // This should change state of 'a' to be disposed as we perform interprocedural analysis. + }|] + + void M2(A a) => a.Dispose(); +}"); + } + + [Fact] + public async Task DisposableCreationNotAssignedToAVariable_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public int X; + public A(int i) { } + + public void Dispose() + { + } + + public void M() + { + } +} + +class Test +{ + [|void M1() + { + new A(1); + new A(2).M(); + var x = new A(3).X; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(22, 9), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(23, 9), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(24, 17)); + } + + [Fact] + public async Task DisposableCreationPassedToDisposableConstructor_NoDiagnostic() + { + // Dispose ownership transfer + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : IDisposable +{ + private readonly A _a; + public B(A a) + { + _a = a; + } + + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + var b = new B(new A()); + b.Dispose(); + + var a = new A(); + B b2 = null; + try + { + b2 = new B(a); + } + finally + { + if (b2 != null) + { + b2.Dispose(); + } + } + + var a2 = new A(); + B b3 = null; + try + { + b3 = new B(a2); + } + finally + { + if (b3 != null) + { + b3.Dispose(); + } + } + }|] +}"); + } + + [Fact] + public async Task DisposableObjectOnlyDisposedOnExceptionPath_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + var a = new A(1); + try + { + ThrowException(); + } + catch (Exception) + { + a.Dispose(); + } + } + + void M2() + { + var a = new A(2); + try + { + ThrowException(); + } + catch (System.IO.IOException) + { + a.Dispose(); + } + } + + void M3() + { + var a = new A(3); + try + { + ThrowException(); + } + catch (System.IO.IOException) + { + a.Dispose(); + } + catch (Exception) + { + a.Dispose(); + } + } + + void M4(bool flag) + { + var a = new A(4); + try + { + ThrowException(); + } + catch (System.IO.IOException) + { + if (flag) + { + a.Dispose(); + } + } + }|] + + void ThrowException() + { + throw new NotImplementedException(); + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(16, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(29, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(42, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(4)").WithLocation(59, 17)); + } + + [Fact] + public async Task DisposableObjectDisposed_FinallyPath_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + var a = new A(); + try + { + ThrowException(); + } + finally + { + a.Dispose(); + } + } + + void M2() + { + var a = new A(); + try + { + ThrowException(); + } + catch (Exception) + { + } + finally + { + a.Dispose(); + } + } + + void M3() + { + var a = new A(); + try + { + ThrowException(); + a.Dispose(); + a = null; + } + catch (System.IO.IOException) + { + } + finally + { + if (a != null) + { + a.Dispose(); + } + } + }|] + + void ThrowException() + { + throw new NotImplementedException(); + } +}"); + } + + [Fact] + public async Task DelegateCreation_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class Test +{ + [|void M1() + { + Func createA = M2; + A a = createA(); + a.Dispose(); + } + + A M2() + { + return new A(); + }|] +}"); + } + + [Fact] + public async Task MultipleReturnStatements_AllInstancesReturned_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [|A M1(bool flag) + { + A a; + if (flag) + { + A a2 = new A(); + a = a2; + return a; + } + + A a3 = new A(); + a = a3; + return a; + }|] +}"); + } + + [Fact] + public async Task MultipleReturnStatements_AllInstancesEscapedWithOutParameter_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [|void M1(bool flag, out A a) + { + if (flag) + { + A a2 = new A(); + a = a2; + return; + } + + A a3 = new A(); + a = a3; + return; + }|] +}"); + } + + [Fact] + public async Task MultipleReturnStatements_AllButOneInstanceReturned_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +public class Test +{ + [|A M1(int flag, bool flag2, bool flag3) + { + A a = null; + if (flag == 0) + { + A a2 = new A(1); // Escaped with return inside below nested 'if', not disposed on other paths. + a = a2; + + if (!flag2) + { + if (flag3) + { + return a; + } + } + } + else + { + a = new A(2); // Escaped with return inside below nested 'else', not disposed on other paths. + if (flag == 1) + { + a = new A(3); // Never disposed. + } + else + { + if (flag3) + { + a = new A(4); // Escaped with return inside below 'else', not disposed on other paths. + } + + if (flag2) + { + } + else + { + return a; + } + } + } + + A a3 = new A(5); // Always escaped with below return, ensure no diagnostic. + a = a3; + return a; + }|] +}", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(1)").WithLocation(19, 20), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(2)").WithLocation(32, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(35, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(4)").WithLocation(41, 25)); + } + + [Fact] + public async Task MultipleReturnStatements_AllButOneInstanceEscapedWithOutParameter_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +class B : A +{ +} + +public class Test +{ + [|void M1(int flag, bool flag2, bool flag3, out A a) + { + a = null; + if (flag == 0) + { + A a2 = new A(); // Escaped with return inside below nested 'if'. + a = a2; + + if (!flag2) + { + if (flag3) + { + return; + } + } + } + else + { + a = new A(); // Escaped with return inside below nested 'else'. + if (flag == 1) + { + a = new B(); // Never disposed. + } + else + { + if (flag3) + { + a = new A(); // Escaped with return inside below 'else'. + } + + if (flag2) + { + } + else + { + return; + } + } + } + + A a3 = new A(); // Escaped with below return. + a = a3; + return; + }|] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new B()").WithLocation(38, 21)); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_AssignedToTuple_Escaped_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [|(A, int) M1() + { + A a = new A(); + return (a, 0); + } + + (A, int) M2() + { + A a = new A(); + (A, int) b = (a, 0); + return b; + }|] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + internal async Task DisposableAllocation_AssignedToTuple_Escaped_SpecialCases_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [| + // Nested tuple + ((A, int), int) M1() + { + A a = new A(); + ((A, int), int) b = ((a, 0), 1); + return b; + } + + // Declaration expression target + A M2() + { + A a = new A(); + var ((a2, x), y) = ((a, 0), 1); + return a2; + } + + // Declaration expression target with discards + A M3() + { + A a = new A(); + var ((a2, _), _) = ((a, 0), 1); + return a2; + } + + // Declaration expressions in target + A M4() + { + A a = new A(); + ((var a2, var x), var y) = ((a, 0), 1); + return a2; + } + + // Discards in target + A M5() + { + A a = new A(); + ((var a2, _), _) = ((a, 0), 1); + return a2; + } + + // Tuple with multiple disposable escape + (A, A) M6() + { + A a = new A(); + A a2 = new A(); + var b = (a, a2); + return b; + } + |] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_AssignedToTuple_NotDisposed_SpecialCases_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + + public void Dispose() + { + } +} + +public class Test +{ + [| + // Nested tuple + ((A, int), (A, int)) M1() + { + A a = new A(1); // Should be flagged. + A a2 = new A(2); + ((A, int), (A, int)) b = ((a2, 0), (a2, 0)); + return b; + } + + // Declaration expression target + A M2() + { + A a = new A(3); // Should be flagged. + var ((a2, x), y) = ((a, 0), 1); + return null; + } + + // Declaration expression target with discards + A M3() + { + A a = new A(4); // Should be flagged. + var ((a2, _), _) = ((a, 0), 1); + return null; + } + + // Declaration expressions in target + A M4() + { + A a = new A(5); // Should be flagged. + ((var a2, var x), var y) = ((a, 0), 1); + return null; + } + + // Discards in target + A M5() + { + A a = new A(6); // Should be flagged. + ((var a2, _), _) = ((a, 0), 1); + return null; + } + + // Tuple with multiple disposable escape + (A, A) M6() + { + A a = new A(7); // Should be flagged. + A a2 = new A(8); + var b = (a2, a2); + return b; + } + |] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs, + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(19, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(28, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(4)").WithLocation(36, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(5)").WithLocation(44, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(6)").WithLocation(52, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(7)").WithLocation(60, 15)); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_EscapedTupleLiteral_SpecialCases_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [| + // Tuple literal escaped cases. + ((A, int), int) M1() + { + A a = new A(); + return ((a, 0), 1); + } + + (A, A) M2() + { + A a = new A(); + A a2 = new A(); + return (a, a2); + } + + void M3(out (A, A) arg) + { + A a = new A(); + A a2 = new A(); + arg = (a, a2); + } + + void M4(out (A, A) arg) + { + A a = new A(); + A a2 = new A(); + var a3 = (a, a2); + arg = a3; + } + + void M5(ref (A, A) arg) + { + A a = new A(); + A a2 = new A(); + var a3 = (a, a2); + arg = a3; + } + |] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_AddedToTupleLiteral_SpecialCases_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +public class Test +{ + [| + // Tuple literal assignment cases. + void M1() + { + A a = new A(1); + var x = ((a, 0), 1); + } + + void M2() + { + A a = new A(2); + A a2 = new A(3); + var x = (a, a2); + } + + void M3(out (A, A) arg) + { + A a = new A(4); + A a2 = new A(5); + arg = (a, a2); + arg = default((A, A)); + } + + void M4(out (A, A) arg) + { + A a = new A(6); + A a2 = new A(7); + var a3 = (a, a2); + arg = a3; + arg = default((A, A)); + } + |] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs, + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(18, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(24, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(25, 16), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(4)").WithLocation(31, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(5)").WithLocation(32, 16), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(6)").WithLocation(39, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(7)").WithLocation(40, 16)); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_AssignedToTuple_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [|void M1() + { + A a = new A(); + var b = (a, 0); + } + + void M2() + { + A a = new A(); + (A, int) b = (a, 0); + }|] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs, + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(15, 15), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A()").WithLocation(21, 15)); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_AssignedToTuple_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [|void M1() + { + A a = new A(); + var b = (a, 0); + b.a.Dispose(); + } + + void M2() + { + A a = new A(); + (A, int) b = (a, 0); + a.Dispose(); + }|] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs, + parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3)); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_AssignedToTuple_Item1_Disposed_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public void Dispose() + { + } +} + +public class Test +{ + [|void M1() + { + A a = new A(); + var b = (a, 0); + b.Item1.Dispose(); + }|] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs, + parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3)); + } + + [Fact, WorkItem(1571, "https://github.com/dotnet/roslyn-analyzers/issues/1571")] + public async Task DisposableAllocation_DeconstructionAssignmentToTuple_DeconstructMethod_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.Collections.Generic; + +internal static class KeyValuePairExtensions +{ + public static void Deconstruct(this KeyValuePair pair, out TKey key, out TValue value) + { + key = pair.Key; + value = pair.Value; + } +} + +class A : IDisposable +{ + public A(int i) { } + public int X { get; } + public void Dispose() + { + } + + public int M() => 0; +} + +public class Test +{ + [|void M1(IDictionary map) + { + foreach ((A a, _) in map) + { + var x = new A(1); + var y = a.M(); + } + } + + void M2(IDictionary map) + { + foreach (var (a, _) in map) + { + var x = new A(2); + var y = a.M(); + } + } + + void M3(KeyValuePair pair, int y) + { + A a; + (a, y) = pair; + var x = new A(3); + }|] +}" + TestResources.NetFX.ValueTuple.tuplelib_cs, + parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(31, 21), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(40, 21), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(49, 17)); + } + + [Fact] + public async Task DifferentDisposePatternsInFinally_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [| + void M1() + { + // Allocated before try, disposed in finally with conditional access. + A a = new A(1); + try + { + } + finally + { + a?.Dispose(); + } + } + + void M2() + { + // Allocated in try, disposed in finally with conditional access. + A a = null; + try + { + a = new A(2); + } + finally + { + a?.Dispose(); + } + } + + void M3() + { + // Allocated before try, disposed in finally with null check. + A a = new A(3); + try + { + } + finally + { + if (a != null) + { + a.Dispose(); + } + } + } + + void M4() + { + // Allocated in try, disposed in finally with null check. + A a = null; + try + { + a = new A(4); + } + finally + { + if (a != null) + { + a.Dispose(); + } + } + } + + void M5() + { + // Allocated before try, disposed in finally with helper method. + A a = new A(5); + try + { + } + finally + { + DisposeHelper(a); + } + } + + void M6() + { + // Allocated in try, disposed in finally with helper method. + A a = null; + try + { + a = new A(6); + } + finally + { + DisposeHelper(a); + } + } + + void DisposeHelper(IDisposable a) + { + if (a != null) + { + a.Dispose(); + } + } + + void M7(bool flag) + { + // Allocated before try, disposed in try and assigned to null, disposed in finally with conditional access. + A a = new A(7); + try + { + if (flag) + { + a.Dispose(); + a = null; + } + } + finally + { + a?.Dispose(); + } + } + + void M8(bool flag1, bool flag2) + { + // Conditionally allocated in try, disposed in try and assigned to null, disposed in finally with conditional access. + A a = null; + try + { + if (flag1) + { + a = new A(8); + } + + if (flag2) + { + a.Dispose(); + a = null; + } + } + finally + { + a?.Dispose(); + } + } + + void M9(bool flag) + { + // Allocated before try, disposed in catch and all exit points from try, but not in finally. + A a = new A(9); + try + { + if (flag) + { + a.Dispose(); + a = null; + return; + } + + a.Dispose(); + } + catch (Exception ex) + { + a?.Dispose(); + } + finally + { + } + } + + void M10(bool flag1, bool flag2) + { + // Conditionally allocated in try, disposed in catch and all exit points from try, but not in finally. + A a = null; + try + { + if (flag1) + { + a = new A(10); + } + + if (flag2) + { + a?.Dispose(); + return; + } + + if (a != null) + { + a.Dispose(); + } + } + catch (Exception ex) + { + a?.Dispose(); + } + finally + { + } + } + + private IDisposable A; + void M11(bool flag) + { + // Allocated before try, escaped or disposed at all exit points from try, and disposed with conditional access in finally. + A a = new A(9); + try + { + if (flag) + { + a.Dispose(); + a = null; + return; + } + + this.A = a; // Escaped. + a = null; + } + finally + { + a?.Dispose(); + } + } + + void M12(bool flag1, bool flag2) + { + // Conditionally allocated in try, escaped or disposed at all exit points from try, and disposed with conditional access in finally. + A a = null; + try + { + if (flag1) + { + a = new A(10); + } + + if (flag2) + { + this.A = a; // Escaped. + a = null; + return; + } + + if (a != null) + { + a.Dispose(); + a = null; + } + } + finally + { + a?.Dispose(); + } + } + |] +}"); + } + + [Fact] + public async Task DifferentDisposePatternsInFinally_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; + +class A : IDisposable +{ + public A(int i) { } + public void Dispose() + { + } +} + +class Test +{ + [| + void M1(bool flag) + { + // Allocated before try, disposed only on some paths in finally with conditional access. + A a = new A(1); + try + { + } + finally + { + if (flag) + { + a?.Dispose(); + } + } + } + + void M2(bool flag) + { + // Allocated in try, disposed only on some paths in finally with conditional access. + A a = null; + try + { + a = new A(2); + } + finally + { + if (flag) + { + a?.Dispose(); + } + } + } + + void M3(bool flag) + { + // Allocated before try, disposed in finally with null checks on different variable. + // It is not recommended to have dispose logic of a variable depend on multiple variables/flags, as the + // lifetime of allocations might change when code within the try is refactored. + A a = null; + A b = null; + try + { + if (flag) + { + a = new A(3); + b = new A(31); + } + } + finally + { + if (b != null) + { + a.Dispose(); + b.Dispose(); + } + } + } + + void M4(bool flag) + { + // Allocated in try, disposed in finally with null checks on multiple variables. + // It is not recommended to have dispose logic of a variable depend on another variable, as the + // lifetime of allocations might change when code within the try is refactored. + A a = null; + A b = null; + try + { + if (flag) + { + a = new A(4); + b = new A(41); + } + } + finally + { + if (a != null && b != null) + { + a.Dispose(); + b.Dispose(); + } + } + } + + void M5(bool flag) + { + // Allocated before try, disposed on some paths in finally with helper method. + A a = new A(5); + try + { + } + finally + { + DisposeHelper(a, flag); + } + } + + void M6(bool flag) + { + // Allocated in try, disposed in finally with helper method depending on a bool check. + // It is not recommended to have dispose logic of a variable depend on another flag, as the + // lifetime of allocation and flag value might change when code within the try is refactored. + A a = null; + try + { + if (flag) + { + a = new A(6); + } + } + finally + { + DisposeHelper(a, flag); + } + } + + void DisposeHelper(IDisposable a, bool flag) + { + if (flag) + { + a?.Dispose(); + } + } + + void M7(bool flag) + { + // Allocated before try, leaked on some paths in try, disposed in finally with conditional access. + A a = new A(7); + try + { + if (flag) + { + a = null; // Leaked here, but need path sensitive analysis to flag this. + } + } + finally + { + a?.Dispose(); + } + } + + void M8(bool flag1, bool flag2) + { + // Conditionally allocated in try, leaked on some paths in try, disposed in finally with conditional access. + A a = null; + try + { + if (flag1) + { + a = new A(8); + } + + if (flag2) + { + a.Dispose(); + a = null; + } + else + { + a = null; // Leaked here, needs path sensitive analysis. + } + } + finally + { + a?.Dispose(); + } + } + + void M9(bool flag) + { + // Allocated before try, disposed in catch and but leaked from some exit points in try. + A a = new A(9); + try + { + if (flag) + { + a = null; // Leaked here. + return; + } + + a.Dispose(); + } + catch (Exception ex) + { + a?.Dispose(); + } + finally + { + } + } + + void M10(bool flag1, bool flag2) + { + // Conditionally allocated in try, leaked from some exit points in catch. + A a = null; + try + { + if (flag1) + { + a = new A(10); + } + + if (flag2) + { + a?.Dispose(); + return; + } + + if (a != null) + { + a.Dispose(); + } + } + catch (Exception ex) + { + if (flag1) + { + a?.Dispose(); // Leaked here, but need enhanced exceptional path dispose analysis to flag this. + } + } + finally + { + } + } + + private IDisposable A; + void M11(bool flag) + { + // Allocated before try, leaked before escaped at some points in try. + A a = new A(11); + try + { + if (flag) + { + a.Dispose(); + a = null; + return; + } + + a = null; // Leaked here. + this.A = a; // Escaped has no effect as it is already leaked. + } + finally + { + a?.Dispose(); + } + } + + void M12(bool flag1, bool flag2, bool flag3) + { + // Conditionally allocated in try, escaped and leaked on separate exit points from try, and disposed with conditional access in finally. + A a = null; + try + { + if (flag1) + { + a = new A(12); + } + + if (flag2) + { + this.A = a; // Escaped. + a = null; + return; + } + else if (flag3) + { + a = new A(121); // Previous allocation potentially leaked here, but need path sensitive analysis to flag here. + } + } + finally + { + a?.Dispose(); + } + } + |] +}", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(1)").WithLocation(18, 15), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(2)").WithLocation(37, 17), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(3)").WithLocation(59, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(4)").WithLocation(84, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(41)").WithLocation(85, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(5)").WithLocation(101, 15), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(6)").WithLocation(121, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(8)").WithLocation(163, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(9)").WithLocation(185, 15), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "new A(11)").WithLocation(243, 15)); + } + + [Fact, WorkItem(2212, "https://github.com/dotnet/roslyn-analyzers/issues/2212")] + public async Task ReturnDisposableObjectWrappenInTask_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Threading.Tasks; + +class C : IDisposable +{ + public void Dispose() + { + } + + public Task M1_Task() + { + [|return Task.FromResult(new C());|] + } +}"); + } + + [Fact, WorkItem(2212, "https://github.com/dotnet/roslyn-analyzers/issues/2212")] + public async Task AwaitedButNotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.Threading.Tasks; + +class C : IDisposable +{ + public void Dispose() + { + } + + [| + public Task M1_Task() + { + return Task.FromResult(new C()); + } + + public async Task M2_Task() + { + var c = await M1_Task().ConfigureAwait(false); + } + |] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "await M1_Task().ConfigureAwait(false)").WithLocation(19, 17)); + } + + [Fact, WorkItem(2212, "https://github.com/dotnet/roslyn-analyzers/issues/2212")] + public async Task AwaitedButNotDisposed_TaskWrappingField_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.Threading.Tasks; + +class C : IDisposable +{ + private C _c; + public void Dispose() + { + } + + [| + public Task M1_Task() + { + return Task.FromResult(_c); + } + + public async Task M2_Task() + { + var c = await M1_Task().ConfigureAwait(false); + } + |] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "await M1_Task().ConfigureAwait(false)").WithLocation(20, 17)); + } + + [Fact, WorkItem(2347, "https://github.com/dotnet/roslyn-analyzers/issues/2347")] + public async Task ReturnDisposableObjectInAsyncMethod_DisposedInCaller_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System; +using System.Threading.Tasks; + +class C : IDisposable +{ + public void Dispose() + { + } + + [| + public async Task M1_Task(object context) + { + await Task.Yield(); + return new C(); + } + + public async Task M2_Task() + { + var c = await M1_Task(null).ConfigureAwait(false); + c.Dispose(); + } + |] +}"); + } + + [Fact, WorkItem(2347, "https://github.com/dotnet/roslyn-analyzers/issues/2347")] + public async Task ReturnDisposableObjectInAsyncMethod_NotDisposedInCaller_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System; +using System.Threading.Tasks; + +class C : IDisposable +{ + public void Dispose() + { + } + + [| + public async Task M1_Task(object context) + { + await Task.Yield(); + return new C(); + } + + public async Task M2_Task() + { + var c = await M1_Task(null).ConfigureAwait(false); + } + |] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "await M1_Task(null).ConfigureAwait(false)").WithLocation(20, 17)); + } + + [Fact, WorkItem(2361, "https://github.com/dotnet/roslyn-analyzers/issues/2361")] + public async Task ExpressionBodiedMethod_ReturnsDisposableObject_NoDiagnostic() + { + await TestDiagnosticMissingAsync(@" +using System.IO; + +class C +{ + [|Stream M() => File.OpenRead(""C:/somewhere/"");|] +}"); + } + + [Fact, WorkItem(2361, "https://github.com/dotnet/roslyn-analyzers/issues/2361")] + public async Task ReturnsDisposableObject_NotDisposed_Diagnostic() + { + await TestDiagnosticsAsync(@" +using System.IO; + +class C +{ + [| + Stream GetStream() => File.OpenRead(""C:/somewhere/""); + + void M2() + { + var stream = GetStream(); + } + |] +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "GetStream()").WithLocation(11, 22)); + } + + [Fact, WorkItem(2497, "https://github.com/dotnet/roslyn-analyzers/issues/2497")] + public async Task UsingStatementInCatch() + { + await TestDiagnosticsAsync(@" +using System; +class C : IDisposable +{ + public void Dispose() { } + void M1() + { + try + { + } + catch (Exception) + { + [|using (var c = new C())|] + { + } + } + } +}"); + } + + [Fact, WorkItem(2497, "https://github.com/dotnet/roslyn-analyzers/issues/2497")] + public async Task TryFinallyStatementInCatch() + { + await TestDiagnosticsAsync(@" +using System; +class C : IDisposable +{ + public void Dispose() { } + void M1() + { + try + { + } + catch (Exception) + { + C c = null; + try + { + [|c = new C();|] + } + finally + { + c.Dispose(); + } + } + } +}"); + } + + [Fact, WorkItem(2497, "https://github.com/dotnet/roslyn-analyzers/issues/2497")] + public async Task UsingStatementInFinally() + { + await TestDiagnosticsAsync(@" +using System; +class C : IDisposable +{ + public void Dispose() { } + void M1() + { + try + { + } + finally + { + [|using (var c = new C())|] + { + } + } + } +}"); + } + + [Fact] + public async Task MissingDisposeInMethodWithAttributes() + { + await TestDiagnosticsAsync(@" +using System; +class C : IDisposable +{ + public void Dispose() { } + + [Obsolete()] + void M1() + { + var c = [|new C()|]; + } +}", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/DummyLanguageService.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/DummyLanguageService.cs index 2e8860e3547fa..389e06012ca51 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/DummyLanguageService.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/DummyLanguageService.cs @@ -13,6 +13,11 @@ internal class DummyLanguageService : IDummyLanguageService { public const string LanguageName = "Dummy"; + [ImportingConstructor] + public DummyLanguageService() + { + } + // do nothing } } diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/CSharpFormatterTestsBase.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/CSharpFormatterTestsBase.cs index 370169208ba22..01a1ae57a8bb2 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/CSharpFormatterTestsBase.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/CSharpFormatterTestsBase.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation; using Microsoft.CodeAnalysis.Editor.Implementation.Formatting.Indentation; @@ -87,7 +88,7 @@ private static async Task TokenFormatWorkerAsync(TestWorkspace workspace, ITextB var rules = formattingRuleProvider.CreateRule(document, position).Concat(Formatter.GetDefaultFormattingRules(document)); var documentOptions = await document.GetOptionsAsync(); - var formatter = new SmartTokenFormatter(documentOptions, rules, root); + var formatter = new CSharpSmartTokenFormatter(documentOptions, rules, root); var changes = await formatter.FormatTokenAsync(workspace, token, CancellationToken.None); ApplyChanges(buffer, changes); diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs index ebca590cbcfe7..e91bc7c31cd82 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Test.Utilities; @@ -1301,7 +1301,7 @@ await AssertIndentNotUsingSmartTokenFormatterButUsingIndenterAsync( expectedIndentation: 8); } - [WpfFact(Skip = "PROTOTYPE(patterns2): need to implement indentation for recursive patterns")] + [WpfFact] [Trait(Traits.Feature, Traits.Features.SmartIndent)] public async Task IndentPatternPropertyFirst() { diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterTests.cs index df3a6fb03232f..daf44b8e40093 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterTests.cs @@ -2618,7 +2618,7 @@ static void M() expectedIndentation: 8); } - [WpfFact(Skip = "PROTOTYPE(patterns2): need to implement indentation for recursive patterns"), Trait(Traits.Feature, Traits.Features.SmartIndent)] + [WpfFact, Trait(Traits.Feature, Traits.Features.SmartIndent)] public void PatternPropertyIndentFirst() { var code = @" @@ -2661,7 +2661,7 @@ void M(object o) expectedIndentation: 12); } - [WpfFact(Skip = "PROTOTYPE(patterns2): need to implement indentation for recursive patterns"), Trait(Traits.Feature, Traits.Features.SmartIndent)] + [WpfFact, Trait(Traits.Feature, Traits.Features.SmartIndent)] public void PatternPropertyIndentNestedFirst() { var code = @" diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs index 20bd16e4d82fd..3ad86728b76f3 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Utilities; using Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation; @@ -3493,7 +3494,7 @@ private async Task AutoFormatOnMarkerAsync(string initialMarkup, string expected } Assert.Equal(tokenKind, endToken.Kind()); - var formatter = new SmartTokenFormatter(tuple.Item1, tuple.Item2, root); + var formatter = new CSharpSmartTokenFormatter(tuple.Item1, tuple.Item2, root); var tokenRange = FormattingRangeHelper.FindAppropriateRange(endToken); if (tokenRange == null) diff --git a/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs b/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs index 44347a658226a..d646a7ae0b7ac 100644 --- a/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs @@ -25,6 +25,8 @@ public class GenerateVariableTests : AbstractCSharpDiagnosticProviderBasedUserDi private const int ReadonlyFieldIndex = 1; private const int PropertyIndex = 2; private const int LocalIndex = 3; + private const int Parameter = 4; + private const int ParameterAndOverrides = 5; internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => (null, new CSharpGenerateVariableCodeFixProvider()); @@ -216,7 +218,27 @@ void Method(int i) [|goo|] = 1; } }", -new[] { string.Format(FeaturesResources.Generate_field_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_property_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_local_0, "goo") }); +new[] { string.Format(FeaturesResources.Generate_field_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_property_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_local_0, "goo"), string.Format(FeaturesResources.Generate_parameter_0, "goo") }); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] + public async Task TestSimpleWriteInOverrideCount() + { + await TestExactActionSetOfferedAsync( +@" +abstract class Base +{ + public abstract void Method(int i); +} + +class Class : Base +{ + public override void Method(int i) + { + [|goo|] = 1; + } +}", +new[] { string.Format(FeaturesResources.Generate_field_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_property_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_local_0, "goo"), string.Format(FeaturesResources.Generate_parameter_0, "goo"), string.Format(FeaturesResources.Generate_parameter_0_and_overrides_implementations, "goo") }); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] @@ -371,7 +393,7 @@ void Method(out int i) Method(out [|goo|]); } }", -new[] { string.Format(FeaturesResources.Generate_field_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_local_0, "goo") }); +new[] { string.Format(FeaturesResources.Generate_field_1_0, "goo", "Class"), string.Format(FeaturesResources.Generate_local_0, "goo"), string.Format(FeaturesResources.Generate_parameter_0, "goo") }); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] @@ -2001,7 +2023,7 @@ static void Main() [|p|]++; } }", -new[] { string.Format(FeaturesResources.Generate_field_1_0, "p", "Program"), string.Format(FeaturesResources.Generate_property_1_0, "p", "Program"), string.Format(FeaturesResources.Generate_local_0, "p") }); +new[] { string.Format(FeaturesResources.Generate_field_1_0, "p", "Program"), string.Format(FeaturesResources.Generate_property_1_0, "p", "Program"), string.Format(FeaturesResources.Generate_local_0, "p"), string.Format(FeaturesResources.Generate_parameter_0, "p") }); await TestInRegularAndScriptAsync( @"class Program @@ -4513,7 +4535,7 @@ void Goo() #line hidden } "; - await TestExactActionSetOfferedAsync(code, new[] { string.Format(FeaturesResources.Generate_local_0, "Bar") }); + await TestExactActionSetOfferedAsync(code, new[] { string.Format(FeaturesResources.Generate_local_0, "Bar"), string.Format(FeaturesResources.Generate_parameter_0, "Bar") }); await TestInRegularAndScriptAsync(code, @" @@ -8940,5 +8962,143 @@ class Blah } }"); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] + public async Task TestAddParameter() + { + await TestInRegularAndScriptAsync( +@"class Class +{ + void Method() + { + [|goo|]; + } +}", +@"class Class +{ + void Method(object goo) + { + goo; + } +}", index: Parameter); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] + public async Task TestAddParameter_DoesntAddToInterface() + { + await TestInRegularAndScriptAsync( +@"interface Interface +{ + void Method(); +} + +class Class +{ + public void Method() + { + [|goo|]; + } +}", +@"interface Interface +{ + void Method(); +} + +class Class +{ + public void Method(object goo) + { + [|goo|]; + } +}", index: Parameter); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] + public async Task TestAddParameterAndOverrides_AddsToInterface() + { + await TestInRegularAndScriptAsync( +@"interface Interface +{ + void Method(); +} + +class Class : Interface +{ + public void Method() + { + [|goo|]; + } +}", +@"interface Interface +{ + void Method(object goo); +} + +class Class : Interface +{ + public void Method(object goo) + { + [|goo|]; + } +}", index: ParameterAndOverrides); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] + public async Task TestAddParameterIsOfCorrectType() + { + await TestInRegularAndScriptAsync( + @"class Class +{ + void Method() + { + M1([|goo|]); + } + + void M1(int a); +}", + @"class Class +{ + void Method(int goo) + { + M1(goo); + } + + void M1(int a); +}", index: Parameter); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] + public async Task TestAddParameterAndOverrides_IsOfCorrectType() + { + await TestInRegularAndScriptAsync( +@"interface Interface +{ + void Method(); +} + +class Class : Interface +{ + public void Method() + { + M1([|goo|]); + } + + void M1(int a); +}", +@"interface Interface +{ + void Method(int goo); +} + +class Class : Interface +{ + public void Method(int goo) + { + M1(goo); + } + + void M1(int a); +}", index: ParameterAndOverrides); + } } } diff --git a/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs b/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs index f1926ee3d731d..f01022355dc4f 100644 --- a/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs +++ b/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs @@ -1732,7 +1732,7 @@ public abstract class Base public class TestClass : Base { - public void TestMeth[||]od() + public override void TestMeth[||]od() { System.Console.WriteLine(""Hello World""); } @@ -1767,7 +1767,6 @@ public abstract class Base public abstract class TestClass : Base { - public abstract void TestMethod(); } }"; await TestWithPullMemberDialogAsync(testText, expected, new (string, bool)[] { ("TestMethod", true) }, index: 0); @@ -2173,7 +2172,7 @@ abstract class B class D : B { - int X => 7; + override int X => 7; }"; await TestWithPullMemberDialogAsync(testText, expected, selection: new[] { ("X", true) }, index: 1); } @@ -2249,7 +2248,7 @@ public abstract class BaseClass public class TestClass : BaseClass { - public event EventHandler Event1 + public override event EventHandler Event1 { add { diff --git a/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs b/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs index 4716db5c39900..e75ed380bb9a7 100644 --- a/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs +++ b/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs @@ -6863,5 +6863,141 @@ public static void Test() } }", optionName); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] + public async Task DoesNotUseLocalFunctionName_PreferUnused() + { + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + int [|x|] = M2(); + x = 2; + return x; + + void unused() { } + } + + int M2() => 0; +}", +@"class C +{ + int M() + { + int unused1 = M2(); + int x = 2; + return x; + + void unused() { } + } + + int M2() => 0; +}", options: PreferUnusedLocal); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] + public async Task CanUseLocalFunctionParameterName_PreferUnused() + { + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + int [|x|] = M2(); + x = 2; + return x; + + void MLocal(int unused) { } + } + + int M2() => 0; +}", +@"class C +{ + int M() + { + int unused = M2(); + int x = 2; + return x; + + void MLocal(int unused) { } + } + + int M2() => 0; +}", options: PreferUnusedLocal); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] + public async Task DoesNotUseLambdaFunctionParameterNameWithCSharpLessThan8_PreferUnused() + { + await TestInRegularAndScriptAsync( +@" +using System; +class C +{ + int M() + { + int [|x|] = M2(); + x = 2; + Action myLambda = unused => { }; + + return x; + } + + int M2() => 0; +}", +@" +using System; +class C +{ + int M() + { + int unused1 = M2(); + int x = 2; + Action myLambda = unused => { }; + + return x; + } + + int M2() => 0; +}", options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] + public async Task CanUseLambdaFunctionParameterNameWithCSharp8_PreferUnused() + { + await TestInRegularAndScriptAsync( +@" +using System; +class C +{ + int M() + { + int [|x|] = M2(); + x = 2; + Action myLambda = unused => { }; + + return x; + } + + int M2() => 0; +}", +@" +using System; +class C +{ + int M() + { + int unused = M2(); + int x = 2; + Action myLambda = unused => { }; + + return x; + } + + int M2() => 0; +}", options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } } } diff --git a/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs b/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs index d565a09b21305..3d2fadb17bb40 100644 --- a/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs +++ b/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs @@ -1,11 +1,14 @@ // 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.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.UseIsNullCheck; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; @@ -88,7 +91,7 @@ class C { void M(string s) { - if (!(s is null)) + if (s is object) return; } }"); @@ -114,7 +117,7 @@ class C { void M(string s) { - if (!(s is null)) + if (s is object) return; } }"); diff --git a/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs b/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs index dd5d95993d12c..a845d11923ace 100644 --- a/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs +++ b/src/EditorFeatures/CSharpTest/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs @@ -1,11 +1,14 @@ // 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.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.UseIsNullCheck; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; @@ -141,7 +144,7 @@ class C { void M(string s) { - if (!(s is null)) + if (s is object) return; } }"); @@ -249,6 +252,35 @@ public static void NotNull(T value) "); } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] + public async Task TestValueParameterTypeIsUnconstrainedGenericNegated() + { + await TestInRegularAndScriptAsync( +@" +class C +{ + public static void NotNull(T value) + { + if (![||]ReferenceEquals(value, null)) + { + return; + } + } +} +", @" +class C +{ + public static void NotNull(T value) + { + if (value is object) + { + return; + } + } +} +"); + } + [WorkItem(23581, "https://github.com/dotnet/roslyn/issues/23581")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] public async Task TestValueParameterTypeIsRefConstraintGeneric() @@ -280,6 +312,36 @@ public static void NotNull(T value) where T:class "); } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] + public async Task TestValueParameterTypeIsRefConstraintGenericNegated() + { + await TestInRegularAndScriptAsync( +@" +class C +{ + public static void NotNull(T value) where T:class + { + if (![||]ReferenceEquals(value, null)) + { + return; + } + } +} +", +@" +class C +{ + public static void NotNull(T value) where T:class + { + if (value is object) + { + return; + } + } +} +"); + } + [WorkItem(23581, "https://github.com/dotnet/roslyn/issues/23581")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] public async Task TestValueParameterTypeIsValueConstraintGeneric() @@ -299,6 +361,24 @@ public static void NotNull(T value) where T:struct "); } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] + public async Task TestValueParameterTypeIsValueConstraintGenericNegated() + { + await TestMissingAsync( +@" +class C +{ + public static void NotNull(T value) where T:struct + { + if (![||]ReferenceEquals(value, null)) + { + return; + } + } +} +"); + } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] public async Task TestFixAllNested1() { diff --git a/src/EditorFeatures/CSharpTest/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs b/src/EditorFeatures/CSharpTest/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs index 56161ada44391..537b3e5872488 100644 --- a/src/EditorFeatures/CSharpTest/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs +++ b/src/EditorFeatures/CSharpTest/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseSimpleUsingStatement @@ -646,5 +647,293 @@ void M() } }", parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestCollision1() + { + await TestMissingInRegularAndScriptAsync( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream = File.OpenRead(""test"")) + { + } + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestNoCollision1() + { + await TestInRegularAndScript1Async( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + { + } + } +}", +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + using Stream stream1 = File.OpenRead(""test""); + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestCollision2() + { + await TestMissingInRegularAndScriptAsync( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + { + Stream stream; + } + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestNoCollision2() + { + await TestInRegularAndScript1Async( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + { + Stream stream2; + } + } +}", +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + using Stream stream1 = File.OpenRead(""test""); + Stream stream2; + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestCollision3() + { + await TestMissingInRegularAndScriptAsync( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + { + Goo(out var stream); + } + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestNoCollision3() + { + await TestInRegularAndScript1Async( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + { + Goo(out var stream2); + } + } +}", +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + using Stream stream1 = File.OpenRead(""test""); + Goo(out var stream2); + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestCollision4() + { + await TestMissingInRegularAndScriptAsync( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + Goo(out var stream); + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestNoCollision4() + { + await TestInRegularAndScript1Async( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + Goo(out var stream2); + } +}", +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + } + using Stream stream1 = File.OpenRead(""test""); + Goo(out var stream2); + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestCollision5() + { + await TestMissingInRegularAndScriptAsync( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + Stream stream1; + } + [||]using (Stream stream1 = File.OpenRead(""test"")) + { + } + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } + + [WorkItem(35879, "https://github.com/dotnet/roslyn/issues/35879")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestNoCollision5() + { + await TestInRegularAndScript1Async( +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + Stream stream1; + } + [||]using (Stream stream2 = File.OpenRead(""test"")) + { + } + } +}", +@"using System.IO; + +class Program +{ + static void Main() + { + using (Stream stream = File.OpenRead(""test"")) + { + Stream stream1; + } + using Stream stream2 = File.OpenRead(""test""); + } +}", +parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } } } diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs index 9d36655870d4c..91e63aa21b521 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs @@ -15,12 +15,13 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; using Roslyn.Test.Utilities; +using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.Workspaces { [UseExportProvider] - public partial class WorkspaceTests + public partial class WorkspaceTests : TestBase { private TestWorkspace CreateWorkspace(bool disablePartialSolutions = true) { @@ -853,6 +854,32 @@ public async Task TestAdditionalFile_Properties() } } + [Fact] + public async Task TestAnalyzerConfigFile_Properties() + { + using (var workspace = CreateWorkspace()) + { + var document = new TestHostDocument("public class C { }"); + var analyzerConfigDoc = new TestHostDocument("root = true"); + var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, analyzerConfigDocuments: new[] { analyzerConfigDoc }); + + workspace.AddTestProject(project1); + + var project = workspace.CurrentSolution.Projects.Single(); + + Assert.Equal(1, project.Documents.Count()); + Assert.Equal(1, project.AnalyzerConfigDocuments.Count()); + Assert.Equal(1, project.State.AnalyzerConfigDocumentIds.Count()); + + var doc = project.GetDocument(analyzerConfigDoc.Id); + Assert.Null(doc); + + var analyzerConfigDocument = project.GetAnalyzerConfigDocument(analyzerConfigDoc.Id); + + Assert.Equal("root = true", (await analyzerConfigDocument.GetTextAsync()).ToString()); + } + } + [Fact] public async Task TestAdditionalFile_DocumentChanged() { @@ -887,6 +914,41 @@ public async Task TestAdditionalFile_DocumentChanged() } } + [Fact] + public async Task TestAnalyzerConfigFile_DocumentChanged() + { + using (var workspace = CreateWorkspace()) + { + var startText = @"root = true"; + var newText = @"root = false"; + var document = new TestHostDocument("public class C { }"); + var analyzerConfigPath = PathUtilities.CombineAbsoluteAndRelativePaths(Temp.CreateDirectory().Path, ".editorconfig"); + var analyzerConfigDoc = new TestHostDocument(startText, filePath: analyzerConfigPath); + var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, analyzerConfigDocuments: new[] { analyzerConfigDoc }); + + workspace.AddTestProject(project1); + var buffer = analyzerConfigDoc.GetTextBuffer(); + workspace.OnAnalyzerConfigDocumentOpened(analyzerConfigDoc.Id, analyzerConfigDoc.GetOpenTextContainer()); + + var project = workspace.CurrentSolution.Projects.Single(); + var oldVersion = await project.GetSemanticVersionAsync(); + + // fork the solution to introduce a change. + var oldSolution = workspace.CurrentSolution; + var newSolution = oldSolution.WithAnalyzerConfigDocumentText(analyzerConfigDoc.Id, SourceText.From(newText)); + workspace.TryApplyChanges(newSolution); + + var doc = workspace.CurrentSolution.GetAnalyzerConfigDocument(analyzerConfigDoc.Id); + + // new text should have been pushed into buffer + Assert.Equal(newText, buffer.CurrentSnapshot.GetText()); + + // Text changes are considered top level changes and they change the project's semantic version. + Assert.Equal(await doc.GetTextVersionAsync(), await doc.GetTopLevelChangeTextVersionAsync()); + Assert.NotEqual(oldVersion, await doc.Project.GetSemanticVersionAsync()); + } + } + [Fact, WorkItem(31540, "https://github.com/dotnet/roslyn/issues/31540")] public async Task TestAdditionalFile_OpenClose() { @@ -922,6 +984,41 @@ public async Task TestAdditionalFile_OpenClose() } } + [Fact] + public async Task TestAnalyzerConfigFile_OpenClose() + { + using (var workspace = CreateWorkspace()) + { + var startText = @"root = true"; + var document = new TestHostDocument("public class C { }"); + var analyzerConfigDoc = new TestHostDocument(startText); + var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, analyzerConfigDocuments: new[] { analyzerConfigDoc }); + + workspace.AddTestProject(project1); + var buffer = analyzerConfigDoc.GetTextBuffer(); + var doc = workspace.CurrentSolution.GetAnalyzerConfigDocument(analyzerConfigDoc.Id); + var text = await doc.GetTextAsync(CancellationToken.None); + var version = await doc.GetTextVersionAsync(CancellationToken.None); + + workspace.OnAnalyzerConfigDocumentOpened(analyzerConfigDoc.Id, analyzerConfigDoc.GetOpenTextContainer()); + + // Make sure that analyzer config documents are included in GetOpenDocumentIds. + var openDocumentIds = workspace.GetOpenDocumentIds(); + Assert.Single(openDocumentIds); + Assert.Equal(analyzerConfigDoc.Id, openDocumentIds.Single()); + + workspace.OnAnalyzerConfigDocumentClosed(analyzerConfigDoc.Id, TextLoader.From(TextAndVersion.Create(text, version))); + + // Make sure that closed analyzer config documents are not include in GetOpenDocumentIds. + Assert.Empty(workspace.GetOpenDocumentIds()); + + // Reopen and close to make sure we are not leaking anything. + workspace.OnAnalyzerConfigDocumentOpened(analyzerConfigDoc.Id, analyzerConfigDoc.GetOpenTextContainer()); + workspace.OnAnalyzerConfigDocumentClosed(analyzerConfigDoc.Id, TextLoader.From(TextAndVersion.Create(text, version))); + Assert.Empty(workspace.GetOpenDocumentIds()); + } + } + [Fact] public void TestAdditionalFile_AddRemove() { @@ -960,6 +1057,44 @@ public void TestAdditionalFile_AddRemove() } } + [Fact] + public void TestAnalyzerConfigFile_AddRemove() + { + using (var workspace = CreateWorkspace()) + { + var startText = @"root = true"; + var document = new TestHostDocument("public class C { }"); + var analyzerConfigDoc = new TestHostDocument(startText, "original.config"); + var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, analyzerConfigDocuments: new[] { analyzerConfigDoc }); + workspace.AddTestProject(project1); + + var project = workspace.CurrentSolution.Projects.Single(); + + // fork the solution to introduce a change. + var newDocId = DocumentId.CreateNewId(project.Id); + var oldSolution = workspace.CurrentSolution; + var newSolution = oldSolution.AddAnalyzerConfigDocument(newDocId, "app.config", SourceText.From("text")); + + var doc = workspace.CurrentSolution.GetAnalyzerConfigDocument(analyzerConfigDoc.Id); + + workspace.TryApplyChanges(newSolution); + + Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); + Assert.Equal(2, workspace.CurrentSolution.GetProject(project1.Id).AnalyzerConfigDocuments.Count()); + + // Now remove the newly added document + + oldSolution = workspace.CurrentSolution; + newSolution = oldSolution.RemoveAnalyzerConfigDocument(newDocId); + + workspace.TryApplyChanges(newSolution); + + Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); + Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).AnalyzerConfigDocuments.Count()); + Assert.Equal("original.config", workspace.CurrentSolution.GetProject(project1.Id).AnalyzerConfigDocuments.Single().Name); + } + } + [Fact] public void TestAdditionalFile_AddRemove_FromProject() { @@ -990,6 +1125,36 @@ public void TestAdditionalFile_AddRemove_FromProject() } } + [Fact] + public void TestAnalyzerConfigFile_AddRemove_FromProject() + { + using (var workspace = CreateWorkspace()) + { + var startText = @"root = true"; + var document = new TestHostDocument("public class C { }"); + var analyzerConfigDoc = new TestHostDocument(startText, "original.config"); + var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, analyzerConfigDocuments: new[] { analyzerConfigDoc }); + workspace.AddTestProject(project1); + + var project = workspace.CurrentSolution.Projects.Single(); + + // fork the solution to introduce a change. + var doc = project.AddAnalyzerConfigDocument("app.config", SourceText.From("text")); + workspace.TryApplyChanges(doc.Project.Solution); + + Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); + Assert.Equal(2, workspace.CurrentSolution.GetProject(project1.Id).AnalyzerConfigDocuments.Count()); + + // Now remove the newly added document + project = workspace.CurrentSolution.Projects.Single(); + workspace.TryApplyChanges(project.RemoveAnalyzerConfigDocument(doc.Id).Solution); + + Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); + Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).AnalyzerConfigDocuments.Count()); + Assert.Equal("original.config", workspace.CurrentSolution.GetProject(project1.Id).AnalyzerConfigDocuments.Single().Name); + } + } + [Fact, WorkItem(31540, "https://github.com/dotnet/roslyn/issues/31540")] public void TestAdditionalFile_GetDocumentIdsWithFilePath() { @@ -1011,6 +1176,28 @@ public void TestAdditionalFile_GetDocumentIdsWithFilePath() } } + [Fact] + public void TestAnalyzerConfigFile_GetDocumentIdsWithFilePath() + { + using (var workspace = CreateWorkspace()) + { + const string docFilePath = "filePath1"; + var document = new TestHostDocument("public class C { }", filePath: docFilePath); + var analyzerConfigDocFilePath = PathUtilities.CombineAbsoluteAndRelativePaths(Temp.CreateDirectory().Path, ".editorconfig"); + var analyzerConfigDoc = new TestHostDocument(@"root = true", filePath: analyzerConfigDocFilePath); + var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, analyzerConfigDocuments: new[] { analyzerConfigDoc }); + workspace.AddTestProject(project1); + + var documentIdsWithFilePath = workspace.CurrentSolution.GetDocumentIdsWithFilePath(docFilePath); + Assert.Single(documentIdsWithFilePath); + Assert.Equal(document.Id, documentIdsWithFilePath.Single()); + + documentIdsWithFilePath = workspace.CurrentSolution.GetDocumentIdsWithFilePath(analyzerConfigDocFilePath); + Assert.Single(documentIdsWithFilePath); + Assert.Equal(analyzerConfigDoc.Id, documentIdsWithFilePath.Single()); + } + } + [Fact, WorkItem(209299, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=209299")] public async Task TestLinkedFilesStayInSync() { diff --git a/src/EditorFeatures/Core.Wpf/BraceMatching/ClassificationTypeFormatDefinitions.cs b/src/EditorFeatures/Core.Wpf/BraceMatching/ClassificationTypeFormatDefinitions.cs index 11563fe295fdf..cc3720497680e 100644 --- a/src/EditorFeatures/Core.Wpf/BraceMatching/ClassificationTypeFormatDefinitions.cs +++ b/src/EditorFeatures/Core.Wpf/BraceMatching/ClassificationTypeFormatDefinitions.cs @@ -16,7 +16,8 @@ internal sealed class ClassificationTypeFormatDefinitions [UserVisible(true)] private class BraceMatchingFormatDefinition : ClassificationFormatDefinition { - private BraceMatchingFormatDefinition() + [ImportingConstructor] + public BraceMatchingFormatDefinition() { this.DisplayName = EditorFeaturesResources.Brace_Matching; this.BackgroundColor = Color.FromRgb(0xDB, 0xE0, 0xCC); diff --git a/src/EditorFeatures/Core.Wpf/Classification/ClassificationTypeFormatDefinitions.cs b/src/EditorFeatures/Core.Wpf/Classification/ClassificationTypeFormatDefinitions.cs index 7422a4071831d..bdf1bdd7da16b 100644 --- a/src/EditorFeatures/Core.Wpf/Classification/ClassificationTypeFormatDefinitions.cs +++ b/src/EditorFeatures/Core.Wpf/Classification/ClassificationTypeFormatDefinitions.cs @@ -23,7 +23,8 @@ internal sealed class ClassificationTypeFormatDefinitions [ExcludeFromCodeCoverage] private class PreprocessorTextFormatDefinition : ClassificationFormatDefinition { - private PreprocessorTextFormatDefinition() + [ImportingConstructor] + public PreprocessorTextFormatDefinition() { this.DisplayName = EditorFeaturesResources.Preprocessor_Text; this.ForegroundColor = Colors.Black; @@ -39,7 +40,8 @@ private PreprocessorTextFormatDefinition() [ExcludeFromCodeCoverage] private class PunctuationFormatDefinition : ClassificationFormatDefinition { - private PunctuationFormatDefinition() + [ImportingConstructor] + public PunctuationFormatDefinition() { this.DisplayName = EditorFeaturesResources.Punctuation; this.ForegroundColor = Colors.Black; @@ -56,7 +58,8 @@ private PunctuationFormatDefinition() [ExcludeFromCodeCoverage] private class StringVerbatimFormatDefinition : ClassificationFormatDefinition { - private StringVerbatimFormatDefinition() + [ImportingConstructor] + public StringVerbatimFormatDefinition() { this.DisplayName = EditorFeaturesResources.String_Verbatim; this.ForegroundColor = Colors.Maroon; @@ -81,7 +84,8 @@ private StringVerbatimFormatDefinition() [ExcludeFromCodeCoverage] private class StringEscapeCharacterFormatDefinition : ClassificationFormatDefinition { - private StringEscapeCharacterFormatDefinition() + [ImportingConstructor] + public StringEscapeCharacterFormatDefinition() { this.DisplayName = EditorFeaturesResources.String_Escape_Character; this.ForegroundColor = s_stringEscapeColor; @@ -100,7 +104,8 @@ private StringEscapeCharacterFormatDefinition() [ExcludeFromCodeCoverage] private class ControlKeywordFormatDefinition : ClassificationFormatDefinition { - private ControlKeywordFormatDefinition() + [ImportingConstructor] + public ControlKeywordFormatDefinition() { this.DisplayName = EditorFeaturesResources.Keyword_Control; } @@ -117,7 +122,8 @@ private ControlKeywordFormatDefinition() [ExcludeFromCodeCoverage] private class OperatorOverloadedFormatDefinition : ClassificationFormatDefinition { - private OperatorOverloadedFormatDefinition() + [ImportingConstructor] + public OperatorOverloadedFormatDefinition() { this.DisplayName = EditorFeaturesResources.Operator_Overloaded; } @@ -133,7 +139,8 @@ private OperatorOverloadedFormatDefinition() [ExcludeFromCodeCoverage] private class SymbolStaticFormatDefinition : ClassificationFormatDefinition { - private SymbolStaticFormatDefinition() + [ImportingConstructor] + public SymbolStaticFormatDefinition() { this.DisplayName = EditorFeaturesResources.Symbol_Static; // The static classification is intended to be an additive classification @@ -171,7 +178,8 @@ private SymbolStaticFormatDefinition() [ExcludeFromCodeCoverage] private class UserTypeClassesFormatDefinition : ClassificationFormatDefinition { - private UserTypeClassesFormatDefinition() + [ImportingConstructor] + public UserTypeClassesFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Classes; this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF); @@ -189,7 +197,8 @@ private UserTypeClassesFormatDefinition() [ExcludeFromCodeCoverage] private class UserTypeDelegatesFormatDefinition : ClassificationFormatDefinition { - private UserTypeDelegatesFormatDefinition() + [ImportingConstructor] + public UserTypeDelegatesFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Delegates; this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF); @@ -207,7 +216,8 @@ private UserTypeDelegatesFormatDefinition() [ExcludeFromCodeCoverage] private class UserTypeEnumsFormatDefinition : ClassificationFormatDefinition { - private UserTypeEnumsFormatDefinition() + [ImportingConstructor] + public UserTypeEnumsFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Enums; this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF); @@ -225,7 +235,8 @@ private UserTypeEnumsFormatDefinition() [ExcludeFromCodeCoverage] private class UserTypeInterfacesFormatDefinition : ClassificationFormatDefinition { - private UserTypeInterfacesFormatDefinition() + [ImportingConstructor] + public UserTypeInterfacesFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Interfaces; this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF); @@ -242,7 +253,8 @@ private UserTypeInterfacesFormatDefinition() [UserVisible(true)] private class UserTypeModulesFormatDefinition : ClassificationFormatDefinition { - private UserTypeModulesFormatDefinition() + [ImportingConstructor] + public UserTypeModulesFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Modules; this.ForegroundColor = Color.FromRgb(43, 145, 175); @@ -260,7 +272,8 @@ private UserTypeModulesFormatDefinition() [ExcludeFromCodeCoverage] private class UserTypeStructuresFormatDefinition : ClassificationFormatDefinition { - private UserTypeStructuresFormatDefinition() + [ImportingConstructor] + public UserTypeStructuresFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Structures; this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF); @@ -278,7 +291,8 @@ private UserTypeStructuresFormatDefinition() [ExcludeFromCodeCoverage] private class UserTypeTypeParametersFormatDefinition : ClassificationFormatDefinition { - private UserTypeTypeParametersFormatDefinition() + [ImportingConstructor] + public UserTypeTypeParametersFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Types_Type_Parameters; this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF); @@ -297,7 +311,8 @@ private UserTypeTypeParametersFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersFieldNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersFieldNameFormatDefinition() + [ImportingConstructor] + public UserMembersFieldNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Fields; } @@ -314,7 +329,8 @@ private UserMembersFieldNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersEnumMemberNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersEnumMemberNameFormatDefinition() + [ImportingConstructor] + public UserMembersEnumMemberNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Enum_Members; } @@ -331,7 +347,8 @@ private UserMembersEnumMemberNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersConstantNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersConstantNameFormatDefinition() + [ImportingConstructor] + public UserMembersConstantNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Constants; } @@ -348,7 +365,8 @@ private UserMembersConstantNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersLocalNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersLocalNameFormatDefinition() + [ImportingConstructor] + public UserMembersLocalNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Locals; } @@ -365,7 +383,8 @@ private UserMembersLocalNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersParameterNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersParameterNameFormatDefinition() + [ImportingConstructor] + public UserMembersParameterNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Parameters; } @@ -382,7 +401,8 @@ private UserMembersParameterNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersMethodNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersMethodNameFormatDefinition() + [ImportingConstructor] + public UserMembersMethodNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Methods; } @@ -399,7 +419,8 @@ private UserMembersMethodNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersExtensionMethodNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersExtensionMethodNameFormatDefinition() + [ImportingConstructor] + public UserMembersExtensionMethodNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Extension_Methods; } @@ -416,7 +437,8 @@ private UserMembersExtensionMethodNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersPropertyNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersPropertyNameFormatDefinition() + [ImportingConstructor] + public UserMembersPropertyNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Properties; } @@ -432,7 +454,8 @@ private UserMembersPropertyNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersEventNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersEventNameFormatDefinition() + [ImportingConstructor] + public UserMembersEventNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Events; } @@ -448,7 +471,8 @@ private UserMembersEventNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersNamespaceNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersNamespaceNameFormatDefinition() + [ImportingConstructor] + public UserMembersNamespaceNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Namespaces; } @@ -465,7 +489,8 @@ private UserMembersNamespaceNameFormatDefinition() [ExcludeFromCodeCoverage] private class UserMembersLabelNameFormatDefinition : ClassificationFormatDefinition { - private UserMembersLabelNameFormatDefinition() + [ImportingConstructor] + public UserMembersLabelNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.User_Members_Labels; } @@ -481,7 +506,8 @@ private UserMembersLabelNameFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentAttributeNameFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentAttributeNameFormatDefinition() + [ImportingConstructor] + public XmlDocCommentAttributeNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Attribute_Name; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -497,7 +523,8 @@ private XmlDocCommentAttributeNameFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentAttributeQuotesFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentAttributeQuotesFormatDefinition() + [ImportingConstructor] + public XmlDocCommentAttributeQuotesFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Attribute_Quotes; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -515,7 +542,8 @@ private XmlDocCommentAttributeQuotesFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentAttributeValueFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentAttributeValueFormatDefinition() + [ImportingConstructor] + public XmlDocCommentAttributeValueFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Attribute_Value; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -531,7 +559,8 @@ private XmlDocCommentAttributeValueFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentCDataSectionFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentCDataSectionFormatDefinition() + [ImportingConstructor] + public XmlDocCommentCDataSectionFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_CData_Section; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -547,7 +576,8 @@ private XmlDocCommentCDataSectionFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentCommentFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentCommentFormatDefinition() + [ImportingConstructor] + public XmlDocCommentCommentFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Comment; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -563,7 +593,8 @@ private XmlDocCommentCommentFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentDelimiterFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentDelimiterFormatDefinition() + [ImportingConstructor] + public XmlDocCommentDelimiterFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Delimiter; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -579,7 +610,8 @@ private XmlDocCommentDelimiterFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentEntityReferenceFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentEntityReferenceFormatDefinition() + [ImportingConstructor] + public XmlDocCommentEntityReferenceFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Entity_Reference; this.ForegroundColor = Colors.Green; @@ -595,7 +627,8 @@ private XmlDocCommentEntityReferenceFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentNameFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentNameFormatDefinition() + [ImportingConstructor] + public XmlDocCommentNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Name; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -611,7 +644,8 @@ private XmlDocCommentNameFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentProcessingInstructionFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentProcessingInstructionFormatDefinition() + [ImportingConstructor] + public XmlDocCommentProcessingInstructionFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Processing_Instruction; this.ForegroundColor = Color.FromRgb(0x80, 0x80, 0x80); // CIDARKGRAY @@ -627,7 +661,8 @@ private XmlDocCommentProcessingInstructionFormatDefinition() [ExcludeFromCodeCoverage] private class XmlDocCommentTextFormatDefinition : ClassificationFormatDefinition { - private XmlDocCommentTextFormatDefinition() + [ImportingConstructor] + public XmlDocCommentTextFormatDefinition() { this.DisplayName = EditorFeaturesResources.XML_Doc_Comments_Text; this.ForegroundColor = Colors.Green; @@ -665,7 +700,8 @@ private XmlDocCommentTextFormatDefinition() [ExcludeFromCodeCoverage] private class RegexCommentFormatDefinition : ClassificationFormatDefinition { - private RegexCommentFormatDefinition() + [ImportingConstructor] + public RegexCommentFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Comment; this.ForegroundColor = s_regexCommentColor; @@ -681,7 +717,8 @@ private RegexCommentFormatDefinition() [ExcludeFromCodeCoverage] private class RegexCharacterClassFormatDefinition : ClassificationFormatDefinition { - private RegexCharacterClassFormatDefinition() + [ImportingConstructor] + public RegexCharacterClassFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Character_Class; this.ForegroundColor = s_characterClassColor; @@ -697,7 +734,8 @@ private RegexCharacterClassFormatDefinition() [ExcludeFromCodeCoverage] private class RegexAnchorFormatDefinition : ClassificationFormatDefinition { - private RegexAnchorFormatDefinition() + [ImportingConstructor] + public RegexAnchorFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Anchor; this.ForegroundColor = s_regexAnchorAndQuantifierColor; @@ -713,7 +751,8 @@ private RegexAnchorFormatDefinition() [ExcludeFromCodeCoverage] private class RegexQuantifierFormatDefinition : ClassificationFormatDefinition { - private RegexQuantifierFormatDefinition() + [ImportingConstructor] + public RegexQuantifierFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Quantifier; this.ForegroundColor = s_regexAnchorAndQuantifierColor; @@ -729,7 +768,8 @@ private RegexQuantifierFormatDefinition() [ExcludeFromCodeCoverage] private class RegexGroupingFormatDefinition : ClassificationFormatDefinition { - private RegexGroupingFormatDefinition() + [ImportingConstructor] + public RegexGroupingFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Grouping; this.ForegroundColor = s_regexGroupingAndAlternationColor; @@ -745,7 +785,8 @@ private RegexGroupingFormatDefinition() [ExcludeFromCodeCoverage] private class RegexAlternationFormatDefinition : ClassificationFormatDefinition { - private RegexAlternationFormatDefinition() + [ImportingConstructor] + public RegexAlternationFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Alternation; this.ForegroundColor = s_regexGroupingAndAlternationColor; @@ -761,7 +802,8 @@ private RegexAlternationFormatDefinition() [ExcludeFromCodeCoverage] private class RegexTextFormatDefinition : ClassificationFormatDefinition { - private RegexTextFormatDefinition() + [ImportingConstructor] + public RegexTextFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_Text; this.ForegroundColor = s_regexTextColor; @@ -777,7 +819,8 @@ private RegexTextFormatDefinition() [ExcludeFromCodeCoverage] private class RegexSelfEscapedCharacterFormatDefinition : ClassificationFormatDefinition { - private RegexSelfEscapedCharacterFormatDefinition() + [ImportingConstructor] + public RegexSelfEscapedCharacterFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_SelfEscapedCharacter; @@ -797,7 +840,8 @@ private RegexSelfEscapedCharacterFormatDefinition() [ExcludeFromCodeCoverage] private class RegexOtherEscapeFormatDefinition : ClassificationFormatDefinition { - private RegexOtherEscapeFormatDefinition() + [ImportingConstructor] + public RegexOtherEscapeFormatDefinition() { this.DisplayName = EditorFeaturesWpfResources.Regex_OtherEscape; this.ForegroundColor = s_regexOtherEscapeColor; @@ -813,7 +857,8 @@ private RegexOtherEscapeFormatDefinition() [UserVisible(true)] private class XmlLiteralAttributeNameFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralAttributeNameFormatDefinition() + [ImportingConstructor] + public XmlLiteralAttributeNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Attribute_Name; this.ForegroundColor = Color.FromRgb(185, 100, 100); // HC_LIGHTRED @@ -828,7 +873,8 @@ private XmlLiteralAttributeNameFormatDefinition() [UserVisible(true)] private class XmlLiteralAttributeQuotesFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralAttributeQuotesFormatDefinition() + [ImportingConstructor] + public XmlLiteralAttributeQuotesFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Attribute_Quotes; this.ForegroundColor = Color.FromRgb(85, 85, 85); // HC_LIGHTBLACK @@ -843,7 +889,8 @@ private XmlLiteralAttributeQuotesFormatDefinition() [UserVisible(true)] private class XmlLiteralAttributeValueFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralAttributeValueFormatDefinition() + [ImportingConstructor] + public XmlLiteralAttributeValueFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Attribute_Value; this.ForegroundColor = Color.FromRgb(100, 100, 185); // HC_LIGHTBLUE @@ -858,7 +905,8 @@ private XmlLiteralAttributeValueFormatDefinition() [UserVisible(true)] private class XmlLiteralCDataSectionFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralCDataSectionFormatDefinition() + [ImportingConstructor] + public XmlLiteralCDataSectionFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_CData_Section; this.ForegroundColor = Color.FromRgb(192, 192, 192); // HC_LIGHTGRAY @@ -873,7 +921,8 @@ private XmlLiteralCDataSectionFormatDefinition() [UserVisible(true)] private class XmlLiteralCommentFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralCommentFormatDefinition() + [ImportingConstructor] + public XmlLiteralCommentFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Comment; this.ForegroundColor = Color.FromRgb(98, 151, 85); // HC_LIGHTGREEN @@ -888,7 +937,8 @@ private XmlLiteralCommentFormatDefinition() [UserVisible(true)] private class XmlLiteralDelimiterFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralDelimiterFormatDefinition() + [ImportingConstructor] + public XmlLiteralDelimiterFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Delimiter; this.ForegroundColor = Color.FromRgb(100, 100, 185); // HC_LIGHTBLUE @@ -903,7 +953,8 @@ private XmlLiteralDelimiterFormatDefinition() [UserVisible(true)] private class XmlLiteralEmbeddedExpressionFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralEmbeddedExpressionFormatDefinition() + [ImportingConstructor] + public XmlLiteralEmbeddedExpressionFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Embedded_Expression; this.ForegroundColor = Color.FromRgb(85, 85, 85); // HC_LIGHTBLACK @@ -919,7 +970,8 @@ private XmlLiteralEmbeddedExpressionFormatDefinition() [UserVisible(true)] private class XmlLiteralEntityReferenceFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralEntityReferenceFormatDefinition() + [ImportingConstructor] + public XmlLiteralEntityReferenceFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Entity_Reference; this.ForegroundColor = Color.FromRgb(185, 100, 100); // HC_LIGHTRED @@ -934,7 +986,8 @@ private XmlLiteralEntityReferenceFormatDefinition() [UserVisible(true)] private class XmlLiteralNameFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralNameFormatDefinition() + [ImportingConstructor] + public XmlLiteralNameFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Name; this.ForegroundColor = Color.FromRgb(132, 70, 70); // HC_LIGHTMAROON @@ -949,7 +1002,8 @@ private XmlLiteralNameFormatDefinition() [UserVisible(true)] private class XmlLiteralProcessingInstructionFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralProcessingInstructionFormatDefinition() + [ImportingConstructor] + public XmlLiteralProcessingInstructionFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Processing_Instruction; this.ForegroundColor = Color.FromRgb(192, 192, 192); // HC_LIGHTGRAY @@ -964,7 +1018,8 @@ private XmlLiteralProcessingInstructionFormatDefinition() [UserVisible(true)] private class XmlLiteralTextFormatDefinition : ClassificationFormatDefinition { - private XmlLiteralTextFormatDefinition() + [ImportingConstructor] + public XmlLiteralTextFormatDefinition() { this.DisplayName = EditorFeaturesResources.VB_XML_Literals_Text; this.ForegroundColor = Color.FromRgb(85, 85, 85); // HC_LIGHTBLACK diff --git a/src/EditorFeatures/Core.Wpf/ConflictTagDefinition.cs b/src/EditorFeatures/Core.Wpf/ConflictTagDefinition.cs index 0e95cfd7b0f86..fa61a92de634c 100644 --- a/src/EditorFeatures/Core.Wpf/ConflictTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/ConflictTagDefinition.cs @@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Editor.Shared.Tagging.Tags [ExcludeFromCodeCoverage] internal class ConflictTagDefinition : MarkerFormatDefinition { + [ImportingConstructor] public ConflictTagDefinition() { this.Border = new Pen(Brushes.Red, thickness: 1.5); diff --git a/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs index 198024c4ce44f..003d4b940a7d3 100644 --- a/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs @@ -19,7 +19,8 @@ namespace Microsoft.CodeAnalysis.Editor.Diagnostics [UserVisible(false)] internal sealed class UnnecessaryCodeFormatDefinition : ClassificationFormatDefinition { - private UnnecessaryCodeFormatDefinition() + [ImportingConstructor] + public UnnecessaryCodeFormatDefinition() { this.DisplayName = EditorFeaturesResources.Unnecessary_Code; this.ForegroundOpacity = 0.6; diff --git a/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs index f459daa28ac38..a64deeff694c7 100644 --- a/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs @@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue [ExcludeFromCodeCoverage] internal sealed class ActiveStatementTagFormatDefinition : MarkerFormatDefinition { + [ImportingConstructor] public ActiveStatementTagFormatDefinition() { // TODO (tomat): bug 777271 diff --git a/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs index 90c9e29bb81d3..07c03a8553538 100644 --- a/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs @@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue [UserVisible(true)] internal sealed class EditAndContinueErrorTypeFormatDefinition : EditorFormatDefinition { + [ImportingConstructor] public EditAndContinueErrorTypeFormatDefinition() { this.ForegroundBrush = Brushes.Purple; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameConflictTagDefinition.cs b/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameConflictTagDefinition.cs index 8994181ada3d1..247c35e1f1b95 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameConflictTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameConflictTagDefinition.cs @@ -17,6 +17,7 @@ internal class RenameConflictTagDefinition : MarkerFormatDefinition public static double StrokeThickness => 1.5; public static double[] StrokeDashArray => new[] { 8.0, 4.0 }; + [ImportingConstructor] public RenameConflictTagDefinition() { this.Border = new Pen(Brushes.Red, thickness: StrokeThickness) { DashStyle = new DashStyle(StrokeDashArray, 0) }; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFieldBackgroundAndBorderTagDefinition.cs b/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFieldBackgroundAndBorderTagDefinition.cs index a4eb1bc4b8c32..8ce2c9ca21165 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFieldBackgroundAndBorderTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFieldBackgroundAndBorderTagDefinition.cs @@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.HighlightTag [ExcludeFromCodeCoverage] internal class RenameFieldBackgroundAndBorderTagDefinition : MarkerFormatDefinition { + [ImportingConstructor] public RenameFieldBackgroundAndBorderTagDefinition() { // The Border color should match the BackgroundColor from the diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFixupTagDefinition.cs b/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFixupTagDefinition.cs index 41bd0f9e3282f..94a15765a7040 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFixupTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/HighlightTags/RenameFixupTagDefinition.cs @@ -17,6 +17,7 @@ internal class RenameFixupTagDefinition : MarkerFormatDefinition public static double StrokeThickness => 1.0; public static double[] StrokeDashArray => new[] { 4.0, 4.0 }; + [ImportingConstructor] public RenameFixupTagDefinition() { this.Border = new Pen(Brushes.Green, thickness: StrokeThickness) { DashStyle = new DashStyle(StrokeDashArray, 0) }; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/Taggers/ClassificationTypeDefinitions.cs b/src/EditorFeatures/Core.Wpf/InlineRename/Taggers/ClassificationTypeDefinitions.cs index 0cb1cf41635ff..10ba7c5ddcfbb 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/Taggers/ClassificationTypeDefinitions.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/Taggers/ClassificationTypeDefinitions.cs @@ -25,7 +25,8 @@ internal sealed class ClassificationTypeDefinitions [UserVisible(true)] private class InlineRenameFieldFormatDefinition : ClassificationFormatDefinition { - private InlineRenameFieldFormatDefinition() + [ImportingConstructor] + public InlineRenameFieldFormatDefinition() { this.DisplayName = EditorFeaturesResources.Inline_Rename_Field_Text; this.ForegroundColor = Color.FromRgb(0x00, 0x64, 0x00); diff --git a/src/EditorFeatures/Core.Wpf/Interactive/InteractiveDocumentNavigationServiceFactory.cs b/src/EditorFeatures/Core.Wpf/Interactive/InteractiveDocumentNavigationServiceFactory.cs index f7069e82eb0a1..64756a9d88dfe 100644 --- a/src/EditorFeatures/Core.Wpf/Interactive/InteractiveDocumentNavigationServiceFactory.cs +++ b/src/EditorFeatures/Core.Wpf/Interactive/InteractiveDocumentNavigationServiceFactory.cs @@ -13,7 +13,7 @@ internal sealed class InteractiveDocumentNavigationServiceFactory : IWorkspaceSe private readonly IDocumentNavigationService _singleton; [ImportingConstructor] - private InteractiveDocumentNavigationServiceFactory() + public InteractiveDocumentNavigationServiceFactory() { _singleton = new InteractiveDocumentNavigationService(); } diff --git a/src/EditorFeatures/Core.Wpf/Interactive/InteractiveScriptEnvironmentServiceFactory.cs b/src/EditorFeatures/Core.Wpf/Interactive/InteractiveScriptEnvironmentServiceFactory.cs index a7853aed04ce0..f3c1cf7ce99bd 100644 --- a/src/EditorFeatures/Core.Wpf/Interactive/InteractiveScriptEnvironmentServiceFactory.cs +++ b/src/EditorFeatures/Core.Wpf/Interactive/InteractiveScriptEnvironmentServiceFactory.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.Interactive [ExportWorkspaceServiceFactory(typeof(IScriptEnvironmentService), WorkspaceKind.Interactive), Shared] internal sealed class InteractiveScriptEnvironmentServiceFactory : IWorkspaceServiceFactory { + [ImportingConstructor] + public InteractiveScriptEnvironmentServiceFactory() + { + } + private sealed class Service : IScriptEnvironmentService { private readonly InteractiveWorkspace _workspace; diff --git a/src/EditorFeatures/Core.Wpf/Interactive/InteractiveSupportsFeatureService.cs b/src/EditorFeatures/Core.Wpf/Interactive/InteractiveSupportsFeatureService.cs index d13cc6debe73c..80bd77c758207 100644 --- a/src/EditorFeatures/Core.Wpf/Interactive/InteractiveSupportsFeatureService.cs +++ b/src/EditorFeatures/Core.Wpf/Interactive/InteractiveSupportsFeatureService.cs @@ -14,6 +14,11 @@ internal sealed class InteractiveSupportsFeatureService [ExportWorkspaceService(typeof(ITextBufferSupportsFeatureService), WorkspaceKind.Interactive), Shared] internal class InteractiveTextBufferSupportsFeatureService : ITextBufferSupportsFeatureService { + [ImportingConstructor] + public InteractiveTextBufferSupportsFeatureService() + { + } + public bool SupportsCodeFixes(ITextBuffer textBuffer) { if (textBuffer != null) @@ -52,6 +57,11 @@ public bool SupportsNavigationToAnyPosition(ITextBuffer textBuffer) [ExportWorkspaceService(typeof(IDocumentSupportsFeatureService), WorkspaceKind.Interactive), Shared] internal class InteractiveDocumentSupportsFeatureService : IDocumentSupportsFeatureService { + [ImportingConstructor] + public InteractiveDocumentSupportsFeatureService() + { + } + public bool SupportsCodeFixes(Document document) { // TODO: Implement this. diff --git a/src/EditorFeatures/Core.Wpf/NavigateTo/DefaultNavigateToPreviewServiceFactory.cs b/src/EditorFeatures/Core.Wpf/NavigateTo/DefaultNavigateToPreviewServiceFactory.cs index b28524f853c0d..9c63c1d914115 100644 --- a/src/EditorFeatures/Core.Wpf/NavigateTo/DefaultNavigateToPreviewServiceFactory.cs +++ b/src/EditorFeatures/Core.Wpf/NavigateTo/DefaultNavigateToPreviewServiceFactory.cs @@ -13,6 +13,11 @@ internal sealed class DefaultNavigateToPreviewServiceFactory : IWorkspaceService private Lazy _singleton = new Lazy(() => new DefaultNavigateToPreviewService()); + [ImportingConstructor] + public DefaultNavigateToPreviewServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return _singleton.Value; diff --git a/src/EditorFeatures/Core.Wpf/Notification/EditorNotificationServiceFactory.cs b/src/EditorFeatures/Core.Wpf/Notification/EditorNotificationServiceFactory.cs index 8614fa169d564..d40fb752a68cc 100644 --- a/src/EditorFeatures/Core.Wpf/Notification/EditorNotificationServiceFactory.cs +++ b/src/EditorFeatures/Core.Wpf/Notification/EditorNotificationServiceFactory.cs @@ -17,6 +17,11 @@ internal class EditorNotificationServiceFactory : IWorkspaceServiceFactory private static EditorDialogService s_singleton; + [ImportingConstructor] + public EditorNotificationServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { lock (s_gate) diff --git a/src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs b/src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs index fc84fe968f92f..0db565d30ea45 100644 --- a/src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs +++ b/src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Composition; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -134,6 +135,27 @@ public SolutionPreviewResult GetSolutionPreviews(Solution oldSolution, Solution CreateRemovedAdditionalDocumentPreviewViewAsync(oldSolution.GetAdditionalDocument(documentId), zoomLevel, c))); } + foreach (var documentId in projectChanges.GetChangedAnalyzerConfigDocuments()) + { + cancellationToken.ThrowIfCancellationRequested(); + previewItems.Add(new SolutionPreviewItem(documentId.ProjectId, documentId, c => + CreateChangedAnalyzerConfigDocumentPreviewViewAsync(oldSolution.GetAnalyzerConfigDocument(documentId), newSolution.GetAnalyzerConfigDocument(documentId), zoomLevel, c))); + } + + foreach (var documentId in projectChanges.GetAddedAnalyzerConfigDocuments()) + { + cancellationToken.ThrowIfCancellationRequested(); + previewItems.Add(new SolutionPreviewItem(documentId.ProjectId, documentId, c => + CreateAddedAnalyzerConfigDocumentPreviewViewAsync(newSolution.GetAnalyzerConfigDocument(documentId), zoomLevel, c))); + } + + foreach (var documentId in projectChanges.GetRemovedAnalyzerConfigDocuments()) + { + cancellationToken.ThrowIfCancellationRequested(); + previewItems.Add(new SolutionPreviewItem(oldProject.Id, documentId, c => + CreateRemovedAnalyzerConfigDocumentPreviewViewAsync(oldSolution.GetAnalyzerConfigDocument(documentId), zoomLevel, c))); + } + foreach (var metadataReference in projectChanges.GetAddedMetadataReferences()) { cancellationToken.ThrowIfCancellationRequested(); @@ -250,32 +272,50 @@ private Task CreateAddedDocumentPreviewViewCoreAsync(ITextBuffer newBuff return CreateNewDifferenceViewerAsync(null, workspace, originalBuffer, changedBuffer, zoomLevel, cancellationToken); } - public Task CreateAddedDocumentPreviewViewAsync(Document document, double zoomLevel, CancellationToken cancellationToken) + private Task CreateAddedTextDocumentPreviewViewAsync( + TextDocument document, + double zoomLevel, + Func createBuffer, + Action openTextDocument, + CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var newBuffer = CreateNewBuffer(document, cancellationToken); + var newBuffer = createBuffer(document, cancellationToken); // Create PreviewWorkspace around the buffer to be displayed in the diff preview // so that all IDE services (colorizer, squiggles etc.) light up in this buffer. var rightWorkspace = new PreviewWorkspace( - document.WithText(newBuffer.AsTextContainer().CurrentText).Project.Solution); - rightWorkspace.OpenDocument(document.Id); + document.Project.Solution.WithTextDocumentText(document.Id, newBuffer.AsTextContainer().CurrentText)); + openTextDocument(rightWorkspace, document.Id); return CreateAddedDocumentPreviewViewCoreAsync(newBuffer, rightWorkspace, document, zoomLevel, cancellationToken); } - public Task CreateAddedAdditionalDocumentPreviewViewAsync(TextDocument document, double zoomLevel, CancellationToken cancellationToken) + public Task CreateAddedDocumentPreviewViewAsync(Document document, double zoomLevel, CancellationToken cancellationToken) { - cancellationToken.ThrowIfCancellationRequested(); - var newBuffer = CreateNewPlainTextBuffer(document, cancellationToken); + return CreateAddedTextDocumentPreviewViewAsync( + document, zoomLevel, + createBuffer: (textDocument, cancellationToken) => CreateNewBuffer((Document)textDocument, cancellationToken), + openTextDocument: (workspace, documentId) => workspace.OpenDocument(documentId), + cancellationToken); + } - // Create PreviewWorkspace around the buffer to be displayed in the diff preview - // so that all IDE services (colorizer, squiggles etc.) light up in this buffer. - var rightWorkspace = new PreviewWorkspace( - document.Project.Solution.WithAdditionalDocumentText(document.Id, newBuffer.AsTextContainer().CurrentText)); - rightWorkspace.OpenAdditionalDocument(document.Id); + public Task CreateAddedAdditionalDocumentPreviewViewAsync(TextDocument document, double zoomLevel, CancellationToken cancellationToken) + { + return CreateAddedTextDocumentPreviewViewAsync( + document, zoomLevel, + createBuffer: CreateNewPlainTextBuffer, + openTextDocument: (workspace, documentId) => workspace.OpenAdditionalDocument(documentId), + cancellationToken); + } - return CreateAddedDocumentPreviewViewCoreAsync(newBuffer, rightWorkspace, document, zoomLevel, cancellationToken); + public Task CreateAddedAnalyzerConfigDocumentPreviewViewAsync(TextDocument document, double zoomLevel, CancellationToken cancellationToken) + { + return CreateAddedTextDocumentPreviewViewAsync( + document, zoomLevel, + createBuffer: CreateNewPlainTextBuffer, + openTextDocument: (workspace, documentId) => workspace.OpenAnalyzerConfigDocument(documentId), + cancellationToken); } public Task CreateRemovedDocumentPreviewViewAsync(Document document, CancellationToken cancellationToken) @@ -301,7 +341,14 @@ private Task CreateRemovedDocumentPreviewViewCoreAsync(ITextBuffer oldBu return CreateNewDifferenceViewerAsync(workspace, null, originalBuffer, changedBuffer, zoomLevel, cancellationToken); } - public Task CreateRemovedDocumentPreviewViewAsync(Document document, double zoomLevel, CancellationToken cancellationToken) + private Task CreateRemovedTextDocumentPreviewViewAsync( + TextDocument document, + double zoomLevel, + Func createBuffer, + Func removeTextDocument, + Func addTextDocument, + Action openTextDocument, + CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -315,46 +362,51 @@ public Task CreateRemovedDocumentPreviewViewAsync(Document document, dou // the diff view would long have been dismissed by the time user edits the code) // resulting in crashes. Instead we create a new buffer from the same content. // TODO: We could use ITextBufferCloneService instead here to clone the original buffer. - var oldBuffer = CreateNewBuffer(document, cancellationToken); + var oldBuffer = createBuffer(document, cancellationToken); // Create PreviewWorkspace around the buffer to be displayed in the diff preview // so that all IDE services (colorizer, squiggles etc.) light up in this buffer. - var leftDocument = document.Project - .RemoveDocument(document.Id) - .AddDocument(document.Name, oldBuffer.AsTextContainer().CurrentText); - var leftWorkspace = new PreviewWorkspace(leftDocument.Project.Solution); - leftWorkspace.OpenDocument(leftDocument.Id); + var leftDocumentId = DocumentId.CreateNewId(document.Project.Id); + var solutionWithRemovedDocument = removeTextDocument(document.Project.Solution, document.Id); + var leftSolution = addTextDocument(solutionWithRemovedDocument, leftDocumentId, document.Name, oldBuffer.AsTextContainer().CurrentText); + var leftDocument = leftSolution.GetTextDocument(leftDocumentId); + var leftWorkspace = new PreviewWorkspace(leftSolution); + openTextDocument(leftWorkspace, leftDocument.Id); return CreateRemovedDocumentPreviewViewCoreAsync(oldBuffer, leftWorkspace, leftDocument, zoomLevel, cancellationToken); } - public Task CreateRemovedAdditionalDocumentPreviewViewAsync(TextDocument document, double zoomLevel, CancellationToken cancellationToken) + public Task CreateRemovedDocumentPreviewViewAsync(Document document, double zoomLevel, CancellationToken cancellationToken) { - cancellationToken.ThrowIfCancellationRequested(); - - // Note: We don't use the original buffer that is associated with oldDocument - // (and possibly open in the editor) for oldBuffer below. This is because oldBuffer - // will be used inside a projection buffer inside our inline diff preview below - // and platform's implementation currently has a bug where projection buffers - // are being leaked. This leak means that if we use the original buffer that is - // currently visible in the editor here, the projection buffer span calculation - // would be triggered every time user changes some code in this buffer (even though - // the diff view would long have been dismissed by the time user edits the code) - // resulting in crashes. Instead we create a new buffer from the same content. - // TODO: We could use ITextBufferCloneService instead here to clone the original buffer. - var oldBuffer = CreateNewPlainTextBuffer(document, cancellationToken); + return CreateRemovedTextDocumentPreviewViewAsync( + document, zoomLevel, + createBuffer: (textDocument, cancellationToken) => CreateNewBuffer((Document)textDocument, cancellationToken), + removeTextDocument: (solution, documentId) => solution.RemoveDocument(documentId), + addTextDocument: (solution, documentId, name, text) => solution.AddDocument(documentId, name, text), + openTextDocument: (workspace, documentId) => workspace.OpenDocument(documentId), + cancellationToken); + } - // Create PreviewWorkspace around the buffer to be displayed in the diff preview - // so that all IDE services (colorizer, squiggles etc.) light up in this buffer. - var leftDocumentId = DocumentId.CreateNewId(document.Project.Id); - var leftSolution = document.Project.Solution - .RemoveAdditionalDocument(document.Id) - .AddAdditionalDocument(leftDocumentId, document.Name, oldBuffer.AsTextContainer().CurrentText); - var leftDocument = leftSolution.GetAdditionalDocument(leftDocumentId); - var leftWorkspace = new PreviewWorkspace(leftSolution); - leftWorkspace.OpenAdditionalDocument(leftDocumentId); + public Task CreateRemovedAdditionalDocumentPreviewViewAsync(TextDocument document, double zoomLevel, CancellationToken cancellationToken) + { + return CreateRemovedTextDocumentPreviewViewAsync( + document, zoomLevel, + createBuffer: CreateNewPlainTextBuffer, + removeTextDocument: (solution, documentId) => solution.RemoveAdditionalDocument(documentId), + addTextDocument: (solution, documentId, name, text) => solution.AddAdditionalDocument(documentId, name, text), + openTextDocument: (workspace, documentId) => workspace.OpenAdditionalDocument(documentId), + cancellationToken); + } - return CreateRemovedDocumentPreviewViewCoreAsync(oldBuffer, leftWorkspace, leftDocument, zoomLevel, cancellationToken); + public Task CreateRemovedAnalyzerConfigDocumentPreviewViewAsync(TextDocument document, double zoomLevel, CancellationToken cancellationToken) + { + return CreateRemovedTextDocumentPreviewViewAsync( + document, zoomLevel, + createBuffer: CreateNewPlainTextBuffer, + removeTextDocument: (solution, documentId) => solution.RemoveAnalyzerConfigDocument(documentId), + addTextDocument: (solution, documentId, name, text) => solution.AddAnalyzerConfigDocument(documentId, name, text), + openTextDocument: (workspace, documentId) => workspace.OpenAnalyzerConfigDocument(documentId), + cancellationToken); } public Task CreateChangedDocumentPreviewViewAsync(Document oldDocument, Document newDocument, CancellationToken cancellationToken) @@ -445,8 +497,21 @@ public Task CreateChangedDocumentPreviewViewAsync(Document oldDocument, leftWorkspace, rightWorkspace, zoomLevel, cancellationToken); } - public Task CreateChangedAdditionalDocumentPreviewViewAsync(TextDocument oldDocument, TextDocument newDocument, double zoomLevel, CancellationToken cancellationToken) + // NOTE: We are only sharing this code between additional documents and analyzer config documents, + // which are essentially plain text documents. Regular source documents need special handling + // and hence have a different implementation. + private Task CreateChangedAdditionalOrAnalyzerConfigDocumentPreviewViewAsync( + TextDocument oldDocument, + TextDocument newDocument, + double zoomLevel, + Func removeTextDocument, + Func addTextDocument, + Func withDocumentText, + Action openTextDocument, + CancellationToken cancellationToken) { + Debug.Assert(oldDocument.Kind == TextDocumentKind.AdditionalDocument || oldDocument.Kind == TextDocumentKind.AnalyzerConfigDocument); + cancellationToken.ThrowIfCancellationRequested(); // Note: We don't use the original buffer that is associated with oldDocument @@ -479,21 +544,42 @@ public Task CreateChangedAdditionalDocumentPreviewViewAsync(TextDocument // Create PreviewWorkspaces around the buffers to be displayed on the left and right // so that all IDE services (colorizer, squiggles etc.) light up in these buffers. var leftDocumentId = DocumentId.CreateNewId(oldDocument.Project.Id); - var leftSolution = oldDocument.Project.Solution - .RemoveAdditionalDocument(oldDocument.Id) - .AddAdditionalDocument(leftDocumentId, oldDocument.Name, oldBuffer.AsTextContainer().CurrentText); + var solutionWithRemovedDocument = removeTextDocument(oldDocument.Project.Solution, oldDocument.Id); + var leftSolution = addTextDocument(solutionWithRemovedDocument, leftDocumentId, oldDocument.Name, oldBuffer.AsTextContainer().CurrentText); var leftWorkspace = new PreviewWorkspace(leftSolution); - leftWorkspace.OpenAdditionalDocument(leftDocumentId); + openTextDocument(leftWorkspace, leftDocumentId); var rightWorkSpace = new PreviewWorkspace( - oldDocument.Project.Solution.WithAdditionalDocumentText(oldDocument.Id, newBuffer.AsTextContainer().CurrentText)); - rightWorkSpace.OpenAdditionalDocument(newDocument.Id); + withDocumentText(oldDocument.Project.Solution, oldDocument.Id, newBuffer.AsTextContainer().CurrentText, PreservationMode.PreserveValue)); + openTextDocument(rightWorkSpace, newDocument.Id); return CreateChangedDocumentViewAsync( oldBuffer, newBuffer, description, originalLineSpans, changedLineSpans, leftWorkspace, rightWorkSpace, zoomLevel, cancellationToken); } + public Task CreateChangedAdditionalDocumentPreviewViewAsync(TextDocument oldDocument, TextDocument newDocument, double zoomLevel, CancellationToken cancellationToken) + { + return CreateChangedAdditionalOrAnalyzerConfigDocumentPreviewViewAsync( + oldDocument, newDocument, zoomLevel, + removeTextDocument: (solution, documentId) => solution.RemoveAdditionalDocument(documentId), + addTextDocument: (solution, documentId, name, text) => solution.AddAdditionalDocument(documentId, name, text), + withDocumentText: (solution, documentId, newText, mode) => solution.WithAdditionalDocumentText(documentId, newText, mode), + openTextDocument: (workspace, documentId) => workspace.OpenAdditionalDocument(documentId), + cancellationToken); + } + + public Task CreateChangedAnalyzerConfigDocumentPreviewViewAsync(TextDocument oldDocument, TextDocument newDocument, double zoomLevel, CancellationToken cancellationToken) + { + return CreateChangedAdditionalOrAnalyzerConfigDocumentPreviewViewAsync( + oldDocument, newDocument, zoomLevel, + removeTextDocument: (solution, documentId) => solution.RemoveAnalyzerConfigDocument(documentId), + addTextDocument: (solution, documentId, name, text) => solution.AddAnalyzerConfigDocument(documentId, name, text), + withDocumentText: (solution, documentId, newText, mode) => solution.WithAnalyzerConfigDocumentText(documentId, newText, mode), + openTextDocument: (workspace, documentId) => workspace.OpenAnalyzerConfigDocument(documentId), + cancellationToken); + } + private Task CreateChangedDocumentViewAsync(ITextBuffer oldBuffer, ITextBuffer newBuffer, string description, List originalSpans, List changedSpans, PreviewWorkspace leftWorkspace, PreviewWorkspace rightWorkspace, double zoomLevel, CancellationToken cancellationToken) diff --git a/src/EditorFeatures/Core.Wpf/PreviewWarningTagDefinition.cs b/src/EditorFeatures/Core.Wpf/PreviewWarningTagDefinition.cs index 75c87566fc7bf..4e66a8b17931d 100644 --- a/src/EditorFeatures/Core.Wpf/PreviewWarningTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/PreviewWarningTagDefinition.cs @@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Editor.Shared.Tagging.Tags [ExcludeFromCodeCoverage] internal class PreviewWarningTagDefinition : MarkerFormatDefinition { + [ImportingConstructor] public PreviewWarningTagDefinition() { this.Border = new Pen(new SolidColorBrush(Color.FromRgb(230, 117, 64)), thickness: 1.5); diff --git a/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/DefinitionHighlightTagDefinition.cs b/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/DefinitionHighlightTagDefinition.cs index 3371a6175b4ba..bf0230153425a 100644 --- a/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/DefinitionHighlightTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/DefinitionHighlightTagDefinition.cs @@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting [UserVisible(true)] internal class DefinitionHighlightTagDefinition : MarkerFormatDefinition { + [ImportingConstructor] public DefinitionHighlightTagDefinition() { // NOTE: This is the same color used by the editor for reference highlighting diff --git a/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/WrittenReferenceHighlightTagDefinition.cs b/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/WrittenReferenceHighlightTagDefinition.cs index 29dd7fe81b807..d9a5ab920fb89 100644 --- a/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/WrittenReferenceHighlightTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/ReferenceHighlighting/WrittenReferenceHighlightTagDefinition.cs @@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting [UserVisible(true)] internal class WrittenReferenceHighlightTagDefinition : MarkerFormatDefinition { + [ImportingConstructor] public WrittenReferenceHighlightTagDefinition() { // NOTE: This is the same color used by the editor for reference highlighting diff --git a/src/EditorFeatures/Core.Wpf/RenameTracking/RenameTrackingTagDefinition.cs b/src/EditorFeatures/Core.Wpf/RenameTracking/RenameTrackingTagDefinition.cs index d82239266b351..5f2a5786a4db2 100644 --- a/src/EditorFeatures/Core.Wpf/RenameTracking/RenameTrackingTagDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/RenameTracking/RenameTrackingTagDefinition.cs @@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking [ExcludeFromCodeCoverage] internal class RenameTrackingTagDefinition : MarkerFormatDefinition { + [ImportingConstructor] public RenameTrackingTagDefinition() { this.Border = new Pen(Brushes.Black, thickness: 1.0) { DashStyle = new DashStyle(new[] { 0.5, 4.0 }, 1) }; diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixAllGetFixesService.cs b/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixAllGetFixesService.cs index 4d7bf6a852d67..65ce7713506ab 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixAllGetFixesService.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixAllGetFixesService.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions [ExportWorkspaceServiceFactory(typeof(IFixAllGetFixesService), ServiceLayer.Host), Shared] internal class FixAllGetFixesService : IFixAllGetFixesService, IWorkspaceServiceFactory { + [ImportingConstructor] + public FixAllGetFixesService() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return this; diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActions/SuggestedAction.cs b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActions/SuggestedAction.cs index f293990d1cc0b..42e2068856395 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActions/SuggestedAction.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActions/SuggestedAction.cs @@ -34,6 +34,8 @@ internal abstract partial class SuggestedAction : ForegroundThreadAffinitizedObj protected readonly object Provider; internal readonly CodeAction CodeAction; + private bool _isApplied; + private ICodeActionEditHandlerService EditHandler => SourceProvider.EditHandler; internal SuggestedAction( @@ -163,9 +165,11 @@ private void InvokeWorker( FunctionId.CodeFixes_ApplyChanges, KeyValueLogMessage.Create(LogType.UserAction, m => CreateLogProperties(m)), cancellationToken)) { // Note: we want to block the UI thread here so the user cannot modify anything while the codefix applies - EditHandler.ApplyAsync(Workspace, getFromDocument(), + var applicationTask = EditHandler.ApplyAsync(Workspace, getFromDocument(), operations.ToImmutableArray(), CodeAction.Title, - progressTracker, cancellationToken).Wait(cancellationToken); + progressTracker, cancellationToken); + applicationTask.Wait(cancellationToken); + _isApplied = applicationTask.Result; } } } @@ -308,5 +312,18 @@ public override int GetHashCode() } #endregion + + internal TestAccessor GetTestAccessor() + => new TestAccessor(this); + + internal readonly struct TestAccessor + { + private readonly SuggestedAction _suggestedAction; + + public TestAccessor(SuggestedAction suggestedAction) + => _suggestedAction = suggestedAction; + + public ref bool IsApplied => ref _suggestedAction._isApplied; + } } } diff --git a/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.Update.cs b/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.Update.cs index 185d6fe2433ff..4f7623418294a 100644 --- a/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.Update.cs +++ b/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.Update.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// 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.Concurrent; @@ -34,7 +34,8 @@ internal partial class SymbolSearchUpdateEngine internal const string ChecksumAttributeName = "checksum"; internal const string UpToDateAttributeName = "upToDate"; internal const string TooOldAttributeName = "tooOld"; - internal const string NugetOrgSource = "nuget.org"; + internal const string NugetOrgSourceName = "nuget.org"; + internal const string NugetOrgSourceUri = "https://api.nuget.org/v3/index.json"; public const string HostId = "RoslynNuGetSearch"; private const string MicrosoftAssemblyReferencesName = "MicrosoftAssemblyReferences"; @@ -59,9 +60,9 @@ internal partial class SymbolSearchUpdateEngine private readonly IDatabaseFactoryService _databaseFactoryService; private readonly Func _reportAndSwallowException; - private Task LogInfoAsync(string text) => _logService.LogInfoAsync(text); + private Task LogInfoAsync(string text) => _logService.LogInfoAsync(text, _updateCancellationToken); - private Task LogExceptionAsync(Exception e, string text) => _logService.LogExceptionAsync(e.ToString(), text); + private Task LogExceptionAsync(Exception e, string text) => _logService.LogExceptionAsync(e.ToString(), text, _updateCancellationToken); public Task UpdateContinuouslyAsync(string source, string localSettingsDirectory) { @@ -106,7 +107,7 @@ public Updater(SymbolSearchUpdateEngine service, string source, string localSett internal async Task UpdateInBackgroundAsync() { // We only support this single source currently. - if (_source != NugetOrgSource) + if (_source != NugetOrgSourceUri) { return; } @@ -227,24 +228,24 @@ private async Task DownloadFullDatabaseAsync() try { var title = string.Format(EditorFeaturesWpfResources.Downloading_IntelliSense_index_for_0, _source); - await _service._progressService.OnDownloadFullDatabaseStartedAsync(title).ConfigureAwait(false); + await _service._progressService.OnDownloadFullDatabaseStartedAsync(title, _service._updateCancellationToken).ConfigureAwait(false); var (succeeded, delay) = await DownloadFullDatabaseWorkerAsync().ConfigureAwait(false); if (succeeded) { - await _service._progressService.OnDownloadFullDatabaseSucceededAsync().ConfigureAwait(false); + await _service._progressService.OnDownloadFullDatabaseSucceededAsync(_service._updateCancellationToken).ConfigureAwait(false); } else { await _service._progressService.OnDownloadFullDatabaseFailedAsync( - EditorFeaturesWpfResources.Downloading_index_failed).ConfigureAwait(false); + EditorFeaturesWpfResources.Downloading_index_failed, _service._updateCancellationToken).ConfigureAwait(false); } return delay; } catch (OperationCanceledException) { - await _service._progressService.OnDownloadFullDatabaseCanceledAsync().ConfigureAwait(false); + await _service._progressService.OnDownloadFullDatabaseCanceledAsync(_service._updateCancellationToken).ConfigureAwait(false); throw; } catch (Exception e) @@ -252,7 +253,7 @@ await _service._progressService.OnDownloadFullDatabaseFailedAsync( var message = string.Format( EditorFeaturesWpfResources.Downloading_index_failed_0, "\r\n" + e.ToString()); - await _service._progressService.OnDownloadFullDatabaseFailedAsync(message).ConfigureAwait(false); + await _service._progressService.OnDownloadFullDatabaseFailedAsync(message, _service._updateCancellationToken).ConfigureAwait(false); throw; } } diff --git a/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.cs b/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.cs index 2bc83cd9a6ce3..257f41f14ccc0 100644 --- a/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.cs +++ b/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngine.cs @@ -160,7 +160,7 @@ public Task> FindReferenceAssemb string name, int arity, CancellationToken cancellationToken) { // Our reference assembly data is stored in the nuget.org DB. - if (!_sourceToDatabase.TryGetValue(NugetOrgSource, out var databaseWrapper)) + if (!_sourceToDatabase.TryGetValue(NugetOrgSourceName, out var databaseWrapper)) { // Don't have a database to search. return SpecializedTasks.EmptyImmutableArray(); diff --git a/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngineFactory.cs b/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngineFactory.cs index b6d81f69dd7be..6892872a51492 100644 --- a/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngineFactory.cs +++ b/src/EditorFeatures/Core.Wpf/SymbolSearch/SymbolSearchUpdateEngineFactory.cs @@ -102,23 +102,23 @@ public CallbackObject(ISymbolSearchLogService logService, ISymbolSearchProgressS _progressService = progressService; } - public Task LogExceptionAsync(string exception, string text) - => _logService.LogExceptionAsync(exception, text); + public Task LogExceptionAsync(string exception, string text, CancellationToken cancellationToken) + => _logService.LogExceptionAsync(exception, text, cancellationToken); - public Task LogInfoAsync(string text) - => _logService.LogInfoAsync(text); + public Task LogInfoAsync(string text, CancellationToken cancellationToken) + => _logService.LogInfoAsync(text, cancellationToken); - public Task OnDownloadFullDatabaseStartedAsync(string title) - => _progressService.OnDownloadFullDatabaseStartedAsync(title); + public Task OnDownloadFullDatabaseStartedAsync(string title, CancellationToken cancellationToken) + => _progressService.OnDownloadFullDatabaseStartedAsync(title, cancellationToken); - public Task OnDownloadFullDatabaseSucceededAsync() - => _progressService.OnDownloadFullDatabaseSucceededAsync(); + public Task OnDownloadFullDatabaseSucceededAsync(CancellationToken cancellation) + => _progressService.OnDownloadFullDatabaseSucceededAsync(cancellation); - public Task OnDownloadFullDatabaseCanceledAsync() - => _progressService.OnDownloadFullDatabaseCanceledAsync(); + public Task OnDownloadFullDatabaseCanceledAsync(CancellationToken cancellationToken) + => _progressService.OnDownloadFullDatabaseCanceledAsync(cancellationToken); - public Task OnDownloadFullDatabaseFailedAsync(string message) - => _progressService.OnDownloadFullDatabaseFailedAsync(message); + public Task OnDownloadFullDatabaseFailedAsync(string message, CancellationToken cancellationToken) + => _progressService.OnDownloadFullDatabaseFailedAsync(message, cancellationToken); } } } diff --git a/src/EditorFeatures/Core.Wpf/Tags/DefaultImageMonikerService.cs b/src/EditorFeatures/Core.Wpf/Tags/DefaultImageMonikerService.cs index 8119374870465..bf1be310bed96 100644 --- a/src/EditorFeatures/Core.Wpf/Tags/DefaultImageMonikerService.cs +++ b/src/EditorFeatures/Core.Wpf/Tags/DefaultImageMonikerService.cs @@ -1,6 +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.Collections.Immutable; +using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Editor.Wpf; using Microsoft.VisualStudio.Imaging; using Microsoft.VisualStudio.Imaging.Interop; @@ -12,6 +13,11 @@ internal class DefaultImageMonikerService : IImageMonikerService { public const string Name = nameof(DefaultImageMonikerService); + [ImportingConstructor] + public DefaultImageMonikerService() + { + } + public bool TryGetImageMoniker(ImmutableArray tags, out ImageMoniker imageMoniker) { var glyph = tags.GetFirstGlyph(); diff --git a/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs b/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs index 5ab6255c5149a..822ed1cb7c3e4 100644 --- a/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs +++ b/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs @@ -37,7 +37,7 @@ internal class FindReferencesCommandHandler : VSCommanding.ICommandHandler EditorFeaturesResources.Find_References; [ImportingConstructor] - internal FindReferencesCommandHandler( + public FindReferencesCommandHandler( [ImportMany] IEnumerable> streamingPresenters, IAsynchronousOperationListenerProvider listenerProvider) { diff --git a/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs b/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs index b7f5ec3f6cbad..badc5cf65ec7b 100644 --- a/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs +++ b/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs @@ -27,6 +27,11 @@ DefinitionItem GetThirdPartyDefinitionItem( [ExportWorkspaceService(typeof(IDefinitionsAndReferencesFactory)), Shared] internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReferencesFactory { + [ImportingConstructor] + public DefaultDefinitionsAndReferencesFactory() + { + } + /// /// Provides an extension point that allows for other workspace layers to add additional /// results to the results found by the FindReferences engine. diff --git a/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs b/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs index f97b5b35c8dce..c0f05fd0e5dc1 100644 --- a/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs +++ b/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.Editor.GoToDefinition internal class GoToDefinitionCommandHandler : VSCommanding.ICommandHandler { + [ImportingConstructor] + public GoToDefinitionCommandHandler() + { + } + public string DisplayName => EditorFeaturesResources.Go_to_Definition; private (Document, IGoToDefinitionService) GetDocumentAndService(ITextSnapshot snapshot) diff --git a/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionEditHandlerService.cs b/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionEditHandlerService.cs index f35256651ae37..c71acbf7da3c5 100644 --- a/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionEditHandlerService.cs +++ b/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionEditHandlerService.cs @@ -94,7 +94,7 @@ public SolutionPreviewResult GetPreviews( return currentResult; } - public async Task ApplyAsync( + public async Task ApplyAsync( Workspace workspace, Document fromDocument, ImmutableArray operations, string title, IProgressTracker progressTracker, @@ -104,7 +104,7 @@ public async Task ApplyAsync( if (operations.IsDefaultOrEmpty) { - return; + return _renameService.ActiveSession is null; } if (_renameService.ActiveSession != null) @@ -112,7 +112,7 @@ public async Task ApplyAsync( workspace.Services.GetService()?.SendNotification( EditorFeaturesResources.Cannot_apply_operation_while_a_rename_session_is_active, severity: NotificationSeverity.Error); - return; + return false; } #if DEBUG && false @@ -133,6 +133,8 @@ public async Task ApplyAsync( var oldSolution = workspace.CurrentSolution; + bool applied; + // Determine if we're making a simple text edit to a single file or not. // If we're not, then we need to make a linked global undo to wrap the // application of these operations. This way we should be able to undo @@ -151,7 +153,7 @@ public async Task ApplyAsync( using (workspace.Services.GetService().RegisterUndoTransaction(text, title)) { - operations.Single().Apply(workspace, cancellationToken); + applied = operations.Single().TryApply(workspace, progressTracker, cancellationToken); } } else @@ -168,7 +170,7 @@ public async Task ApplyAsync( transaction.AddDocument(fromDocument.Id); } - ProcessOperations( + applied = ProcessOperations( workspace, operations, progressTracker, cancellationToken); @@ -178,6 +180,7 @@ public async Task ApplyAsync( var updatedSolution = operations.OfType().FirstOrDefault()?.ChangedSolution ?? oldSolution; TryNavigateToLocationOrStartRenameSession(workspace, oldSolution, updatedSolution, cancellationToken); + return applied; } private TextDocument TryGetSingleChangedText( @@ -214,11 +217,13 @@ private TextDocument TryGetSingleChangedText( if (projectChange.GetAddedAdditionalDocuments().Any() || projectChange.GetAddedAnalyzerReferences().Any() || projectChange.GetAddedDocuments().Any() || + projectChange.GetAddedAnalyzerConfigDocuments().Any() || projectChange.GetAddedMetadataReferences().Any() || projectChange.GetAddedProjectReferences().Any() || projectChange.GetRemovedAdditionalDocuments().Any() || projectChange.GetRemovedAnalyzerReferences().Any() || projectChange.GetRemovedDocuments().Any() || + projectChange.GetRemovedAnalyzerConfigDocuments().Any() || projectChange.GetRemovedMetadataReferences().Any() || projectChange.GetRemovedProjectReferences().Any()) { @@ -227,27 +232,41 @@ private TextDocument TryGetSingleChangedText( var changedAdditionalDocuments = projectChange.GetChangedAdditionalDocuments().ToImmutableArray(); var changedDocuments = projectChange.GetChangedDocuments().ToImmutableArray(); + var changedAnalyzerConfigDocuments = projectChange.GetChangedAnalyzerConfigDocuments().ToImmutableArray(); - if (changedAdditionalDocuments.Length + changedDocuments.Length != 1) + if (changedAdditionalDocuments.Length + changedDocuments.Length + changedAnalyzerConfigDocuments.Length != 1) { return null; } if (changedDocuments.Any(id => newSolution.GetDocument(id).HasInfoChanged(oldSolution.GetDocument(id))) || - changedAdditionalDocuments.Any(id => newSolution.GetAdditionalDocument(id).HasInfoChanged(oldSolution.GetAdditionalDocument(id)))) + changedAdditionalDocuments.Any(id => newSolution.GetAdditionalDocument(id).HasInfoChanged(oldSolution.GetAdditionalDocument(id))) || + changedAnalyzerConfigDocuments.Any(id => newSolution.GetAnalyzerConfigDocument(id).HasInfoChanged(oldSolution.GetAnalyzerConfigDocument(id)))) { return null; } - return changedDocuments.Length == 1 - ? oldSolution.GetDocument(changedDocuments[0]) - : oldSolution.GetAdditionalDocument(changedAdditionalDocuments[0]); + if (changedDocuments.Length == 1) + { + return oldSolution.GetDocument(changedDocuments[0]); + } + else if (changedAdditionalDocuments.Length == 1) + { + return oldSolution.GetAdditionalDocument(changedAdditionalDocuments[0]); + } + else + { + return oldSolution.GetAnalyzerConfigDocument(changedAnalyzerConfigDocuments[0]); + } } - private static void ProcessOperations( + /// if all expected are applied successfully; + /// otherwise, . + private static bool ProcessOperations( Workspace workspace, ImmutableArray operations, IProgressTracker progressTracker, CancellationToken cancellationToken) { + var applied = true; var seenApplyChanges = false; foreach (var operation in operations) { @@ -262,8 +281,10 @@ private static void ProcessOperations( seenApplyChanges = true; } - operation.TryApply(workspace, progressTracker, cancellationToken); + applied &= operation.TryApply(workspace, progressTracker, cancellationToken); } + + return applied; } private void TryNavigateToLocationOrStartRenameSession(Workspace workspace, Solution oldSolution, Solution newSolution, CancellationToken cancellationToken) diff --git a/src/EditorFeatures/Core/Implementation/CodeRefactorings/ICodeActionEditHandlerService.cs b/src/EditorFeatures/Core/Implementation/CodeRefactorings/ICodeActionEditHandlerService.cs index f4a38d5cf44b2..71acc82492638 100644 --- a/src/EditorFeatures/Core/Implementation/CodeRefactorings/ICodeActionEditHandlerService.cs +++ b/src/EditorFeatures/Core/Implementation/CodeRefactorings/ICodeActionEditHandlerService.cs @@ -16,7 +16,7 @@ internal interface ICodeActionEditHandlerService SolutionPreviewResult GetPreviews( Workspace workspace, ImmutableArray operations, CancellationToken cancellationToken); - Task ApplyAsync( + Task ApplyAsync( Workspace workspace, Document fromDocument, ImmutableArray operations, string title, IProgressTracker progressTracker, diff --git a/src/EditorFeatures/Core/Implementation/CommentSelection/CommentUncommentSelectionCommandHandler.cs b/src/EditorFeatures/Core/Implementation/CommentSelection/CommentUncommentSelectionCommandHandler.cs index caaced69998d6..b3caae2734ebb 100644 --- a/src/EditorFeatures/Core/Implementation/CommentSelection/CommentUncommentSelectionCommandHandler.cs +++ b/src/EditorFeatures/Core/Implementation/CommentSelection/CommentUncommentSelectionCommandHandler.cs @@ -34,7 +34,7 @@ internal class CommentUncommentSelectionCommandHandler : private readonly IEditorOperationsFactoryService _editorOperationsFactoryService; [ImportingConstructor] - internal CommentUncommentSelectionCommandHandler( + public CommentUncommentSelectionCommandHandler( ITextUndoHistoryRegistry undoHistoryRegistry, IEditorOperationsFactoryService editorOperationsFactoryService) { diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingService.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingService.cs index 25d9126529726..7221fa2da89f0 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingService.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingService.cs @@ -30,7 +30,8 @@ internal sealed class ActiveStatementTrackingService : IActiveStatementTrackingS { private TrackingSession _sessionOpt; - internal ActiveStatementTrackingService() + [ImportingConstructor] + public ActiveStatementTrackingService() { } diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs index 20d11f8d8d187..3957b2d45a9cd 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue [ExportWorkspaceServiceFactory(typeof(IActiveStatementTrackingService), ServiceLayer.Editor), Shared] internal sealed class ActiveStatementTrackingServiceFactory : IWorkspaceServiceFactory { + [ImportingConstructor] + public ActiveStatementTrackingServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return new ActiveStatementTrackingService(); diff --git a/src/EditorFeatures/Core/Implementation/Formatting/Indentation/AbstractSmartTokenFormatterCommandHandler.cs b/src/EditorFeatures/Core/Implementation/Formatting/Indentation/AbstractSmartTokenFormatterCommandHandler.cs index 4b2570d4eb0fc..b6e2f60bdef05 100644 --- a/src/EditorFeatures/Core/Implementation/Formatting/Indentation/AbstractSmartTokenFormatterCommandHandler.cs +++ b/src/EditorFeatures/Core/Implementation/Formatting/Indentation/AbstractSmartTokenFormatterCommandHandler.cs @@ -23,6 +23,8 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Formatting.Indentation { + using Microsoft.CodeAnalysis.Indentation; + internal abstract class AbstractSmartTokenFormatterCommandHandler : IChainedCommandHandler { @@ -139,7 +141,7 @@ internal void ExecuteCommandWorker(ReturnKeyCommandArgs args, CancellationToken return; } - var indentationService = document.GetLanguageService(); + var indentationService = document.GetLanguageService(); var indentation = indentationService.GetDesiredIndentation(document, currentPosition.GetContainingLine().LineNumber, cancellationToken); diff --git a/src/EditorFeatures/Core/Implementation/InfoBar/EditorInfoBarService.cs b/src/EditorFeatures/Core/Implementation/InfoBar/EditorInfoBarService.cs index f4931a206ae92..1e6a9e60d3517 100644 --- a/src/EditorFeatures/Core/Implementation/InfoBar/EditorInfoBarService.cs +++ b/src/EditorFeatures/Core/Implementation/InfoBar/EditorInfoBarService.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Workspaces [ExportWorkspaceService(typeof(IInfoBarService)), Shared] internal class EditorInfoBarService : IInfoBarService { + [ImportingConstructor] + public EditorInfoBarService() + { + } + public void ShowInfoBarInActiveView(string message, params InfoBarUI[] items) => ShowInfoBarInGlobalView(message, items); diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs index f24d361cfd32c..7277465adfed2 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs @@ -153,7 +153,7 @@ public AsyncCompletionData.CommitResult TryCommit( AsyncCompletionLogger.LogCommitTypeImportCompletionItem(); } } - + if (session.TextView.Properties.TryGetProperty(CompletionSource.TargetTypeFilterExperimentEnabled, out bool isExperimentEnabled) && isExperimentEnabled) { // Capture the % of committed completion items that would have appeared in the "Target type matches" filter diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CompletionSource.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CompletionSource.cs index 7c4cb2759c3b5..df98d8b31a065 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CompletionSource.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CompletionSource.cs @@ -96,10 +96,11 @@ public AsyncCompletionData.CompletionStartData InitializeCompletion( return AsyncCompletionData.CompletionStartData.DoesNotParticipateInCompletion; } - if (!document.Project.Solution.Workspace.Options.GetOption(CompletionOptions.BlockForCompletionItems, service.Language)) - { - _textView.Options.GlobalOptions.SetOptionValue(NonBlockingCompletionEditorOption, true); - } + // The Editor supports the option per textView. + // There could be mixed desired behavior per textView and even per same completion session. + // The right fix would be to send this information as a result of the method. + // Then, the Editor would choose the right behavior for mixed cases. + _textView.Options.GlobalOptions.SetOptionValue(NonBlockingCompletionEditorOption, !document.Project.Solution.Workspace.Options.GetOption(CompletionOptions.BlockForCompletionItems, service.Language)); // In case of calls with multiple completion services for the same view (e.g. TypeScript and C#), those completion services must not be called simultaneously for the same session. // Therefore, in each completion session we use a list of commit character for a specific completion service and a specific content type. diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/RecentItemsManager.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/RecentItemsManager.cs index e45b5e0721ddf..af703ece3f8c1 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/RecentItemsManager.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/RecentItemsManager.cs @@ -15,6 +15,11 @@ internal class RecentItemsManager /// private object _mruUpdateLock = new object(); + [ImportingConstructor] + public RecentItemsManager() + { + } + public ImmutableArray RecentItems { get; private set; } = ImmutableArray.Empty; public void MakeMostRecentItem(string item) diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/QuickInfo/QuickInfoSourceProvider.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/QuickInfo/QuickInfoSourceProvider.cs index cc3171ad1d76d..c461b5d5a81e6 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/QuickInfo/QuickInfoSourceProvider.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/QuickInfo/QuickInfoSourceProvider.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo [Name("RoslynQuickInfoProvider")] internal partial class QuickInfoSourceProvider : IAsyncQuickInfoSourceProvider { + [ImportingConstructor] + public QuickInfoSourceProvider() + { + } + public IAsyncQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer) { return new QuickInfoSource(textBuffer); diff --git a/src/EditorFeatures/Core/Implementation/Interactive/Completion/InteractiveCommandCompletionService.cs b/src/EditorFeatures/Core/Implementation/Interactive/Completion/InteractiveCommandCompletionService.cs index 7f1624a4d51ac..4b1a71f24c6c2 100644 --- a/src/EditorFeatures/Core/Implementation/Interactive/Completion/InteractiveCommandCompletionService.cs +++ b/src/EditorFeatures/Core/Implementation/Interactive/Completion/InteractiveCommandCompletionService.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Completion [ExportLanguageServiceFactory(typeof(CompletionService), InteractiveLanguageNames.InteractiveCommand), Shared] internal class InteractiveCommandCompletionServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public InteractiveCommandCompletionServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) { return new InteractiveCommandCompletionService(languageServices.WorkspaceServices.Workspace); diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs b/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs index 9de83e2a1a607..8cac356eac20e 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs +++ b/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs @@ -46,6 +46,7 @@ internal class MetadataAsSourceFileService : IMetadataAsSourceFileService private string _rootTemporaryPathWithGuid; private readonly string _rootTemporaryPath; + [ImportingConstructor] public MetadataAsSourceFileService() { _rootTemporaryPath = Path.Combine(Path.GetTempPath(), "MetadataAsSource"); diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs b/src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs index 9fd78c50d5a29..27375ab36aa96 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs +++ b/src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.MetadataAsSource [Shared] internal class SymbolMappingServiceFactory : IWorkspaceServiceFactory { + [ImportingConstructor] + public SymbolMappingServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return new SymbolMappingService(); diff --git a/src/EditorFeatures/Core/Implementation/Organizing/OrganizeDocumentCommandHandler.cs b/src/EditorFeatures/Core/Implementation/Organizing/OrganizeDocumentCommandHandler.cs index 6e315b9bba2a3..6d52399725cf9 100644 --- a/src/EditorFeatures/Core/Implementation/Organizing/OrganizeDocumentCommandHandler.cs +++ b/src/EditorFeatures/Core/Implementation/Organizing/OrganizeDocumentCommandHandler.cs @@ -27,13 +27,19 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Organizing [Name(PredefinedCommandHandlerNames.OrganizeDocument)] internal class OrganizeDocumentCommandHandler : VSCommanding.ICommandHandler, + VSCommanding.ICommandHandler, VSCommanding.ICommandHandler { + [ImportingConstructor] + public OrganizeDocumentCommandHandler() + { + } + public string DisplayName => EditorFeaturesResources.Organize_Document; public VSCommanding.CommandState GetCommandState(OrganizeDocumentCommandArgs args) { - return GetCommandState(args, _ => EditorFeaturesResources.Organize_Document); + return GetCommandState(args, _ => EditorFeaturesResources.Organize_Document, needsSemantics: true); } public bool ExecuteCommand(OrganizeDocumentCommandArgs args, CommandExecutionContext context) @@ -56,14 +62,19 @@ public bool ExecuteCommand(OrganizeDocumentCommandArgs args, CommandExecutionCon return true; } + public VSCommanding.CommandState GetCommandState(SortImportsCommandArgs args) + { + return GetCommandState(args, o => o.SortImportsDisplayStringWithAccelerator, needsSemantics: false); + } + public VSCommanding.CommandState GetCommandState(SortAndRemoveUnnecessaryImportsCommandArgs args) { - return GetCommandState(args, o => o.SortAndRemoveUnusedImportsDisplayStringWithAccelerator); + return GetCommandState(args, o => o.SortAndRemoveUnusedImportsDisplayStringWithAccelerator, needsSemantics: true); } - private VSCommanding.CommandState GetCommandState(EditorCommandArgs args, Func descriptionString) + private VSCommanding.CommandState GetCommandState(EditorCommandArgs args, Func descriptionString, bool needsSemantics) { - if (IsCommandSupported(args, out var workspace)) + if (IsCommandSupported(args, needsSemantics, out var workspace)) { var organizeImportsService = workspace.Services.GetLanguageServices(args.SubjectBuffer).GetService(); return new VSCommanding.CommandState(isAvailable: true, displayText: descriptionString(organizeImportsService)); @@ -74,7 +85,7 @@ private VSCommanding.CommandState GetCommandState(EditorCommandArgs args, Func { + [ImportingConstructor] + public RenameTrackingCancellationCommandHandler() + { + } + public string DisplayName => EditorFeaturesResources.Rename_Tracking_Cancellation; public bool ExecuteCommand(EscapeKeyCommandArgs args, CommandExecutionContext context) diff --git a/src/EditorFeatures/Core/Implementation/SmartIndent/IBlankLineIndentationService.cs b/src/EditorFeatures/Core/Implementation/SmartIndent/IBlankLineIndentationService.cs deleted file mode 100644 index 1d4c36a6f3193..0000000000000 --- a/src/EditorFeatures/Core/Implementation/SmartIndent/IBlankLineIndentationService.cs +++ /dev/null @@ -1,23 +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.Threading; -using Microsoft.CodeAnalysis.Formatting; - -namespace Microsoft.CodeAnalysis.Editor -{ - internal interface IBlankLineIndentationService - { - /// - /// Determines indentation for a blank line (i.e. after hitting enter at the end of a line, - /// or after moving to a blank line). - /// - /// Specifically, this function operates as if the line specified by - /// is blank. The actual contents of the line do not matter. All indentation information is - /// determined from the previous lines in the document. - /// - /// This function will always succeed. - /// - IndentationResult GetBlankLineIndentation( - Document document, int lineNumber, FormattingOptions.IndentStyle indentStyle, CancellationToken cancellationToken); - } -} diff --git a/src/EditorFeatures/Core/Implementation/SmartIndent/IIndentationService.cs b/src/EditorFeatures/Core/Implementation/SmartIndent/IIndentationService.cs index 92ff2e89b03c1..3c1d2d6abb721 100644 --- a/src/EditorFeatures/Core/Implementation/SmartIndent/IIndentationService.cs +++ b/src/EditorFeatures/Core/Implementation/SmartIndent/IIndentationService.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; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; @@ -18,6 +19,7 @@ namespace Microsoft.CodeAnalysis.Editor /// current line. With this tuple, both forms can be expressed, and the implementor does not /// have to convert from one to the other. /// + [Obsolete("Use Microsoft.CodeAnalysis.Indentation.IndentationResult instead.")] internal struct IndentationResult { /// @@ -36,13 +38,20 @@ public IndentationResult(int basePosition, int offset) : this() this.BasePosition = basePosition; this.Offset = offset; } + + public static implicit operator Indentation.IndentationResult(IndentationResult result) + => new Indentation.IndentationResult(result.BasePosition, result.Offset); } + // Removal of this interface tracked with https://github.com/dotnet/roslyn/issues/35872 + [Obsolete("Use Microsoft.CodeAnalysis.Indentation.IIndentationService instead.")] internal interface IIndentationService : ILanguageService { Task GetDesiredIndentation(Document document, int lineNumber, CancellationToken cancellationToken); } + // Removal of this interface tracked with https://github.com/dotnet/roslyn/issues/35872 + [Obsolete("Use Microsoft.CodeAnalysis.Indentation.IIndentationService instead.")] internal interface ISynchronousIndentationService : ILanguageService { /// diff --git a/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndent.cs b/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndent.cs index 72f0c9cc59b16..77e594d4b4e0e 100644 --- a/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndent.cs +++ b/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndent.cs @@ -10,6 +10,10 @@ using Microsoft.VisualStudio.Text.Editor; using Roslyn.Utilities; +using NewIndentationService = Microsoft.CodeAnalysis.Indentation.IIndentationService; +using OldIndentationService = Microsoft.CodeAnalysis.Editor.IIndentationService; +using OldSynchronousIndentationService = Microsoft.CodeAnalysis.Editor.ISynchronousIndentationService; + namespace Microsoft.CodeAnalysis.Editor.Implementation.SmartIndent { internal partial class SmartIndent : ISmartIndent @@ -40,21 +44,39 @@ public void Dispose() using (Logger.LogBlock(FunctionId.SmartIndentation_Start, cancellationToken)) { var document = lineToBeIndented.Snapshot.GetOpenDocumentInCurrentContextWithChanges(); - var syncService = document?.GetLanguageService(); + if (document == null) + { + return null; + } - if (syncService != null) + // First, try to go through the normal feature-layer indentation service. + var newService = document.GetLanguageService(); + if (newService != null) { - var result = syncService.GetDesiredIndentation(document, lineToBeIndented.LineNumber, cancellationToken); + var result = newService.GetDesiredIndentation(document, lineToBeIndented.LineNumber, cancellationToken); return result?.GetIndentation(_textView, lineToBeIndented); } - var asyncService = document?.GetLanguageService(); - if (asyncService != null) + // If we don't have a feature-layer service, try to fall back to the legacy + // editor-feature-layer interfaces. + +#pragma warning disable CS0618 // Type or member is obsolete + var oldSyncService = document.GetLanguageService(); + if (oldSyncService != null) { - var result = asyncService.GetDesiredIndentation(document, lineToBeIndented.LineNumber, cancellationToken).WaitAndGetResult(cancellationToken); + var result = (Indentation.IndentationResult?)oldSyncService.GetDesiredIndentation(document, lineToBeIndented.LineNumber, cancellationToken); return result?.GetIndentation(_textView, lineToBeIndented); } + var oldAsyncService = document.GetLanguageService(); + if (oldAsyncService != null) + { + var result = (Indentation.IndentationResult?)oldAsyncService.GetDesiredIndentation(document, lineToBeIndented.LineNumber, cancellationToken).WaitAndGetResult(cancellationToken); + return result?.GetIndentation(_textView, lineToBeIndented); + } +#pragma warning restore CS0618 // Type or member is obsolete + + return null; } } diff --git a/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndentProvider.cs b/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndentProvider.cs index a55b8c39f514f..07542b0757cbc 100644 --- a/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndentProvider.cs +++ b/src/EditorFeatures/Core/Implementation/SmartIndent/SmartIndentProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.SmartIndent [ContentType(ContentTypeNames.RoslynContentType)] internal class SmartIndentProvider : ISmartIndentProvider { + [ImportingConstructor] + public SmartIndentProvider() + { + } + public ISmartIndent CreateSmartIndent(ITextView textView) { if (textView == null) diff --git a/src/EditorFeatures/Core/Implementation/SolutionChangeSummary.cs b/src/EditorFeatures/Core/Implementation/SolutionChangeSummary.cs index 9e6399069f579..ce485a3b3e12b 100644 --- a/src/EditorFeatures/Core/Implementation/SolutionChangeSummary.cs +++ b/src/EditorFeatures/Core/Implementation/SolutionChangeSummary.cs @@ -26,10 +26,14 @@ public SolutionChangeSummary(Solution oldSolution, Solution newSolution, Solutio p.GetRemovedDocuments().Count() + p.GetAddedAdditionalDocuments().Count() + p.GetChangedAdditionalDocuments().Count() + - p.GetRemovedAdditionalDocuments().Count(); + p.GetRemovedAdditionalDocuments().Count() + + p.GetAddedAnalyzerConfigDocuments().Count() + + p.GetChangedAnalyzerConfigDocuments().Count() + + p.GetRemovedAnalyzerConfigDocuments().Count(); if (p.GetAddedDocuments().Any() || p.GetRemovedDocuments().Any() || p.GetAddedAdditionalDocuments().Any() || p.GetRemovedAdditionalDocuments().Any() || + p.GetAddedAnalyzerConfigDocuments().Any() || p.GetRemovedAnalyzerConfigDocuments().Any() || p.GetAddedMetadataReferences().Any() || p.GetRemovedMetadataReferences().Any() || p.GetAddedProjectReferences().Any() || p.GetRemovedProjectReferences().Any() || p.GetAddedAnalyzerReferences().Any() || p.GetRemovedAnalyzerReferences().Any()) diff --git a/src/EditorFeatures/Core/Implementation/TextBufferAssociatedViewService.cs b/src/EditorFeatures/Core/Implementation/TextBufferAssociatedViewService.cs index d4376dea26259..a4f0819b12a76 100644 --- a/src/EditorFeatures/Core/Implementation/TextBufferAssociatedViewService.cs +++ b/src/EditorFeatures/Core/Implementation/TextBufferAssociatedViewService.cs @@ -29,6 +29,11 @@ internal class TextBufferAssociatedViewService : ITextViewConnectionListener, IT private static readonly ConditionalWeakTable> s_map = new ConditionalWeakTable>(); + [ImportingConstructor] + public TextBufferAssociatedViewService() + { + } + public event EventHandler SubjectBuffersConnected; void ITextViewConnectionListener.SubjectBuffersConnected(ITextView textView, ConnectionReason reason, IReadOnlyCollection subjectBuffers) diff --git a/src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentOptions.cs b/src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentOptions.cs index f1d612ee2bb06..fa27184f59e00 100644 --- a/src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentOptions.cs +++ b/src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentOptions.cs @@ -15,6 +15,11 @@ internal static class TodoCommentOptions [ExportOptionProvider, Shared] internal class TodoCommentOptionsProvider : IOptionProvider { + [ImportingConstructor] + public TodoCommentOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( TodoCommentOptions.TokenList); } diff --git a/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingServiceFactory.cs b/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingServiceFactory.cs index 30ba82dcac9ef..d6c0d41244dc3 100644 --- a/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingServiceFactory.cs +++ b/src/EditorFeatures/Core/Implementation/Workspaces/EditorErrorReportingServiceFactory.cs @@ -12,6 +12,11 @@ internal class EditorErrorReportingServiceFactory : IWorkspaceServiceFactory { private readonly IErrorReportingService _singleton = new EditorErrorReportingService(); + [ImportingConstructor] + public EditorErrorReportingServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return _singleton; diff --git a/src/EditorFeatures/Core/Implementation/Workspaces/ProjectCacheServiceFactory.cs b/src/EditorFeatures/Core/Implementation/Workspaces/ProjectCacheServiceFactory.cs index e9ef3eefba101..78d19923dc9db 100644 --- a/src/EditorFeatures/Core/Implementation/Workspaces/ProjectCacheServiceFactory.cs +++ b/src/EditorFeatures/Core/Implementation/Workspaces/ProjectCacheServiceFactory.cs @@ -12,6 +12,11 @@ internal partial class ProjectCacheHostServiceFactory : IWorkspaceServiceFactory { private const int ImplicitCacheTimeoutInMS = 10000; + [ImportingConstructor] + public ProjectCacheHostServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { if (workspaceServices.Workspace.Kind != WorkspaceKind.Host) diff --git a/src/EditorFeatures/Core/ModernCommands/SortImportsCommandArgs.cs b/src/EditorFeatures/Core/ModernCommands/SortImportsCommandArgs.cs new file mode 100644 index 0000000000000..c57c23b0eec82 --- /dev/null +++ b/src/EditorFeatures/Core/ModernCommands/SortImportsCommandArgs.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.CodeAnalysis; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Text.Editor.Commanding; + +namespace Microsoft.CodeAnalysis.Editor.Commanding.Commands +{ + /// + /// Arguments for the Sort Imports command being invoked. + /// + [ExcludeFromCodeCoverage] + internal class SortImportsCommandArgs : EditorCommandArgs + { + public SortImportsCommandArgs(ITextView textView, ITextBuffer subjectBuffer) + : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/EditorFeatures/Core/Options/BraceCompletionOptions.cs b/src/EditorFeatures/Core/Options/BraceCompletionOptions.cs index aa20bdb670b74..520c0733ef173 100644 --- a/src/EditorFeatures/Core/Options/BraceCompletionOptions.cs +++ b/src/EditorFeatures/Core/Options/BraceCompletionOptions.cs @@ -16,6 +16,11 @@ internal static class BraceCompletionOptions [ExportOptionProvider, Shared] internal class BraceCompletionOptionsProvider : IOptionProvider { + [ImportingConstructor] + public BraceCompletionOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( BraceCompletionOptions.Enable); } diff --git a/src/EditorFeatures/Core/Options/CompletionOptions.cs b/src/EditorFeatures/Core/Options/CompletionOptions.cs index a968349c1b44c..4f53352c21c0b 100644 --- a/src/EditorFeatures/Core/Options/CompletionOptions.cs +++ b/src/EditorFeatures/Core/Options/CompletionOptions.cs @@ -23,6 +23,11 @@ internal static class EditorCompletionOptions [ExportOptionProvider, Shared] internal class EditorCompletionOptionsProvider : IOptionProvider { + [ImportingConstructor] + public EditorCompletionOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( EditorCompletionOptions.UseSuggestionMode, EditorCompletionOptions.UseSuggestionMode_Debugger); diff --git a/src/EditorFeatures/Core/Options/ExtensionManagerOptions.cs b/src/EditorFeatures/Core/Options/ExtensionManagerOptions.cs index 5beefa0a3a6ab..1e20d3f2b8d95 100644 --- a/src/EditorFeatures/Core/Options/ExtensionManagerOptions.cs +++ b/src/EditorFeatures/Core/Options/ExtensionManagerOptions.cs @@ -15,6 +15,11 @@ internal partial class ExtensionManagerOptions [ExportOptionProvider, Shared] internal class ExtensionManagerOptionsProvider : IOptionProvider { + [ImportingConstructor] + public ExtensionManagerOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( ExtensionManagerOptions.DisableCrashingExtensions); } diff --git a/src/EditorFeatures/Core/Options/NavigationBarOptions.cs b/src/EditorFeatures/Core/Options/NavigationBarOptions.cs index a1041f87f6002..5ec0beb982d13 100644 --- a/src/EditorFeatures/Core/Options/NavigationBarOptions.cs +++ b/src/EditorFeatures/Core/Options/NavigationBarOptions.cs @@ -15,6 +15,11 @@ internal static class NavigationBarOptions [ExportOptionProvider, Shared] internal class NavigationBarOptionsProvider : IOptionProvider { + [ImportingConstructor] + public NavigationBarOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( NavigationBarOptions.ShowNavigationBar); } diff --git a/src/EditorFeatures/Core/Options/SignatureHelpOptions.cs b/src/EditorFeatures/Core/Options/SignatureHelpOptions.cs index f4f0794f2d967..18794151b5164 100644 --- a/src/EditorFeatures/Core/Options/SignatureHelpOptions.cs +++ b/src/EditorFeatures/Core/Options/SignatureHelpOptions.cs @@ -15,6 +15,11 @@ internal static class SignatureHelpOptions [ExportOptionProvider, Shared] internal class SignatureHelpOptionsProvider : IOptionProvider { + [ImportingConstructor] + public SignatureHelpOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( SignatureHelpOptions.ShowSignatureHelp); } diff --git a/src/EditorFeatures/Core/Shared/DefaultTextBufferSupportsFeatureService.cs b/src/EditorFeatures/Core/Shared/DefaultTextBufferSupportsFeatureService.cs index 5ee14958b7755..b904878b582dd 100644 --- a/src/EditorFeatures/Core/Shared/DefaultTextBufferSupportsFeatureService.cs +++ b/src/EditorFeatures/Core/Shared/DefaultTextBufferSupportsFeatureService.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.Editor.Shared [ExportWorkspaceService(typeof(ITextBufferSupportsFeatureService), ServiceLayer.Editor), Shared] internal sealed class DefaultTextBufferSupportsFeatureService : ITextBufferSupportsFeatureService { + [ImportingConstructor] + public DefaultTextBufferSupportsFeatureService() + { + } + public bool SupportsCodeFixes(ITextBuffer textBuffer) { return true; diff --git a/src/EditorFeatures/Core/Shared/Extensions/SmartIndentExtensions.cs b/src/EditorFeatures/Core/Shared/Extensions/SmartIndentExtensions.cs index 4a94941bffae1..27969fbddbe67 100644 --- a/src/EditorFeatures/Core/Shared/Extensions/SmartIndentExtensions.cs +++ b/src/EditorFeatures/Core/Shared/Extensions/SmartIndentExtensions.cs @@ -6,9 +6,9 @@ namespace Microsoft.CodeAnalysis.Editor.Shared.Extensions { - internal static class SmartIndentExtensions + internal static class IndentationResultExtensions { - public static int GetIndentation(this IndentationResult result, ITextView textView, ITextSnapshotLine lineToBeIndented) + public static int GetIndentation(this Indentation.IndentationResult result, ITextView textView, ITextSnapshotLine lineToBeIndented) { var position = new SnapshotPoint(lineToBeIndented.Snapshot, result.BasePosition); var pointInSurfaceSnapshot = textView.BufferGraph.MapUpToSnapshot(position, PointTrackingMode.Positive, PositionAffinity.Successor, textView.TextSnapshot); diff --git a/src/EditorFeatures/Core/Shared/Options/ComponentOnOffOptions.cs b/src/EditorFeatures/Core/Shared/Options/ComponentOnOffOptions.cs index 93d85500ef965..aecc1babdf788 100644 --- a/src/EditorFeatures/Core/Shared/Options/ComponentOnOffOptions.cs +++ b/src/EditorFeatures/Core/Shared/Options/ComponentOnOffOptions.cs @@ -31,6 +31,11 @@ internal static class EditorComponentOnOffOptions [ExportOptionProvider, Shared] internal class EditorComponentOnOffOptionsProvider : IOptionProvider { + [ImportingConstructor] + public EditorComponentOnOffOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( EditorComponentOnOffOptions.Adornment, EditorComponentOnOffOptions.Tagger, diff --git a/src/EditorFeatures/Core/Shared/Options/FeatureOnOffOptions.cs b/src/EditorFeatures/Core/Shared/Options/FeatureOnOffOptions.cs index ebeef97d4e3ab..2d6cefe7aca88 100644 --- a/src/EditorFeatures/Core/Shared/Options/FeatureOnOffOptions.cs +++ b/src/EditorFeatures/Core/Shared/Options/FeatureOnOffOptions.cs @@ -44,10 +44,6 @@ internal static class FeatureOnOffOptions nameof(FeatureOnOffOptions), nameof(AutoFormattingOnTyping), defaultValue: true, storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.Auto Formatting On Typing")); - public static readonly PerLanguageOption AutoFormattingOnReturn = new PerLanguageOption( - nameof(FeatureOnOffOptions), nameof(AutoFormattingOnReturn), defaultValue: true, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.Auto Formatting On Return")); - public static readonly PerLanguageOption AutoFormattingOnCloseBrace = new PerLanguageOption( nameof(FeatureOnOffOptions), nameof(AutoFormattingOnCloseBrace), defaultValue: true, storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.Auto Formatting On Close Brace")); @@ -105,6 +101,11 @@ internal static class FeatureOnOffOptions [ExportOptionProvider, Shared] internal class FeatureOnOffOptionsProvider : IOptionProvider { + [ImportingConstructor] + public FeatureOnOffOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( FeatureOnOffOptions.EndConstruct, FeatureOnOffOptions.AutomaticInsertionOfAbstractOrInterfaceMembers, @@ -117,7 +118,6 @@ internal class FeatureOnOffOptionsProvider : IOptionProvider FeatureOnOffOptions.AutoInsertBlockCommentStartString, FeatureOnOffOptions.PrettyListing, FeatureOnOffOptions.AutoFormattingOnTyping, - FeatureOnOffOptions.AutoFormattingOnReturn, FeatureOnOffOptions.AutoFormattingOnCloseBrace, FeatureOnOffOptions.AutoFormattingOnSemicolon, FeatureOnOffOptions.RenameTrackingPreview, diff --git a/src/EditorFeatures/Core/Shared/Options/InternalFeatureOnOffOptions.cs b/src/EditorFeatures/Core/Shared/Options/InternalFeatureOnOffOptions.cs index 37d2ff7dc273b..26e2aaec8861f 100644 --- a/src/EditorFeatures/Core/Shared/Options/InternalFeatureOnOffOptions.cs +++ b/src/EditorFeatures/Core/Shared/Options/InternalFeatureOnOffOptions.cs @@ -74,6 +74,11 @@ internal static class InternalFeatureOnOffOptions [ExportOptionProvider, Shared] internal class InternalFeatureOnOffOptionsProvider : IOptionProvider { + [ImportingConstructor] + public InternalFeatureOnOffOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( InternalFeatureOnOffOptions.BraceMatching, InternalFeatureOnOffOptions.Classification, diff --git a/src/EditorFeatures/Core/Shared/Options/PerformanceFunctionIdOptionsProvider.cs b/src/EditorFeatures/Core/Shared/Options/PerformanceFunctionIdOptionsProvider.cs index 9ee350da2aa87..01efd2fe55d18 100644 --- a/src/EditorFeatures/Core/Shared/Options/PerformanceFunctionIdOptionsProvider.cs +++ b/src/EditorFeatures/Core/Shared/Options/PerformanceFunctionIdOptionsProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.Shared.Options [ExportOptionProvider, Shared] internal class PerformanceFunctionIdOptionsProvider : IOptionProvider { + [ImportingConstructor] + public PerformanceFunctionIdOptionsProvider() + { + } + public ImmutableArray Options { get diff --git a/src/EditorFeatures/Core/Shared/Preview/PreviewWorkspace.cs b/src/EditorFeatures/Core/Shared/Preview/PreviewWorkspace.cs index d6f4214ea7f2a..b8fa348212d77 100644 --- a/src/EditorFeatures/Core/Shared/Preview/PreviewWorkspace.cs +++ b/src/EditorFeatures/Core/Shared/Preview/PreviewWorkspace.cs @@ -68,6 +68,14 @@ public override void OpenAdditionalDocument(DocumentId documentId, bool activate this.OnAdditionalDocumentOpened(documentId, text.Container); } + public override void OpenAnalyzerConfigDocument(DocumentId documentId, bool activate = true) + { + var document = this.CurrentSolution.GetAnalyzerConfigDocument(documentId); + var text = document.GetTextSynchronously(CancellationToken.None); + + this.OnAnalyzerConfigDocumentOpened(documentId, text.Container); + } + public override void CloseDocument(DocumentId documentId) { var document = this.CurrentSolution.GetDocument(documentId); @@ -86,6 +94,15 @@ public override void CloseAdditionalDocument(DocumentId documentId) this.OnAdditionalDocumentClosed(documentId, TextLoader.From(TextAndVersion.Create(text, version))); } + public override void CloseAnalyzerConfigDocument(DocumentId documentId) + { + var document = this.CurrentSolution.GetAnalyzerConfigDocument(documentId); + var text = document.GetTextSynchronously(CancellationToken.None); + var version = document.GetTextVersionSynchronously(CancellationToken.None); + + this.OnAnalyzerConfigDocumentClosed(documentId, TextLoader.From(TextAndVersion.Create(text, version))); + } + protected override void Dispose(bool finalize) { base.Dispose(finalize); diff --git a/src/EditorFeatures/Core/Shared/Utilities/ClassificationTypeMap.cs b/src/EditorFeatures/Core/Shared/Utilities/ClassificationTypeMap.cs index 6c5d1a9063ef4..8098e9e3f8f59 100644 --- a/src/EditorFeatures/Core/Shared/Utilities/ClassificationTypeMap.cs +++ b/src/EditorFeatures/Core/Shared/Utilities/ClassificationTypeMap.cs @@ -19,7 +19,7 @@ internal class ClassificationTypeMap [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - internal ClassificationTypeMap( + public ClassificationTypeMap( IClassificationTypeRegistryService registryService) { _registryService = registryService; diff --git a/src/EditorFeatures/Core/Undo/DefaultSourceTextUndoService.cs b/src/EditorFeatures/Core/Undo/DefaultSourceTextUndoService.cs index 57cac1949e803..ed6a42486ec42 100644 --- a/src/EditorFeatures/Core/Undo/DefaultSourceTextUndoService.cs +++ b/src/EditorFeatures/Core/Undo/DefaultSourceTextUndoService.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Editor.Undo [ExportWorkspaceService(typeof(ISourceTextUndoService), ServiceLayer.Default), Shared] internal sealed class DefaultSourceTextUndoService : ISourceTextUndoService { + [ImportingConstructor] + public DefaultSourceTextUndoService() + { + } + public ISourceTextUndoTransaction RegisterUndoTransaction(SourceText sourceText, string description) { return null; diff --git a/src/EditorFeatures/Core/Undo/NoOpGlobalUndoServiceFactory.cs b/src/EditorFeatures/Core/Undo/NoOpGlobalUndoServiceFactory.cs index ba8d610e6ead4..7ea5668d06cc4 100644 --- a/src/EditorFeatures/Core/Undo/NoOpGlobalUndoServiceFactory.cs +++ b/src/EditorFeatures/Core/Undo/NoOpGlobalUndoServiceFactory.cs @@ -16,6 +16,11 @@ internal class NoOpGlobalUndoServiceFactory : IWorkspaceServiceFactory private readonly NoOpGlobalUndoService _singleton = new NoOpGlobalUndoService(); + [ImportingConstructor] + public NoOpGlobalUndoServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return _singleton; diff --git a/src/EditorFeatures/Core/Wrapping/AbstractWrapper.cs b/src/EditorFeatures/Core/Wrapping/AbstractWrapper.cs index d464f3b15688f..08332f8296501 100644 --- a/src/EditorFeatures/Core/Wrapping/AbstractWrapper.cs +++ b/src/EditorFeatures/Core/Wrapping/AbstractWrapper.cs @@ -7,6 +7,8 @@ namespace Microsoft.CodeAnalysis.Editor.Wrapping { + using Microsoft.CodeAnalysis.Indentation; + /// /// Common implementation of all . This type takes care of a lot of common logic for /// all of them, including: @@ -21,9 +23,9 @@ namespace Microsoft.CodeAnalysis.Editor.Wrapping /// internal abstract partial class AbstractSyntaxWrapper : ISyntaxWrapper { - protected IBlankLineIndentationService IndentationService { get; } + protected IIndentationService IndentationService { get; } - protected AbstractSyntaxWrapper(IBlankLineIndentationService indentationService) + protected AbstractSyntaxWrapper(IIndentationService indentationService) { this.IndentationService = indentationService; } diff --git a/src/EditorFeatures/Core/Wrapping/BinaryExpression/AbstractBinaryExpressionWrapper.cs b/src/EditorFeatures/Core/Wrapping/BinaryExpression/AbstractBinaryExpressionWrapper.cs index 8fb66c6d5a17e..079fb588cabab 100644 --- a/src/EditorFeatures/Core/Wrapping/BinaryExpression/AbstractBinaryExpressionWrapper.cs +++ b/src/EditorFeatures/Core/Wrapping/BinaryExpression/AbstractBinaryExpressionWrapper.cs @@ -6,10 +6,11 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.Editor.Wrapping.BinaryExpression { + using Microsoft.CodeAnalysis.Indentation; + internal abstract partial class AbstractBinaryExpressionWrapper : AbstractSyntaxWrapper where TBinaryExpressionSyntax : SyntaxNode { @@ -17,7 +18,7 @@ internal abstract partial class AbstractBinaryExpressionWrapper /// Base type for all wrappers that involve wrapping a comma-separated list of items. /// @@ -30,7 +32,7 @@ internal abstract partial class AbstractSeparatedSyntaxListWrapper< protected abstract string Wrap_every_item { get; } - protected AbstractSeparatedSyntaxListWrapper(IBlankLineIndentationService indentationService) + protected AbstractSeparatedSyntaxListWrapper(IIndentationService indentationService) : base(indentationService) { } diff --git a/src/EditorFeatures/Test/Diagnostics/DiagnosticDataSerializerTests.cs b/src/EditorFeatures/Test/Diagnostics/DiagnosticDataSerializerTests.cs index 066ddd87b5cec..88879235ea557 100644 --- a/src/EditorFeatures/Test/Diagnostics/DiagnosticDataSerializerTests.cs +++ b/src/EditorFeatures/Test/Diagnostics/DiagnosticDataSerializerTests.cs @@ -212,6 +212,11 @@ private static void AssertDiagnostics(DiagnosticData item1, DiagnosticData item2 [ExportWorkspaceServiceFactory(typeof(IPersistentStorageService), "DiagnosticDataSerializerTest"), Shared] public class PersistentStorageServiceFactory : IWorkspaceServiceFactory { + [ImportingConstructor] + public PersistentStorageServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return new Service(); diff --git a/src/EditorFeatures/Test/EditorConfig/LegacyEditorConfigDocumentOptionsProviderTests.cs b/src/EditorFeatures/Test/EditorConfig/LegacyEditorConfigDocumentOptionsProviderTests.cs index b04431771f7fd..0b2ba77406115 100644 --- a/src/EditorFeatures/Test/EditorConfig/LegacyEditorConfigDocumentOptionsProviderTests.cs +++ b/src/EditorFeatures/Test/EditorConfig/LegacyEditorConfigDocumentOptionsProviderTests.cs @@ -71,6 +71,11 @@ public void OrderingOfEditorConfigMaintained() [Shared] private class MockFileWatcher : IFileWatcher { + [ImportingConstructor] + public MockFileWatcher() + { + } + #pragma warning disable CS0067 // the event is unused public event ConventionsFileChangedAsyncEventHandler ConventionFileChanged; diff --git a/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs b/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs index f04ae8408ead9..edfe16eb11dff 100644 --- a/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs +++ b/src/EditorFeatures/Test/SolutionCrawler/WorkCoordinatorTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.SolutionCrawler { [UseExportProvider] - public class WorkCoordinatorTests + public class WorkCoordinatorTests : TestBase { private const string SolutionCrawler = nameof(SolutionCrawler); @@ -485,6 +485,35 @@ public async Task Document_AdditionalFileChange() } } + [Fact] + public async Task Document_AnalyzerConfigFileChange() + { + using (var workspace = new WorkCoordinatorWorkspace(SolutionCrawler)) + { + var solution = GetInitialSolutionInfo_2Projects_10Documents(workspace); + workspace.OnSolutionAdded(solution); + await WaitWaiterAsync(workspace.ExportProvider); + + var project = solution.Projects[0]; + var analyzerConfigDocFilePath = PathUtilities.CombineAbsoluteAndRelativePaths(Temp.CreateDirectory().Path, ".editorconfig"); + var analyzerConfigFile = DocumentInfo.Create(DocumentId.CreateNewId(project.Id), ".editorconfig", filePath: analyzerConfigDocFilePath); + + var worker = await ExecuteOperation(workspace, w => w.OnAnalyzerConfigDocumentAdded(analyzerConfigFile)); + Assert.Equal(5, worker.SyntaxDocumentIds.Count); + Assert.Equal(5, worker.DocumentIds.Count); + + worker = await ExecuteOperation(workspace, w => w.ChangeAnalyzerConfigDocument(analyzerConfigFile.Id, SourceText.From("//"))); + + Assert.Equal(5, worker.SyntaxDocumentIds.Count); + Assert.Equal(5, worker.DocumentIds.Count); + + worker = await ExecuteOperation(workspace, w => w.OnAnalyzerConfigDocumentRemoved(analyzerConfigFile.Id)); + + Assert.Equal(5, worker.SyntaxDocumentIds.Count); + Assert.Equal(5, worker.DocumentIds.Count); + } + } + [Fact, WorkItem(670335, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/670335")] public async Task Document_Cancellation() { diff --git a/src/EditorFeatures/Test2/Classification/ClassificationTests.vb b/src/EditorFeatures/Test2/Classification/ClassificationTests.vb index 3c8da3429772e..3f763337d8f1e 100644 --- a/src/EditorFeatures/Test2/Classification/ClassificationTests.vb +++ b/src/EditorFeatures/Test2/Classification/ClassificationTests.vb @@ -118,6 +118,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Classification Private Class NoCompilationEditorClassificationService Implements IClassificationService + + Public Sub New() + End Sub + Public Sub AddLexicalClassifications(text As SourceText, textSpan As TextSpan, result As List(Of ClassifiedSpan), cancellationToken As CancellationToken) Implements IClassificationService.AddLexicalClassifications End Sub diff --git a/src/EditorFeatures/Test2/CodeFixes/CodeFixServiceTests.vb b/src/EditorFeatures/Test2/CodeFixes/CodeFixServiceTests.vb index 50ad0b6fa6ea7..6eba60b45984a 100644 --- a/src/EditorFeatures/Test2/CodeFixes/CodeFixServiceTests.vb +++ b/src/EditorFeatures/Test2/CodeFixes/CodeFixServiceTests.vb @@ -187,6 +187,10 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.CodeFixes.UnitTests Private Class WorkspaceCodeFixProvider Inherits CodeFixProvider + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create("TEST0000") @@ -207,6 +211,10 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.CodeFixes.UnitTests Public Class ProjectCodeFixProvider Inherits CodeFixProvider + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create("TEST1111") diff --git a/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb b/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb index 3552a2e6165e7..cc0e9d1fcf06b 100644 --- a/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb @@ -249,7 +249,7 @@ class c { void M() { 3.$$ } } End Function - + Public Async Function TestTypingDotBeforeExistingDot(completionImplementation As CompletionImplementation) As Task ' Starting C# 8.0 two dots are considered as a DotDotToken of a Range expression. ' However, typing dot before a single dot (and adding the second one) should lead to a completion @@ -283,7 +283,7 @@ class c { void M() { this.$$ToString() } } End Function - + Public Async Function TestInvokingCompletionBetweenTwoDots(completionImplementation As CompletionImplementation) As Task ' Starting C# 8.0 two dots are considered as a DotDotToken of a Range expression. ' However, we may want to have a completion when invoking it aqfter the first dot. @@ -3832,10 +3832,86 @@ class C End Using End Function + + + Public Async Function TestSwitchBetweenBlockingAndNoBlockOnCompletion(completionImplementation As CompletionImplementation) As Task + Dim tcs = New TaskCompletionSource(Of Boolean) + Dim provider = New TaskControlledCompletionProvider(tcs.Task) + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + + using $$ + , {provider}) + +#Disable Warning BC42358 ' Because this call is not awaited, execution of the current method continues before the call is completed + Task.Run(Function() + Task.Delay(TimeSpan.FromSeconds(10)) + tcs.SetResult(True) + Return True + End Function) +#Enable Warning BC42358 ' Because this call is not awaited, execution of the current method continues before the call is completed + + state.SendTypeChars("Sys.") + Await state.WaitForAsynchronousOperationsAsync() + Await state.AssertCompletionSession() + Assert.Contains("System.", state.GetLineTextFromCaretPosition()) + + ' reset the input + For i As Integer = 1 To "System.".Length + state.SendBackspace() + Next + state.SendEscape() + + Await state.WaitForAsynchronousOperationsAsync() + + ' reset the task + tcs = New TaskCompletionSource(Of Boolean) + provider.UpdateTask(tcs.Task) + + ' Switch to the non-blocking mode + state.Workspace.Options = state.Workspace.Options.WithChangedOption( + CompletionOptions.BlockForCompletionItems, LanguageNames.CSharp, False) + + ' re-use of TestNoBlockOnCompletionItems1 + state.SendTypeChars("Sys.") + Await state.WaitForAsynchronousOperationsAsync() + Await state.AssertNoCompletionSession() + Assert.Contains("Sys.", state.GetLineTextFromCaretPosition()) + tcs.SetResult(True) + + For i As Integer = 1 To "Sys.".Length + state.SendBackspace() + Next + state.SendEscape() + + Await state.WaitForAsynchronousOperationsAsync() + + ' reset the task + tcs = New TaskCompletionSource(Of Boolean) + provider.UpdateTask(tcs.Task) + + ' Switch to the blocking mode + state.Workspace.Options = state.Workspace.Options.WithChangedOption( + CompletionOptions.BlockForCompletionItems, LanguageNames.CSharp, True) + +#Disable Warning BC42358 ' Because this call is not awaited, execution of the current method continues before the call is completed + Task.Run(Function() + Task.Delay(TimeSpan.FromSeconds(10)) + tcs.SetResult(True) + Return True + End Function) +#Enable Warning BC42358 ' Because this call is not awaited, execution of the current method continues before the call is completed + + state.SendTypeChars("Sys.") + Await state.WaitForAsynchronousOperationsAsync() + Await state.AssertCompletionSession() + Assert.Contains("System.", state.GetLineTextFromCaretPosition()) + End Using + End Function + Private Class TaskControlledCompletionProvider Inherits CompletionProvider - Private ReadOnly _task As Task + Private _task As Task Public Event ProviderCalled() @@ -3843,6 +3919,10 @@ class C _task = task End Sub + Public Sub UpdateTask(task As Task) + _task = task + End Sub + Public Overrides Function ProvideCompletionsAsync(context As CompletionContext) As Task RaiseEvent ProviderCalled() Return _task @@ -4952,6 +5032,231 @@ namespace NS2 End Using End Function + + + + Public Async Function TypingDotsAfterInt(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + ) + + state.SendTypeChars(".") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var range = array[first..];", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingDotsAfterClassAndAfterIntProperty(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + ) + + state.SendTypeChars(".") + Await state.AssertSelectedCompletionItem("A", isHardSelected:=True) + state.SendTypeChars(".") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var range = array[d.A..];", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingDotsAfterClassAndAfterIntMethod(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + 0; +} +]]>) + + state.SendTypeChars(".") + Await state.AssertSelectedCompletionItem("A", isHardSelected:=True) + state.SendTypeChars("().") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var range = array[d.A()..];", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingDotsAfterClassAndAfterDecimalProperty(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + ) + + state.SendTypeChars(".") + Await state.AssertSelectedCompletionItem("GetHashCode", isHardSelected:=True) + state.SendTypeChars("A.") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var range = array[d.A..];", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingDotsAfterClassAndAfterDoubleMethod(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + 0; +} +]]>) + + state.SendTypeChars(".") + Await state.AssertSelectedCompletionItem("GetHashCode", isHardSelected:=True) + state.SendTypeChars("A().") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var range = array[d.A()..];", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingDotsAfterIntWithinArrayDeclaration(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + ) + + state.SendTypeChars(".") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var array = new int[d..];", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingDotsAfterIntInVariableDeclaration(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + ) + + state.SendTypeChars(".") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars(".") + Assert.Contains("var e = d..;", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + + + + + Public Async Function TypingToStringAfterIntInVariableDeclaration(completionImplementation As CompletionImplementation) As Task + Using state = TestStateFactory.CreateCSharpTestState(completionImplementation, + ) + + state.SendTypeChars(".") + Await state.AssertCompletionSession() + Assert.True(state.IsSoftSelected()) + state.SendTypeChars("ToStr(") + Assert.Contains("var e = d.ToString(", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal) + End Using + End Function + Private Class MultipleChangeCompletionProvider Inherits CompletionProvider diff --git a/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb b/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb index fab2eb3c3bbab..32a8f9a7262ac 100644 --- a/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb @@ -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. +Imports System.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Completion Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions @@ -3147,6 +3148,10 @@ End Class Friend Class MockSnippetInfoService Implements ISnippetInfoService + + Public Sub New() + End Sub + Public Function GetSnippetsAsync_NonBlocking() As IEnumerable(Of SnippetInfo) Implements ISnippetInfoService.GetSnippetsIfAvailable Return SpecializedCollections.SingletonEnumerable(New SnippetInfo("Shortcut", "Title", "Description", "Path")) End Function diff --git a/src/EditorFeatures/TestUtilities/ChangeSignature/TestChangeSignatureOptionsService.cs b/src/EditorFeatures/TestUtilities/ChangeSignature/TestChangeSignatureOptionsService.cs index e7b80c23162b6..1f6fc31e3ce23 100644 --- a/src/EditorFeatures/TestUtilities/ChangeSignature/TestChangeSignatureOptionsService.cs +++ b/src/EditorFeatures/TestUtilities/ChangeSignature/TestChangeSignatureOptionsService.cs @@ -14,6 +14,11 @@ internal class TestChangeSignatureOptionsService : IChangeSignatureOptionsServic public bool IsCancelled = true; public int[] UpdatedSignature = null; + [ImportingConstructor] + public TestChangeSignatureOptionsService() + { + } + public ChangeSignatureOptionsResult GetChangeSignatureOptions(ISymbol symbol, ParameterConfiguration parameters, INotificationService notificationService) { var list = parameters.ToListOfParameters(); diff --git a/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs b/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs index a72b576cc2210..b9c766ff6d418 100644 --- a/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs +++ b/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Completion; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.AsyncCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.LanguageServices; diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs b/src/EditorFeatures/TestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs index 0271c458b5927..744feeba49239 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs @@ -44,7 +44,7 @@ protected async Task TestDiagnosticsAsync( var diagnostics = await GetDiagnosticsAsync(workspace, parameters).ConfigureAwait(false); // Special case for single diagnostic reported with annotated span. - if (expected.Length == 1) + if (expected.Length == 1 && !expected[0].HasLocation) { var hostDocumentsWithAnnotations = workspace.Documents.Where(d => d.SelectedSpans.Any()); if (hostDocumentsWithAnnotations.Count() == 1) diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestGenerateTypeOptionsService.cs b/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestGenerateTypeOptionsService.cs index 227e6ed8bf61f..b1e5a01ea7a4c 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestGenerateTypeOptionsService.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestGenerateTypeOptionsService.cs @@ -26,6 +26,11 @@ internal class TestGenerateTypeOptionsService : IGenerateTypeOptionsService public string DefaultNamespace = null; public bool IsCancelled = false; + [ImportingConstructor] + public TestGenerateTypeOptionsService() + { + } + // Actual input public string ClassName { get; private set; } public GenerateTypeDialogOptions GenerateTypeDialogOptions { get; private set; } diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestProjectManagementService.cs b/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestProjectManagementService.cs index 2a7fcb85782c2..fd2a6776e628b 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestProjectManagementService.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/GenerateType/TestProjectManagementService.cs @@ -12,6 +12,11 @@ internal class TestProjectManagementService : IProjectManagementService { private string _defaultNamespace; + [ImportingConstructor] + public TestProjectManagementService() + { + } + public IList GetFolders(ProjectId projectId, Workspace workspace) { return null; diff --git a/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs b/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs index 8adb0f6d0db07..f48c568a81b22 100644 --- a/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs +++ b/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.ExtractInterface [ExportWorkspaceService(typeof(IExtractInterfaceOptionsService), ServiceLayer.Default), Shared] internal class TestExtractInterfaceOptionsService : IExtractInterfaceOptionsService { + [ImportingConstructor] + public TestExtractInterfaceOptionsService() + { + } + public IEnumerable AllExtractableMembers { get; private set; } public string DefaultInterfaceName { get; private set; } public List ConflictingTypeNames { get; private set; } diff --git a/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs b/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs index 4f9eb2713e17f..ce2d8ee6e101a 100644 --- a/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs +++ b/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs @@ -21,6 +21,8 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Formatting { + using Microsoft.CodeAnalysis.Indentation; + public abstract class CoreFormatterTestsBase { internal abstract string GetLanguageName(); @@ -70,7 +72,7 @@ protected void TestBlankLineIndentationService( var indentationLineFromBuffer = snapshot.GetLineFromLineNumber(indentationLine); var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); - var blankLineIndenter = (IBlankLineIndentationService)document.GetLanguageService(); + var blankLineIndenter = document.GetLanguageService(); var indentStyle = workspace.Options.GetOption(FormattingOptions.SmartIndent, GetLanguageName()); var blankLineIndentResult = blankLineIndenter.GetBlankLineIndentation( document, indentationLine, indentStyle, CancellationToken.None); diff --git a/src/EditorFeatures/TestUtilities/InProcRemoteHostClientFactory.cs b/src/EditorFeatures/TestUtilities/InProcRemoteHostClientFactory.cs index 4f5330cff84e7..a3fe656f84566 100644 --- a/src/EditorFeatures/TestUtilities/InProcRemoteHostClientFactory.cs +++ b/src/EditorFeatures/TestUtilities/InProcRemoteHostClientFactory.cs @@ -22,6 +22,11 @@ internal static class RemoteHostOptions [ExportOptionProvider, Shared] internal class RemoteHostOptionsProvider : IOptionProvider { + [ImportingConstructor] + public RemoteHostOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( RemoteHostOptions.RemoteHostTest); } @@ -29,6 +34,11 @@ internal class RemoteHostOptionsProvider : IOptionProvider [ExportWorkspaceService(typeof(IRemoteHostClientFactory)), Shared] internal class InProcRemoteHostClientFactory : IRemoteHostClientFactory { + [ImportingConstructor] + public InProcRemoteHostClientFactory() + { + } + public Task CreateAsync(Workspace workspace, CancellationToken cancellationToken) { if (workspace.Options.GetOption(RemoteHostOptions.RemoteHostTest)) diff --git a/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs b/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs index e368de5731b2c..98d7eec8c8ce2 100644 --- a/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs +++ b/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs @@ -15,6 +15,11 @@ class TestMoveToNamespaceOptionsService : IMoveToNamespaceOptionsService private MoveToNamespaceOptionsResult _optionsResult = DefaultOptions; + [ImportingConstructor] + public TestMoveToNamespaceOptionsService() + { + } + public MoveToNamespaceOptionsResult GetChangeNamespaceOptions(string defaultNamespace, ImmutableArray availableNamespaces, ISyntaxFactsService syntaxFactsService) => _optionsResult; diff --git a/src/EditorFeatures/TestUtilities/Preview/MockPreviewPaneService.cs b/src/EditorFeatures/TestUtilities/Preview/MockPreviewPaneService.cs index 429f872c35c86..aa77324ba4654 100644 --- a/src/EditorFeatures/TestUtilities/Preview/MockPreviewPaneService.cs +++ b/src/EditorFeatures/TestUtilities/Preview/MockPreviewPaneService.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Preview [ExportWorkspaceService(typeof(IPreviewPaneService), ServiceLayer.Host), Shared] internal class MockPreviewPaneService : IPreviewPaneService { + [ImportingConstructor] + public MockPreviewPaneService() + { + } + public object GetPreviewPane(DiagnosticData diagnostic, string language, string projectType, IReadOnlyList previewContents) { var contents = previewContents ?? SpecializedCollections.EmptyEnumerable(); diff --git a/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs b/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs index 43f61a822c0b9..1b9874390e748 100644 --- a/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs +++ b/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs @@ -63,8 +63,7 @@ private InProcRemoteHostClient( _inprocServices = inprocServices; _remotableDataRpc = remotableDataRpc; - _rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target: this); - _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); + _rpc = stream.CreateStreamJsonRpc(target: this, inprocServices.Logger); // handle disconnected situation _rpc.Disconnected += OnRpcDisconnected; diff --git a/src/EditorFeatures/TestUtilities/RenameTracking/MockPreviewDialogService.cs b/src/EditorFeatures/TestUtilities/RenameTracking/MockPreviewDialogService.cs index 1ffe113d6d938..c334887a1a513 100644 --- a/src/EditorFeatures/TestUtilities/RenameTracking/MockPreviewDialogService.cs +++ b/src/EditorFeatures/TestUtilities/RenameTracking/MockPreviewDialogService.cs @@ -19,6 +19,11 @@ internal class MockPreviewDialogService : IPreviewDialogService, IWorkspaceServi public Glyph TopLevelGlyph; public bool ShowCheckBoxes; + [ImportingConstructor] + public MockPreviewDialogService() + { + } + public Solution PreviewChanges(string title, string helpString, string description, string topLevelName, Glyph topLevelGlyph, Solution newSolution, Solution oldSolution, bool showCheckBoxes = true) { Called = true; diff --git a/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs b/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs index 8c67ffc3acb3a..725aee77cd080 100644 --- a/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs +++ b/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests [PartNotDiscoverable] internal class StubVsEditorAdaptersFactoryService : IVsEditorAdaptersFactoryService { + [ImportingConstructor] + public StubVsEditorAdaptersFactoryService() + { + } + public IVsCodeWindow CreateVsCodeWindowAdapter(IServiceProvider serviceProvider) { throw new NotImplementedException(); diff --git a/src/EditorFeatures/TestUtilities/TestExperimentationService.cs b/src/EditorFeatures/TestUtilities/TestExperimentationService.cs index 456ec8a836ced..de5d49ed533f2 100644 --- a/src/EditorFeatures/TestUtilities/TestExperimentationService.cs +++ b/src/EditorFeatures/TestUtilities/TestExperimentationService.cs @@ -14,6 +14,11 @@ internal sealed class TestExperimentationService : IExperimentationService { private Dictionary _experimentsOptionValues = new Dictionary(); + [ImportingConstructor] + public TestExperimentationService() + { + } + public void SetExperimentOption(string experimentName, bool enabled) { _experimentsOptionValues[experimentName] = enabled; diff --git a/src/EditorFeatures/TestUtilities/TestExportProvider.cs b/src/EditorFeatures/TestUtilities/TestExportProvider.cs index 4f75e251dc25c..02714e2a04dbe 100644 --- a/src/EditorFeatures/TestUtilities/TestExportProvider.cs +++ b/src/EditorFeatures/TestUtilities/TestExportProvider.cs @@ -55,8 +55,8 @@ private static Type[] GetNeutralAndCSharpAndVisualBasicTypes() typeof(CodeAnalysis.VisualBasic.IntroduceVariable.VisualBasicIntroduceVariableService), // Ensures that BasicFeatures is included in the composition typeof(CSharp.ContentType.ContentTypeDefinitions), // CSharp Content Type typeof(VisualBasic.ContentType.ContentTypeDefinitions), // VB Content Type - typeof(VisualBasic.Formatting.Indentation.VisualBasicIndentationService), - typeof(CSharp.Formatting.Indentation.CSharpIndentationService), + typeof(CodeAnalysis.VisualBasic.Indentation.VisualBasicIndentationService), + typeof(CodeAnalysis.CSharp.Indentation.CSharpIndentationService), typeof(CodeAnalysis.CSharp.CSharpCompilationFactoryService), typeof(CodeAnalysis.VisualBasic.VisualBasicCompilationFactoryService), typeof(CodeAnalysis.CSharp.CSharpSyntaxTreeFactoryServiceFactory), // CSharpServicesCore diff --git a/src/EditorFeatures/TestUtilities/TestExtensionErrorHandler.cs b/src/EditorFeatures/TestUtilities/TestExtensionErrorHandler.cs index fe1f57a7c5257..030bf6795828a 100644 --- a/src/EditorFeatures/TestUtilities/TestExtensionErrorHandler.cs +++ b/src/EditorFeatures/TestUtilities/TestExtensionErrorHandler.cs @@ -15,6 +15,11 @@ internal class TestExtensionErrorHandler : IExtensionErrorHandler { private ImmutableList _exceptions = ImmutableList.Empty; + [ImportingConstructor] + public TestExtensionErrorHandler() + { + } + public void HandleError(object sender, Exception exception) { ExceptionUtilities.FailFast(exception); diff --git a/src/EditorFeatures/TestUtilities/TestObscuringTipManager.cs b/src/EditorFeatures/TestUtilities/TestObscuringTipManager.cs index cbea7161f31a4..2f53ee11d1c30 100644 --- a/src/EditorFeatures/TestUtilities/TestObscuringTipManager.cs +++ b/src/EditorFeatures/TestUtilities/TestObscuringTipManager.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests [Export(typeof(IObscuringTipManager))] internal class TestObscuringTipManager : IObscuringTipManager { + [ImportingConstructor] + public TestObscuringTipManager() + { + } + public void PushTip(ITextView view, IObscuringTip tip) { } diff --git a/src/EditorFeatures/TestUtilities/TestWaitIndicator.cs b/src/EditorFeatures/TestUtilities/TestWaitIndicator.cs index df3fc127a558f..65a2d424f779b 100644 --- a/src/EditorFeatures/TestUtilities/TestWaitIndicator.cs +++ b/src/EditorFeatures/TestUtilities/TestWaitIndicator.cs @@ -18,6 +18,7 @@ public sealed class TestWaitIndicator : IWaitIndicator, VisualStudioIndicator.IW private readonly IWaitContext _waitContext; private readonly Microsoft.VisualStudio.Language.Intellisense.Utilities.IWaitContext _platformWaitContext = new UncancellableWaitContext(); + [ImportingConstructor] public TestWaitIndicator() : this(new UncancellableWaitContext()) { diff --git a/src/EditorFeatures/TestUtilities/Workspaces/MefTestWorkspace.cs b/src/EditorFeatures/TestUtilities/Workspaces/MefTestWorkspace.cs index 6fceb4dde4c91..42ed9254c6d90 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/MefTestWorkspace.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/MefTestWorkspace.cs @@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces [Export(typeof(Workspace))] internal class MefTestWorkspace : Workspace { + [ImportingConstructor] public MefTestWorkspace() : base(Microsoft.CodeAnalysis.Host.Mef.MefHostServices.DefaultHost, "MefTest") { diff --git a/src/EditorFeatures/TestUtilities/Workspaces/NoCompilationLanguageServiceFactory.cs b/src/EditorFeatures/TestUtilities/Workspaces/NoCompilationLanguageServiceFactory.cs index 069fa2d448215..29397f0a82a34 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/NoCompilationLanguageServiceFactory.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/NoCompilationLanguageServiceFactory.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces [ExportLanguageServiceFactory(typeof(INoCompilationLanguageService), NoCompilationConstants.LanguageName), Shared] internal class NoCompilationLanguageServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public NoCompilationLanguageServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) { return new NoCompilationLanguageService(); diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestAddMetadataReferenceCodeActionOperationFactoryWorkspaceService.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestAddMetadataReferenceCodeActionOperationFactoryWorkspaceService.cs index 3207ffc9becd8..1875798aff7d2 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestAddMetadataReferenceCodeActionOperationFactoryWorkspaceService.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestAddMetadataReferenceCodeActionOperationFactoryWorkspaceService.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces [ExportWorkspaceService(typeof(IAddMetadataReferenceCodeActionOperationFactoryWorkspaceService), WorkspaceKind.Test), Shared] public class TestAddMetadataReferenceCodeActionOperationFactoryWorkspaceService : IAddMetadataReferenceCodeActionOperationFactoryWorkspaceService { + [ImportingConstructor] + public TestAddMetadataReferenceCodeActionOperationFactoryWorkspaceService() + { + } + public CodeActionOperation CreateAddMetadataReferenceOperation(ProjectId projectId, AssemblyIdentity assemblyIdentity) { return new Operation(projectId, assemblyIdentity); diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestFormattingRuleFactoryServiceFactory.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestFormattingRuleFactoryServiceFactory.cs index b6601e9667702..3ea62cc3e4d44 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestFormattingRuleFactoryServiceFactory.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestFormattingRuleFactoryServiceFactory.cs @@ -13,6 +13,7 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces [ExportWorkspaceServiceFactory(typeof(IHostDependentFormattingRuleFactoryService), WorkspaceKind.Test), Shared] internal sealed class TestFormattingRuleFactoryServiceFactory : IWorkspaceServiceFactory { + [ImportingConstructor] public TestFormattingRuleFactoryServiceFactory() { } diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestHostProject.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestHostProject.cs index cfe3d471f4c7f..d5ffc0fb359b2 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestHostProject.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestHostProject.cs @@ -33,6 +33,7 @@ public class TestHostProject public IEnumerable Documents; public IEnumerable AdditionalDocuments; + public IEnumerable AnalyzerConfigDocuments; public IEnumerable ProjectReferences; public string Name @@ -166,6 +167,7 @@ internal TestHostProject( IList references, IList documents, IList additionalDocuments = null, + IList analyzerConfigDocuments = null, Type hostObjectType = null, bool isSubmission = false, string filePath = null, @@ -182,6 +184,7 @@ internal TestHostProject( _analyzerReferences = analyzerReferences ?? SpecializedCollections.EmptyEnumerable(); this.Documents = documents; this.AdditionalDocuments = additionalDocuments ?? SpecializedCollections.EmptyEnumerable(); + this.AnalyzerConfigDocuments = analyzerConfigDocuments ?? SpecializedCollections.EmptyEnumerable(); ProjectReferences = SpecializedCollections.EmptyEnumerable(); _isSubmission = isSubmission; _hostObjectType = hostObjectType; @@ -203,7 +206,7 @@ public TestHostProject( IEnumerable analyzerReferences = null, string assemblyName = null, string defaultNamespace = null) - : this(workspace, name, language, compilationOptions, parseOptions, SpecializedCollections.SingletonEnumerable(document), SpecializedCollections.EmptyEnumerable(), projectReferences, metadataReferences, analyzerReferences, assemblyName, defaultNamespace) + : this(workspace, name, language, compilationOptions, parseOptions, SpecializedCollections.SingletonEnumerable(document), SpecializedCollections.EmptyEnumerable(), SpecializedCollections.EmptyEnumerable(), projectReferences, metadataReferences, analyzerReferences, assemblyName, defaultNamespace) { } @@ -215,6 +218,7 @@ public TestHostProject( ParseOptions parseOptions = null, IEnumerable documents = null, IEnumerable additionalDocuments = null, + IEnumerable analyzerConfigDocuments = null, IEnumerable projectReferences = null, IEnumerable metadataReferences = null, IEnumerable analyzerReferences = null, @@ -232,6 +236,7 @@ public TestHostProject( _parseOptions = parseOptions ?? this.LanguageServiceProvider.GetService().GetDefaultParseOptions(); this.Documents = documents ?? SpecializedCollections.EmptyEnumerable(); this.AdditionalDocuments = additionalDocuments ?? SpecializedCollections.EmptyEnumerable(); + this.AnalyzerConfigDocuments = analyzerConfigDocuments ?? SpecializedCollections.EmptyEnumerable(); ProjectReferences = projectReferences != null ? projectReferences.Select(p => new ProjectReference(p.Id)) : SpecializedCollections.EmptyEnumerable(); _metadataReferences = metadataReferences ?? new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib }; _analyzerReferences = analyzerReferences ?? SpecializedCollections.EmptyEnumerable(); @@ -255,6 +260,14 @@ public TestHostProject( doc.SetProject(this); } } + + if (analyzerConfigDocuments != null) + { + foreach (var doc in analyzerConfigDocuments) + { + doc.SetProject(this); + } + } } internal void SetSolution(TestHostSolution solution) @@ -271,6 +284,11 @@ internal void SetSolution(TestHostSolution solution) { doc.SetProject(this); } + + foreach (var doc in this.AnalyzerConfigDocuments) + { + doc.SetProject(this); + } } } @@ -296,6 +314,17 @@ internal void RemoveAdditionalDocument(TestHostDocument document) this.AdditionalDocuments = this.AdditionalDocuments.Where(d => d != document); } + internal void AddAnalyzerConfigDocument(TestHostDocument document) + { + this.AnalyzerConfigDocuments = this.AnalyzerConfigDocuments.Concat(new TestHostDocument[] { document }); + document.SetProject(this); + } + + internal void RemoveAnalyzerConfigDocument(TestHostDocument document) + { + this.AnalyzerConfigDocuments = this.AnalyzerConfigDocuments.Where(d => d != document); + } + public string Language { get @@ -322,6 +351,8 @@ public ProjectInfo ToProjectInfo() this.Language, this.FilePath, this.OutputFilePath, + outputRefFilePath: null, + defaultNamespace: null, this.CompilationOptions, this.ParseOptions, this.Documents.Select(d => d.ToDocumentInfo()), @@ -329,8 +360,10 @@ public ProjectInfo ToProjectInfo() this.MetadataReferences, this.AnalyzerReferences, this.AdditionalDocuments.Select(d => d.ToDocumentInfo()), + this.AnalyzerConfigDocuments.Select(d => d.ToDocumentInfo()), this.IsSubmission, - this.HostObjectType) + this.HostObjectType, + hasAllInformation: true) .WithDefaultNamespace(this.DefaultNamespace); } diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.cs index 7894b43966a92..b6bdcc446b55c 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces [ExportWorkspaceService(typeof(ISymbolRenamedCodeActionOperationFactoryWorkspaceService), WorkspaceKind.Test), Shared] public class TestSymbolRenamedCodeActionOperationFactoryWorkspaceService : ISymbolRenamedCodeActionOperationFactoryWorkspaceService { + [ImportingConstructor] + public TestSymbolRenamedCodeActionOperationFactoryWorkspaceService() + { + } + public CodeActionOperation CreateSymbolRenamedOperation(ISymbol symbol, string newName, Solution startingSolution, Solution updatedSolution) { return new Operation(symbol, newName, startingSolution, updatedSolution); diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs index 9633a99b00062..59cbece5c9d3e 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs @@ -33,6 +33,7 @@ public partial class TestWorkspace : Workspace public IList Projects { get; } public IList Documents { get; } public IList AdditionalDocuments { get; } + public IList AnalyzerConfigDocuments { get; } public IList ProjectionDocuments { get; } private readonly BackgroundCompiler _backgroundCompiler; @@ -52,6 +53,7 @@ public TestWorkspace(ExportProvider exportProvider, string workspaceKind = null, this.Projects = new List(); this.Documents = new List(); this.AdditionalDocuments = new List(); + this.AnalyzerConfigDocuments = new List(); this.ProjectionDocuments = new List(); this.CanApplyChangeDocument = true; @@ -108,6 +110,11 @@ protected override void Dispose(bool finalize) document.CloseTextView(); } + foreach (var document in AnalyzerConfigDocuments) + { + document.CloseTextView(); + } + foreach (var document in ProjectionDocuments) { document.CloseTextView(); @@ -157,6 +164,11 @@ public void AddTestProject(TestHostProject project) { this.AdditionalDocuments.Add(doc); } + + foreach (var doc in project.AnalyzerConfigDocuments) + { + this.AnalyzerConfigDocuments.Add(doc); + } } this.OnProjectAdded(project.ToProjectInfo()); @@ -204,7 +216,9 @@ public void OnDocumentRemoved(DocumentId documentId, bool closeDocument = false) public DocumentId GetDocumentId(TestHostDocument hostDocument) { - if (!Documents.Contains(hostDocument) && !AdditionalDocuments.Contains(hostDocument)) + if (!Documents.Contains(hostDocument) && + !AdditionalDocuments.Contains(hostDocument) && + !AnalyzerConfigDocuments.Contains(hostDocument)) { return null; } @@ -222,6 +236,11 @@ public TestHostDocument GetTestAdditionalDocument(DocumentId documentId) return this.AdditionalDocuments.FirstOrDefault(d => d.Id == documentId); } + public TestHostDocument GetTestAnalyzerConfigDocument(DocumentId documentId) + { + return this.AnalyzerConfigDocuments.FirstOrDefault(d => d.Id == documentId); + } + public TestHostProject GetTestProject(DocumentId documentId) { return GetTestProject(documentId.ProjectId); @@ -245,10 +264,13 @@ public override bool CanApplyChange(ApplyChangesKind feature) case ApplyChangesKind.RemoveDocument: case ApplyChangesKind.AddAdditionalDocument: case ApplyChangesKind.RemoveAdditionalDocument: + case ApplyChangesKind.AddAnalyzerConfigDocument: + case ApplyChangesKind.RemoveAnalyzerConfigDocument: return true; case ApplyChangesKind.ChangeDocument: case ApplyChangesKind.ChangeAdditionalDocument: + case ApplyChangesKind.ChangeAnalyzerConfigDocument: return this.CanApplyChangeDocument; case ApplyChangesKind.AddProjectReference: @@ -306,6 +328,28 @@ protected override void ApplyAdditionalDocumentRemoved(DocumentId documentId) this.OnAdditionalDocumentRemoved(documentId); } + protected override void ApplyAnalyzerConfigDocumentTextChanged(DocumentId document, SourceText newText) + { + var testDocument = this.GetTestAnalyzerConfigDocument(document); + testDocument.Update(newText); + } + + protected override void ApplyAnalyzerConfigDocumentAdded(DocumentInfo info, SourceText text) + { + var hostProject = this.GetTestProject(info.Id.ProjectId); + var hostDocument = new TestHostDocument(text.ToString(), info.Name, id: info.Id); + hostProject.AddAnalyzerConfigDocument(hostDocument); + this.OnAnalyzerConfigDocumentAdded(hostDocument.ToDocumentInfo()); + } + + protected override void ApplyAnalyzerConfigDocumentRemoved(DocumentId documentId) + { + var hostProject = this.GetTestProject(documentId.ProjectId); + var hostDocument = this.GetTestAnalyzerConfigDocument(documentId); + hostProject.RemoveAnalyzerConfigDocument(hostDocument); + this.OnAnalyzerConfigDocumentRemoved(documentId); + } + internal override void SetDocumentContext(DocumentId documentId) { OnDocumentContextUpdated(documentId); @@ -607,6 +651,14 @@ public void ChangeAdditionalDocument(DocumentId documentId, SourceText text) this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.AdditionalDocumentChanged, oldSolution, newSolution, documentId.ProjectId, documentId); } + public void ChangeAnalyzerConfigDocument(DocumentId documentId, SourceText text) + { + var oldSolution = this.CurrentSolution; + var newSolution = this.SetCurrentSolution(oldSolution.WithAnalyzerConfigDocumentText(documentId, text)); + + this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.AnalyzerConfigDocumentChanged, oldSolution, newSolution, documentId.ProjectId, documentId); + } + public void ChangeProject(ProjectId projectId, Solution solution) { var oldSolution = this.CurrentSolution; diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_Create.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_Create.cs index c2e0fe927f00e..82fe69aa38501 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_Create.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_Create.cs @@ -37,6 +37,8 @@ public partial class TestWorkspace private const string FeaturesAttributeName = "Features"; private const string DocumentationModeAttributeName = "DocumentationMode"; private const string DocumentElementName = "Document"; + private const string AdditionalDocumentElementName = "AdditionalDocument"; + private const string AnalyzerConfigDocumentElementName = "AnalyzerConfigDocument"; private const string AnalyzerElementName = "Analyzer"; private const string AssemblyNameAttributeName = "AssemblyName"; private const string CommonReferencesAttributeName = "CommonReferences"; diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_XmlConsumption.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_XmlConsumption.cs index 3ca6c40c37757..665dc1943b626 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_XmlConsumption.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace_XmlConsumption.cs @@ -6,6 +6,7 @@ using System.Collections.Immutable; using System.Collections.ObjectModel; using System.Globalization; +using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; @@ -89,7 +90,6 @@ internal static TestWorkspace Create( var workspace = new TestWorkspace(exportProvider, workspaceKind); var projectNameToTestHostProject = new Dictionary(); - var documentElementToFilePath = new Dictionary(); var projectElementToProjectName = new Dictionary(); var filePathToTextBufferMap = new Dictionary(); int projectIdentifier = 0; @@ -102,7 +102,6 @@ internal static TestWorkspace Create( projectElement, exportProvider, workspace, - documentElementToFilePath, filePathToTextBufferMap, documentServiceProvider, ref projectIdentifier, @@ -255,7 +254,6 @@ private static TestHostProject CreateProject( XElement projectElement, ExportProvider exportProvider, TestWorkspace workspace, - Dictionary documentElementToFilePath, Dictionary filePathToTextBufferMap, IDocumentServiceProvider documentServiceProvider, ref int projectId, @@ -311,10 +309,45 @@ private static TestHostProject CreateProject( ref documentId); documents.Add(document); - documentElementToFilePath.Add(documentElement, document.FilePath); } - return new TestHostProject(languageServices, compilationOptions, parseOptions, assemblyName, projectName, references, documents, filePath: filePath, analyzerReferences: analyzers, defaultNamespace: rootNamespace); + var additionalDocuments = new List(); + var additionalDocumentElements = projectElement.Elements(AdditionalDocumentElementName).ToList(); + foreach (var additionalDocumentElement in additionalDocumentElements) + { + var document = CreateDocument( + workspace, + workspaceElement, + additionalDocumentElement, + language, + exportProvider, + languageServices, + filePathToTextBufferMap, + documentServiceProvider, + ref documentId); + + additionalDocuments.Add(document); + } + + var analyzerConfigDocuments = new List(); + var analyzerConfigElements = projectElement.Elements(AnalyzerConfigDocumentElementName).ToList(); + foreach (var analyzerConfigElement in analyzerConfigElements) + { + var document = CreateDocument( + workspace, + workspaceElement, + analyzerConfigElement, + language, + exportProvider, + languageServices, + filePathToTextBufferMap, + documentServiceProvider, + ref documentId); + + analyzerConfigDocuments.Add(document); + } + + return new TestHostProject(languageServices, compilationOptions, parseOptions, assemblyName, projectName, references, documents, additionalDocuments, analyzerConfigDocuments, filePath: filePath, analyzerReferences: analyzers, defaultNamespace: rootNamespace); } private static ParseOptions GetParseOptions(XElement projectElement, string language, HostLanguageServices languageServices) diff --git a/src/EditorFeatures/TestUtilities2/Intellisense/IntelliSenseTestState.vb b/src/EditorFeatures/TestUtilities2/Intellisense/IntelliSenseTestState.vb index a18c38ea3805e..fb031b740ac7e 100644 --- a/src/EditorFeatures/TestUtilities2/Intellisense/IntelliSenseTestState.vb +++ b/src/EditorFeatures/TestUtilities2/Intellisense/IntelliSenseTestState.vb @@ -8,6 +8,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense Friend Class IntelliSenseTestState Implements IIntelliSenseTestState + + Public Sub New() + End Sub + Public Property CurrentCompletionPresenterSession As TestCompletionPresenterSession Implements IIntelliSenseTestState.CurrentCompletionPresenterSession Public Property CurrentSignatureHelpPresenterSession As TestSignatureHelpPresenterSession Implements IIntelliSenseTestState.CurrentSignatureHelpPresenterSession diff --git a/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockDocumentNavigationServiceFactory.vb b/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockDocumentNavigationServiceFactory.vb index 6fe50c3a97839..0fa386af0972e 100644 --- a/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockDocumentNavigationServiceFactory.vb +++ b/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockDocumentNavigationServiceFactory.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers Friend Class MockDocumentNavigationServiceFactory Implements IWorkspaceServiceFactory + + Public Sub New() + End Sub + Public Function CreateService(workspaceServices As HostWorkspaceServices) As IWorkspaceService Implements IWorkspaceServiceFactory.CreateService Return New MockDocumentNavigationService() End Function diff --git a/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockSymbolNavigationServiceFactory.vb b/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockSymbolNavigationServiceFactory.vb index f49f6f8a73e2d..7e9d7e2ede64d 100644 --- a/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockSymbolNavigationServiceFactory.vb +++ b/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockSymbolNavigationServiceFactory.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers Friend Class MockSymbolNavigationServiceFactory Implements IWorkspaceServiceFactory + + Public Sub New() + End Sub + Public Function CreateService(workspaceServices As HostWorkspaceServices) As IWorkspaceService Implements IWorkspaceServiceFactory.CreateService Return New MockSymbolNavigationService() End Function diff --git a/src/EditorFeatures/TestUtilities2/Utilities/MockDocumentNavigationServiceProvider.vb b/src/EditorFeatures/TestUtilities2/Utilities/MockDocumentNavigationServiceProvider.vb index 8db483fb19a68..6b6b80a993a4d 100644 --- a/src/EditorFeatures/TestUtilities2/Utilities/MockDocumentNavigationServiceProvider.vb +++ b/src/EditorFeatures/TestUtilities2/Utilities/MockDocumentNavigationServiceProvider.vb @@ -16,6 +16,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities Private _instance As MockDocumentNavigationService = New MockDocumentNavigationService() + + Public Sub New() + End Sub + Public Function CreateService(workspaceServices As HostWorkspaceServices) As IWorkspaceService Implements IWorkspaceServiceFactory.CreateService Return _instance End Function diff --git a/src/EditorFeatures/TestUtilities2/Utilities/MockSymbolNavigationServiceProvider.vb b/src/EditorFeatures/TestUtilities2/Utilities/MockSymbolNavigationServiceProvider.vb index 6cd5e83713428..3339daf7cdf3f 100644 --- a/src/EditorFeatures/TestUtilities2/Utilities/MockSymbolNavigationServiceProvider.vb +++ b/src/EditorFeatures/TestUtilities2/Utilities/MockSymbolNavigationServiceProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities Private _instance As MockSymbolNavigationService = New MockSymbolNavigationService() + + Public Sub New() + End Sub + Public Function CreateService(workspaceServices As HostWorkspaceServices) As IWorkspaceService Implements IWorkspaceServiceFactory.CreateService Return _instance End Function diff --git a/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb b/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb index fcc7b8a9a596a..8c4c818b3b71d 100644 --- a/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb @@ -23,7 +23,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.AutomaticCompletion Inherits AbstractAutomaticLineEnderCommandHandler - Friend Sub New(undoRegistry As ITextUndoHistoryRegistry, + Public Sub New(undoRegistry As ITextUndoHistoryRegistry, editorOperations As IEditorOperationsFactoryService) MyBase.New(undoRegistry, editorOperations) diff --git a/src/EditorFeatures/VisualBasic/BraceMatching/InterpolatedStringBraceMatcher.vb b/src/EditorFeatures/VisualBasic/BraceMatching/InterpolatedStringBraceMatcher.vb index 412ec1627f588..9cb6c8d845ae0 100644 --- a/src/EditorFeatures/VisualBasic/BraceMatching/InterpolatedStringBraceMatcher.vb +++ b/src/EditorFeatures/VisualBasic/BraceMatching/InterpolatedStringBraceMatcher.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis.Text @@ -11,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.BraceMatching Friend Class InterpolatedStringBraceMatcher Implements IBraceMatcher + + Public Sub New() + End Sub + Public Async Function FindBraces( document As Document, position As Integer, diff --git a/src/EditorFeatures/VisualBasic/BraceMatching/StringLiteralBraceMatcher.vb b/src/EditorFeatures/VisualBasic/BraceMatching/StringLiteralBraceMatcher.vb index 18095668037fd..01a0c6ced1509 100644 --- a/src/EditorFeatures/VisualBasic/BraceMatching/StringLiteralBraceMatcher.vb +++ b/src/EditorFeatures/VisualBasic/BraceMatching/StringLiteralBraceMatcher.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis.Text @@ -9,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.BraceMatching Friend Class StringLiteralBraceMatcher Implements IBraceMatcher + + Public Sub New() + End Sub + Public Async Function FindBraces(document As Document, position As Integer, Optional cancellationToken As CancellationToken = Nothing) As Task(Of BraceMatchingResult?) Implements IBraceMatcher.FindBracesAsync diff --git a/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicDirectiveTriviaBraceMatcher.vb b/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicDirectiveTriviaBraceMatcher.vb index 2f479df0e6b80..197749b29fcb0 100644 --- a/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicDirectiveTriviaBraceMatcher.vb +++ b/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicDirectiveTriviaBraceMatcher.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Syntax @@ -13,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.BraceMatching ElseDirectiveTriviaSyntax, EndIfDirectiveTriviaSyntax, RegionDirectiveTriviaSyntax, EndRegionDirectiveTriviaSyntax) + + Public Sub New() + End Sub + Friend Overrides Function GetMatchingConditionalDirectives(directive As DirectiveTriviaSyntax, cancellationToken As CancellationToken) As List(Of DirectiveTriviaSyntax) Return directive.GetMatchingConditionalDirectives(cancellationToken)?.ToList() End Function diff --git a/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicEmbeddedLanguageBraceMatcher.vb b/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicEmbeddedLanguageBraceMatcher.vb index 6275e3eacef57..447591e2fc312 100644 --- a/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicEmbeddedLanguageBraceMatcher.vb +++ b/src/EditorFeatures/VisualBasic/BraceMatching/VisualBasicEmbeddedLanguageBraceMatcher.vb @@ -1,10 +1,15 @@ ' 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.ComponentModel.Composition Imports Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.BraceMatching Friend Class VisualBasicEmbeddedLanguageBraceMatcher Inherits AbstractEmbeddedLanguageBraceMatcher + + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb b/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb index 583f65b4f0991..8e783554f6931 100644 --- a/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb @@ -11,5 +11,9 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.ChangeSignature Friend Class VisualBasicChangeSignatureCommandHandler Inherits AbstractChangeSignatureCommandHandler + + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb index ccc66c805fdd6..19f81d14a9e2b 100644 --- a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb +++ b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb @@ -12,6 +12,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages Public Shared Shadows Instance As New VisualBasicEmbeddedLanguageEditorFeaturesProvider() + Public Sub New() MyBase.New(VisualBasicEmbeddedLanguagesProvider.Info) End Sub diff --git a/src/EditorFeatures/VisualBasic/Formatting/Indentation/SmartTokenFormatterCommandHandler.vb b/src/EditorFeatures/VisualBasic/Formatting/Indentation/SmartTokenFormatterCommandHandler.vb index 06f4d3f4ac7da..e058298dd3195 100644 --- a/src/EditorFeatures/VisualBasic/Formatting/Indentation/SmartTokenFormatterCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/Formatting/Indentation/SmartTokenFormatterCommandHandler.vb @@ -5,8 +5,10 @@ Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Formatting.Indentation Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Formatting.Rules +Imports Microsoft.CodeAnalysis.Indentation Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Text +Imports Microsoft.CodeAnalysis.VisualBasic.Indentation Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.Text.Operations Imports Microsoft.VisualStudio.Utilities @@ -20,8 +22,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation Friend Class SmartTokenFormatterCommandHandler Inherits AbstractSmartTokenFormatterCommandHandler - Private ReadOnly _formattingRules As IEnumerable(Of AbstractFormattingRule) - Public Sub New(undoHistoryRegistry As ITextUndoHistoryRegistry, editorOperationsFactoryService As IEditorOperationsFactoryService) @@ -37,7 +37,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation End Function Protected Overrides Function CreateSmartTokenFormatter(optionSet As OptionSet, formattingRules As IEnumerable(Of AbstractFormattingRule), root As SyntaxNode) As ISmartTokenFormatter - Return New SmartTokenFormatter(optionSet, formattingRules, DirectCast(root, CompilationUnitSyntax)) + Return New VisualBasicSmartTokenFormatter(optionSet, formattingRules, DirectCast(root, CompilationUnitSyntax)) End Function Protected Overrides Function UseSmartTokenFormatter(root As SyntaxNode, diff --git a/src/EditorFeatures/VisualBasic/GoToBase/VisualBasicGoToBaseService.vb b/src/EditorFeatures/VisualBasic/GoToBase/VisualBasicGoToBaseService.vb index bcc95ef9b4eb6..14d00be2d0732 100644 --- a/src/EditorFeatures/VisualBasic/GoToBase/VisualBasicGoToBaseService.vb +++ b/src/EditorFeatures/VisualBasic/GoToBase/VisualBasicGoToBaseService.vb @@ -8,5 +8,9 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.GoToBase Friend Class VisualBasicGoToBaseService Inherits AbstractGoToBaseService + + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasic/GoToDefinition/VisualBasicGoToDefinitionSymbolService.vb b/src/EditorFeatures/VisualBasic/GoToDefinition/VisualBasicGoToDefinitionSymbolService.vb index 228b4a7d70945..15887a85319a7 100644 --- a/src/EditorFeatures/VisualBasic/GoToDefinition/VisualBasicGoToDefinitionSymbolService.vb +++ b/src/EditorFeatures/VisualBasic/GoToDefinition/VisualBasicGoToDefinitionSymbolService.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.GoToDefinition Friend Class VisualBasicGoToDefinitionSymbolService Inherits AbstractGoToDefinitionSymbolService + + Public Sub New() + End Sub + Protected Overrides Function FindRelatedExplicitlyDeclaredSymbol(symbol As ISymbol, compilation As Compilation) As ISymbol Return symbol.FindRelatedExplicitlyDeclaredSymbol(compilation) End Function diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/AccessorDeclarationHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/AccessorDeclarationHighlighter.vb index d0b9ba7df2c2f..1dd57b47330f5 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/AccessorDeclarationHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/AccessorDeclarationHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class AccessorDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)() If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is AccessorStatementSyntax Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.vb index 2e44cf8ff4edf..f680d33ca4a3a 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConditionalPreprocessorHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class ConditionalPreprocessorHighlighter Inherits AbstractKeywordHighlighter(Of DirectiveTriviaSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(directive As DirectiveTriviaSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim conditionals = directive.GetMatchingConditionalDirectives(cancellationToken) If conditionals Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConstructorDeclarationHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConstructorDeclarationHighlighter.vb index 7196ea11dab96..c7aee2392e925 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConstructorDeclarationHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ConstructorDeclarationHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class ConstructorDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)() If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is SubNewStatementSyntax Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/DoLoopBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/DoLoopBlockHighlighter.vb index 0f3f39d61eff3..1d31737f5b741 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/DoLoopBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/DoLoopBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class DoLoopBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) If node.IsIncorrectContinueStatement(SyntaxKind.ContinueDoStatement) Then Return SpecializedCollections.EmptyEnumerable(Of TextSpan)() diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EnumBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EnumBlockHighlighter.vb index 1837c7150d6f3..158459a521414 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EnumBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EnumBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class EnumBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim endBlockStatement = TryCast(node, EndBlockStatementSyntax) If endBlockStatement IsNot Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventBlockHighlighter.vb index 586f189d84471..26d8b4fbb9259 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class EventBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim eventBlock = node.GetAncestor(Of EventBlockSyntax)() If eventBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventDeclarationHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventDeclarationHighlighter.vb index 65aecdb7ac622..f88c81d74defa 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventDeclarationHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/EventDeclarationHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class EventDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of EventStatementSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetHighlights(eventDeclaration As EventStatementSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) ' If the ancestor is not a event block, treat this as a single line event. ' Otherwise, let the EventBlockHighlighter take over. diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ForLoopBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ForLoopBlockHighlighter.vb index 9d0d47496a689..b6d8af2923499 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ForLoopBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/ForLoopBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class ForLoopBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim forBlock = GetForBlockFromNode(node) If forBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MethodDeclarationHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MethodDeclarationHighlighter.vb index 9e96edf3ae875..90a30111f2ffd 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MethodDeclarationHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MethodDeclarationHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class MethodDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)() If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is MethodStatementSyntax Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineIfBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineIfBlockHighlighter.vb index 7429214411000..ac4d9bcdc8e00 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineIfBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineIfBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class MultiLineIfBlockHighlighter Inherits AbstractKeywordHighlighter(Of MultiLineIfBlockSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(ifBlock As MultiLineIfBlockSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineLambdaExpressionHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineLambdaExpressionHighlighter.vb index 4f6cef1592891..555efcb7cdae0 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineLambdaExpressionHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/MultiLineLambdaExpressionHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class MultiLineLambdaExpressionHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim lambdaExpression = node.GetAncestor(Of MultiLineLambdaExpressionSyntax)() If lambdaExpression Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/NamespaceBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/NamespaceBlockHighlighter.vb index 9d5bbffb57d30..e2af210c0724f 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/NamespaceBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/NamespaceBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class NamespaceBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim namespaceBlock = node.GetAncestor(Of NamespaceBlockSyntax)() If namespaceBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/OperatorDeclarationHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/OperatorDeclarationHighlighter.vb index 44716ca7df8e1..b9ef8693995e7 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/OperatorDeclarationHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/OperatorDeclarationHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class OperatorDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)() If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is OperatorStatementSyntax Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyBlockHighlighter.vb index d5af67da2d860..c36fabde6c392 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class PropertyBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim propertyBlock = node.GetAncestor(Of PropertyBlockSyntax)() If propertyBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyDeclarationHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyDeclarationHighlighter.vb index 0d2e779bd1900..e9bb339875e22 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyDeclarationHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/PropertyDeclarationHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class PropertyDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of PropertyStatementSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetHighlights(propertyDeclaration As PropertyStatementSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) ' If the ancestor is not a property block, treat this as an auto-property. ' Otherwise, let the PropertyBlockHighlighter take over. diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/RegionHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/RegionHighlighter.vb index 9eecb7df02e13..f4a347a4b9faa 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/RegionHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/RegionHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class RegionHighlighter Inherits AbstractKeywordHighlighter(Of DirectiveTriviaSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(directive As DirectiveTriviaSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) If TypeOf directive Is RegionDirectiveTriviaSyntax OrElse TypeOf directive Is EndRegionDirectiveTriviaSyntax Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SelectBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SelectBlockHighlighter.vb index c26856ac6b0fc..aa14680eb0860 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SelectBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SelectBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class SelectBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) If node.IsIncorrectExitStatement(SyntaxKind.ExitSelectStatement) Then Return SpecializedCollections.EmptyEnumerable(Of TextSpan)() diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SingleLineIfBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SingleLineIfBlockHighlighter.vb index 708645598f87f..b4ed8bc43e3af 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SingleLineIfBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SingleLineIfBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class SingleLineIfBlockHighlighter Inherits AbstractKeywordHighlighter(Of SingleLineIfStatementSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(ifStatement As SingleLineIfStatementSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SyncLockBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SyncLockBlockHighlighter.vb index fd483db43a6f6..5bc843f920bef 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SyncLockBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/SyncLockBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class SyncLockBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim syncLockBlock = node.GetAncestor(Of SyncLockBlockSyntax)() If syncLockBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TryBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TryBlockHighlighter.vb index 36545e885d0c5..c97fe7d5b819a 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TryBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TryBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class TryBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) If TypeOf node Is ExitStatementSyntax AndAlso node.Kind <> SyntaxKind.ExitTryStatement Then Return SpecializedCollections.EmptyEnumerable(Of TextSpan)() diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TypeBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TypeBlockHighlighter.vb index 7b3905aee81cf..4be0923cd2c73 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TypeBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/TypeBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class TypeBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim endBlockStatement = TryCast(node, EndBlockStatementSyntax) If endBlockStatement IsNot Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/UsingBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/UsingBlockHighlighter.vb index 481b7d0b15b14..a941849f1ed76 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/UsingBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/UsingBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class UsingBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim usingBlock = node.GetAncestor(Of UsingBlockSyntax)() If usingBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WhileBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WhileBlockHighlighter.vb index 4789419861997..c2de386c8c80b 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WhileBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WhileBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class WhileBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) If node.IsIncorrectContinueStatement(SyntaxKind.ContinueWhileStatement) Then Return SpecializedCollections.EmptyEnumerable(Of TextSpan)() diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WithBlockHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WithBlockHighlighter.vb index 52e6206daf650..e71f809322ce4 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WithBlockHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/WithBlockHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class WithBlockHighlighter Inherits AbstractKeywordHighlighter(Of SyntaxNode) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim withBlock = node.GetAncestor(Of WithBlockSyntax)() If withBlock Is Nothing Then diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCDataHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCDataHighlighter.vb index 841e857550fd4..b985ffeef10b1 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCDataHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCDataHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class XmlCDataHighlighter Inherits AbstractKeywordHighlighter(Of XmlCDataSectionSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(xmlComment As XmlCDataSectionSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCommentHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCommentHighlighter.vb index ebe5c8c84e77c..91cee8d9629f6 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCommentHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlCommentHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class XmlCommentHighlighter Inherits AbstractKeywordHighlighter(Of XmlCommentSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(xmlComment As XmlCommentSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlDocumentPrologueHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlDocumentPrologueHighlighter.vb index 967eb9f9f721d..ed6bdc0fb7361 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlDocumentPrologueHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlDocumentPrologueHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class XmlProcessingInstructionHighlighter Inherits AbstractKeywordHighlighter(Of XmlProcessingInstructionSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(xmlProcessingInstruction As XmlProcessingInstructionSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlElementHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlElementHighlighter.vb index ed1a014cf6aab..081a73a8970bd 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlElementHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlElementHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class XmlElementHighlighter Inherits AbstractKeywordHighlighter(Of XmlNodeSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(node As XmlNodeSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlEmbeddedExpressionHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlEmbeddedExpressionHighlighter.vb index 4718d91612e5f..4f9552125959c 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlEmbeddedExpressionHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlEmbeddedExpressionHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class XmlEmbeddedExpressionHighlighter Inherits AbstractKeywordHighlighter(Of XmlEmbeddedExpressionSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(xmlEmbeddExpression As XmlEmbeddedExpressionSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlProcessingInstructionHighlighter.vb b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlProcessingInstructionHighlighter.vb index c9e518a84b771..d4485e9a1698f 100644 --- a/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlProcessingInstructionHighlighter.vb +++ b/src/EditorFeatures/VisualBasic/Highlighting/KeywordHighlighters/XmlProcessingInstructionHighlighter.vb @@ -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. +Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.Implementation.Highlighting Imports Microsoft.CodeAnalysis.Text @@ -10,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting Friend Class XmlDeclarationHighlighter Inherits AbstractKeywordHighlighter(Of XmlDeclarationSyntax) + + Public Sub New() + End Sub + Protected Overloads Overrides Function GetHighlights(xmlDocumentPrologue As XmlDeclarationSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan) Dim highlights As New List(Of TextSpan) diff --git a/src/EditorFeatures/VisualBasic/LineCommit/CommitCommandHandler.vb b/src/EditorFeatures/VisualBasic/LineCommit/CommitCommandHandler.vb index b3170401eab32..3ec9f9ba962b9 100644 --- a/src/EditorFeatures/VisualBasic/LineCommit/CommitCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/LineCommit/CommitCommandHandler.vb @@ -48,7 +48,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LineCommit End Property - Friend Sub New( + Public Sub New( bufferManagerFactory As CommitBufferManagerFactory, editorOperationsFactoryService As IEditorOperationsFactoryService, smartIndentationService As ISmartIndentationService, diff --git a/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb b/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb index dd820792482d5..e4909631cb839 100644 --- a/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb +++ b/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb @@ -24,6 +24,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LineCommit p.Name <> PredefinedCodeCleanupProviderNames.Format End Function + + Public Sub New() + End Sub + Public Sub CommitRegion(spanToFormat As SnapshotSpan, isExplicitFormat As Boolean, useSemantics As Boolean, diff --git a/src/EditorFeatures/VisualBasic/LineSeparators/VisualBasicLineSeparatorService.vb b/src/EditorFeatures/VisualBasic/LineSeparators/VisualBasicLineSeparatorService.vb index ea7384cd77068..f06797076e2f4 100644 --- a/src/EditorFeatures/VisualBasic/LineSeparators/VisualBasicLineSeparatorService.vb +++ b/src/EditorFeatures/VisualBasic/LineSeparators/VisualBasicLineSeparatorService.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LineSeparators Friend Class VisualBasicLineSeparatorService Implements ILineSeparatorService + + Public Sub New() + End Sub + ''' Node types that are interesting for line separation. Private Function IsSeparableBlock(nodeOrToken As SyntaxNodeOrToken) As Boolean If nodeOrToken.IsToken Then diff --git a/src/EditorFeatures/VisualBasic/RenameTracking/BasicRenameTrackingLanguageHeuristicsService.vb b/src/EditorFeatures/VisualBasic/RenameTracking/BasicRenameTrackingLanguageHeuristicsService.vb index 192f43dbd7bab..e3a821927eb66 100644 --- a/src/EditorFeatures/VisualBasic/RenameTracking/BasicRenameTrackingLanguageHeuristicsService.vb +++ b/src/EditorFeatures/VisualBasic/RenameTracking/BasicRenameTrackingLanguageHeuristicsService.vb @@ -9,6 +9,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.RenameTracking Friend NotInheritable Class BasicRenameTrackingLanguageHeuristicsService Implements IRenameTrackingLanguageHeuristicsService + + Public Sub New() + End Sub + Public Function IsIdentifierValidForRenameTracking(name As String) As Boolean Implements IRenameTrackingLanguageHeuristicsService.IsIdentifierValidForRenameTracking Return True End Function diff --git a/src/EditorFeatures/VisualBasic/TextStructureNavigation/TextStructureNavigatorProvider.vb b/src/EditorFeatures/VisualBasic/TextStructureNavigation/TextStructureNavigatorProvider.vb index e0d90eaf0a082..b6ff3f700e3a0 100644 --- a/src/EditorFeatures/VisualBasic/TextStructureNavigation/TextStructureNavigatorProvider.vb +++ b/src/EditorFeatures/VisualBasic/TextStructureNavigation/TextStructureNavigatorProvider.vb @@ -15,7 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.TextStructureNavigation Inherits AbstractTextStructureNavigatorProvider - Friend Sub New( + Public Sub New( selectorService As ITextStructureNavigatorSelectorService, contentTypeService As IContentTypeRegistryService, waitIndicator As IWaitIndicator) diff --git a/src/EditorFeatures/VisualBasic/Wrapping/BinaryExpression/VisualBasicBinaryExpressionWrapper.vb b/src/EditorFeatures/VisualBasic/Wrapping/BinaryExpression/VisualBasicBinaryExpressionWrapper.vb index 8e46ef06f72dc..139c7b523ecc2 100644 --- a/src/EditorFeatures/VisualBasic/Wrapping/BinaryExpression/VisualBasicBinaryExpressionWrapper.vb +++ b/src/EditorFeatures/VisualBasic/Wrapping/BinaryExpression/VisualBasicBinaryExpressionWrapper.vb @@ -1,7 +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. -Imports Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation Imports Microsoft.CodeAnalysis.Editor.Wrapping.BinaryExpression +Imports Microsoft.CodeAnalysis.VisualBasic.Indentation Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Wrapping.BinaryExpression diff --git a/src/EditorFeatures/VisualBasic/Wrapping/SeparatedSyntaxList/AbstractVisualBasicSeparatedSyntaxListWrapper.vb b/src/EditorFeatures/VisualBasic/Wrapping/SeparatedSyntaxList/AbstractVisualBasicSeparatedSyntaxListWrapper.vb index a74cb0c02101c..2e74317421e5b 100644 --- a/src/EditorFeatures/VisualBasic/Wrapping/SeparatedSyntaxList/AbstractVisualBasicSeparatedSyntaxListWrapper.vb +++ b/src/EditorFeatures/VisualBasic/Wrapping/SeparatedSyntaxList/AbstractVisualBasicSeparatedSyntaxListWrapper.vb @@ -1,7 +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. -Imports Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation Imports Microsoft.CodeAnalysis.Editor.Wrapping.SeparatedSyntaxList +Imports Microsoft.CodeAnalysis.VisualBasic.Indentation Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Wrapping.SeparatedSyntaxList Partial Friend MustInherit Class AbstractVisualBasicSeparatedSyntaxListWrapper( diff --git a/src/EditorFeatures/VisualBasic/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb b/src/EditorFeatures/VisualBasic/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb index 6fba60ad7026d..6df637572200a 100644 --- a/src/EditorFeatures/VisualBasic/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb +++ b/src/EditorFeatures/VisualBasic/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb @@ -18,6 +18,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Wrapping New VisualBasicParameterWrapper(), New VisualBasicBinaryExpressionWrapper()) + Public Sub New() MyBase.New(s_wrappers) End Sub diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb index b840c6f7c8f4a..0cd4b711e8450 100644 --- a/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb @@ -92,7 +92,7 @@ End Class currentProject = newSln.Projects.Single() Dim additionalDocument = currentProject.GetAdditionalDocument(additionalDocId) - Dim additionalStream As AdditionalText = New AdditionalTextDocument(additionalDocument.State) + Dim additionalStream As AdditionalText = New AdditionalTextWithState(additionalDocument.State) Dim options = New AnalyzerOptions(ImmutableArray.Create(additionalStream)) Dim analyzer = New OptionsDiagnosticAnalyzer(Of SyntaxKind)(expectedOptions:=options) diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/GenerateVariable/GenerateVariableTests.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/GenerateVariable/GenerateVariableTests.vb index e47dfe34d5fc9..268b772380d88 100644 --- a/src/EditorFeatures/VisualBasicTest/Diagnostics/GenerateVariable/GenerateVariableTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/GenerateVariable/GenerateVariableTests.vb @@ -2623,7 +2623,7 @@ End Class") Public Async Function TestPreferReadOnlyIfAfterReadOnlyAssignment() As Task - await TestInRegularAndScriptAsync( + Await TestInRegularAndScriptAsync( "class C private readonly _goo as integer @@ -2667,7 +2667,7 @@ end class") Public Async Function TestPlaceFieldBasedOnSurroundingStatements() As Task - await TestInRegularAndScriptAsync( + Await TestInRegularAndScriptAsync( "class Class private _goo as integer private _quux as integer @@ -2831,5 +2831,150 @@ End Module", End Module", index:=2) End Function + + + Public Async Function TestAddParameter() As Task + Await TestInRegularAndScriptAsync( +"Module Program + Sub Main(args As String()) + Goo([|bar|]) + End Sub +End Module", +"Module Program + Sub Main(args As String(), bar As Object) + Goo(bar) + End Sub +End Module", +index:=4) + End Function + + + Public Async Function TestAddParameterDoesntAddToOverride() As Task + Await TestInRegularAndScriptAsync( +"Class Base + Public Overridable Sub Method(args As String()) + End Sub +End Class +Class Program + Public Overrides Sub Main(args As String()) + Goo([|bar|]) + End Sub +End Class", +"Class Base + Public Overridable Sub Method(args As String()) + End Sub +End Class +Class Program + Public Overrides Sub Main(args As String(), bar As Object) + Goo(bar) + End Sub +End Class", +index:=4) + End Function + + + Public Async Function TestAddParameterAndOverridesAddsToOverrides() As Task + Await TestInRegularAndScriptAsync( +"Class Base + Public Overridable Sub Method(args As String()) + End Sub +End Class +Class Program + Inherits Base + Public Overrides Sub Method(args As String()) + Goo([|bar|]) + End Sub +End Class", +"Class Base + Public Overridable Sub Method(args As String(), bar As Object) + End Sub +End Class +Class Program + Inherits Base + Public Overrides Sub Method(args As String(), bar As Object) + Goo(bar) + End Sub +End Class", +index:=5) + End Function + + + Public Async Function TestAddParameterIsOfCorrectType() As Task + Await TestInRegularAndScriptAsync( +"Module Program + Sub Main(args As String()) + Goo([|bar|]) + End Sub + Sub Goo(arg As Integer) + End Sub +End Module", +"Module Program + Sub Main(args As String(), bar As Integer) + Goo(bar) + End Sub + Sub Goo(arg As Integer) + End Sub +End Module", +index:=4) + End Function + + + Public Async Function TestAddParameterAndOverridesIsOfCorrectType() As Task + Await TestInRegularAndScriptAsync( +"Class Base + Public Overridable Sub Method(args As String()) + End Sub +End Class +Class Program + Inherits Base + Public Overrides Sub Method(args As String()) + Goo([|bar|]) + End Sub + Sub Goo(arg As Integer) + End Sub +End Class", +"Class Base + Public Overridable Sub Method(args As String(), bar As Integer) + End Sub +End Class +Class Program + Inherits Base + Public Overrides Sub Method(args As String(), bar As Integer) + Goo(bar) + End Sub + Sub Goo(arg As Integer) + End Sub +End Class", +index:=5) + End Function + + + Public Async Function TestAddParameterAndOverridesNotOfferedToNonOverride1() As Task + Await TestActionCountAsync( +"Module Program + Sub Main(args As String()) + Goo([|bar|]) + End Sub +End Module", +count:=5) + End Function + + + Public Async Function TestAddParameterAndOverridesNotOfferedToNonOverride2() As Task + Await TestActionCountAsync( +"Class Base + Public Overridable Sub Method(args As String()) + End Sub +End Class +Class Program + Inherits Base + Public Sub Method(args As String()) + Goo([|bar|]) + End Sub + Sub Goo(arg As Integer) + End Sub +End Class", +count:=5) + End Function End Class End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.vb b/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.vb new file mode 100644 index 0000000000000..958b1cb3883fe --- /dev/null +++ b/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposableFieldsShouldBeDisposedTests.vb @@ -0,0 +1,1255 @@ +' 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 Microsoft.CodeAnalysis.CodeFixes +Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics +Imports Microsoft.CodeAnalysis.DisposeAnalysis + +Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.DisposeAnalysis + Public Class DisposableFieldsShouldBeDisposedTests + Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest + Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As (DiagnosticAnalyzer, CodeFixProvider) + Return (New DisposableFieldsShouldBeDisposedDiagnosticAnalyzer(), Nothing) + End Function + + ' Ensure that we explicitly test missing diagnostic, which has no corresponding code fix (non-fixable diagnostic). + Private Overloads Function TestDiagnosticMissingAsync(initialMarkup As String) As Task + Return TestDiagnosticMissingAsync(initialMarkup, New TestParameters(retainNonFixableDiagnostics:=True)) + End Function + + Private Overloads Function TestDiagnosticsAsync(initialMarkup As String, ParamArray expected As DiagnosticDescription()) As Task + Return TestDiagnosticsAsync(initialMarkup, New TestParameters(retainNonFixableDiagnostics:=True), expected) + End Function + + Private Shared Function Diagnostic(id As String, Optional sqiggledText As String = Nothing) As DiagnosticDescription + Return TestHelpers.Diagnostic(id, sqiggledText) + End Function + + + Public Async Function DisposableAllocationInConstructor_AssignedDirectly_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private ReadOnly a As A|] + Sub New() + a = New A() + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocationInConstructor_AssignedDirectly_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private ReadOnly [|a|] As A + Sub New() + a = New A() + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocationInMethod_AssignedDirectly_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub SomeMethod() + a = New A() + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocationInMethod_AssignedDirectly_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A + Sub SomeMethod() + a = New A() + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocationInFieldInitializer_AssignedDirectly_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A() + Private ReadOnly a2 As New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + a2.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocationInFieldInitializer_AssignedDirectly_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A() + Private ReadOnly a2 As New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "a").WithLocation(12, 13), + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "a2").WithLocation(13, 22)) + End Function + + + Public Async Function StaticField_NotDisposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private Shared a As A = New A() + Private Shared ReadOnly a2 As New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedThroughLocal_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub SomeMethod() + Dim l = New A() + a = l + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedThroughLocal_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A + Sub SomeMethod() + Dim l = New A() + a = l + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocation_AssignedThroughParameter_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub New(p As A) + p = New A() + a = p + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedThroughParameter_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A + Sub New(p As A) + p = New A() + a = p + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableSymbolWithoutAllocation_AssignedThroughParameter_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub New(p As A) + a = p + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableSymbolWithoutAllocation_AssignedThroughParameter_NotDisposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub New(p As A) + a = p + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedThroughInstanceInvocation_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub New() + a = GetA() + End Sub + + Private Function GetA() As A + Return New A() + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedThroughInstanceInvocation_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A + Sub New() + a = GetA() + End Sub + + Private Function GetA() As A + Return New A() + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocation_AssignedThroughStaticCreateInvocation_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A|] + Sub New() + a = Create() + End Sub + + Private Shared Function Create() As A + Return New A() + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedThroughStaticCreateInvocation_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A + Sub New() + a = Create() + End Sub + + Private Shared Function Create() As A + Return New A() + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocation_AssignedInDifferentType_DisposedInContainingType_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Public a As A|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class + +Class WrapperB + Dim b As B + Public Sub Create() + b.a = new A() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedInDifferentType_DisposedInDifferentNonDisposableType_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Public a As A|] + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class WrapperB + Dim b As B + + Public Sub Create() + b.a = new A() + End Sub + + Public Sub Dispose() + b.a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedInDifferentType_NotDisposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Public a As A|] + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public Sub M(b As B) + b.a = new A() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedWithConditionalAccess_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a?.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedToLocal_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + Dim l = a + l.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AssignedToLocal_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A = New A() + + Public Sub Dispose() Implements IDisposable.Dispose + Dim l = a + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocation_IfElseStatement_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A + Private b As A|] + + Public Sub New(ByVal flag As Boolean) + Dim l As A = New A() + If flag Then + a = l + Else + b = l + End If + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + Dim l As A = Nothing + If a IsNot Nothing Then + l = a + ElseIf b IsNot Nothing Then + l = b + End If + l.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_IfElseStatement_NotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A + Private b As A|] + + Public Sub New(ByVal flag As Boolean) + Dim l As A = New A() + If flag Then + a = l + Else + b = l + End If + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + Dim l As A = Nothing + If a IsNot Nothing Then + l = a + ElseIf b IsNot Nothing Then + l = b + End If + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "a").WithLocation(12, 13), + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, "b").WithLocation(13, 13)) + End Function + + + Public Async Function DisposableAllocation_EscapedField_NotDisposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeA(a) + End Sub + + Private Shared Sub DisposeA(ByRef a As A) + a.Dispose() + a = Nothing + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_OptimisticPointsToAnalysis_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub PerformSomeCleanup() + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.PerformSomeCleanup() + ClearMyState() + a.Dispose() + End Sub + + Private Sub ClearMyState() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_OptimisticPointsToAnalysis_WithReturn_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub PerformSomeCleanup() + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + Public Disposed As Boolean + + Public Sub Dispose() Implements IDisposable.Dispose + If Disposed Then + Return + End If + + a.PerformSomeCleanup() + ClearMyState() + a.Dispose() + End Sub + + Private Sub ClearMyState() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_IfStatementInDispose_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Public Class Test + Implements IDisposable + [|Private ReadOnly a As A = New A()|] + Private cancelled As Boolean + + Public Sub Dispose() Implements IDisposable.Dispose + If cancelled Then + a.GetType() + End If + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedinDisposeOverride_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +MustInherit Class Base + Implements IDisposable + Public Overridable Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Derived + Inherits Base + + [|Private ReadOnly a As A = New A()|] + + Public Overrides Sub Dispose() + MyBase.Dispose() + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedWithDisposeBoolInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub Dispose(disposed As Boolean) + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose(True) + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedInsideDisposeBool_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub Dispose(disposed As Boolean) + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + Dispose(True) + End Sub + + Public Sub Dispose(disposed As Boolean) + a.Dispose(disposed) + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedWithDisposeCloseInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub Close() + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.Close() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_AllDisposedMethodsMixed_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub Dispose(disposed As Boolean) + End Sub + + Public Sub Close() + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A() + Private a2 As A = New A() + Private a3 As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.Close() + End Sub + + Public Sub Dispose(disposed As Boolean) + a2.Dispose() + End Sub + + Public Sub Close() + a3.Dispose(True) + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedInsideDisposeClose_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub Dispose(disposed As Boolean) + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + Dispose(True) + End Sub + + Public Sub Dispose(disposed As Boolean) + a.Dispose(disposed) + End Sub +End Class") + End Function + + + Public Async Function SystemThreadingTask_SpecialCase_NotDisposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Threading.Tasks + +Public Class A + Implements IDisposable + + [|Private ReadOnly t As Task|] + + Public Sub New() + t = New Task(Nothing) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedWithDisposeAsyncInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Threading.Tasks + +Class A + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeAsync() + End Sub + + Public Function DisposeAsync() As Task + Return Task.CompletedTask + End Function +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + a.DisposeAsync() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedInsideDisposeCoreAsync_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Threading.Tasks + +MustInherit Class A + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeAsync() + End Sub + + Public Function DisposeAsync() As Task + Return Task.CompletedTask + End Function + + Protected MustOverride Function DisposeCoreAsync(initialized As Boolean) As Task +End Class + +Class A2 + Inherits A + + Protected Overrides Function DisposeCoreAsync(initialized As Boolean) As Task + Return Task.CompletedTask + End Function +End Class + +Class B + Inherits A + + [|Private a As New A2()|] + + Protected Overrides Function DisposeCoreAsync(initialized As Boolean) As Task + Return a.DisposeAsync() + End Function +End Class") + End Function + + + Public Async Function DisposableAllocation_DisposedInInvokedMethod_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private a As A = New A()|] + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeHelper() + End Sub + + Public Sub DisposeHelper() + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_NotDisposedInInvokedMethod_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private [|a|] As A = New A() + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeHelper() + End Sub + + Public Sub DisposeHelper() + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocation_DisposedInInvokedMethod_DisposableTypeInMetadata_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.IO + +Class B + Implements IDisposable + + [|Private a As FileStream = File.Open("""", FileMode.Create)|] + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeHelper() + End Sub + + Private Sub DisposeHelper() + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function DisposableAllocation_NotDisposedInInvokedMethod_DisposableTypeInMetadata_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System +Imports System.IO + +Class B + Implements IDisposable + + Private [|a|] As FileStream = File.Open("""", FileMode.Create) + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeHelper() + End Sub + + Private Sub DisposeHelper() + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocation_DisposedInInvokedMethodMultipleLevelsDown_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.IO + +Class B + Implements IDisposable + + [|Private a As FileStream = File.Open("""", FileMode.Create)|] + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeHelper() + End Sub + + Private Sub DisposeHelper() + Helper.PerformDispose(a) + End Sub +End Class + +Public Module Helper + Public Sub PerformDispose(ByVal a As IDisposable) + a.Dispose() + End Sub +End Module") + End Function + + + Public Async Function DisposableAllocation_NotDisposedInInvokedMethodMultipleLevelsDown_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System +Imports System.IO + +Class B + Implements IDisposable + + Private [|a|] As FileStream = File.Open("""", FileMode.Create) + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeHelper() + End Sub + + Private Sub DisposeHelper() + Helper.PerformDispose(a) + End Sub +End Class + +Public Module Helper + Public Sub PerformDispose(ByVal a As IDisposable) + End Sub +End Module", + Diagnostic(IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId)) + End Function + + + Public Async Function DisposableAllocationInConstructor_DisposedInGeneratedCodeFile_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + [|Private ReadOnly a As A|] + Sub New() + a = New A() + End Sub + + _ + Public Sub Dispose() Implements IDisposable.Dispose + a.Dispose() + End Sub +End Class") + End Function + End Class +End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb b/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb new file mode 100644 index 0000000000000..6f714a05ee532 --- /dev/null +++ b/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb @@ -0,0 +1,2830 @@ +' 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 Microsoft.CodeAnalysis.CodeFixes +Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics +Imports Microsoft.CodeAnalysis.DisposeAnalysis + +Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.DisposeAnalysis + Public Class DisposeObjectsBeforeLosingScopeTests + Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest + Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As (DiagnosticAnalyzer, CodeFixProvider) + Return (New DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer(), Nothing) + End Function + + ' Ensure that we explicitly test missing diagnostic, which has no corresponding code fix (non-fixable diagnostic). + Private Overloads Function TestDiagnosticMissingAsync(initialMarkup As String) As Task + Return TestDiagnosticMissingAsync(initialMarkup, New TestParameters(retainNonFixableDiagnostics:=True)) + End Function + + Private Overloads Function TestDiagnosticsAsync(initialMarkup As String, ParamArray expected As DiagnosticDescription()) As Task + Return TestDiagnosticsAsync(initialMarkup, New TestParameters(retainNonFixableDiagnostics:=True), expected) + End Function + + Private Shared Function Diagnostic(id As String, Optional sqiggledText As String = Nothing) As DiagnosticDescription + Return TestHelpers.Diagnostic(id, sqiggledText) + End Function + + + Public Async Function LocalWithDisposableInitializer_DisposeCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As New A()|] + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function LocalWithDisposableInitializer_NoDisposeCall_Diagnostic() As Task + Await TestDiagnosticsAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + Dim a As [|New A()|] + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)) + End Function + + + Public Async Function LocalWithDisposableAssignment_DisposeCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As A + a = New A() + a.Dispose() + + Dim b As New A() + a = b + a.Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function LocalWithDisposableAssignment_NoDisposeCall_Diagnostic() As Task + Await TestDiagnosticsAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + Dim a As A + a = [|New A()|] + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)) + End Function + + + Public Async Function ParameterWithDisposableAssignment_DisposeCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(a As A) + [|a = New A() + a.Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function ParameterWithDisposableAssignment_NoDisposeCall_Diagnostic() As Task + Await TestDiagnosticsAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(a As A) + a = [|New A()|] + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId)) + End Function + + + Public Async Function RefParametersWithDisposableAssignment_NoDisposeCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(ByRef a As A) + [|a = New A()|] + End Sub +End Class") + End Function + + + Public Async Function LocalWithMultipleDisposableAssignment_DisposeCallOnSome_Diagnostic() As Task + Await TestDiagnosticsAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + Dim a As A + [|a = New A(1) + a = New A(2) + a.Dispose() + a = New A(3)|] + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(1)").WithLocation(15, 13), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(3)").WithLocation(18, 13)) + End Function + + + Public Async Function FieldWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class Test + Public a As A + Sub M1(p As Test) + [|p.a = New A() + + Dim l As New Test() + l.a = New A() + + Me.a = New A()|] + End Sub +End Class") + End Function + + + Public Async Function PropertyWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class Test + Public Property a As A + Sub M1(p As Test) + [|p.a = New A() + + Dim l As New Test() + l.a = New A() + + Me.a = New A()|] + End Sub +End Class") + End Function + + + Public Async Function Interprocedural_DisposedInHelper_MethodInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(t2 As Test2) + [|DisposeHelper(new A()) + t2.DisposeHelper_MethodOnDifferentType(new A()) + DisposeHelper_MultiLevelDown(new A())|] + End Sub + + Sub DisposeHelper(a As A) + a.Dispose() + End Sub + + Sub DisposeHelper_MultiLevelDown(a As A) + DisposeHelper(a) + End Sub +End Class + +Class Test2 + Sub DisposeHelper_MethodOnDifferentType(a As A) + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function Interprocedural_DisposeOwnershipTransfer_MethodInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public a As A + Sub M1() + [|DisposeOwnershipTransfer(new A()) + Dim t2 = New Test2() + t2.DisposeOwnershipTransfer_MethodOnDifferentType(new A()) + DisposeOwnershipTransfer_MultiLevelDown(new A())|] + End Sub + + Sub DisposeOwnershipTransfer(a As A) + Me.a = a + End Sub + + Sub DisposeOwnershipTransfer_MultiLevelDown(a As A) + DisposeOwnershipTransfer(a) + End Sub +End Class + +Class Test2 + Public a As A + Sub DisposeOwnershipTransfer_MethodOnDifferentType(a As A) + Me.a = a + End Sub +End Class") + End Function + + + Public Async Function Interprocedural_NoDisposeOwnershipTransfer_MethodInvocation_Diagnostic() As Task + Await TestDiagnosticsAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public a As A + Sub M1(t2 As Test2) + [|NoDisposeOwnershipTransfer(new A(1)) + t2.NoDisposeOwnershipTransfer_MethodOnDifferentType(new A(2)) + NoDisposeOwnershipTransfer_MultiLevelDown(new A(3))|] + End Sub + + Sub NoDisposeOwnershipTransfer(a As A) + Dim str = a.ToString() + Dim b = a + End Sub + + Sub NoDisposeOwnershipTransfer_MultiLevelDown(a As A) + NoDisposeOwnershipTransfer(a) + End Sub +End Class + +Class Test2 + Public a As A + Public Sub NoDisposeOwnershipTransfer_MethodOnDifferentType(a As A) + Dim str = a.ToString() + Dim b = a + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(15, 36), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(16, 61), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(3)").WithLocation(17, 51)) + End Function + + + Public Async Function Interprocedural_DisposedInHelper_ConstructorInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim unused = new DisposeHelperType(new A()) + DisposeHelper_MultiLevelDown(new A())|] + End Sub + + Sub DisposeHelper(a As A) + Dim unused = new DisposeHelperType(a) + End Sub + + Sub DisposeHelper_MultiLevelDown(a As A) + DisposeHelper(a) + End Sub +End Class + +Class DisposeHelperType + Public Sub New(a As A) + a.Dispose() + End Sub +End Class") + End Function + + + Public Async Function Interprocedural_DisposeOwnershipTransfer_ConstructorInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim unused = new DisposableOwnerType(new A()) + DisposeOwnershipTransfer_MultiLevelDown(new A())|] + End Sub + + Sub DisposeOwnershipTransfer(a As A) + Dim unused = new DisposableOwnerType(a) + End Sub + + Sub DisposeOwnershipTransfer_MultiLevelDown(a As A) + DisposeOwnershipTransfer(a) + End Sub +End Class + +Class DisposableOwnerType + Public a As A + Public Sub New(a As A) + Me.a = a + End Sub +End Class") + End Function + + + Public Async Function Interprocedural_NoDisposeOwnershipTransfer_ConstructorInvocation_Diagnostic() As Task + Await TestDiagnosticsAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim unused = new NotDisposableOwnerType(new A(1)) + NoDisposeOwnershipTransfer_MultiLevelDown(new A(2))|] + End Sub + + Sub NoDisposeOwnershipTransfer(a As A) + Dim unused = new NotDisposableOwnerType(a) + End Sub + + Sub NoDisposeOwnershipTransfer_MultiLevelDown(a As A) + NoDisposeOwnershipTransfer(a) + End Sub +End Class + +Class NotDisposableOwnerType + Public a As A + Public Sub New(a As A) + Dim str = a.ToString() + Dim b = a + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(1)").WithLocation(14, 49), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "new A(2)").WithLocation(15, 51)) + End Function + + + Public Async Function DisposeOwnershipTransfer_AtConstructorInvocation_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +" + + A2 + +Imports System + +Class Test + Private Function M1() As DisposableOwnerType + Return [|New DisposableOwnerType(New A())|] + End Function +End Class + + + + +Imports System + +Public Class A + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Public Class DisposableOwnerType + Public Sub New(ByVal a As A) + End Sub +End Class + + +") + End Function + + + Public Async Function DisposableCreationInLoop_DisposedInFinally_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class Test + Public Sub M() + [|Dim disposeMe As IDisposable = Nothing + Try + For Each c In ""Foo"" + If disposeMe Is Nothing Then + disposeMe = New A() + End If + Next + Finally + If disposeMe IsNot Nothing Then + disposeMe.Dispose() + End If + End Try|] + End Sub +End Class + +Public Class A + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class") + End Function + + + Public Async Function LocalWithDisposableAssignment_DisposeBoolCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub + + Public Sub Dispose(b As Boolean) + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As A + a = New A() + a.Dispose(true) + + Dim b As New A() + a = b + a.Dispose(true)|] + End Sub +End Class") + End Function + + + Public Async Function LocalWithDisposableAssignment_CloseCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub + + Public Sub Close() + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As A + a = New A() + a.Close() + + Dim b As New A() + a = b + a.Close()|] + End Sub +End Class") + End Function + + + Public Async Function LocalWithDisposableAssignment_DisposeAsyncCall_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System +Imports System.Threading.Tasks + +Class A + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + DisposeAsync() + End Sub + + Public Function DisposeAsync() As Task + Return Task.CompletedTask + End Function +End Class + +Class Test + Async Function M1() As Task + [|Dim a As A + a = New A() + Await a.DisposeAsync() + + Dim b As New A() + a = b + Await a.DisposeAsync()|] + End Function +End Class") + End Function + + + Public Async Function ArrayElementWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public Property a As A + Sub M1(a As A()) + [|a(0) = New A()|] ' TODO: https://github.com/dotnet/roslyn-analyzers/issues/1577 + End Sub +End Class") + End Function + + + Public Async Function ArrayElementWithDisposableAssignment_ConstantIndex_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public Property a As A + Sub M1(a As A()) + [|a(0) = New A() + a(0).Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function ArrayElementWithDisposableAssignment_NonConstantIndex_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public Property a As A + Sub M1(a As A(), i As Integer) + [|a(i) = New A() + a(i).Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function ArrayElementWithDisposableAssignment_NonConstantIndex_02_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +$"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Public Property a As A + Sub M1(a As A(), i As Integer, j As Integer) + [|a(i) = New A() + i = j ' Value of i is now unknown + a(i).Dispose()|] ' We don't know the points to value of a(i), so don't flag 'New A()' + End Sub +End Class") + End Function + + + Public Async Function ArrayInitializer_ElementWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As A() = New A() { New A() }|] ' TODO: https://github.com/dotnet/roslyn-analyzers/issues/1577 + End Sub +End Class") + End Function + + + Public Async Function ArrayInitializer_ElementWithDisposableAssignment_ConstantIndex_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As A() = New A() {New A()} + a(0).Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function ArrayInitializer_ElementWithDisposableAssignment_NonConstantIndex_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(i As Integer) + [|Dim a As A() = New A() {New A()} + a(i).Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function CollectionInitializer_ElementWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections.Generic + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As List(Of A) = New List(Of A) From { New A() }|] ' TODO: https://github.com/dotnet/roslyn-analyzers/issues/1577 + End Sub +End Class") + End Function + + + Public Async Function CollectionInitializer_ElementWithDisposableAssignment_ConstantIndex_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + Imports System.Collections.Generic + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1() + [|Dim a As List(Of A) = New List(Of A) From {New A()} + a(0).Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function CollectionInitializer_ElementWithDisposableAssignment_NonConstantIndex_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections.Generic + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class Test + Sub M1(i As Integer) + [|Dim a As List(Of A) = New List(Of A) From {New A()} + a(i).Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function CollectionAdd_SpecialCases_ElementWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections +Imports System.Collections.Generic + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class NonGenericList + Implements ICollection + + Public Sub Add(item As A) + End Sub + + Public ReadOnly Property Count As Integer Implements ICollection.Count + Get + Throw New NotImplementedException() + End Get + End Property + + Public ReadOnly Property SyncRoot As Object Implements ICollection.SyncRoot + Get + Throw New NotImplementedException() + End Get + End Property + + Public ReadOnly Property IsSynchronized As Boolean Implements ICollection.IsSynchronized + Get + Throw New NotImplementedException() + End Get + End Property + + Public Sub CopyTo(array As Array, index As Integer) Implements ICollection.CopyTo + Throw New NotImplementedException() + End Sub + + Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator + Throw New NotImplementedException() + End Function +End Class + +Class Test + Private Sub M1() + [|Dim a As New List(Of A)() + a.Add(New A(1)) + + Dim b As A = New A(2) + a.Add(b) + + Dim l As New NonGenericList() + l.Add(New A(3)) + + b = New A(4) + l.Add(b)|] + End Sub +End Class") + End Function + + + Public Async Function CollectionAdd_IReadOnlyCollection_SpecialCases_ElementWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections +Imports System.Collections.Concurrent +Imports System.Collections.Generic + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class MyReadOnlyCollection + Implements IReadOnlyCollection(Of A) + + Public Sub Add(ByVal item As A) + End Sub + + Public ReadOnly Property Count As Integer Implements IReadOnlyCollection(Of A).Count + Get + Throw New NotImplementedException() + End Get + End Property + + Public Function GetEnumerator() As IEnumerator(Of A) Implements IEnumerable(Of A).GetEnumerator + Throw New NotImplementedException() + End Function + + Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator + Throw New NotImplementedException() + End Function +End Class + +Class Test + Private Sub M1() + [|Dim myReadOnlyCollection = New MyReadOnlyCollection() + myReadOnlyCollection.Add(New A(1)) + Dim a As A = New A(2) + myReadOnlyCollection.Add(a) + + Dim bag = New ConcurrentBag(Of A)() + bag.Add(New A(3)) + Dim a2 As A = New A(4) + bag.Add(a2)|] + End Sub +End Class") + End Function + + + Public Async Function MemberInitializerWithDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections.Generic + +Class A + Implements IDisposable + Public X As Integer + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class Test + Public a As A + Sub M1() + [|Dim a = New Test With {.a = New A() With { .X = 1 }} |] + End Sub +End Class") + End Function + + + Public Async Function StructImplementingIDisposable_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Structure A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Structure + +Class Test + Sub M1() + [|Dim a As New A()|] + End Sub +End Class") + End Function + + + Public Async Function NonUserDefinedConversions_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Inherits A +End Class + +Class Test + Sub M1() + [|Dim obj As Object = New A() ' Implicit conversion from A to object + DirectCast(obj, A).Dispose() ' Explicit conversion from object to A + + Dim a As A = new B() ' Implicit conversion from B to A + a.Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function NonUserDefinedConversions_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Inherits A +End Class + +Class Test + Sub M1() + [|Dim obj As Object = New A() ' Implicit conversion from A to object + Dim a As A = DirectCast(New B(), A)|] ' Explicit conversion from B to A + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(15, 29), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New B()").WithLocation(16, 33)) + End Function + + + Public Async Function UserDefinedConversions_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Shared Widening Operator CType(ByVal value As A) As B + value.Dispose() + Return Nothing + End Operator + + Public Shared Widening Operator CType(ByVal value As B) As A + value.Dispose() + Return Nothing + End Operator +End Class + +Class B + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Private Sub M1() + [|Dim a As A = New B() ' Implicit user defined conversion + Dim b As B = CType(New A(), B)|] ' Explicit user defined conversion + End Sub +End Class") + End Function + + + Public Async Function LocalWithDisposableAssignment_ByRef_DisposedInCallee_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [|Sub M1() + Dim a As New A() + M2(a) + End Sub + + Sub M2(ByRef a as A) + a.Dispose() + a = Nothing + End Sub|] +End Class") + End Function + + + Public Async Function LocalWithDisposableAssignment_ByRefEscape_AbstractVirtualMethod_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Public Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Public MustInherit Class Test + Sub M1() + [|Dim a As New A() + M2(a) + + a = New A() + M3(a)|] + End Sub + + Public Overridable Sub M2(ByRef a as A) + End Sub + + Public MustOverride Sub M3(ByRef a as A) +End Class") + End Function + + + Public Async Function LocalWithDefaultOfDisposableAssignment_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + Sub M1() + [|Dim a As A = Nothing|] + End Sub +End Module") + End Function + + + Public Async Function NullCoalesce_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(a As A) + [|Dim b As A = If(a, New A()) + b.Dispose() + + Dim c As New A() + Dim d As A = If(c, a) + d.Dispose() + + a = New A() + Dim e As A = If(a, New A()) + e.Dispose()|] + End Sub +End Class") + End Function + + + Public Async Function NullCoalesce_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + Sub M1(a As A) + Dim b As A = If(a, [|New A()|]) + a.Dispose() + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(11, 28)) + End Function + + + Public Async Function WhileLoop_DisposeOnBackEdge_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + Sub M1(flag As Boolean) + [|Dim a As New A() + While True + a.Dispose() + If flag Then + Exit While ' All 'A' instances have been disposed on this path, so no diagnostic should be reported. + End If + a = New A() + End While|] + End Sub +End Module") + End Function + + + + Public Async Function WhileLoop_MissingDisposeOnExit_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A(1) ' Allocated outside the loop and disposed inside a loop is not a recommended pattern and is flagged. + While True + a.Dispose() + a = New A(2) ' This instance will not be disposed on loop exit. + End While + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(1)").WithLocation(14, 18), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(2)").WithLocation(17, 17)) + End Function + + + Public Async Function WhileLoop_MissingDisposeOnEntry_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A(1) ' This instance will never be disposed. + While True + a = New A(2) + a.Dispose() + End While + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(1)").WithLocation(14, 18)) + End Function + + + Public Async Function DoWhileLoop_DisposeOnBackEdge_NoDiagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1(flag As Boolean) + Dim a As New A() + Do While True + a.Dispose() + If flag Then + Exit Do ' All 'A' instances have been disposed on this path, so no diagnostic should be reported. + End If + a = New A() + Loop + End Sub|] +End Module") + End Function + + + Public Async Function DoWhileLoop_MissingDisposeOnExit_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A(1) + Do + a.Dispose() + a = New A(2) ' This instance will not be disposed on loop exit. + Loop While True + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(2)").WithLocation(17, 17)) + End Function + + + Public Async Function DoWhileLoop_MissingDisposeOnEntry_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A(1) ' This instance will never be disposed. + Do While True + a = New A(2) + a.Dispose() + Loop + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(1)").WithLocation(14, 18)) + End Function + + + Public Async Function ForLoop_DisposeOnBackEdge_MayBeNotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1(flag As Boolean) + Dim a As New A(1) ' Allocation outside a loop, dispose inside a loop is not a recommended pattern and should fire diagnostic. + For i As Integer = 0 To 10 + a.Dispose() + If flag Then + Exit For ' All 'A' instances have been disposed on this path. + End If + a = New A(2) ' This can leak on loop exit, and is flagged as a maybe disposed violation. + Next + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(1)").WithLocation(14, 18), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(2)").WithLocation(20, 17)) + End Function + + + Public Async Function ForLoop_MissingDisposeOnExit_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A(1) ' Allocation outside a loop, dispose inside a loop is not a recommended pattern and should fire diagnostic. + For i As Integer = 0 To 10 + a.Dispose() + a = New A(2) ' This instance will not be disposed on loop exit. + Next + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(1)").WithLocation(14, 18), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(2)").WithLocation(17, 17)) + End Function + + + Public Async Function ForLoop_MissingDisposeOnEntry_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A(1) ' This instance will never be disposed. + For i As Integer = 0 To 10 + a = New A(2) + a.Dispose() + Next + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(1)").WithLocation(14, 18)) + End Function + + + Public Async Function IfStatement_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class B + Inherits A +End Class + +Class Test + [|Private Sub M1(a As A, param As String) + Dim a1 As New A() + Dim a2 As B = new B() + Dim b As A + If param IsNot Nothing Then + a = a1 + b = new B() + Else + a = a2 + b = new A() + End If + + a.Dispose() ' a points to either a1 or a2. + b.Dispose() ' b points to either instance created in if or else. + End Sub|] +End Class") + End Function + + + Public Async Function IfStatement_02_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Inherits A +End Class + +Class Test + [|Private Sub M1(a As A, param As String, param2 As String) + Dim a1 As New A() + Dim a2 As B = new B() + Dim b As A + If param IsNot Nothing Then + a = a1 + b = new B() + If param = """" Then + a = new B() + Else + If param2 IsNot Nothing Then + b = new A() + Else + b = new B() + End If + End If + Else + a = a2 + b = new A() + End If + + a.Dispose() ' a points to either a1 or a2 or instance created in 'if(param == """")'. + b.Dispose() ' b points to either instance created in outer if or outer else or innermost if or innermost else. + End Sub|] +End Class") + End Function + + + Public Async Function IfStatement_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub New() + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Inherits A +End Class + +Class C + Inherits B +End Class + +Class D + Inherits C +End Class + +Class E + Inherits D +End Class + +Class Test + [|Private Sub M1(ByVal a As A, ByVal param As String, ByVal param2 As String) + Dim a1 As A = New A(1) ' Maybe disposed. + Dim a2 As B = New B() ' Never disposed. + Dim b As A + + If param IsNot Nothing Then + a = a1 + b = New C() ' Never disposed. + Else + a = a2 + b = New D() ' Never disposed. + End If + + ' a points to either a1 or a2. + ' b points to either instance created in if or else. + + If param IsNot Nothing Then + Dim c As A = New A(2) + a = c + b = a1 + Else + Dim d As C = New E() + b = d + a = b + End If + + a.Dispose() ' a points to either c or d. + b.Dispose() ' b points to either a1 or d. + End Sub|] +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New B()").WithLocation(34, 23), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New C()").WithLocation(39, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New D()").WithLocation(42, 17)) + End Function + + + Public Async Function IfStatement_02_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub New() + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Inherits A +End Class + +Class C + Inherits B +End Class + +Class D + Inherits C +End Class + +Class E + Inherits D +End Class + +Class Test + [|Private Sub M1(ByVal a As A, ByVal param As String, ByVal param2 As String) + Dim a1 As A = New B() ' Never disposed + Dim a2 As B = New C() ' Never disposed + Dim b As A + If param IsNot Nothing Then + a = a1 + b = New A(1) ' Always disposed + If param = """" Then + a = New D() ' Never disposed + Else + If param2 IsNot Nothing Then + b = New A(2) ' Maybe disposed + Else + b = New A(3) ' Maybe disposed + If param = """" Then + b = New A(4) ' Maybe disposed + End If + End If + + If param2 = """" Then + b.Dispose() ' b points to one of the three instances of A created above. + b = New A(5) ' Always disposed + End If + End If + Else + a = a2 + b = New A(6) ' Maybe disposed + If param2 IsNot Nothing Then + a = New A(7) ' Always disposed + Else + a = New A(8) ' Always disposed + b = New A(9) ' Always disposed + End If + + a.Dispose() + End If + + b.Dispose() + End Sub|] +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New B()").WithLocation(33, 23), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New C()").WithLocation(34, 23), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New D()").WithLocation(40, 21)) + End Function + + + Public Async Function UsingStatement_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [|Private Sub M1() + Using a As New A() + End Using + + Dim b As A = New A() + Using b + End Using + + Using c As New A(), d = New A() + End Using + + Using a As A = Nothing + End Using + End Sub|] +End Class") + End Function + + + Public Async Function UsingStatementInTryCatch_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System.IO + +Class Test + Private Sub M1() + Try + [|Using ms = New MemoryStream()|] + End Using + Catch + End Try + End Sub +End Class") + End Function + + + Public Async Function NestedTryFinallyInTryCatch_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System.IO + +Class Test + Private Sub M1() + Try + [|Dim ms = New MemoryStream()|] + Try + Finally + ms?.Dispose() + End Try + Catch + End Try + End Sub +End Class") + End Function + + + Public Async Function ReturnStatement_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections.Generic + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [|Private Function M1() As A + Return New A() + End Function + + Private Function M2(a As A) As A + a = New A() + Return a + End Function + + Private Function M3(a As A) As A + a = New A() + Dim b = a + Return b + End Function + + Public Iterator Function M4() As IEnumerable(Of A) + Yield New A + End Function|] +End Class") + End Function + + + Public Async Function ReturnStatement_02_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Collections.Generic + +Class A + Implements I, IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Interface I +End Interface + +Class Test + [|Private Function M1() As I + Return New A() + End Function + + Private Function M2() As I + Return TryCast(New A(), I) + End Function|] +End Class") + End Function + + + Public Async Function LambdaInvocation_EmptyBody_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As A + a = New A() + + Dim myLambda As System.Action = Sub() + End Sub + + myLambda() ' This should not change state of 'a'. + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(12, 13)) + End Function + + + Public Async Function LambdaInvocation_DisposesCapturedValue_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As New A() + + Dim myLambda As System.Action = Sub() + a.Dispose() + End Sub + + myLambda() ' This should change state of 'a' to be Disposed. + End Sub|] +End Module") + End Function + + + Public Async Function LambdaInvocation_CapturedValueAssignedNewDisposable_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As A + + Dim myLambda As System.Action = Sub() + a = New A() + End Sub + + myLambda() ' This should change state of 'a' to be NotDisposed and fire a diagnostic. + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(14, 49)) + End Function + + + Public Async Function LambdaInvocation_ChangesCapturedValueContextSensitive_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As A + + Dim myLambda As System.Action(Of A) = Sub(b As A) + a = b + End Sub + + myLambda(New A()) ' This should change state of 'a' to be NotDisposed and fire a diagnostic. + End Sub|] +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(18, 18)) + End Function + + + Public Async Function DelegateInvocation_EmptyBody_NoArguments_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As A + a = New A() + + Dim myDelegate As System.Action = AddressOf M2 + myDelegate() ' This should not change state of 'a' as it is not passed as argument. + End Sub|] + + Sub M2() + End Sub +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(12, 13)) + End Function + + + Public Async Function DelegateInvocation_PassedAsArgumentButNotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As A + a = New A() + + Dim myDelegate As System.Action(Of A) = AddressOf M2 + myDelegate(a) ' This should not change state of 'a'. + End Sub|] + + Sub M2(a As A) + End Sub +End Module", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A()").WithLocation(12, 13)) + End Function + + + Public Async Function DelegateInvocation_DisposesCapturedValue_NoDiagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Module Test + [|Sub M1() + Dim a As A + a = New A() + + Dim myDelegate As System.Action(Of A) = AddressOf M2 + myDelegate(a) ' This should change state of 'a' to be disposed as we perform interprocedural analysis. + End Sub|] + + Sub M2(a As A) + a.Dispose() + End Sub +End Module") + End Function + + + Public Async Function DisposableCreationNotAssignedToAVariable_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public X As Integer + + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Sub M() + End Sub +End Class + +Class Test + [|Private Sub M1() + New A(1) ' Error + New A(2).M() ' Error + Dim x = New A(3).X + End Sub|] +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(3)").WithLocation(21, 17)) + End Function + + + Public Async Function DisposableCreationPassedToDisposableConstructor_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + + Public X As Integer + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Implements IDisposable + + Private ReadOnly _a As A + Public Sub New(ByVal a As A) + _a = a + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [|Private Sub M1() + Dim b = New B(New A()) + b.Dispose() + Dim a = New A() + Dim b2 As B = Nothing + Try + b2 = New B(a) + Finally + If b2 IsNot Nothing Then + b2.Dispose() + End If + End Try + + Dim a2 = New A() + Dim b3 As B = Nothing + Try + b3 = New B(a2) + Finally + If b3 IsNot Nothing Then + b3.Dispose() + End If + End Try + End Sub|] +End Class") + End Function + + + Public Async Function DisposableObjectOnlyDisposedOnExceptionPath_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [|Private Sub M1() + Dim a = New A(1) + Try + ThrowException() + Catch ex As Exception + a.Dispose() + End Try + End Sub + + Private Sub M2() + Dim a = New A(2) + Try + ThrowException() + Catch ex As System.IO.IOException + a.Dispose() + End Try + End Sub + + Private Sub M3() + Dim a = New A(3) + Try + ThrowException() + Catch ex As System.IO.IOException + a.Dispose() + Catch ex As Exception + a.Dispose() + End Try + End Sub + + Private Sub M4(flag As Boolean) + Dim a = New A(4) + Try + ThrowException() + Catch ex As System.IO.IOException + If flag Then + a.Dispose() + End If + End Try + End Sub|] + + Private Sub ThrowException() + Throw New NotImplementedException() + End Sub +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(1)").WithLocation(14, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(2)").WithLocation(23, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(3)").WithLocation(32, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(4)").WithLocation(43, 17)) + End Function + + + Public Async Function DisposableObjectDisposed_FinallyPath_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [|Private Sub M1() + Dim a = New A() + Try + ThrowException() + Finally + a.Dispose() + End Try + End Sub + + Private Sub M2() + Dim a = New A() + Try + ThrowException() + Catch ex As Exception + Finally + a.Dispose() + End Try + End Sub + + Private Sub M3() + Dim a = New A() + Try + ThrowException() + a.Dispose() + a = Nothing + Catch ex As System.IO.IOException + Finally + If a IsNot Nothing Then + a.Dispose() + End If + End Try + End Sub|] + + Private Sub ThrowException() + Throw New NotImplementedException() + End Sub +End Class") + End Function + + + Public Async Function DelegateCreation_Disposed_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + + End Sub +End Class + +Class Test + [|Sub M1() + Dim createA As Func(Of A) = AddressOf M2 + Dim a As A = createA() + a.Dispose() + End Sub + + Function M2() As A + Return New A() + End Function|] +End Class") + End Function + + + Public Async Function MultipleReturnStatements_AllInstancesReturned_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Threading.Tasks +Imports System.Runtime.InteropServices + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Public Class Test + [|Private Function M1(ByVal flag As Boolean) As A + Dim a As A + If flag Then + Dim a2 As New A() + a = a2 + Return a + End If + + Dim a3 As New A() + a = a3 + Return a + End Function|] +End Class") + End Function + + + Public Async Function MultipleReturnStatements_AllInstancesEscapedWithOutParameter_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Threading.Tasks +Imports System.Runtime.InteropServices + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Public Class Test + [|Private Sub M1(ByVal flag As Boolean, ByRef a As A) + If flag Then + Dim a2 As New A() + a = a2 + Return + End If + + Dim a3 As New A() + a = a3 + Return + End Sub|] +End Class") + End Function + + + Public Async Function MultipleReturnStatements_AllButOneInstanceReturned_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System +Imports System.Threading.Tasks +Imports System.Runtime.InteropServices + +Class A + Implements IDisposable + + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Public Class Test + [|Private Function M1(flag As Integer, flag2 As Boolean, flag3 As Boolean) As A + Dim a As A = Nothing + If flag = 0 Then + Dim a2 As A = New A(1) ' Escaped with return inside below nested 'if', not disposed on other paths. + a = a2 + If Not flag2 Then + If flag3 Then + Return a + End If + End If + Else + a = New A(2) ' Escaped with return inside below nested 'else', not disposed on other paths. + If flag = 1 Then + a = New A(3) ' Never disposed on any path. + Else + If flag3 Then + a = New A(4) ' Escaped with return inside below 'else', not disposed on other paths. + End If + + If flag2 Then + Else + Return a + End If + End If + End If + + Dim a3 As A = New A(5) ' Always escaped with below return, ensure no diagnostic. + a = a3 + Return a + End Function|] +End Class", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(1)").WithLocation(19, 27), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(2)").WithLocation(27, 17), + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(3)").WithLocation(29, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(4)").WithLocation(32, 25)) + End Function + + + Public Async Function MultipleReturnStatements_AllButOneInstanceEscapedWithOutParameter_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System +Imports System.Threading.Tasks +Imports System.Runtime.InteropServices + +Class A + Implements IDisposable + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class B + Inherits A +End Class + +Public Class Test + [|Private Sub M1(flag As Integer, flag2 As Boolean, flag3 As Boolean, ByRef a As A) + a = Nothing + If flag = 0 Then + Dim a2 As A = New A() ' Escaped with return inside below nested 'if'. + a = a2 + If Not flag2 Then + If flag3 Then + Return + End If + End If + Else + a = New A() ' Escaped with return inside below nested 'else'. + If flag = 1 Then + a = New B() ' Never disposed + Else + If flag3 Then + a = New A() ' Escaped with return inside below 'else'. + End If + + If flag2 Then + Else + Return + End If + End If + End If + + Dim a3 As A = New A() ' Escaped with below return. + a = a3 + Return + End Sub|] +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New B()").WithLocation(29, 21)) + End Function + + + Public Async Function DifferentDisposePatternsInFinally_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System + +Class A + Implements IDisposable + + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [| + Private Sub M1() + Dim a As A = New A(1) + + Try + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M2() + Dim a As A = Nothing + + Try + a = New A(2) + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M3() + Dim a As A = New A(3) + + Try + Finally + If a IsNot Nothing Then + a?.Dispose() + End If + End Try + End Sub + + Private Sub M4() + Dim a As A = Nothing + + Try + a = New A(4) + Finally + If a IsNot Nothing Then + a?.Dispose() + End If + End Try + End Sub + + Private Sub M5() + Dim a As A = New A(5) + + Try + Finally + DisposeHelper(a) + End Try + End Sub + + Private Sub M6() + Dim a As A = Nothing + + Try + a = New A(6) + Finally + DisposeHelper(a) + End Try + End Sub + + Private Sub DisposeHelper(a As IDisposable) + If a IsNot Nothing Then + a?.Dispose() + End If + End Sub + + Private Sub M7(flag As Boolean) + Dim a As A = New A(7) + + Try + If flag Then + a.Dispose() + a = Nothing + End If + + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M8(flag1 As Boolean, flag2 As Boolean) + Dim a As A = Nothing + + Try + If flag1 Then + a = New A(8) + End If + + If flag2 Then + a.Dispose() + a = Nothing + End If + + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M9(flag As Boolean) + Dim a As A = New A(9) + + Try + If flag Then + a.Dispose() + a = Nothing + Return + End If + + a.Dispose() + Catch ex As Exception + a?.Dispose() + Finally + End Try + End Sub + + Private Sub M10(flag1 As Boolean, flag2 As Boolean) + Dim a As A = Nothing + + Try + If flag1 Then + a = New A(10) + End If + + If flag2 Then + a?.Dispose() + Return + End If + + If a IsNot Nothing Then + a.Dispose() + End If + + Catch ex As Exception + a?.Dispose() + Finally + End Try + End Sub + + Private A As IDisposable + + Private Sub M11(flag As Boolean) + Dim a As A = New A(9) + + Try + If flag Then + a.Dispose() + a = Nothing + Return + End If + + Me.A = a + a = Nothing + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M12(flag1 As Boolean, flag2 As Boolean) + Dim a As A = Nothing + + Try + If flag1 Then + a = New A(10) + End If + + If flag2 Then + Me.A = a + a = Nothing + Return + End If + + If a IsNot Nothing Then + a.Dispose() + a = Nothing + End If + + Finally + a?.Dispose() + End Try + End Sub + |] +End Class") + End Function + + + Public Async Function DifferentDisposePatternsInFinally_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System + +Class A + Implements IDisposable + + Public Sub New(i As Integer) + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub +End Class + +Class Test + [| + Private Sub M1(flag As Boolean) + Dim a As A = New A(1) + + Try + Finally + If flag Then + a?.Dispose() + End If + End Try + End Sub + + Private Sub M2(flag As Boolean) + Dim a As A = Nothing + + Try + a = New A(2) + Finally + If flag Then + a?.Dispose() + End If + End Try + End Sub + + Private Sub M3(flag As Boolean) + Dim a As A = Nothing + Dim b As A = Nothing + + Try + If flag Then + a = New A(3) + b = New A(31) + End If + Finally + If b IsNot Nothing Then + a.Dispose() + b.Dispose() + End If + End Try + End Sub + + Private Sub M4(flag As Boolean) + Dim a As A = Nothing + Dim b As A = Nothing + + Try + If flag Then + a = New A(4) + b = New A(41) + End If + Finally + If a IsNot Nothing AndAlso b IsNot Nothing Then + a.Dispose() + b.Dispose() + End If + End Try + End Sub + + Private Sub M5(flag As Boolean) + Dim a As A = New A(5) + + Try + Finally + DisposeHelper(a, flag) + End Try + End Sub + + Private Sub M6(flag As Boolean) + Dim a As A = Nothing + + Try + If flag Then + a = New A(6) + End If + Finally + DisposeHelper(a, flag) + End Try + End Sub + + Private Sub DisposeHelper(a As IDisposable, flag As Boolean) + If flag Then + a?.Dispose() + End If + End Sub + + Private Sub M7(flag As Boolean) + Dim a As A = New A(7) + + Try + If flag Then + a = Nothing + End If + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M8(flag1 As Boolean, flag2 As Boolean) + Dim a As A = Nothing + + Try + If flag1 Then + a = New A(8) + End If + + If flag2 Then + a.Dispose() + a = Nothing + Else + a = Nothing + End If + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M9(flag As Boolean) + Dim a As A = New A(9) + + Try + If flag Then + a = Nothing + Return + End If + + a.Dispose() + Catch ex As Exception + a?.Dispose() + Finally + End Try + End Sub + + Private Sub M10(flag1 As Boolean, flag2 As Boolean) + Dim a As A = Nothing + + Try + If flag1 Then + a = New A(10) + End If + + If flag2 Then + a?.Dispose() + Return + End If + + If a IsNot Nothing Then + a.Dispose() + End If + Catch ex As Exception + If flag1 Then + a?.Dispose() + End If + + Finally + End Try + End Sub + + Private A As IDisposable + + Private Sub M11(flag As Boolean) + Dim a As A = New A(11) + + Try + If flag Then + a.Dispose() + a = Nothing + Return + End If + + a = Nothing + Me.A = a + Finally + a?.Dispose() + End Try + End Sub + + Private Sub M12(flag1 As Boolean, flag2 As Boolean, flag3 As Boolean) + Dim a As A = Nothing + + Try + If flag1 Then + a = New A(12) + End If + + If flag2 Then + Me.A = a + a = Nothing + Return + ElseIf flag3 Then + a = New A(121) + End If + + Finally + a?.Dispose() + End Try + End Sub + |] +End Class", + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(1)").WithLocation(16, 22), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(2)").WithLocation(30, 17), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(3)").WithLocation(44, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(4)").WithLocation(61, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(41)").WithLocation(62, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(5)").WithLocation(73, 22), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(6)").WithLocation(86, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(8)").WithLocation(116, 21), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(9)").WithLocation(131, 22), + Diagnostic(IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, "New A(11)").WithLocation(174, 22)) + End Function + + + Public Async Function ReturnDisposableObjectWrappenInTask_NoDiagnostic() As Task + Await TestDiagnosticMissingAsync( +"Imports System +Imports System.Threading.Tasks + +Class C + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + Public Function M1_Task() As Task(Of C) + [|Return Task.FromResult(New C())|] + End Function +End Class") + End Function + + + Public Async Function AwaitedButNotDisposed_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System +Imports System.Threading.Tasks + +Class C + Implements IDisposable + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + [| + Public Function M1_Task() As Task(Of C) + Return Task.FromResult(New C()) + End Function + + Public Async Function M2_Task() As Task + Dim c = Await M1_Task().ConfigureAwait(False) + End Function + |] +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "Await M1_Task().ConfigureAwait(False)").WithLocation(16, 17)) + End Function + + + Public Async Function AwaitedButNotDisposed_TaskWrappingField_Diagnostic() As Task + Await TestDiagnosticsAsync( +"Imports System +Imports System.Threading.Tasks + +Class C + Implements IDisposable + + Private _c As C + + Public Sub Dispose() Implements IDisposable.Dispose + End Sub + + [| + Public Function M1_Task() As Task(Of C) + Return Task.FromResult(_c) + End Function + + Public Async Function M2_Task() As Task + Dim c = Await M1_Task().ConfigureAwait(False) + End Function + |] +End Class", + Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "Await M1_Task().ConfigureAwait(False)").WithLocation(18, 17)) + End Function + End Class +End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/Formatting/Indentation/SmartTokenFormatter_FormatTokenTests.vb b/src/EditorFeatures/VisualBasicTest/Formatting/Indentation/SmartTokenFormatter_FormatTokenTests.vb index 79e3fc25f4fdb..08064993d473d 100644 --- a/src/EditorFeatures/VisualBasicTest/Formatting/Indentation/SmartTokenFormatter_FormatTokenTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Formatting/Indentation/SmartTokenFormatter_FormatTokenTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.Text.Shared.Extensions +Imports Microsoft.CodeAnalysis.VisualBasic.Indentation Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.Text.Editor Imports Moq @@ -198,7 +199,7 @@ End Class Assert.True(VisualBasicIndentationService.ShouldUseSmartTokenFormatterInsteadOfIndenter( formattingRules, root, line.AsTextLine, workspace.Options, Nothing, ignoreMissingToken)) - Dim smartFormatter = New SmartTokenFormatter(Await document.GetOptionsAsync(CancellationToken.None), formattingRules, root) + Dim smartFormatter = New VisualBasicSmartTokenFormatter(Await document.GetOptionsAsync(CancellationToken.None), formattingRules, root) Dim changes = Await smartFormatter.FormatTokenAsync(workspace, token, Nothing) Using edit = buffer.CreateEdit() diff --git a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmException.cs b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmException.cs index cc19bc77974a9..a573c4ad81bbe 100644 --- a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmException.cs +++ b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmException.cs @@ -14,6 +14,7 @@ namespace Microsoft.VisualStudio.Debugger // Summary: // Base exception class for all exceptions within this API. [DebuggerDisplay("\\{DkmException Code={Code,h}\\}")] + [Serializable] public class DkmException : ApplicationException { private readonly DkmExceptionCode _code; diff --git a/src/Features/CSharp/Portable/AddAccessibilityModifiers/CSharpAddAccessibilityModifiersCodeFixProvider.cs b/src/Features/CSharp/Portable/AddAccessibilityModifiers/CSharpAddAccessibilityModifiersCodeFixProvider.cs index f157ad5c6fca1..0693e4a609176 100644 --- a/src/Features/CSharp/Portable/AddAccessibilityModifiers/CSharpAddAccessibilityModifiersCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddAccessibilityModifiers/CSharpAddAccessibilityModifiersCodeFixProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.AddAccessibilityModifiers [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpAddAccessibilityModifiersCodeFixProvider : AbstractAddAccessibilityModifiersCodeFixProvider { + [ImportingConstructor] + public CSharpAddAccessibilityModifiersCodeFixProvider() + { + } + protected override SyntaxNode MapToDeclarator(SyntaxNode node) { switch (node) diff --git a/src/Features/CSharp/Portable/AddAnonymousTypeMemberName/CSharpAddAnonymousTypeMemberNameCodeFixProvider.cs b/src/Features/CSharp/Portable/AddAnonymousTypeMemberName/CSharpAddAnonymousTypeMemberNameCodeFixProvider.cs index 9a5ac7fbc7ffc..f74f94dee4b7a 100644 --- a/src/Features/CSharp/Portable/AddAnonymousTypeMemberName/CSharpAddAnonymousTypeMemberNameCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddAnonymousTypeMemberName/CSharpAddAnonymousTypeMemberNameCodeFixProvider.cs @@ -19,6 +19,11 @@ internal class CSharpAddAnonymousTypeMemberNameCodeFixProvider { private const string CS0746 = nameof(CS0746); // Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access. + [ImportingConstructor] + public CSharpAddAnonymousTypeMemberNameCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS0746); diff --git a/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs b/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs index d28c001528d2e..cc87a6d81a185 100644 --- a/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Diagnostics.AddBraces [ExtensionOrder(After = PredefinedCodeFixProviderNames.AddAwait)] internal sealed class CSharpAddBracesCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpAddBracesCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.AddBracesDiagnosticId); diff --git a/src/Features/CSharp/Portable/AddFileBanner/CSharpAddFileBannerCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/AddFileBanner/CSharpAddFileBannerCodeRefactoringProvider.cs index 859d3d3d100d1..0b268d374040b 100644 --- a/src/Features/CSharp/Portable/AddFileBanner/CSharpAddFileBannerCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/AddFileBanner/CSharpAddFileBannerCodeRefactoringProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.AddFileBanner Name = PredefinedCodeRefactoringProviderNames.AddFileBanner), Shared] internal class CSharpAddFileBannerCodeRefactoringProvider : AbstractAddFileBannerCodeRefactoringProvider { + [ImportingConstructor] + public CSharpAddFileBannerCodeRefactoringProvider() + { + } + protected override bool IsCommentStartCharacter(char ch) => ch == '/'; diff --git a/src/Features/CSharp/Portable/AddImport/CSharpAddImportCodeFixProvider.cs b/src/Features/CSharp/Portable/AddImport/CSharpAddImportCodeFixProvider.cs index 4afeedb79b295..d868af0c43c34 100644 --- a/src/Features/CSharp/Portable/AddImport/CSharpAddImportCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddImport/CSharpAddImportCodeFixProvider.cs @@ -151,6 +151,7 @@ internal class CSharpAddImportCodeFixProvider : AbstractAddImportCodeFixProvider { public override ImmutableArray FixableDiagnosticIds => AddImportDiagnosticIds.FixableDiagnosticIds; + [ImportingConstructor] public CSharpAddImportCodeFixProvider() { } diff --git a/src/Features/CSharp/Portable/AddImport/CSharpAddImportFeatureService.cs b/src/Features/CSharp/Portable/AddImport/CSharpAddImportFeatureService.cs index 3acb74b9edaed..60efa202e3e74 100644 --- a/src/Features/CSharp/Portable/AddImport/CSharpAddImportFeatureService.cs +++ b/src/Features/CSharp/Portable/AddImport/CSharpAddImportFeatureService.cs @@ -26,6 +26,11 @@ namespace Microsoft.CodeAnalysis.CSharp.AddImport [ExportLanguageService(typeof(IAddImportFeatureService), LanguageNames.CSharp), Shared] internal class CSharpAddImportFeatureService : AbstractAddImportFeatureService { + [ImportingConstructor] + public CSharpAddImportFeatureService() + { + } + protected override bool CanAddImport(SyntaxNode node, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) diff --git a/src/Features/CSharp/Portable/AddImport/CSharpAddMissingImportsFeatureService.cs b/src/Features/CSharp/Portable/AddImport/CSharpAddMissingImportsFeatureService.cs index 78be43bce1f1a..73c3d654c5b36 100644 --- a/src/Features/CSharp/Portable/AddImport/CSharpAddMissingImportsFeatureService.cs +++ b/src/Features/CSharp/Portable/AddImport/CSharpAddMissingImportsFeatureService.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.AddMissingImports [ExportLanguageService(typeof(IAddMissingImportsFeatureService), LanguageNames.CSharp), Shared] internal class CSharpAddMissingImportsFeatureService : AbstractAddMissingImportsFeatureService { + [ImportingConstructor] + public CSharpAddMissingImportsFeatureService() + { + } + protected sealed override ImmutableArray FixableDiagnosticIds => AddImportDiagnosticIds.FixableDiagnosticIds; } } diff --git a/src/Features/CSharp/Portable/AddMissingReference/CSharpAddMissingReferenceCodeFixProvider.cs b/src/Features/CSharp/Portable/AddMissingReference/CSharpAddMissingReferenceCodeFixProvider.cs index f36ba71d06776..78701636cdd39 100644 --- a/src/Features/CSharp/Portable/AddMissingReference/CSharpAddMissingReferenceCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddMissingReference/CSharpAddMissingReferenceCodeFixProvider.cs @@ -19,6 +19,7 @@ internal class CSharpAddMissingReferenceCodeFixProvider : AbstractAddMissingRefe public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS0012); + [ImportingConstructor] public CSharpAddMissingReferenceCodeFixProvider() { } diff --git a/src/Features/CSharp/Portable/AddObsoleteAttribute/CSharpAddObsoleteAttributeCodeFixProvider.cs b/src/Features/CSharp/Portable/AddObsoleteAttribute/CSharpAddObsoleteAttributeCodeFixProvider.cs index bc21ca5b20cfe..1293f9b3b87ff 100644 --- a/src/Features/CSharp/Portable/AddObsoleteAttribute/CSharpAddObsoleteAttributeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddObsoleteAttribute/CSharpAddObsoleteAttributeCodeFixProvider.cs @@ -20,6 +20,7 @@ internal class CSharpAddObsoleteAttributeCodeFixProvider "CS1064" // The best overloaded Add method 'MyCollection.Add(int)' for the collection initializer element is obsolete" ); + [ImportingConstructor] public CSharpAddObsoleteAttributeCodeFixProvider() : base(CSharpSyntaxFactsService.Instance, CSharpFeaturesResources.Add_Obsolete) { diff --git a/src/Features/CSharp/Portable/AddPackage/CSharpAddSpecificPackageCodeFixProvider.cs b/src/Features/CSharp/Portable/AddPackage/CSharpAddSpecificPackageCodeFixProvider.cs index 94e07255e6cf8..59eed152cef8c 100644 --- a/src/Features/CSharp/Portable/AddPackage/CSharpAddSpecificPackageCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddPackage/CSharpAddSpecificPackageCodeFixProvider.cs @@ -12,6 +12,11 @@ internal class CSharpAddSpecificPackageCodeFixProvider : AbstractAddSpecificPack { private const string CS8179 = nameof(CS8179); // Predefined type 'System.ValueTuple`2' is not defined or imported + [ImportingConstructor] + public CSharpAddSpecificPackageCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS8179); diff --git a/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs b/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs index e55d45fbc0a01..41e1b162d1ec8 100644 --- a/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs @@ -34,6 +34,11 @@ internal class CSharpAddParameterCodeFixProvider : AbstractAddParameterCodeFixPr CS1501, CS1503, CS1660, CS1729, CS1739, IDEDiagnosticIds.UnboundConstructorId); + [ImportingConstructor] + public CSharpAddParameterCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => AddParameterFixableDiagnosticIds; diff --git a/src/Features/CSharp/Portable/AliasAmbiguousType/CSharpAliasAmbiguousTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/AliasAmbiguousType/CSharpAliasAmbiguousTypeCodeFixProvider.cs index 4d40ee8b7d6a4..c7fd5b74ffdf2 100644 --- a/src/Features/CSharp/Portable/AliasAmbiguousType/CSharpAliasAmbiguousTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AliasAmbiguousType/CSharpAliasAmbiguousTypeCodeFixProvider.cs @@ -17,6 +17,11 @@ internal class CSharpAliasAmbiguousTypeCodeFixProvider : AbstractAliasAmbiguousT /// private const string CS0104 = nameof(CS0104); + [ImportingConstructor] + public CSharpAliasAmbiguousTypeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0104); diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs index 9c4a59bc8fb54..6c4fa20636e66 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class CSharpFeaturesResources { @@ -394,6 +394,15 @@ internal static string conversion_operator { } } + /// + /// Looks up a localized string similar to Convert switch statement to expression. + /// + internal static string Convert_switch_statement_to_expression { + get { + return ResourceManager.GetString("Convert_switch_statement_to_expression", resourceCulture); + } + } + /// /// Looks up a localized string similar to Convert to 'for'. /// @@ -1159,6 +1168,15 @@ internal static string Sort_accessibility_modifiers { } } + /// + /// Looks up a localized string similar to &Sort Usings. + /// + internal static string Sort_Usings { + get { + return ResourceManager.GetString("Sort_Usings", resourceCulture); + } + } + /// /// Looks up a localized string similar to struct. /// @@ -1350,6 +1368,15 @@ internal static string Use_is_null_check { } } + /// + /// Looks up a localized string similar to Use 'switch' expression. + /// + internal static string Use_switch_expression { + get { + return ResourceManager.GetString("Use_switch_expression", resourceCulture); + } + } + /// /// Looks up a localized string similar to use 'var' instead of explicit type. /// diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx index c4fb759a0ef10..57deeae65bf63 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx @@ -599,4 +599,13 @@ Make 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + &Sort Usings + + + Convert switch statement to expression + + + Use 'switch' expression + diff --git a/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs b/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs index 4155724610f34..2a02a2c801b1f 100644 --- a/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs +++ b/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs @@ -72,6 +72,11 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ SyntaxKind.ParenthesizedLambdaExpression, SyntaxKind.SimpleLambdaExpression); + [ImportingConstructor] + public CSharpChangeSignatureService() + { + } + public override async Task<(ISymbol symbol, int selectedIndex)> GetInvocationSymbolAsync( Document document, int position, bool restrictToDeclarations, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs index 67f40a7906c18..d17ae736a6fa9 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs @@ -35,6 +35,11 @@ internal class CSharpAddAwaitCodeFixProvider : AbstractAddAwaitCodeFixProvider /// private const string CS0029 = nameof(CS0029); + [ImportingConstructor] + public CSharpAddAwaitCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0029, CS4014, CS4016); protected override async Task GetDescriptionAndNodeAsync( diff --git a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpConvertToAsyncMethodCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpConvertToAsyncMethodCodeFixProvider.cs index c94d9e2987bbf..5a658e0852750 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpConvertToAsyncMethodCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpConvertToAsyncMethodCodeFixProvider.cs @@ -20,6 +20,11 @@ internal class CSharpConvertToAsyncMethodCodeFixProvider : AbstractChangeToAsync /// private const string CS4008 = nameof(CS4008); + [ImportingConstructor] + public CSharpConvertToAsyncMethodCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS4008); } diff --git a/src/Features/CSharp/Portable/CodeFixes/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider.cs index 9a96f2ab575e7..28a99a1d055b2 100644 --- a/src/Features/CSharp/Portable/CodeFixes/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider.cs @@ -19,6 +19,11 @@ internal class CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStri { private const string CS8361 = nameof(CS8361); //A conditional expression cannot be used directly in a string interpolation because the ':' ends the interpolation.Parenthesize the conditional expression. + [ImportingConstructor] + public CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider() + { + } + // CS8361 is a syntax error and it is unlikely that there is more than one CS8361 at a time. public override FixAllProvider GetFixAllProvider() => null; diff --git a/src/Features/CSharp/Portable/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs index e95d519aeacf6..09983b06698cf 100644 --- a/src/Features/CSharp/Portable/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs @@ -29,6 +29,7 @@ internal class CSharpFixReturnTypeCodeFixProvider : SyntaxEditorBasedCodeFixProv // error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create("CS0127", "CS1997", "CS0201"); + [ImportingConstructor] public CSharpFixReturnTypeCodeFixProvider() : base(supportsFixAll: false) { diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs index ebfa9cd64d75d..4bc0652ce7e6b 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs @@ -20,6 +20,11 @@ internal class GenerateEnumMemberCodeFixProvider : AbstractGenerateMemberCodeFix { private const string CS0117 = nameof(CS0117); // error CS0117: 'Color' does not contain a definition for 'Red' + [ImportingConstructor] + public GenerateEnumMemberCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS0117); } diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs index f61f5ba1fcffc..f52db0a03b3e8 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs @@ -22,6 +22,11 @@ internal class GenerateConversionCodeFixProvider : AbstractGenerateMemberCodeFix private const string CS0029 = nameof(CS0029); // error CS0029: Cannot implicitly convert type 'type' to 'type' private const string CS0030 = nameof(CS0030); // error CS0030: Cannot convert type 'type' to 'type' + [ImportingConstructor] + public GenerateConversionCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS0029, CS0030); } diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs index b49ac42a8ed43..fb3d48735d741 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs @@ -20,6 +20,11 @@ internal class GenerateDeconstructMethodCodeFixProvider : CodeFixProvider { private const string CS8129 = nameof(CS8129); // No suitable Deconstruct instance or extension method was found... + [ImportingConstructor] + public GenerateDeconstructMethodCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS8129); public override FixAllProvider GetFixAllProvider() diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs index 2c98ef1b2597b..ac35c4869edad 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs @@ -54,6 +54,11 @@ internal static class GenerateMethodDiagnosticIds [ExtensionOrder(After = PredefinedCodeFixProviderNames.GenerateEnumMember, Before = PredefinedCodeFixProviderNames.PopulateSwitch)] internal class GenerateMethodCodeFixProvider : AbstractGenerateMemberCodeFixProvider { + [ImportingConstructor] + public GenerateMethodCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = GenerateMethodDiagnosticIds.FixableDiagnosticIds; diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs index 40cff496eb63b..e956fc6e2995d 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs @@ -28,6 +28,11 @@ internal class GenerateTypeCodeFixProvider : AbstractGenerateMemberCodeFixProvid private const string CS0426 = nameof(CS0426); // error CS0426: The type name 'S' does not exist in the type 'Program' private const string CS0616 = nameof(CS0616); // error CS0616: 'x' is not an attribute class + [ImportingConstructor] + public GenerateTypeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS0103, CS0117, CS0234, CS0246, CS0305, CS0308, CS0426, CS0616, IDEDiagnosticIds.UnboundIdentifierId); } diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs index 3944a0dadc940..c01db183e3481 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs @@ -15,6 +15,11 @@ internal partial class HideBaseCodeFixProvider : CodeFixProvider { internal const string CS0108 = nameof(CS0108); // 'SomeClass.SomeMember' hides inherited member 'SomeClass.SomeMember'. Use the new keyword if hiding was intended. + [ImportingConstructor] + public HideBaseCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0108); public override FixAllProvider GetFixAllProvider() diff --git a/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpAddYieldCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpAddYieldCodeFixProvider.cs index 8339ba77ff412..248ea98b1c63f 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpAddYieldCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpAddYieldCodeFixProvider.cs @@ -30,6 +30,11 @@ internal class CSharpAddYieldCodeFixProvider : AbstractIteratorCodeFixProvider /// private const string CS0266 = nameof(CS0266); + [ImportingConstructor] + public CSharpAddYieldCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS0029, CS0266); } diff --git a/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpChangeToIEnumerableCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpChangeToIEnumerableCodeFixProvider.cs index f99faff036224..11f3fe697c31e 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpChangeToIEnumerableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Iterator/CSharpChangeToIEnumerableCodeFixProvider.cs @@ -25,6 +25,11 @@ internal class CSharpChangeToIEnumerableCodeFixProvider : AbstractIteratorCodeFi /// private const string CS1624 = nameof(CS1624); + [ImportingConstructor] + public CSharpChangeToIEnumerableCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS1624); } diff --git a/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs index 8921617b34b95..5c4e2b7bef880 100644 --- a/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.MakeStatementAsynchronous [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.MakeStatementAsynchronous), Shared] internal class CSharpMakeStatementAsynchronousCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpMakeStatementAsynchronousCodeFixProvider() + { + } + // error CS8414: foreach statement cannot operate on variables of type 'IAsyncEnumerable' because 'IAsyncEnumerable' does not contain a public instance definition for 'GetEnumerator'. Did you mean 'await foreach'? // error CS8418: 'IAsyncDisposable': type used in a using statement must be implicitly convertible to 'System.IDisposable'. Did you mean 'await using' rather than 'using'? public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create("CS8414", "CS8418"); diff --git a/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs index 7a3a96e2c5691..a985926854a6d 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.DeclareAsNullable [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.DeclareAsNullable), Shared] internal class CSharpDeclareAsNullableCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpDeclareAsNullableCodeFixProvider() + { + } + // warning CS8603: Possible null reference return. // warning CS8600: Converting null literal or possible null value to non-nullable type. public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create("CS8603", "CS8600"); diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.cs index 9fd0e5e6916fc..f75bdc1563505 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.cs @@ -24,6 +24,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.RemoveUnnecessaryCast [ExtensionOrder(After = PredefinedCodeFixProviderNames.ImplementInterface)] internal partial class RemoveUnnecessaryCastCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public RemoveUnnecessaryCastCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.RemoveUnnecessaryCastDiagnosticId); diff --git a/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs index a6d0a256c867f..dc91152a8f1bb 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs @@ -18,6 +18,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.Suppression [ExportSuppressionFixProvider(PredefinedCodeFixProviderNames.Suppression, LanguageNames.CSharp), Shared] internal class CSharpSuppressionCodeFixProvider : AbstractSuppressionCodeFixProvider { + [ImportingConstructor] + public CSharpSuppressionCodeFixProvider() + { + } + protected override SyntaxTriviaList CreatePragmaRestoreDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine) { var restoreKeyword = SyntaxFactory.Token(SyntaxKind.RestoreKeyword); diff --git a/src/Features/CSharp/Portable/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs index ef6cf268904fe..e1561cf45b27c 100644 --- a/src/Features/CSharp/Portable/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseInterpolatedVerbatimString [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal partial class CSharpUseInterpolatedVerbatimStringCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpUseInterpolatedVerbatimStringCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create("CS8401"); diff --git a/src/Features/CSharp/Portable/CodeLens/CSharpCodeLensDisplayInfoService.cs b/src/Features/CSharp/Portable/CodeLens/CSharpCodeLensDisplayInfoService.cs index 0353a27fada94..3c0c329233de7 100644 --- a/src/Features/CSharp/Portable/CodeLens/CSharpCodeLensDisplayInfoService.cs +++ b/src/Features/CSharp/Portable/CodeLens/CSharpCodeLensDisplayInfoService.cs @@ -15,6 +15,11 @@ internal sealed class CSharpCodeLensDisplayInfoService : ICodeLensDisplayInfoSer SymbolDisplayFormat.CSharpErrorMessageFormat.RemoveMemberOptions( SymbolDisplayMemberOptions.IncludeExplicitInterface); + [ImportingConstructor] + public CSharpCodeLensDisplayInfoService() + { + } + /// /// Returns the node that should be displayed /// diff --git a/src/Features/CSharp/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.cs index 05250e3ecceb7..0ff47b07ab37f 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.AddAwait [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.AddAwait), Shared] internal partial class CSharpAddAwaitCodeRefactoringProvider : AbstractAddAwaitCodeRefactoringProvider { + [ImportingConstructor] + public CSharpAddAwaitCodeRefactoringProvider() + { + } + protected override string GetTitle() => CSharpFeaturesResources.Add_await; diff --git a/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs index caa0fb8ece956..dfd20d1a0b58a 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs @@ -26,6 +26,11 @@ internal sealed class CSharpConvertLocalFunctionToMethodCodeRefactoringProvider private static readonly SyntaxAnnotation s_delegateToReplaceAnnotation = new SyntaxAnnotation(); private static readonly SyntaxGenerator s_generator = CSharpSyntaxGenerator.Instance; + [ImportingConstructor] + public CSharpConvertLocalFunctionToMethodCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/CSharp/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs index 9225b708cc5a9..2b8d63b0da936 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs @@ -29,6 +29,11 @@ internal partial class InlineTemporaryCodeRefactoringProvider : CodeRefactoringP internal static readonly SyntaxAnnotation InitializerAnnotation = new SyntaxAnnotation(); internal static readonly SyntaxAnnotation ExpressionToInlineAnnotation = new SyntaxAnnotation(); + [ImportingConstructor] + public InlineTemporaryCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/CSharp/Portable/CodeRefactorings/MoveType/CSharpMoveTypeService.cs b/src/Features/CSharp/Portable/CodeRefactorings/MoveType/CSharpMoveTypeService.cs index 258568edf93c8..e88b9f7d9a78c 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/MoveType/CSharpMoveTypeService.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/MoveType/CSharpMoveTypeService.cs @@ -11,5 +11,9 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.MoveType internal class CSharpMoveTypeService : AbstractMoveTypeService { + [ImportingConstructor] + public CSharpMoveTypeService() + { + } } } diff --git a/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpChangeNamespaceService.cs b/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpChangeNamespaceService.cs index 2fcb30053e365..b092e5e94c691 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpChangeNamespaceService.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpChangeNamespaceService.cs @@ -23,6 +23,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ChangeNamespace internal sealed class CSharpChangeNamespaceService : AbstractChangeNamespaceService { + [ImportingConstructor] + public CSharpChangeNamespaceService() + { + } + protected override async Task> GetValidContainersFromAllLinkedDocumentsAsync( Document document, SyntaxNode container, diff --git a/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpSyncNamespaceCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpSyncNamespaceCodeRefactoringProvider.cs index fb964d9261bd0..638449848139e 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpSyncNamespaceCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/SyncNamespace/CSharpSyncNamespaceCodeRefactoringProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.SyncNamespace internal sealed class CSharpSyncNamespaceCodeRefactoringProvider : AbstractSyncNamespaceCodeRefactoringProvider { + [ImportingConstructor] + public CSharpSyncNamespaceCodeRefactoringProvider() + { + } + protected override async Task TryGetApplicableInvocationNodeAsync(Document document, TextSpan span, CancellationToken cancellationToken) { if (!span.IsEmpty) diff --git a/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseExplicitTypeCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseExplicitTypeCodeRefactoringProvider.cs index 91c246530b45e..7c70ae670238e 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseExplicitTypeCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseExplicitTypeCodeRefactoringProvider.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.UseExplicitType [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.UseExplicitType), Shared] internal class UseExplicitTypeCodeRefactoringProvider : AbstractUseTypeCodeRefactoringProvider { + [ImportingConstructor] + public UseExplicitTypeCodeRefactoringProvider() + { + } + protected override string Title => CSharpFeaturesResources.Use_explicit_type; diff --git a/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseImplicitTypeCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseImplicitTypeCodeRefactoringProvider.cs index b90008f7944cd..75cadd61f5cc6 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseImplicitTypeCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/UseExplicitOrImplicitType/UseImplicitTypeCodeRefactoringProvider.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.UseImplicitType [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.UseImplicitType), Shared] internal partial class UseImplicitTypeCodeRefactoringProvider : AbstractUseTypeCodeRefactoringProvider { + [ImportingConstructor] + public UseImplicitTypeCodeRefactoringProvider() + { + } + protected override string Title => CSharpFeaturesResources.Use_implicit_type; diff --git a/src/Features/CSharp/Portable/CommentSelection/CSharpCommentSelectionService.cs b/src/Features/CSharp/Portable/CommentSelection/CSharpCommentSelectionService.cs index f9cc15ab6bf92..02165b722f5e7 100644 --- a/src/Features/CSharp/Portable/CommentSelection/CSharpCommentSelectionService.cs +++ b/src/Features/CSharp/Portable/CommentSelection/CSharpCommentSelectionService.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.CommentSelection [ExportLanguageService(typeof(ICommentSelectionService), LanguageNames.CSharp), Shared] internal class CSharpCommentSelectionService : AbstractCommentSelectionService { + [ImportingConstructor] + public CSharpCommentSelectionService() + { + } + public override string SingleLineCommentString => "//"; public override bool SupportsBlockComment => true; public override string BlockCommentStartString => "/*"; diff --git a/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs b/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs index a8fc581087768..cfb943680f91e 100644 --- a/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs +++ b/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion [ExportLanguageServiceFactory(typeof(CompletionService), LanguageNames.CSharp), Shared] internal class CSharpCompletionServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpCompletionServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) { return new CSharpCompletionService(languageServices.WorkspaceServices.Workspace); diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs index 793aa76c2ac60..d58a8d9e31a63 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs @@ -43,7 +43,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) IEnumerable members = semanticModel.LookupSymbols(position, type); members = members.Where(m => m.CanBeReferencedByName && IsFieldOrReadableProperty(m) && - !m.IsImplicitlyDeclared && + !m.IsImplicitlyDeclared && !m.IsStatic); // Filter out those members that have already been typed diff --git a/src/Features/CSharp/Portable/Completion/SuggestionMode/CSharpSuggestionModeCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/SuggestionMode/CSharpSuggestionModeCompletionProvider.cs index 13917090855f1..a801fc0daa0eb 100644 --- a/src/Features/CSharp/Portable/Completion/SuggestionMode/CSharpSuggestionModeCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/SuggestionMode/CSharpSuggestionModeCompletionProvider.cs @@ -81,17 +81,6 @@ protected override async Task GetSuggestionModeItemAsync( return null; } - private bool IsImplicitArrayCreation(SemanticModel semanticModel, SyntaxToken token, int position, ITypeInferenceService typeInferrer, CancellationToken cancellationToken) - { - if (token.IsKind(SyntaxKind.NewKeyword) && token.Parent.IsKind(SyntaxKind.ObjectCreationExpression)) - { - var type = typeInferrer.InferType(semanticModel, token.Parent, objectAsDefault: false, cancellationToken: cancellationToken); - return type != null && type is IArrayTypeSymbol; - } - - return false; - } - private bool IsAnonymousObjectCreation(SyntaxToken token) { if (token.Parent is AnonymousObjectCreationExpressionSyntax) diff --git a/src/Features/CSharp/Portable/ConflictMarkerResolution/CSharpResolveConflictMarkerCodeFixProvider.cs b/src/Features/CSharp/Portable/ConflictMarkerResolution/CSharpResolveConflictMarkerCodeFixProvider.cs index d7b25f8cc97b1..52ef99ace8beb 100644 --- a/src/Features/CSharp/Portable/ConflictMarkerResolution/CSharpResolveConflictMarkerCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ConflictMarkerResolution/CSharpResolveConflictMarkerCodeFixProvider.cs @@ -11,6 +11,7 @@ internal class CSharpResolveConflictMarkerCodeFixProvider : AbstractResolveConfl { private const string CS8300 = nameof(CS8300); // Merge conflict marker encountered + [ImportingConstructor] public CSharpResolveConflictMarkerCodeFixProvider() : base(CS8300) { diff --git a/src/Features/CSharp/Portable/ConvertAnonymousTypeToClass/CSharpConvertAnonymousTypeToClassCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertAnonymousTypeToClass/CSharpConvertAnonymousTypeToClassCodeRefactoringProvider.cs index 09a39e3fec588..d1419a42357d3 100644 --- a/src/Features/CSharp/Portable/ConvertAnonymousTypeToClass/CSharpConvertAnonymousTypeToClassCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertAnonymousTypeToClass/CSharpConvertAnonymousTypeToClassCodeRefactoringProvider.cs @@ -18,6 +18,11 @@ internal class CSharpConvertAnonymousTypeToClassCodeRefactoringProvider : AnonymousObjectCreationExpressionSyntax, NamespaceDeclarationSyntax> { + [ImportingConstructor] + public CSharpConvertAnonymousTypeToClassCodeRefactoringProvider() + { + } + protected override ObjectCreationExpressionSyntax CreateObjectCreationExpression( NameSyntax nameNode, AnonymousObjectCreationExpressionSyntax anonymousObject) { diff --git a/src/Features/CSharp/Portable/ConvertAnonymousTypeToTuple/CSharpConvertAnonymousTypeToTupleCodeFixProvider.cs b/src/Features/CSharp/Portable/ConvertAnonymousTypeToTuple/CSharpConvertAnonymousTypeToTupleCodeFixProvider.cs index 247768694413c..5891ad6bfbf70 100644 --- a/src/Features/CSharp/Portable/ConvertAnonymousTypeToTuple/CSharpConvertAnonymousTypeToTupleCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ConvertAnonymousTypeToTuple/CSharpConvertAnonymousTypeToTupleCodeFixProvider.cs @@ -16,6 +16,11 @@ internal class CSharpConvertAnonymousTypeToTupleCodeFixProvider TupleExpressionSyntax, AnonymousObjectCreationExpressionSyntax> { + [ImportingConstructor] + public CSharpConvertAnonymousTypeToTupleCodeFixProvider() + { + } + protected override TupleExpressionSyntax ConvertToTuple(AnonymousObjectCreationExpressionSyntax anonCreation) => SyntaxFactory.TupleExpression( SyntaxFactory.Token(SyntaxKind.OpenParenToken).WithTriviaFrom(anonCreation.OpenBraceToken), diff --git a/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs index d8f0eefea0457..ebf6683b2a482 100644 --- a/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs @@ -25,6 +25,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertAutoPropertyToFullProperty [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider)), Shared] internal class CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider : AbstractConvertAutoPropertyToFullPropertyCodeRefactoringProvider { + [ImportingConstructor] + public CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider() + { + } + internal override SyntaxNode GetProperty(SyntaxToken token) { var containingProperty = token.Parent.FirstAncestorOrSelf(); diff --git a/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs index d5e6288e0c32a..d3857528f9a4e 100644 --- a/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs @@ -18,6 +18,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertForEachToFor internal sealed class CSharpConvertForEachToForCodeRefactoringProvider : AbstractConvertForEachToForCodeRefactoringProvider { + [ImportingConstructor] + public CSharpConvertForEachToForCodeRefactoringProvider() + { + } + protected override string Title => CSharpFeaturesResources.Convert_to_for; protected override ForEachStatementSyntax GetForEachStatement(TextSpan selection, SyntaxToken token) diff --git a/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs index 9e3315198bc34..aa3b9c19703bf 100644 --- a/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs @@ -23,6 +23,11 @@ internal class CSharpConvertForToForEachCodeRefactoringProvider : TypeSyntax, VariableDeclaratorSyntax> { + [ImportingConstructor] + public CSharpConvertForToForEachCodeRefactoringProvider() + { + } + protected override string GetTitle() => CSharpFeaturesResources.Convert_to_foreach; diff --git a/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs index bd463feaf7fb3..f8d33df459513 100644 --- a/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertIfToSwitch [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(CSharpConvertIfToSwitchCodeRefactoringProvider)), Shared] internal sealed partial class CSharpConvertIfToSwitchCodeRefactoringProvider : AbstractConvertIfToSwitchCodeRefactoringProvider { + [ImportingConstructor] + public CSharpConvertIfToSwitchCodeRefactoringProvider() + { + } + protected override IAnalyzer CreateAnalyzer(ISyntaxFactsService syntaxFacts, SemanticModel semanticModel) => new CSharpAnalyzer(syntaxFacts, semanticModel); diff --git a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs index 2d9c6ba5c6dfb..76ba1e663fd9a 100644 --- a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs +++ b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs @@ -25,6 +25,11 @@ internal sealed class CSharpConvertLinqQueryToForEachProvider : AbstractConvertL { private static readonly TypeSyntax VarNameIdentifier = SyntaxFactory.IdentifierName("var"); + [ImportingConstructor] + public CSharpConvertLinqQueryToForEachProvider() + { + } + protected override string Title => CSharpFeaturesResources.Convert_to_foreach; protected override bool TryConvert( diff --git a/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs b/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs index 5e75b1b64a1e1..12ca702b8cded 100644 --- a/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs +++ b/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertLinq.ConvertForEachToLinqQuery internal sealed class CSharpConvertForEachToLinqQueryProvider : AbstractConvertForEachToLinqQueryProvider { + [ImportingConstructor] + public CSharpConvertForEachToLinqQueryProvider() + { + } + protected override IConverter CreateDefaultConverter( ForEachInfo forEachInfo) => new DefaultConverter(forEachInfo); diff --git a/src/Features/CSharp/Portable/ConvertNumericLiteral/CSharpConvertNumericLiteralCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertNumericLiteral/CSharpConvertNumericLiteralCodeRefactoringProvider.cs index 24d8b56283bec..4b0d4060be812 100644 --- a/src/Features/CSharp/Portable/ConvertNumericLiteral/CSharpConvertNumericLiteralCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertNumericLiteral/CSharpConvertNumericLiteralCodeRefactoringProvider.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertNumericLiteral [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(CSharpConvertNumericLiteralCodeRefactoringProvider)), Shared] internal sealed class CSharpConvertNumericLiteralCodeRefactoringProvider : AbstractConvertNumericLiteralCodeRefactoringProvider { + [ImportingConstructor] + public CSharpConvertNumericLiteralCodeRefactoringProvider() + { + } + protected override (string hexPrefix, string binaryPrefix) GetNumericLiteralPrefixes() => (hexPrefix: "0x", binaryPrefix: "0b"); } } diff --git a/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.Rewriter.cs b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.Rewriter.cs new file mode 100644 index 0000000000000..badcdcb27c85b --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.Rewriter.cs @@ -0,0 +1,282 @@ +// 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.Diagnostics; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.CSharp.ConvertSwitchStatementToExpression +{ + using static SyntaxFactory; + + internal sealed partial class ConvertSwitchStatementToExpressionCodeFixProvider + { + private sealed class Rewriter : CSharpSyntaxVisitor + { + private ExpressionSyntax _assignmentTargetOpt; + private readonly bool _isAllThrowStatements; + + private Rewriter(bool isAllThrowStatements) + { + _isAllThrowStatements = isAllThrowStatements; + } + + public static StatementSyntax Rewrite( + SwitchStatementSyntax switchStatement, SemanticModel semanticModel, SyntaxEditor editor, + SyntaxKind nodeToGenerate, bool shouldMoveNextStatementToSwitchExpression) + { + var rewriter = new Rewriter(isAllThrowStatements: nodeToGenerate == SyntaxKind.ThrowStatement); + + // Rewrite the switch statement as a switch expression. + var switchExpression = rewriter.RewriteSwitchStatement(switchStatement, + allowMoveNextStatementToSwitchExpression: shouldMoveNextStatementToSwitchExpression); + + // Only on simple assignments we attempt to remove variable declarators. + var isSimpleAssignment = nodeToGenerate == SyntaxKind.SimpleAssignmentExpression; + var generateDeclaration = isSimpleAssignment && rewriter.TryRemoveVariableDeclarators(switchStatement, semanticModel, editor); + + // Generate the final statement to wrap the switch expression, e.g. a "return" or an assignment. + return rewriter.GetFinalStatement(switchExpression, + switchStatement.SwitchKeyword.LeadingTrivia, nodeToGenerate, generateDeclaration); + } + + private bool TryRemoveVariableDeclarators(SwitchStatementSyntax switchStatement, SemanticModel semanticModel, SyntaxEditor editor) + { + Debug.Assert(_assignmentTargetOpt != null); + + // Try to remove variable declarator only if it's a simple identifier. + if (!_assignmentTargetOpt.IsKind(SyntaxKind.IdentifierName)) + { + return false; + } + + var symbol = semanticModel.GetSymbolInfo(_assignmentTargetOpt).Symbol; + if (symbol == null) + { + return false; + } + + if (symbol.Kind != SymbolKind.Local) + { + return false; + } + + var syntaxReferences = symbol.DeclaringSyntaxReferences; + if (syntaxReferences.Length != 1) + { + return false; + } + + if (!(syntaxReferences[0].GetSyntax() is VariableDeclaratorSyntax declarator)) + { + return false; + } + + if (declarator.Initializer != null) + { + return false; + } + + var symbolName = symbol.Name; + var declaratorSpanStart = declarator.SpanStart; + var switchStatementSpanStart = switchStatement.SpanStart; + + // Check for uses before the switch expression. + foreach (var descendentNode in declarator.GetAncestor().DescendantNodes()) + { + var nodeSpanStart = descendentNode.SpanStart; + if (nodeSpanStart <= declaratorSpanStart) + { + // We haven't yet reached the declarator node. + continue; + } + + if (nodeSpanStart >= switchStatementSpanStart) + { + // We've reached the switch statement. + break; + } + + if (descendentNode.IsKind(SyntaxKind.IdentifierName, out IdentifierNameSyntax identifierName) && + identifierName.Identifier.ValueText == symbolName && + symbol.Equals(semanticModel.GetSymbolInfo(identifierName).Symbol)) + { + // The variable is being used outside the switch statement. + return false; + } + } + + // Safe to remove declarator node. + editor.RemoveNode(symbol.DeclaringSyntaxReferences[0].GetSyntax()); + return true; + } + + private StatementSyntax GetFinalStatement( + ExpressionSyntax switchExpression, + SyntaxTriviaList leadingTrivia, + SyntaxKind nodeToGenerate, + bool generateDeclaration) + { + switch (nodeToGenerate) + { + case SyntaxKind.ReturnStatement: + return ReturnStatement( + Token(leadingTrivia, SyntaxKind.ReturnKeyword, trailing: default), + switchExpression, + Token(SyntaxKind.SemicolonToken)); + case SyntaxKind.ThrowStatement: + return ThrowStatement( + Token(leadingTrivia, SyntaxKind.ThrowKeyword, trailing: default), + switchExpression, + Token(SyntaxKind.SemicolonToken)); + } + + Debug.Assert(SyntaxFacts.IsAssignmentExpression(nodeToGenerate)); + Debug.Assert(_assignmentTargetOpt != null); + + return generateDeclaration + ? GenerateVariableDeclaration(switchExpression, leadingTrivia) + : GenerateAssignment(switchExpression, nodeToGenerate, leadingTrivia); + } + + private ExpressionStatementSyntax GenerateAssignment(ExpressionSyntax switchExpression, SyntaxKind assignmentKind, SyntaxTriviaList leadingTrivia) + { + Debug.Assert(_assignmentTargetOpt != null); + + return ExpressionStatement( + AssignmentExpression(assignmentKind, + left: _assignmentTargetOpt, + right: switchExpression)) + .WithLeadingTrivia(leadingTrivia); + } + + private ExpressionStatementSyntax GenerateVariableDeclaration(ExpressionSyntax switchExpression, SyntaxTriviaList leadingTrivia) + { + Debug.Assert(_assignmentTargetOpt is IdentifierNameSyntax); + return ExpressionStatement( + AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, + left: DeclarationExpression(IdentifierName(Identifier(leadingTrivia, "var", trailing: default)), + SingleVariableDesignation(((IdentifierNameSyntax)_assignmentTargetOpt).Identifier)), + right: switchExpression)); + } + + private SwitchExpressionArmSyntax GetSwitchExpressionArm(SwitchSectionSyntax node) + { + Debug.Assert(node.Labels.Count == 1); + + return SwitchExpressionArm( + pattern: GetPattern(node.Labels[0], out var whenClauseOpt), + whenClause: whenClauseOpt, + expression: RewriteStatements(node.Statements)); + } + + private static PatternSyntax GetPattern(SwitchLabelSyntax switchLabel, out WhenClauseSyntax whenClauseOpt) + { + switch (switchLabel.Kind()) + { + case SyntaxKind.CasePatternSwitchLabel: + var node = (CasePatternSwitchLabelSyntax)switchLabel; + whenClauseOpt = node.WhenClause; + return node.Pattern; + + case SyntaxKind.CaseSwitchLabel: + whenClauseOpt = null; + return ConstantPattern(((CaseSwitchLabelSyntax)switchLabel).Value); + + case SyntaxKind.DefaultSwitchLabel: + whenClauseOpt = null; + return DiscardPattern(); + + case var value: + throw ExceptionUtilities.UnexpectedValue(value); + } + } + + public override ExpressionSyntax VisitAssignmentExpression(AssignmentExpressionSyntax node) + { + if (_assignmentTargetOpt == null) + { + _assignmentTargetOpt = node.Left; + } + + return node.Right; + } + + private ExpressionSyntax RewriteStatements(SyntaxList statements) + { + Debug.Assert(statements.Count == 1 || statements.Count == 2); + Debug.Assert(!statements[0].IsKind(SyntaxKind.BreakStatement)); + return Visit(statements[0]); + } + + public override ExpressionSyntax VisitSwitchStatement(SwitchStatementSyntax node) + { + return RewriteSwitchStatement(node); + } + + private ExpressionSyntax RewriteSwitchStatement(SwitchStatementSyntax node, bool allowMoveNextStatementToSwitchExpression = true) + { + var switchArms = node.Sections + // The default label must come last in the switch expression. + .OrderBy(section => section.Labels[0].IsKind(SyntaxKind.DefaultSwitchLabel)) + .Select(s => + (leadingTrivia: s.Labels[0].GetFirstToken().LeadingTrivia, + trailingTrivia: s.Statements[0].GetLastToken().TrailingTrivia, + armExpression: GetSwitchExpressionArm(s))) + .ToList(); + + // This is possibly false only on the top-level switch statement. + // On nested nodes, if there's a subsequent statement, it is most definitely a + // "return" or "throw" which is already validated in the analysis phase. + if (allowMoveNextStatementToSwitchExpression) + { + var nextStatement = node.GetNextStatement(); + if (nextStatement != null) + { + Debug.Assert(nextStatement.IsKind(SyntaxKind.ThrowStatement, SyntaxKind.ReturnStatement)); + switchArms.Add( + (nextStatement.GetFirstToken().LeadingTrivia, + nextStatement.GetLastToken().TrailingTrivia, + SwitchExpressionArm(DiscardPattern(), Visit(nextStatement)))); + } + } + + return SwitchExpression( + node.Expression, + Token(leading: default, SyntaxKind.SwitchKeyword, node.CloseParenToken.TrailingTrivia), + Token(SyntaxKind.OpenBraceToken), + SeparatedList( + switchArms.Select(t => t.armExpression.WithLeadingTrivia(t.leadingTrivia)), + switchArms.Select(t => Token(leading: default, SyntaxKind.CommaToken, t.trailingTrivia))), + Token(SyntaxKind.CloseBraceToken)); + } + + public override ExpressionSyntax VisitReturnStatement(ReturnStatementSyntax node) + { + Debug.Assert(node.Expression != null); + return node.Expression; + } + + public override ExpressionSyntax VisitThrowStatement(ThrowStatementSyntax node) + { + Debug.Assert(node.Expression != null); + // If this is an all-throw switch statement, we return the expression rather than + // creating a throw expression so we can wrap the switch expression inside a throw expression. + return _isAllThrowStatements ? node.Expression : ThrowExpression(node.Expression); + } + + public override ExpressionSyntax VisitExpressionStatement(ExpressionStatementSyntax node) + { + return Visit(node.Expression); + } + + public override ExpressionSyntax DefaultVisit(SyntaxNode node) + { + throw ExceptionUtilities.UnexpectedValue(node.Kind()); + } + } + } +} diff --git a/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs new file mode 100644 index 0000000000000..3949f16cde96a --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs @@ -0,0 +1,91 @@ +// 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.Immutable; +using System.Composition; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.CSharp.ConvertSwitchStatementToExpression +{ + using Constants = ConvertSwitchStatementToExpressionConstants; + + [ExportCodeFixProvider(LanguageNames.CSharp), Shared] + internal sealed partial class ConvertSwitchStatementToExpressionCodeFixProvider : SyntaxEditorBasedCodeFixProvider + { + public override ImmutableArray FixableDiagnosticIds + => ImmutableArray.Create(IDEDiagnosticIds.ConvertSwitchStatementToExpressionDiagnosticId); + + public override Task RegisterCodeFixesAsync(CodeFixContext context) + { + context.RegisterCodeFix( + new MyCodeAction(c => FixAsync(context.Document, context.Diagnostics.First(), c)), + context.Diagnostics); + return Task.CompletedTask; + } + + protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) + { + var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var spans = ArrayBuilder.GetInstance(diagnostics.Length); + try + { + foreach (var diagnostic in diagnostics) + { + cancellationToken.ThrowIfCancellationRequested(); + + var span = diagnostic.AdditionalLocations[0].SourceSpan; + if (spans.Any((s, nodeSpan) => s.Contains(nodeSpan), span)) + { + // Skip nested switch expressions in case of a fix-all operation. + continue; + } + + spans.Add(span); + + var properties = diagnostic.Properties; + var nodeToGenerate = (SyntaxKind)int.Parse(properties[Constants.NodeToGenerateKey]); + var shouldRemoveNextStatement = bool.Parse(properties[Constants.ShouldRemoveNextStatementKey]); + + var switchStatement = (SwitchStatementSyntax)editor.OriginalRoot.FindNode(span); + editor.ReplaceNode(switchStatement, + Rewriter.Rewrite(switchStatement, semanticModel, editor, + nodeToGenerate, shouldMoveNextStatementToSwitchExpression: shouldRemoveNextStatement) + .WithAdditionalAnnotations(Formatter.Annotation)); + + if (shouldRemoveNextStatement) + { + // Already morphed into the top-level switch expression. + var nextStatement = switchStatement.GetNextStatement(); + Debug.Assert(nextStatement.IsKind(SyntaxKind.ThrowStatement, SyntaxKind.ReturnStatement)); + editor.RemoveNode(nextStatement); + } + } + } + finally + { + spans.Free(); + } + } + + private sealed class MyCodeAction : CodeAction.DocumentChangeAction + { + public MyCodeAction(Func> createChangedDocument) : + base(CSharpFeaturesResources.Convert_switch_statement_to_expression, createChangedDocument) + { + } + } + } +} diff --git a/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionConstants.cs b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionConstants.cs new file mode 100644 index 0000000000000..164db7a1e0638 --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionConstants.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +namespace Microsoft.CodeAnalysis.CSharp.ConvertSwitchStatementToExpression +{ + internal static class ConvertSwitchStatementToExpressionConstants + { + public const string NodeToGenerateKey = nameof(NodeToGenerateKey); + public const string ShouldRemoveNextStatementKey = nameof(ShouldRemoveNextStatementKey); + } +} diff --git a/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.Analyzer.cs b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.Analyzer.cs new file mode 100644 index 0000000000000..c58b8e191c4a3 --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.Analyzer.cs @@ -0,0 +1,192 @@ +// 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 Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Microsoft.CodeAnalysis.CSharp.ConvertSwitchStatementToExpression +{ + internal sealed partial class ConvertSwitchStatementToExpressionDiagnosticAnalyzer + { + private sealed class Analyzer : CSharpSyntaxVisitor + { + private ExpressionSyntax _assignmentTargetOpt; + + private Analyzer() + { + } + + public static SyntaxKind Analyze(SwitchStatementSyntax node, out bool shouldRemoveNextStatement) + { + return new Analyzer().AnalyzeSwitchStatement(node, out shouldRemoveNextStatement); + } + + private static bool IsDefaultSwitchLabel(SwitchLabelSyntax node) + { + // default: + if (node.IsKind(SyntaxKind.DefaultSwitchLabel)) + { + return true; + } + + if (node.IsKind(SyntaxKind.CasePatternSwitchLabel, out CasePatternSwitchLabelSyntax @case)) + { + // case _: + if (@case.Pattern.IsKind(SyntaxKind.DiscardPattern)) + { + return true; + } + + // case var _: + // case var x: + if (@case.Pattern.IsKind(SyntaxKind.VarPattern, out VarPatternSyntax varPattern) && + varPattern.Designation.IsKind(SyntaxKind.DiscardDesignation, SyntaxKind.SingleVariableDesignation)) + { + return true; + } + } + + return false; + } + + public override SyntaxKind VisitSwitchStatement(SwitchStatementSyntax node) + { + return AnalyzeSwitchStatement(node, out _); + } + + private SyntaxKind AnalyzeSwitchStatement(SwitchStatementSyntax switchStatement, out bool shouldRemoveNextStatement) + { + shouldRemoveNextStatement = false; + + // Fail if the switch statement is empty or any of sections have more than one "case" label. + // Once we have "or" patterns, we can relax this to accept multi-case sections. + var sections = switchStatement.Sections; + if (sections.Count == 0 || sections.Any(section => section.Labels.Count != 1)) + { + return default; + } + + // If there's no "default" case, we look at the next statement. + // For instance, it could be a "return" statement which we'll use + // as the default case in the switch expression. + var nextStatement = AnalyzeNextStatement(switchStatement, ref shouldRemoveNextStatement); + + // We do need to intersect the next statement analysis result to catch possible + // arm kind mismatch, e.g. a "return" after a non-exhaustive assignment switch. + return Aggregate(nextStatement, sections, (result, section) => Intersect(result, AnalyzeSwitchSection(section))); + } + + private SyntaxKind AnalyzeNextStatement(SwitchStatementSyntax switchStatement, ref bool shouldRemoveNextStatement) + { + if (switchStatement.Sections.Any(section => IsDefaultSwitchLabel(section.Labels[0]))) + { + // Throw can be overridden by other section bodies, therefore it has no effect on the result. + return SyntaxKind.ThrowStatement; + } + + shouldRemoveNextStatement = true; + return AnalyzeNextStatement(switchStatement.GetNextStatement()); + } + + private static SyntaxKind Intersect(SyntaxKind left, SyntaxKind right) + { + if (left == SyntaxKind.ThrowStatement) + { + return right; + } + + if (right == SyntaxKind.ThrowStatement) + { + return left; + } + + if (left == right) + { + return left; + } + + return default; + } + + private SyntaxKind AnalyzeNextStatement(StatementSyntax nextStatement) + { + // Only the following "throw" and "return" can be moved into the switch expression. + return nextStatement.IsKind(SyntaxKind.ThrowStatement, SyntaxKind.ReturnStatement) + ? Visit(nextStatement) + : default; + } + + private SyntaxKind AnalyzeSwitchSection(SwitchSectionSyntax section) + { + switch (section.Statements.Count) + { + case 1: + case 2 when section.Statements[1].IsKind(SyntaxKind.BreakStatement): + return Visit(section.Statements[0]); + default: + return default; + } + } + + private static SyntaxKind Aggregate(SyntaxKind seed, SyntaxList nodes, Func func) + where T : SyntaxNode + { + var result = seed; + foreach (var node in nodes) + { + result = func(result, node); + if (result == default) + { + // No point to continue if any node was not + // convertible to a switch arm's expression + break; + } + } + + return result; + } + + public override SyntaxKind VisitAssignmentExpression(AssignmentExpressionSyntax node) + { + if (_assignmentTargetOpt != null) + { + if (!SyntaxFactory.AreEquivalent(node.Left, _assignmentTargetOpt)) + { + return default; + } + } + else + { + _assignmentTargetOpt = node.Left; + } + + return node.Kind(); + } + + public override SyntaxKind VisitExpressionStatement(ExpressionStatementSyntax node) + { + return Visit(node.Expression); + } + + public override SyntaxKind VisitReturnStatement(ReturnStatementSyntax node) + { + // A "return" statement's expression will be placed in the switch arm expression. + return node.Expression is null ? default : SyntaxKind.ReturnStatement; + } + + public override SyntaxKind VisitThrowStatement(ThrowStatementSyntax node) + { + // A "throw" statement can be converted to a throw expression. + // Gives Failure if Expression is null because a throw expression needs one. + return node.Expression is null ? default : SyntaxKind.ThrowStatement; + } + + public override SyntaxKind DefaultVisit(SyntaxNode node) + { + // In all other cases we return failure result. + return default; + } + } + } +} diff --git a/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.cs new file mode 100644 index 0000000000000..74fd2618627d3 --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionDiagnosticAnalyzer.cs @@ -0,0 +1,79 @@ +// 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.Globalization; +using System.Linq; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Microsoft.CodeAnalysis.CSharp.ConvertSwitchStatementToExpression +{ + using Constants = ConvertSwitchStatementToExpressionConstants; + + [DiagnosticAnalyzer(LanguageNames.CSharp)] + internal sealed partial class ConvertSwitchStatementToExpressionDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer + { + public ConvertSwitchStatementToExpressionDiagnosticAnalyzer() + : base(IDEDiagnosticIds.ConvertSwitchStatementToExpressionDiagnosticId, + new LocalizableResourceString(nameof(CSharpFeaturesResources.Convert_switch_statement_to_expression), CSharpFeaturesResources.ResourceManager, typeof(CSharpFeaturesResources)), + new LocalizableResourceString(nameof(CSharpFeaturesResources.Use_switch_expression), CSharpFeaturesResources.ResourceManager, typeof(CSharpFeaturesResources))) + { + } + + protected override void InitializeWorker(AnalysisContext context) + => context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.SwitchStatement); + + private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) + { + var switchStatement = context.Node; + var syntaxTree = switchStatement.SyntaxTree; + + if (((CSharpParseOptions)syntaxTree.Options).LanguageVersion < LanguageVersion.CSharp8) + { + return; + } + + var options = context.Options; + var cancellationToken = context.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + + var styleOption = optionSet.GetOption(CSharpCodeStyleOptions.PreferSwitchExpression); + if (!styleOption.Value) + { + // User has disabled this feature. + return; + } + + if (switchStatement.GetDiagnostics().Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)) + { + return; + } + + var nodeToGenerate = Analyzer.Analyze((SwitchStatementSyntax)switchStatement, out var shouldRemoveNextStatement); + if (nodeToGenerate == default) + { + return; + } + + context.ReportDiagnostic(Diagnostic.Create(Descriptor, + // Report the diagnostic on the "switch" keyword. + location: switchStatement.GetFirstToken().GetLocation(), + additionalLocations: new[] { switchStatement.GetLocation() }, + properties: ImmutableDictionary.Empty + .Add(Constants.NodeToGenerateKey, ((int)nodeToGenerate).ToString(CultureInfo.InvariantCulture)) + .Add(Constants.ShouldRemoveNextStatementKey, shouldRemoveNextStatement.ToString(CultureInfo.InvariantCulture)))); + } + + public override bool OpenFileOnly(Workspace workspace) + => false; + + public override DiagnosticAnalyzerCategory GetAnalyzerCategory() + => DiagnosticAnalyzerCategory.SemanticSpanAnalysis; + } +} diff --git a/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertConcatenationToInterpolatedStringRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertConcatenationToInterpolatedStringRefactoringProvider.cs index 085e67551b82b..f9f3445950e07 100644 --- a/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertConcatenationToInterpolatedStringRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertConcatenationToInterpolatedStringRefactoringProvider.cs @@ -12,6 +12,11 @@ internal class CSharpConvertConcatenationToInterpolatedStringRefactoringProvider { private const string InterpolatedVerbatimText = "$@\""; + [ImportingConstructor] + public CSharpConvertConcatenationToInterpolatedStringRefactoringProvider() + { + } + protected override SyntaxToken CreateInterpolatedStringStartToken(bool isVerbatim) { return isVerbatim diff --git a/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertPlaceholderToInterpolatedStringRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertPlaceholderToInterpolatedStringRefactoringProvider.cs index 57f5327c85687..6ff9d3fa946c1 100644 --- a/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertPlaceholderToInterpolatedStringRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertPlaceholderToInterpolatedStringRefactoringProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertToInterpolatedString internal partial class CSharpConvertPlaceholderToInterpolatedStringRefactoringProvider : AbstractConvertPlaceholderToInterpolatedStringRefactoringProvider { + [ImportingConstructor] + public CSharpConvertPlaceholderToInterpolatedStringRefactoringProvider() + { + } + protected override SyntaxNode GetInterpolatedString(string text) => SyntaxFactory.ParseExpression("$" + text) as InterpolatedStringExpressionSyntax; } diff --git a/src/Features/CSharp/Portable/ConvertTupleToStruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertTupleToStruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs index 53d4aa5deb9d7..4ebb9f7b63da3 100644 --- a/src/Features/CSharp/Portable/ConvertTupleToStruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertTupleToStruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs @@ -22,6 +22,11 @@ internal class CSharpConvertTupleToStructCodeRefactoringProvider : TypeDeclarationSyntax, NamespaceDeclarationSyntax> { + [ImportingConstructor] + public CSharpConvertTupleToStructCodeRefactoringProvider() + { + } + protected override ObjectCreationExpressionSyntax CreateObjectCreationExpression( NameSyntax nameNode, SyntaxToken openParen, SeparatedSyntaxList arguments, SyntaxToken closeParen) { diff --git a/src/Features/CSharp/Portable/DesignerAttributes/CSharpDesignerAttributeService.cs b/src/Features/CSharp/Portable/DesignerAttributes/CSharpDesignerAttributeService.cs index 7c51a04ef2ad4..cb1d2b3c360f4 100644 --- a/src/Features/CSharp/Portable/DesignerAttributes/CSharpDesignerAttributeService.cs +++ b/src/Features/CSharp/Portable/DesignerAttributes/CSharpDesignerAttributeService.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.CSharp.DesignerAttributes [ExportLanguageServiceFactory(typeof(IDesignerAttributeService), LanguageNames.CSharp), Shared] internal class CSharpDesignerAttributeServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpDesignerAttributeServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) => new CSharpDesignerAttributeService(languageServices.WorkspaceServices.Workspace); } diff --git a/src/Features/CSharp/Portable/Diagnostics/CSharpAnalyzerDriverService.cs b/src/Features/CSharp/Portable/Diagnostics/CSharpAnalyzerDriverService.cs index 3bc604604257d..1aa3afac15366 100644 --- a/src/Features/CSharp/Portable/Diagnostics/CSharpAnalyzerDriverService.cs +++ b/src/Features/CSharp/Portable/Diagnostics/CSharpAnalyzerDriverService.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Diagnostics [ExportLanguageService(typeof(IAnalyzerDriverService), LanguageNames.CSharp), Shared] internal sealed class CSharpAnalyzerDriverService : IAnalyzerDriverService { + [ImportingConstructor] + public CSharpAnalyzerDriverService() + { + } + public void ComputeDeclarationsInSpan( SemanticModel model, TextSpan span, diff --git a/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs b/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs index d102c6487e610..2fe3b630f2af0 100644 --- a/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs +++ b/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.CSharp.DocumentHighlighting [ExportLanguageService(typeof(IDocumentHighlightsService), LanguageNames.CSharp), Shared] internal class CSharpDocumentHighlightsService : AbstractDocumentHighlightsService { + [ImportingConstructor] + public CSharpDocumentHighlightsService() + { + } + protected override async Task> GetAdditionalReferencesAsync( Document document, ISymbol symbol, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs b/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs index c084f4febfa95..b27a58ea84531 100644 --- a/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs +++ b/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs @@ -9,5 +9,9 @@ namespace Microsoft.CodeAnalysis.CSharp.DocumentationComments [ExportLanguageService(typeof(IDocumentationCommentFormattingService), LanguageNames.CSharp), Shared] internal class CSharpDocumentationCommentFormattingService : AbstractDocumentationCommentFormattingService { + [ImportingConstructor] + public CSharpDocumentationCommentFormattingService() + { + } } } diff --git a/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpAddDocCommentNodesCodeFixProvider.cs b/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpAddDocCommentNodesCodeFixProvider.cs index cbfc12c099cde..68dffb1f7cb5b 100644 --- a/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpAddDocCommentNodesCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpAddDocCommentNodesCodeFixProvider.cs @@ -21,6 +21,11 @@ internal class CSharpAddDocCommentNodesCodeFixProvider /// private const string CS1573 = nameof(CS1573); + [ImportingConstructor] + public CSharpAddDocCommentNodesCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS1573); protected override string NodeName { get; } = "param"; diff --git a/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpRemoveDocCommentNodeCodeFixProvider.cs b/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpRemoveDocCommentNodeCodeFixProvider.cs index fc7c090077619..1eaae570f8e6a 100644 --- a/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpRemoveDocCommentNodeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/DocumentationComments/CodeFixes/CSharpRemoveDocCommentNodeCodeFixProvider.cs @@ -29,6 +29,11 @@ internal class CSharpRemoveDocCommentNodeCodeFixProvider : /// private const string CS1710 = nameof(CS1710); + [ImportingConstructor] + public CSharpRemoveDocCommentNodeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS1571, CS1572, CS1710); protected override string DocCommentSignifierToken { get; } = "///"; diff --git a/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs b/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs index 34af7b5d52935..147c2b7b894fa 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs @@ -245,7 +245,7 @@ private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken) // event Action P { add [|{|] ... } remove { ... } } // event Action P { [|add;|] [|remove;|] } var @event = (EventDeclarationSyntax)node; - return CreateSpanForAccessors(@event.AccessorList.Accessors, position); + return @event.AccessorList != null ? CreateSpanForAccessors(@event.AccessorList.Accessors, position) : null; case SyntaxKind.BaseConstructorInitializer: case SyntaxKind.ThisConstructorInitializer: diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index e5f993397a88f..1fde7711cb205 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -22,6 +22,10 @@ namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue [ExportLanguageService(typeof(IEditAndContinueAnalyzer), LanguageNames.CSharp), Shared] internal sealed class CSharpEditAndContinueAnalyzer : AbstractEditAndContinueAnalyzer { + [ImportingConstructor] + public CSharpEditAndContinueAnalyzer() + { + } #region Syntax Analysis private enum ConstructorPart diff --git a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpEmbeddedLanguageFeaturesProvider.cs b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpEmbeddedLanguageFeaturesProvider.cs index 733bcb72ebc56..61286b9e0f0b3 100644 --- a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpEmbeddedLanguageFeaturesProvider.cs +++ b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpEmbeddedLanguageFeaturesProvider.cs @@ -13,6 +13,7 @@ internal class CSharpEmbeddedLanguageFeaturesProvider : AbstractEmbeddedLanguage { public static IEmbeddedLanguageFeaturesProvider Instance = new CSharpEmbeddedLanguageFeaturesProvider(); + [ImportingConstructor] public CSharpEmbeddedLanguageFeaturesProvider() : base(CSharpEmbeddedLanguagesProvider.Info) { } diff --git a/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs b/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs index 06bf1ed3d0101..818b683bab4b1 100644 --- a/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs +++ b/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs @@ -23,6 +23,11 @@ namespace Microsoft.CodeAnalysis.CSharp.EncapsulateField [ExportLanguageService(typeof(AbstractEncapsulateFieldService), LanguageNames.CSharp), Shared] internal class CSharpEncapsulateFieldService : AbstractEncapsulateFieldService { + [ImportingConstructor] + public CSharpEncapsulateFieldService() + { + } + protected async override Task RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/ExtractInterface/CSharpExtractInterfaceService.cs b/src/Features/CSharp/Portable/ExtractInterface/CSharpExtractInterfaceService.cs index 66a7bab44f993..937dd236369d0 100644 --- a/src/Features/CSharp/Portable/ExtractInterface/CSharpExtractInterfaceService.cs +++ b/src/Features/CSharp/Portable/ExtractInterface/CSharpExtractInterfaceService.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ExtractInterface [ExportLanguageService(typeof(AbstractExtractInterfaceService), LanguageNames.CSharp), Shared] internal sealed class CSharpExtractInterfaceService : AbstractExtractInterfaceService { + [ImportingConstructor] + public CSharpExtractInterfaceService() + { + } + protected override async Task GetTypeDeclarationAsync(Document document, int position, TypeDiscoveryRule typeDiscoveryRule, CancellationToken cancellationToken) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpSyntaxTriviaServiceFactory.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpSyntaxTriviaServiceFactory.cs index 349d651fd2570..23b88c0de8e28 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpSyntaxTriviaServiceFactory.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpSyntaxTriviaServiceFactory.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ExtractMethod [ExportLanguageServiceFactory(typeof(ISyntaxTriviaService), LanguageNames.CSharp), Shared] internal class CSharpSyntaxTriviaServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpSyntaxTriviaServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices provider) { return new CSharpSyntaxTriviaService(provider); diff --git a/src/Features/CSharp/Portable/FullyQualify/CSharpFullyQualifyCodeFixProvider.cs b/src/Features/CSharp/Portable/FullyQualify/CSharpFullyQualifyCodeFixProvider.cs index 6982e7a0813a8..a56bf5bad7eb8 100644 --- a/src/Features/CSharp/Portable/FullyQualify/CSharpFullyQualifyCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/FullyQualify/CSharpFullyQualifyCodeFixProvider.cs @@ -42,6 +42,11 @@ internal class CSharpFullyQualifyCodeFixProvider : AbstractFullyQualifyCodeFixPr /// private const string CS0308 = nameof(CS0308); + [ImportingConstructor] + public CSharpFullyQualifyCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get { return ImmutableArray.Create(CS0103, CS0104, CS0246, CS0305, CS0308, IDEDiagnosticIds.UnboundIdentifierId); } diff --git a/src/Features/CSharp/Portable/GenerateConstructor/CSharpGenerateConstructorService.cs b/src/Features/CSharp/Portable/GenerateConstructor/CSharpGenerateConstructorService.cs index e324cc0fa7aee..415ac6b6223b0 100644 --- a/src/Features/CSharp/Portable/GenerateConstructor/CSharpGenerateConstructorService.cs +++ b/src/Features/CSharp/Portable/GenerateConstructor/CSharpGenerateConstructorService.cs @@ -21,6 +21,11 @@ internal class CSharpGenerateConstructorService : AbstractGenerateConstructorSer { private static readonly SyntaxAnnotation s_annotation = new SyntaxAnnotation(); + [ImportingConstructor] + public CSharpGenerateConstructorService() + { + } + protected override bool IsSimpleNameGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken) => node is SimpleNameSyntax; diff --git a/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs b/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs index 2e8ec0d9fa0c6..c20e007bc50af 100644 --- a/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs @@ -50,6 +50,11 @@ internal static class GenerateConstructorDiagnosticIds [ExtensionOrder(After = PredefinedCodeFixProviderNames.FullyQualify)] internal class GenerateConstructorCodeFixProvider : AbstractGenerateMemberCodeFixProvider { + [ImportingConstructor] + public GenerateConstructorCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => GenerateConstructorDiagnosticIds.AllDiagnosticIds; protected override Task> GetCodeActionsAsync( diff --git a/src/Features/CSharp/Portable/GenerateEqualsAndGetHashCodeFromMembers/CSharpGenerateEqualsAndGetHashCodeService.cs b/src/Features/CSharp/Portable/GenerateEqualsAndGetHashCodeFromMembers/CSharpGenerateEqualsAndGetHashCodeService.cs index 475c28d652769..09e98893fe570 100644 --- a/src/Features/CSharp/Portable/GenerateEqualsAndGetHashCodeFromMembers/CSharpGenerateEqualsAndGetHashCodeService.cs +++ b/src/Features/CSharp/Portable/GenerateEqualsAndGetHashCodeFromMembers/CSharpGenerateEqualsAndGetHashCodeService.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateEqualsAndGetHashCodeFromMembers [ExportLanguageService(typeof(IGenerateEqualsAndGetHashCodeService), LanguageNames.CSharp), Shared] internal class CSharpGenerateEqualsAndGetHashCodeService : AbstractGenerateEqualsAndGetHashCodeService { + [ImportingConstructor] + public CSharpGenerateEqualsAndGetHashCodeService() + { + } + protected override bool TryWrapWithUnchecked(ImmutableArray statements, out ImmutableArray wrappedStatements) { wrappedStatements = ImmutableArray.Create( diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateDefaultConstructors/CSharpGenerateDefaultConstructorsService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateDefaultConstructors/CSharpGenerateDefaultConstructorsService.cs index ce115bde4e144..9fb77e075f0b4 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateDefaultConstructors/CSharpGenerateDefaultConstructorsService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateDefaultConstructors/CSharpGenerateDefaultConstructorsService.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateMember.GenerateDefaultConstructo [ExportLanguageService(typeof(IGenerateDefaultConstructorsService), LanguageNames.CSharp), Shared] internal class CSharpGenerateDefaultConstructorsService : AbstractGenerateDefaultConstructorsService { + [ImportingConstructor] + public CSharpGenerateDefaultConstructorsService() + { + } + protected override bool TryInitializeState( SemanticDocument semanticDocument, TextSpan textSpan, CancellationToken cancellationToken, out INamedTypeSymbol classType) diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateEnumMember/CSharpGenerateEnumMemberService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateEnumMember/CSharpGenerateEnumMemberService.cs index dbe05a73d502b..86e10fff39c3e 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateEnumMember/CSharpGenerateEnumMemberService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateEnumMember/CSharpGenerateEnumMemberService.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateMember.GenerateEnumMember internal partial class CSharpGenerateEnumMemberService : AbstractGenerateEnumMemberService { + [ImportingConstructor] + public CSharpGenerateEnumMemberService() + { + } + protected override bool IsIdentifierNameGeneration(SyntaxNode node) { return node is IdentifierNameSyntax; diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs index 3dfd731a8ac0c..3e23e3ae9cb84 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateMember.GenerateParameterizedMemb internal partial class CSharpGenerateConversionService : AbstractGenerateConversionService { + [ImportingConstructor] + public CSharpGenerateConversionService() + { + } + protected override bool IsImplicitConversionGeneration(SyntaxNode node) { return node is ExpressionSyntax && diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateDeconstructMethodService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateDeconstructMethodService.cs index 1440f308408ce..854b6d491031b 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateDeconstructMethodService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateDeconstructMethodService.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateMember.GenerateMethod internal sealed class CSharpGenerateDeconstructMethodService : AbstractGenerateDeconstructMethodService { + [ImportingConstructor] + public CSharpGenerateDeconstructMethodService() + { + } + protected override bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol containingType) => containingType.ContainingTypesOrSelfHasUnsafeKeyword(); diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs index a85f19d33ed8c..d5ca8bb0cb246 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateMember.GenerateMethod internal sealed class CSharpGenerateMethodService : AbstractGenerateMethodService { + [ImportingConstructor] + public CSharpGenerateMethodService() + { + } + protected override bool IsExplicitInterfaceGeneration(SyntaxNode node) => node is MethodDeclarationSyntax; diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateVariable/CSharpGenerateVariableService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateVariable/CSharpGenerateVariableService.cs index b2de88db4a8b6..cee9111dced62 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateVariable/CSharpGenerateVariableService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateVariable/CSharpGenerateVariableService.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.CSharp.GenerateMember.GenerateVariable internal partial class CSharpGenerateVariableService : AbstractGenerateVariableService { + [ImportingConstructor] + public CSharpGenerateVariableService() + { + } + protected override bool IsExplicitInterfaceGeneration(SyntaxNode node) => node is PropertyDeclarationSyntax; diff --git a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs index 75213369bc861..93364276842fa 100644 --- a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs +++ b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs @@ -33,6 +33,11 @@ internal class CSharpGenerateTypeService : { private static readonly SyntaxAnnotation s_annotation = new SyntaxAnnotation(); + [ImportingConstructor] + public CSharpGenerateTypeService() + { + } + protected override string DefaultFileExtension => ".cs"; protected override ExpressionSyntax GetLeftSideOfDot(SimpleNameSyntax simpleName) diff --git a/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs b/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs index aa5dcb39f89dc..61096c4116f9d 100644 --- a/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs @@ -26,6 +26,11 @@ internal class CSharpGenerateVariableCodeFixProvider : AbstractGenerateMemberCod private const string CS0120 = nameof(CS0120); // error CS0120: An object reference is required for the non-static field, method, or property 'A' private const string CS0118 = nameof(CS0118); // error CS0118: 'C' is a type but is used like a variable + [ImportingConstructor] + public CSharpGenerateVariableCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS1061, CS0103, CS0117, CS0539, CS0246, CS0120, CS0118); diff --git a/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassCodeFixProvider.cs b/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassCodeFixProvider.cs index 2e4398638c638..52fd51c0ad9a7 100644 --- a/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassCodeFixProvider.cs @@ -14,6 +14,7 @@ internal class CSharpImplementAbstractClassCodeFixProvider : { private const string CS0534 = nameof(CS0534); // 'Program' does not implement inherited abstract member 'Goo.bar()' + [ImportingConstructor] public CSharpImplementAbstractClassCodeFixProvider() : base(CS0534) { diff --git a/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassService.cs b/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassService.cs index e418a8a8a35f9..39485cad88905 100644 --- a/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassService.cs +++ b/src/Features/CSharp/Portable/ImplementAbstractClass/CSharpImplementAbstractClassService.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ImplementAbstractClass internal class CSharpImplementAbstractClassService : AbstractImplementAbstractClassService { + [ImportingConstructor] + public CSharpImplementAbstractClassService() + { + } + protected override bool TryInitializeState( Document document, SemanticModel model, ClassDeclarationSyntax classNode, CancellationToken cancellationToken, out INamedTypeSymbol classType, out INamedTypeSymbol abstractClassType) diff --git a/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs b/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs index 93d5288acada0..9b831f62ece4d 100644 --- a/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs @@ -25,6 +25,11 @@ internal class CSharpImplementInterfaceCodeFixProvider : CodeFixProvider private const string CS0737 = nameof(CS0737); // 'Class' does not implement interface member 'IInterface.M()'. 'Class.M()' cannot implement an interface member because it is not public. private const string CS0738 = nameof(CS0738); // 'C' does not implement interface member 'I.Method1()'. 'B.Method1()' cannot implement 'I.Method1()' because it does not have the matching return type of 'void'. + [ImportingConstructor] + public CSharpImplementInterfaceCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS0535, CS0737, CS0738); diff --git a/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceService.cs b/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceService.cs index 6419920ddc7e0..236447e668b25 100644 --- a/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceService.cs +++ b/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceService.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ImplementInterface [ExportLanguageService(typeof(IImplementInterfaceService), LanguageNames.CSharp), Shared] internal class CSharpImplementInterfaceService : AbstractImplementInterfaceService { + [ImportingConstructor] + public CSharpImplementInterfaceService() + { + } + protected override bool TryInitializeState( Document document, SemanticModel model, SyntaxNode node, CancellationToken cancellationToken, out SyntaxNode classOrStructDecl, out INamedTypeSymbol classOrStructType, out IEnumerable interfaceTypes) diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpAddParameterCheckCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpAddParameterCheckCodeRefactoringProvider.cs index 1ef856c6c1444..f92387a7f6709 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpAddParameterCheckCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpAddParameterCheckCodeRefactoringProvider.cs @@ -17,6 +17,11 @@ internal class CSharpAddParameterCheckCodeRefactoringProvider : ExpressionSyntax, BinaryExpressionSyntax> { + [ImportingConstructor] + public CSharpAddParameterCheckCodeRefactoringProvider() + { + } + protected override bool IsFunctionDeclaration(SyntaxNode node) => InitializeParameterHelpers.IsFunctionDeclaration(node); diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromParameterCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromParameterCodeRefactoringProvider.cs index 518e5e0be374a..8968ff9d05a68 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromParameterCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromParameterCodeRefactoringProvider.cs @@ -18,6 +18,11 @@ internal class CSharpInitializeMemberFromParameterCodeRefactoringProvider : StatementSyntax, ExpressionSyntax> { + [ImportingConstructor] + public CSharpInitializeMemberFromParameterCodeRefactoringProvider() + { + } + protected override bool IsFunctionDeclaration(SyntaxNode node) => InitializeParameterHelpers.IsFunctionDeclaration(node); diff --git a/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs b/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs index 48bd12e9dbde9..a8275c127d5ca 100644 --- a/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs @@ -28,6 +28,11 @@ namespace Microsoft.CodeAnalysis.CSharp.InlineDeclaration [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal partial class CSharpInlineDeclarationCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpInlineDeclarationCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.InlineDeclarationDiagnosticId); diff --git a/src/Features/CSharp/Portable/IntroduceUsingStatement/CSharpIntroduceUsingStatementCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/IntroduceUsingStatement/CSharpIntroduceUsingStatementCodeRefactoringProvider.cs index 60e4df6d817f1..27dcc5a324430 100644 --- a/src/Features/CSharp/Portable/IntroduceUsingStatement/CSharpIntroduceUsingStatementCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/IntroduceUsingStatement/CSharpIntroduceUsingStatementCodeRefactoringProvider.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.CSharp.IntroduceUsingStatement internal sealed class CSharpIntroduceUsingStatementCodeRefactoringProvider : AbstractIntroduceUsingStatementCodeRefactoringProvider { + [ImportingConstructor] + public CSharpIntroduceUsingStatementCodeRefactoringProvider() + { + } + protected override string CodeActionTitle => CSharpFeaturesResources.Introduce_using_statement; protected override bool CanRefactorToContainBlockStatements(SyntaxNode parent) diff --git a/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService.cs b/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService.cs index dfa866f410c0a..1c1165b238690 100644 --- a/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService.cs +++ b/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService.cs @@ -18,6 +18,11 @@ namespace Microsoft.CodeAnalysis.CSharp.IntroduceVariable internal partial class CSharpIntroduceVariableService : AbstractIntroduceVariableService { + [ImportingConstructor] + public CSharpIntroduceVariableService() + { + } + protected override bool IsInNonFirstQueryClause(ExpressionSyntax expression) { var query = expression.GetAncestor(); diff --git a/src/Features/CSharp/Portable/InvertConditional/CSharpInvertConditionalCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InvertConditional/CSharpInvertConditionalCodeRefactoringProvider.cs index 0302a552a228a..eedf8f7f361d6 100644 --- a/src/Features/CSharp/Portable/InvertConditional/CSharpInvertConditionalCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InvertConditional/CSharpInvertConditionalCodeRefactoringProvider.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.InvertConditional internal class CSharpInvertConditionalCodeRefactoringProvider : AbstractInvertConditionalCodeRefactoringProvider { + [ImportingConstructor] + public CSharpInvertConditionalCodeRefactoringProvider() + { + } + // Show the feature in the condition of the conditional up through the ? token. // Don't offer if the conditional is missing the colon and the conditional is // too incomplete. diff --git a/src/Features/CSharp/Portable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs index 6c32f31eaa435..430c5ce88360e 100644 --- a/src/Features/CSharp/Portable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.CSharp.InvertIf [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.InvertIf), Shared] internal sealed class CSharpInvertIfCodeRefactoringProvider : AbstractInvertIfCodeRefactoringProvider { + [ImportingConstructor] + public CSharpInvertIfCodeRefactoringProvider() + { + } + protected override string GetTitle() => CSharpFeaturesResources.Invert_if; diff --git a/src/Features/CSharp/Portable/InvertLogical/CSharpInvertLogicalCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InvertLogical/CSharpInvertLogicalCodeRefactoringProvider.cs index 75ff778a007c6..f3477b2846118 100644 --- a/src/Features/CSharp/Portable/InvertLogical/CSharpInvertLogicalCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InvertLogical/CSharpInvertLogicalCodeRefactoringProvider.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.InvertLogical internal class CSharpInvertLogicalCodeRefactoringProvider : AbstractInvertLogicalCodeRefactoringProvider { + [ImportingConstructor] + public CSharpInvertLogicalCodeRefactoringProvider() + { + } + protected override SyntaxKind GetKind(int rawKind) => (SyntaxKind)rawKind; diff --git a/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs b/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs index 8e8e61af75b6e..26f1a87b2afec 100644 --- a/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs @@ -22,6 +22,11 @@ namespace Microsoft.CodeAnalysis.CSharp.InvokeDelegateWithConditionalAccess [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(InvokeDelegateWithConditionalAccessCodeFixProvider)), Shared] internal partial class InvokeDelegateWithConditionalAccessCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public InvokeDelegateWithConditionalAccessCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.InvokeDelegateWithConditionalAccessId); // Filter out the diagnostics we created for the faded out code. We don't want diff --git a/src/Features/CSharp/Portable/LanguageServices/CSharpAnonymousTypeDisplayService.cs b/src/Features/CSharp/Portable/LanguageServices/CSharpAnonymousTypeDisplayService.cs index 1e90bbc77cd0d..75a1ce9262f34 100644 --- a/src/Features/CSharp/Portable/LanguageServices/CSharpAnonymousTypeDisplayService.cs +++ b/src/Features/CSharp/Portable/LanguageServices/CSharpAnonymousTypeDisplayService.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.LanguageServices [ExportLanguageService(typeof(IAnonymousTypeDisplayService), LanguageNames.CSharp), Shared] internal class CSharpAnonymousTypeDisplayService : AbstractAnonymousTypeDisplayService { + [ImportingConstructor] + public CSharpAnonymousTypeDisplayService() + { + } + public override IEnumerable GetAnonymousTypeParts( INamedTypeSymbol anonymousType, SemanticModel semanticModel, int position, ISymbolDisplayService displayService) { diff --git a/src/Features/CSharp/Portable/LanguageServices/CSharpSymbolDisplayServiceFactory.cs b/src/Features/CSharp/Portable/LanguageServices/CSharpSymbolDisplayServiceFactory.cs index fc360145ea75f..477551d1e864f 100644 --- a/src/Features/CSharp/Portable/LanguageServices/CSharpSymbolDisplayServiceFactory.cs +++ b/src/Features/CSharp/Portable/LanguageServices/CSharpSymbolDisplayServiceFactory.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.LanguageServices [ExportLanguageServiceFactory(typeof(ISymbolDisplayService), LanguageNames.CSharp), Shared] internal partial class CSharpSymbolDisplayServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpSymbolDisplayServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices provider) { return new CSharpSymbolDisplayService(provider); diff --git a/src/Features/CSharp/Portable/MakeFieldReadonly/CSharpMakeFieldReadonlyCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeFieldReadonly/CSharpMakeFieldReadonlyCodeFixProvider.cs index 125245741231d..f30fab0bc2c83 100644 --- a/src/Features/CSharp/Portable/MakeFieldReadonly/CSharpMakeFieldReadonlyCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/MakeFieldReadonly/CSharpMakeFieldReadonlyCodeFixProvider.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.MakeFieldReadonly [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpMakeFieldReadonlyCodeFixProvider : AbstractMakeFieldReadonlyCodeFixProvider { + [ImportingConstructor] + public CSharpMakeFieldReadonlyCodeFixProvider() + { + } + protected override SyntaxNode GetInitializerNode(VariableDeclaratorSyntax declaration) => declaration.Initializer?.Value; diff --git a/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs index b597748661037..46c86cb91d064 100644 --- a/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.CSharp.MakeLocalFunctionStatic [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(MakeLocalFunctionStaticCodeFixProvider)), Shared] internal class MakeLocalFunctionStaticCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public MakeLocalFunctionStaticCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.MakeLocalFunctionStaticDiagnosticId); diff --git a/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs index 1d765e19fe055..8e02ed6a4045a 100644 --- a/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs @@ -23,6 +23,11 @@ internal class CSharpMakeMethodAsynchronousCodeFixProvider : AbstractMakeMethodA private static readonly SyntaxToken s_asyncToken = SyntaxFactory.Token(SyntaxKind.AsyncKeyword); + [ImportingConstructor] + public CSharpMakeMethodAsynchronousCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS4032, CS4033, CS4034); diff --git a/src/Features/CSharp/Portable/MakeMethodSynchronous/CSharpMakeMethodSynchronousCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeMethodSynchronous/CSharpMakeMethodSynchronousCodeFixProvider.cs index fefa7bcbadcb8..836add50d96bc 100644 --- a/src/Features/CSharp/Portable/MakeMethodSynchronous/CSharpMakeMethodSynchronousCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/MakeMethodSynchronous/CSharpMakeMethodSynchronousCodeFixProvider.cs @@ -17,6 +17,11 @@ internal class CSharpMakeMethodSynchronousCodeFixProvider : AbstractMakeMethodSy { private const string CS1998 = nameof(CS1998); // This async method lacks 'await' operators and will run synchronously. + [ImportingConstructor] + public CSharpMakeMethodSynchronousCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS1998); protected override bool IsAsyncSupportingFunctionSyntax(SyntaxNode node) diff --git a/src/Features/CSharp/Portable/MakeRefStruct/MakeRefStructCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeRefStruct/MakeRefStructCodeFixProvider.cs index 40f34835f18f2..139746f370e68 100644 --- a/src/Features/CSharp/Portable/MakeRefStruct/MakeRefStructCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/MakeRefStruct/MakeRefStructCodeFixProvider.cs @@ -21,6 +21,11 @@ internal class MakeRefStructCodeFixProvider : CodeFixProvider // Error CS8345: Field or auto-implemented property cannot be of certain type unless it is an instance member of a ref struct. private const string CS8345 = nameof(CS8345); + [ImportingConstructor] + public MakeRefStructCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS8345); diff --git a/src/Features/CSharp/Portable/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs b/src/Features/CSharp/Portable/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs index 97fc2f8005130..32844bbc4c9a8 100644 --- a/src/Features/CSharp/Portable/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs @@ -18,6 +18,11 @@ namespace Microsoft.CodeAnalysis.CSharp.MakeStructFieldsWritable [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.MakeStructFieldsWritable), Shared] internal class CSharpMakeStructFieldsWritableCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpMakeStructFieldsWritableCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.MakeStructFieldsWritable); diff --git a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceServiceFactory.cs b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceServiceFactory.cs index 04fd41060413c..9f58480dba16e 100644 --- a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceServiceFactory.cs +++ b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceServiceFactory.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.MetadataAsSource [ExportLanguageServiceFactory(typeof(IMetadataAsSourceService), LanguageNames.CSharp), Shared] internal class CSharpMetadataAsSourceServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpMetadataAsSourceServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices provider) { return new CSharpMetadataAsSourceService(provider); diff --git a/src/Features/CSharp/Portable/MoveDeclarationNearReference/CSharpMoveDeclarationNearReferenceService.cs b/src/Features/CSharp/Portable/MoveDeclarationNearReference/CSharpMoveDeclarationNearReferenceService.cs index 6e2ba6a230195..f94d34c1441b3 100644 --- a/src/Features/CSharp/Portable/MoveDeclarationNearReference/CSharpMoveDeclarationNearReferenceService.cs +++ b/src/Features/CSharp/Portable/MoveDeclarationNearReference/CSharpMoveDeclarationNearReferenceService.cs @@ -18,6 +18,11 @@ internal partial class CSharpMoveDeclarationNearReferenceService : LocalDeclarationStatementSyntax, VariableDeclaratorSyntax> { + [ImportingConstructor] + public CSharpMoveDeclarationNearReferenceService() + { + } + protected override bool IsMeaningfulBlock(SyntaxNode node) { return node is AnonymousFunctionExpressionSyntax || diff --git a/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs b/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs index 538653a68a648..bc61a2555685d 100644 --- a/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs +++ b/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.MoveToNamespace internal class CSharpMoveToNamespaceService : AbstractMoveToNamespaceService { + [ImportingConstructor] + public CSharpMoveToNamespaceService() + { + } + protected override string GetNamespaceName(NamespaceDeclarationSyntax namespaceSyntax) => namespaceSyntax.Name.ToString(); diff --git a/src/Features/CSharp/Portable/NameTupleElement/CSharpNameTupleElementCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/NameTupleElement/CSharpNameTupleElementCodeRefactoringProvider.cs index 7bc12776ce126..695e7bba652cf 100644 --- a/src/Features/CSharp/Portable/NameTupleElement/CSharpNameTupleElementCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/NameTupleElement/CSharpNameTupleElementCodeRefactoringProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.NameTupleElement [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(CSharpNameTupleElementCodeRefactoringProvider)), Shared] internal class CSharpNameTupleElementCodeRefactoringProvider : AbstractNameTupleElementCodeRefactoringProvider { + [ImportingConstructor] + public CSharpNameTupleElementCodeRefactoringProvider() + { + } + protected override bool IsCloseParenOrComma(SyntaxToken token) => token.IsKind(SyntaxKind.CloseParenToken, SyntaxKind.CommaToken); diff --git a/src/Features/CSharp/Portable/NavigateTo/CSharpNavigateToSearchService.cs b/src/Features/CSharp/Portable/NavigateTo/CSharpNavigateToSearchService.cs index 9b303f041e9d3..f950d149a4ab0 100644 --- a/src/Features/CSharp/Portable/NavigateTo/CSharpNavigateToSearchService.cs +++ b/src/Features/CSharp/Portable/NavigateTo/CSharpNavigateToSearchService.cs @@ -9,5 +9,9 @@ namespace Microsoft.CodeAnalysis.CSharp.NavigateTo [ExportLanguageService(typeof(INavigateToSearchService_RemoveInterfaceAboveAndRenameThisAfterInternalsVisibleToUsersUpdate), LanguageNames.CSharp), Shared] internal class CSharpNavigateToSearchService : AbstractNavigateToSearchService { + [ImportingConstructor] + public CSharpNavigateToSearchService() + { + } } } diff --git a/src/Features/CSharp/Portable/OrderModifiers/CSharpOrderModifiersCodeFixProvider.cs b/src/Features/CSharp/Portable/OrderModifiers/CSharpOrderModifiersCodeFixProvider.cs index 9999c6058a3ac..99bc660a9dee5 100644 --- a/src/Features/CSharp/Portable/OrderModifiers/CSharpOrderModifiersCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/OrderModifiers/CSharpOrderModifiersCodeFixProvider.cs @@ -15,6 +15,7 @@ internal class CSharpOrderModifiersCodeFixProvider : AbstractOrderModifiersCodeF { private const string CS0267 = nameof(CS0267); // The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void' + [ImportingConstructor] public CSharpOrderModifiersCodeFixProvider() : base(CSharpSyntaxFactsService.Instance, CSharpCodeStyleOptions.PreferredModifierOrder, CSharpOrderModifiersHelper.Instance) { diff --git a/src/Features/CSharp/Portable/OrganizeImports/CSharpOrganizeImportsService.cs b/src/Features/CSharp/Portable/OrganizeImports/CSharpOrganizeImportsService.cs index 02f434a984ace..0f4ad92ec447f 100644 --- a/src/Features/CSharp/Portable/OrganizeImports/CSharpOrganizeImportsService.cs +++ b/src/Features/CSharp/Portable/OrganizeImports/CSharpOrganizeImportsService.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.OrganizeImports [ExportLanguageService(typeof(IOrganizeImportsService), LanguageNames.CSharp), Shared] internal partial class CSharpOrganizeImportsService : IOrganizeImportsService { + [ImportingConstructor] + public CSharpOrganizeImportsService() + { + } + public async Task OrganizeImportsAsync(Document document, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -26,6 +31,9 @@ public async Task OrganizeImportsAsync(Document document, Cancellation return document.WithSyntaxRoot(newRoot); } + public string SortImportsDisplayStringWithAccelerator => + CSharpFeaturesResources.Sort_Usings; + public string SortAndRemoveUnusedImportsDisplayStringWithAccelerator => CSharpFeaturesResources.Remove_and_Sort_Usings; } diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/ClassDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/ClassDeclarationOrganizer.cs index da98e8cf34c27..16706f844424a 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/ClassDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/ClassDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class ClassDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public ClassDeclarationOrganizer() + { + } + protected override ClassDeclarationSyntax Organize( ClassDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/ConstructorDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/ConstructorDeclarationOrganizer.cs index 200b35043cc65..bb730e5d29f39 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/ConstructorDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/ConstructorDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class ConstructorDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public ConstructorDeclarationOrganizer() + { + } + protected override ConstructorDeclarationSyntax Organize( ConstructorDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/DestructorDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/DestructorDeclarationOrganizer.cs index 3f1701259ad77..0e81440f90025 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/DestructorDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/DestructorDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class DestructorDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public DestructorDeclarationOrganizer() + { + } + protected override DestructorDeclarationSyntax Organize( DestructorDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/EnumDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/EnumDeclarationOrganizer.cs index 385f9b4f036f5..768dbbb00a324 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/EnumDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/EnumDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class EnumDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public EnumDeclarationOrganizer() + { + } + protected override EnumDeclarationSyntax Organize( EnumDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/EventDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/EventDeclarationOrganizer.cs index 8c3f820e8bda2..876d65a3ff31e 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/EventDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/EventDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class EventDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public EventDeclarationOrganizer() + { + } + protected override EventDeclarationSyntax Organize( EventDeclarationSyntax syntax, CancellationToken cancellationToken) @@ -20,7 +25,8 @@ protected override EventDeclarationSyntax Organize( syntax.Type, syntax.ExplicitInterfaceSpecifier, syntax.Identifier, - syntax.AccessorList); + syntax.AccessorList, + syntax.SemicolonToken); } } } diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/EventFieldDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/EventFieldDeclarationOrganizer.cs index 891ca2a7d00de..36681d1eb6d24 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/EventFieldDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/EventFieldDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class EventFieldDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public EventFieldDeclarationOrganizer() + { + } + protected override EventFieldDeclarationSyntax Organize( EventFieldDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/FieldDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/FieldDeclarationOrganizer.cs index d966cbf1825a2..f1d5d3f872630 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/FieldDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/FieldDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class FieldDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public FieldDeclarationOrganizer() + { + } + protected override FieldDeclarationSyntax Organize( FieldDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/IndexerDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/IndexerDeclarationOrganizer.cs index b3dd4194fc43d..bbc81d8b81473 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/IndexerDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/IndexerDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class IndexerDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public IndexerDeclarationOrganizer() + { + } + protected override IndexerDeclarationSyntax Organize( IndexerDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/InterfaceDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/InterfaceDeclarationOrganizer.cs index e608042bb229a..bb136f3a8ac6f 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/InterfaceDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/InterfaceDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class InterfaceDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public InterfaceDeclarationOrganizer() + { + } + protected override InterfaceDeclarationSyntax Organize( InterfaceDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/MethodDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/MethodDeclarationOrganizer.cs index 49883f2caf3d6..dc68d235d4bd2 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/MethodDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/MethodDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class MethodDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public MethodDeclarationOrganizer() + { + } + protected override MethodDeclarationSyntax Organize( MethodDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/OperatorDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/OperatorDeclarationOrganizer.cs index 44597c77545ba..89f725701bb1a 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/OperatorDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/OperatorDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class OperatorDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public OperatorDeclarationOrganizer() + { + } + protected override OperatorDeclarationSyntax Organize( OperatorDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/PropertyDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/PropertyDeclarationOrganizer.cs index 946c85dcf8d62..c1660c41eb0f2 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/PropertyDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/PropertyDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class PropertyDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public PropertyDeclarationOrganizer() + { + } + protected override PropertyDeclarationSyntax Organize( PropertyDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Organizing/Organizers/StructDeclarationOrganizer.cs b/src/Features/CSharp/Portable/Organizing/Organizers/StructDeclarationOrganizer.cs index 259c6e0aa6d44..cb1d8126f9447 100644 --- a/src/Features/CSharp/Portable/Organizing/Organizers/StructDeclarationOrganizer.cs +++ b/src/Features/CSharp/Portable/Organizing/Organizers/StructDeclarationOrganizer.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Organizing.Organizers [ExportSyntaxNodeOrganizer(LanguageNames.CSharp), Shared] internal class StructDeclarationOrganizer : AbstractSyntaxNodeOrganizer { + [ImportingConstructor] + public StructDeclarationOrganizer() + { + } + protected override StructDeclarationSyntax Organize( StructDeclarationSyntax syntax, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/QualifyMemberAccess/CSharpQualifyMemberAccessCodeFixProvider.cs b/src/Features/CSharp/Portable/QualifyMemberAccess/CSharpQualifyMemberAccessCodeFixProvider.cs index 994efa16ad26f..e35123712ad4f 100644 --- a/src/Features/CSharp/Portable/QualifyMemberAccess/CSharpQualifyMemberAccessCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/QualifyMemberAccess/CSharpQualifyMemberAccessCodeFixProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.QualifyMemberAccess [ExtensionOrder(After = PredefinedCodeFixProviderNames.RemoveUnnecessaryCast)] internal class CSharpQualifyMemberAccessCodeFixProvider : AbstractQualifyMemberAccessCodeFixprovider { + [ImportingConstructor] + public CSharpQualifyMemberAccessCodeFixProvider() + { + } + protected override SimpleNameSyntax GetNode(Diagnostic diagnostic, CancellationToken cancellationToken) { var node = diagnostic.Location.FindNode(getInnermostNodeForTie: true, cancellationToken); diff --git a/src/Features/CSharp/Portable/QuickInfo/CSharpQuickInfoSevice.cs b/src/Features/CSharp/Portable/QuickInfo/CSharpQuickInfoSevice.cs index e26e2e051a092..f65b40f3c98f3 100644 --- a/src/Features/CSharp/Portable/QuickInfo/CSharpQuickInfoSevice.cs +++ b/src/Features/CSharp/Portable/QuickInfo/CSharpQuickInfoSevice.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.QuickInfo [ExportLanguageServiceFactory(typeof(QuickInfoService), LanguageNames.CSharp), Shared] internal class CSharpQuickInfoServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpQuickInfoServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) { return new CSharpQuickInfoService(languageServices.WorkspaceServices.Workspace); diff --git a/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs b/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs index 7af284a033b87..11569ed88a6ed 100644 --- a/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs +++ b/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.CSharp.QuickInfo [ExportQuickInfoProvider(QuickInfoProviderNames.Semantic, LanguageNames.CSharp), Shared] internal class CSharpSemanticQuickInfoProvider : CommonSemanticQuickInfoProvider { + [ImportingConstructor] + public CSharpSemanticQuickInfoProvider() + { + } + /// /// If the token is the '=>' in a lambda, or the 'delegate' in an anonymous function, /// return the syntax for the lambda or anonymous function. diff --git a/src/Features/CSharp/Portable/QuickInfo/CSharpSyntacticQuickInfoProvider.cs b/src/Features/CSharp/Portable/QuickInfo/CSharpSyntacticQuickInfoProvider.cs index fe83607ababaa..70c6caabcde86 100644 --- a/src/Features/CSharp/Portable/QuickInfo/CSharpSyntacticQuickInfoProvider.cs +++ b/src/Features/CSharp/Portable/QuickInfo/CSharpSyntacticQuickInfoProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.CSharp.QuickInfo [ExtensionOrder(After = QuickInfoProviderNames.Semantic)] internal class CSharpSyntacticQuickInfoProvider : CommonQuickInfoProvider { + [ImportingConstructor] + public CSharpSyntacticQuickInfoProvider() + { + } + protected override async Task BuildQuickInfoAsync( Document document, SyntaxToken token, diff --git a/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsCodeFixProvider.cs index 6803273a83707..6eaf7b23bb545 100644 --- a/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsCodeFixProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports [ExtensionOrder(After = PredefinedCodeFixProviderNames.AddMissingReference)] internal class CSharpRemoveUnnecessaryImportsCodeFixProvider : AbstractRemoveUnnecessaryImportsCodeFixProvider { + [ImportingConstructor] + public CSharpRemoveUnnecessaryImportsCodeFixProvider() + { + } + protected override string GetTitle() => CSharpFeaturesResources.Remove_Unnecessary_Usings; } diff --git a/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsService.cs b/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsService.cs index e6d9657149493..123fee193a379 100644 --- a/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsService.cs +++ b/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpRemoveUnnecessaryImportsService.cs @@ -9,5 +9,9 @@ namespace Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports [ExportLanguageService(typeof(IRemoveUnnecessaryImportsService), LanguageNames.CSharp), Shared] internal partial class CSharpRemoveUnnecessaryImportsService : AbstractCSharpRemoveUnnecessaryImportsService { + [ImportingConstructor] + public CSharpRemoveUnnecessaryImportsService() + { + } } } diff --git a/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpUnnecessaryImportsService.cs b/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpUnnecessaryImportsService.cs index 6a552d98b215a..ea554d90c3fbc 100644 --- a/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpUnnecessaryImportsService.cs +++ b/src/Features/CSharp/Portable/RemoveUnnecessaryImports/CSharpUnnecessaryImportsService.cs @@ -9,5 +9,9 @@ namespace Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports [ExportLanguageService(typeof(IUnnecessaryImportsService), LanguageNames.CSharp), Shared] internal partial class CSharpUnnecessaryImportsService : AbstractCSharpRemoveUnnecessaryImportsService { + [ImportingConstructor] + public CSharpUnnecessaryImportsService() + { + } } } diff --git a/src/Features/CSharp/Portable/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs index 5213bbd04f30d..58f0a3af4888c 100644 --- a/src/Features/CSharp/Portable/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryParentheses internal class CSharpRemoveUnnecessaryParenthesesCodeFixProvider : AbstractRemoveUnnecessaryParenthesesCodeFixProvider { + [ImportingConstructor] + public CSharpRemoveUnnecessaryParenthesesCodeFixProvider() + { + } + protected override bool CanRemoveParentheses(ParenthesizedExpressionSyntax current, SemanticModel semanticModel) { return CSharpRemoveUnnecessaryParenthesesDiagnosticAnalyzer.CanRemoveParenthesesHelper( diff --git a/src/Features/CSharp/Portable/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs index 114f7b1f9efb4..e302ea41714ec 100644 --- a/src/Features/CSharp/Portable/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.CSharp.RemoveUnreachableCode [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.RemoveUnreachableCode), Shared] internal class CSharpRemoveUnreachableCodeCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpRemoveUnreachableCodeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.RemoveUnreachableCodeDiagnosticId); diff --git a/src/Features/CSharp/Portable/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs index 8ca6bb006105c..3c96d23727638 100644 --- a/src/Features/CSharp/Portable/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs @@ -21,6 +21,11 @@ internal class CSharpRemoveUnusedLocalFunctionCodeFixProvider : SyntaxEditorBase { private const string CS8321 = nameof(CS8321); // The local function 'X' is declared but never used + [ImportingConstructor] + public CSharpRemoveUnusedLocalFunctionCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS8321); diff --git a/src/Features/CSharp/Portable/RemoveUnusedMembers/CSharpRemoveUnusedMembersCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnusedMembers/CSharpRemoveUnusedMembersCodeFixProvider.cs index 5af8e6a2a43d5..6197f78dd83cd 100644 --- a/src/Features/CSharp/Portable/RemoveUnusedMembers/CSharpRemoveUnusedMembersCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnusedMembers/CSharpRemoveUnusedMembersCodeFixProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.RemoveUnusedMembers [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.RemoveUnusedMembers), Shared] internal class CSharpRemoveUnusedMembersCodeFixProvider : AbstractRemoveUnusedMembersCodeFixProvider { + [ImportingConstructor] + public CSharpRemoveUnusedMembersCodeFixProvider() + { + } + /// /// This method adjusts the to remove based on whether or not all variable declarators /// within a field declaration should be removed, diff --git a/src/Features/CSharp/Portable/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs index 2c62dd04e5e5e..4d4f668dcfd48 100644 --- a/src/Features/CSharp/Portable/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs @@ -19,6 +19,11 @@ internal class CSharpRemoveUnusedValuesCodeFixProvider : ExpressionStatementSyntax, LocalDeclarationStatementSyntax, VariableDeclaratorSyntax, ForEachStatementSyntax, SwitchSectionSyntax, SwitchLabelSyntax, CatchClauseSyntax, CatchClauseSyntax> { + [ImportingConstructor] + public CSharpRemoveUnusedValuesCodeFixProvider() + { + } + protected override BlockSyntax WrapWithBlockIfNecessary(IEnumerable statements) => SyntaxFactory.Block(statements); diff --git a/src/Features/CSharp/Portable/RemoveUnusedVariable/CSharpRemoveUnusedVariableCodeFixProvider.cs b/src/Features/CSharp/Portable/RemoveUnusedVariable/CSharpRemoveUnusedVariableCodeFixProvider.cs index 2cadcf8f35c3a..890d6ed138b01 100644 --- a/src/Features/CSharp/Portable/RemoveUnusedVariable/CSharpRemoveUnusedVariableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/RemoveUnusedVariable/CSharpRemoveUnusedVariableCodeFixProvider.cs @@ -17,6 +17,11 @@ internal partial class CSharpRemoveUnusedVariableCodeFixProvider : AbstractRemov public const string CS0168 = nameof(CS0168); public const string CS0219 = nameof(CS0219); + [ImportingConstructor] + public CSharpRemoveUnusedVariableCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0168, CS0219); diff --git a/src/Features/CSharp/Portable/ReplaceDefaultLiteral/CSharpReplaceDefaultLiteralCodeFixProvider.cs b/src/Features/CSharp/Portable/ReplaceDefaultLiteral/CSharpReplaceDefaultLiteralCodeFixProvider.cs index 5db5aee281cae..ec50e3755b72f 100644 --- a/src/Features/CSharp/Portable/ReplaceDefaultLiteral/CSharpReplaceDefaultLiteralCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ReplaceDefaultLiteral/CSharpReplaceDefaultLiteralCodeFixProvider.cs @@ -22,6 +22,11 @@ internal sealed class CSharpReplaceDefaultLiteralCodeFixProvider : CodeFixProvid private const string CS8313 = nameof(CS8313); // A default literal 'default' is not valid as a case constant. Use another literal (e.g. '0' or 'null') as appropriate. If you intended to write the default label, use 'default:' without 'case'. private const string CS8505 = nameof(CS8505); // A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern 'var _'. + [ImportingConstructor] + public CSharpReplaceDefaultLiteralCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS8313, CS8505); diff --git a/src/Features/CSharp/Portable/ReplaceDiscardDeclarationsWithAssignments/CSharpReplaceDiscardDeclarationsWithAssignmentsService.cs b/src/Features/CSharp/Portable/ReplaceDiscardDeclarationsWithAssignments/CSharpReplaceDiscardDeclarationsWithAssignmentsService.cs index af426514023e5..9d8b74bf62bd0 100644 --- a/src/Features/CSharp/Portable/ReplaceDiscardDeclarationsWithAssignments/CSharpReplaceDiscardDeclarationsWithAssignmentsService.cs +++ b/src/Features/CSharp/Portable/ReplaceDiscardDeclarationsWithAssignments/CSharpReplaceDiscardDeclarationsWithAssignmentsService.cs @@ -22,6 +22,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ReplaceDiscardDeclarationsWithAssignment [ExportLanguageService(typeof(IReplaceDiscardDeclarationsWithAssignmentsService), LanguageNames.CSharp), Shared] internal sealed class CSharpReplaceDiscardDeclarationsWithAssignmentsService : IReplaceDiscardDeclarationsWithAssignmentsService { + [ImportingConstructor] + public CSharpReplaceDiscardDeclarationsWithAssignmentsService() + { + } + public Task ReplaceAsync(SyntaxNode memberDeclaration, SemanticModel semanticModel, CancellationToken cancellationToken) { var editor = new SyntaxEditor(memberDeclaration, CSharpSyntaxGenerator.Instance); diff --git a/src/Features/CSharp/Portable/ReplaceDocCommentTextWithTag/CSharpReplaceDocCommentTextWithTagCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ReplaceDocCommentTextWithTag/CSharpReplaceDocCommentTextWithTagCodeRefactoringProvider.cs index d98a6b09f018a..4b632f8bee30b 100644 --- a/src/Features/CSharp/Portable/ReplaceDocCommentTextWithTag/CSharpReplaceDocCommentTextWithTagCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ReplaceDocCommentTextWithTag/CSharpReplaceDocCommentTextWithTagCodeRefactoringProvider.cs @@ -25,6 +25,11 @@ internal class CSharpReplaceDocCommentTextWithTagCodeRefactoringProvider : SyntaxFacts.GetText(SyntaxKind.AsyncKeyword), SyntaxFacts.GetText(SyntaxKind.AwaitKeyword)); + [ImportingConstructor] + public CSharpReplaceDocCommentTextWithTagCodeRefactoringProvider() + { + } + protected override bool IsXmlTextToken(SyntaxToken token) => token.Kind() == SyntaxKind.XmlTextLiteralToken || token.Kind() == SyntaxKind.XmlTextLiteralNewLineToken; diff --git a/src/Features/CSharp/Portable/ReplaceMethodWithProperty/CSharpReplaceMethodWithPropertyService.cs b/src/Features/CSharp/Portable/ReplaceMethodWithProperty/CSharpReplaceMethodWithPropertyService.cs index 10536dd67be29..dfd8adad6d19d 100644 --- a/src/Features/CSharp/Portable/ReplaceMethodWithProperty/CSharpReplaceMethodWithPropertyService.cs +++ b/src/Features/CSharp/Portable/ReplaceMethodWithProperty/CSharpReplaceMethodWithPropertyService.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.ReplaceMethodWithProper [ExportLanguageService(typeof(IReplaceMethodWithPropertyService), LanguageNames.CSharp), Shared] internal class CSharpReplaceMethodWithPropertyService : AbstractReplaceMethodWithPropertyService, IReplaceMethodWithPropertyService { + [ImportingConstructor] + public CSharpReplaceMethodWithPropertyService() + { + } + public SyntaxNode GetMethodDeclaration(SyntaxToken token) { var containingMethod = token.Parent.FirstAncestorOrSelf(); diff --git a/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs b/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs index 966abd9f826ce..11bdfd7b1257b 100644 --- a/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs +++ b/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs @@ -23,6 +23,11 @@ namespace Microsoft.CodeAnalysis.CSharp.ReplacePropertyWithMethods internal partial class CSharpReplacePropertyWithMethodsService : AbstractReplacePropertyWithMethodsService { + [ImportingConstructor] + public CSharpReplacePropertyWithMethodsService() + { + } + public override SyntaxNode GetPropertyDeclaration(SyntaxToken token) { var containingProperty = token.Parent.FirstAncestorOrSelf(); diff --git a/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs index 522ca0803abe8..c3ba2954902de 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("AttributeSignatureHelpProvider", LanguageNames.CSharp), Shared] internal partial class AttributeSignatureHelpProvider : AbstractCSharpSignatureHelpProvider { + [ImportingConstructor] + public AttributeSignatureHelpProvider() + { + } + public override bool IsTriggerCharacter(char ch) { return ch == '(' || ch == ','; diff --git a/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs index bd376e9171ce3..403843dd0de70 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("ConstructorInitializerSignatureHelpProvider", LanguageNames.CSharp), Shared] internal partial class ConstructorInitializerSignatureHelpProvider : AbstractCSharpSignatureHelpProvider { + [ImportingConstructor] + public ConstructorInitializerSignatureHelpProvider() + { + } + public override bool IsTriggerCharacter(char ch) { return ch == '(' || ch == ','; diff --git a/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs index 606beec6209c7..dcfe33ce4c50c 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs @@ -22,6 +22,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("ElementAccessExpressionSignatureHelpProvider", LanguageNames.CSharp), Shared] internal sealed class ElementAccessExpressionSignatureHelpProvider : AbstractCSharpSignatureHelpProvider { + [ImportingConstructor] + public ElementAccessExpressionSignatureHelpProvider() + { + } + public override bool IsTriggerCharacter(char ch) { return IsTriggerCharacterInternal(ch); diff --git a/src/Features/CSharp/Portable/SignatureHelp/GenericNamePartiallyWrittenSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/GenericNamePartiallyWrittenSignatureHelpProvider.cs index 8ea19cef867ef..b85c2aa7c8de6 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/GenericNamePartiallyWrittenSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/GenericNamePartiallyWrittenSignatureHelpProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("GenericNamePartiallyWrittenSignatureHelpProvider", LanguageNames.CSharp), Shared] internal class GenericNamePartiallyWrittenSignatureHelpProvider : GenericNameSignatureHelpProvider { + [ImportingConstructor] + public GenericNamePartiallyWrittenSignatureHelpProvider() + { + } + protected override bool TryGetGenericIdentifier(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, CancellationToken cancellationToken, out SyntaxToken genericIdentifier, out SyntaxToken lessThanToken) { return root.SyntaxTree.IsInPartiallyWrittenGeneric(position, cancellationToken, out genericIdentifier, out lessThanToken); diff --git a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs index ffe86f0091a55..e87d2a2fcef7b 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("GenericNameSignatureHelpProvider", LanguageNames.CSharp), Shared] internal partial class GenericNameSignatureHelpProvider : AbstractCSharpSignatureHelpProvider { + [ImportingConstructor] + public GenericNameSignatureHelpProvider() + { + } + public override bool IsTriggerCharacter(char ch) { return ch == '<' || ch == ','; diff --git a/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.cs index c6edd915cc0c7..1ee646e551999 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("InvocationExpressionSignatureHelpProvider", LanguageNames.CSharp), Shared] internal partial class InvocationExpressionSignatureHelpProvider : AbstractCSharpSignatureHelpProvider { + [ImportingConstructor] + public InvocationExpressionSignatureHelpProvider() + { + } + public override bool IsTriggerCharacter(char ch) { return ch == '(' || ch == ','; diff --git a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs index 80a120cc08f10..a16851bae4486 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp [ExportSignatureHelpProvider("ObjectCreationExpressionSignatureHelpProvider", LanguageNames.CSharp), Shared] internal partial class ObjectCreationExpressionSignatureHelpProvider : AbstractCSharpSignatureHelpProvider { + [ImportingConstructor] + public ObjectCreationExpressionSignatureHelpProvider() + { + } + public override bool IsTriggerCharacter(char ch) { return ch == '(' || ch == ','; diff --git a/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs index 44a6e6a9549f5..09d7bedbe8502 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs @@ -24,6 +24,11 @@ internal class TupleConstructionSignatureHelpProvider : AbstractCSharpSignatureH private static readonly Func> s_getArgumentsWithSeparators = e => e.Arguments.GetWithSeparators(); private static readonly Func> s_getArgumentNames = e => e.Arguments.Select(a => a.NameColon?.Name.Identifier.ValueText ?? string.Empty); + [ImportingConstructor] + public TupleConstructionSignatureHelpProvider() + { + } + public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (GetOuterMostTupleExpressionInSpan(root, position, syntaxFacts, currentSpan, cancellationToken, out var expression)) diff --git a/src/Features/CSharp/Portable/SimplifyThisOrMe/CSharpSimplifyThisOrMeCodeFixProvider.cs b/src/Features/CSharp/Portable/SimplifyThisOrMe/CSharpSimplifyThisOrMeCodeFixProvider.cs index 92c0e35b3d445..94ef624aaa6c1 100644 --- a/src/Features/CSharp/Portable/SimplifyThisOrMe/CSharpSimplifyThisOrMeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/SimplifyThisOrMe/CSharpSimplifyThisOrMeCodeFixProvider.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SimplifyThisOrMe internal partial class CSharpSimplifyThisOrMeCodeFixProvider : AbstractSimplifyThisOrMeCodeFixProvider { + [ImportingConstructor] + public CSharpSimplifyThisOrMeCodeFixProvider() + { + } + protected override string GetTitle() => CSharpFeaturesResources.Remove_this_qualification; diff --git a/src/Features/CSharp/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs b/src/Features/CSharp/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs index 59e3d6f02bac8..8267cf4733488 100644 --- a/src/Features/CSharp/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs @@ -16,6 +16,7 @@ namespace Microsoft.CodeAnalysis.CSharp.SimplifyTypeNames [ExtensionOrder(After = PredefinedCodeFixProviderNames.RemoveUnnecessaryCast)] internal partial class SimplifyTypeNamesCodeFixProvider : AbstractSimplifyTypeNamesCodeFixProvider { + [ImportingConstructor] public SimplifyTypeNamesCodeFixProvider() : base(new CSharpSimplifyTypeNamesDiagnosticAnalyzer()) { diff --git a/src/Features/CSharp/Portable/SolutionCrawler/CSharpDocumentDifferenceService.cs b/src/Features/CSharp/Portable/SolutionCrawler/CSharpDocumentDifferenceService.cs index 80cbcadcab37f..35d3ad10fcc3e 100644 --- a/src/Features/CSharp/Portable/SolutionCrawler/CSharpDocumentDifferenceService.cs +++ b/src/Features/CSharp/Portable/SolutionCrawler/CSharpDocumentDifferenceService.cs @@ -9,5 +9,9 @@ namespace Microsoft.CodeAnalysis.CSharp.SolutionCrawler [ExportLanguageService(typeof(IDocumentDifferenceService), LanguageNames.CSharp), Shared] internal class CSharpDocumentDifferenceService : AbstractDocumentDifferenceService { + [ImportingConstructor] + public CSharpDocumentDifferenceService() + { + } } } diff --git a/src/Features/CSharp/Portable/SpellCheck/CSharpSpellcheckCodeFixProvider.cs b/src/Features/CSharp/Portable/SpellCheck/CSharpSpellcheckCodeFixProvider.cs index 4ed3d0208ece6..1bfdb17064097 100644 --- a/src/Features/CSharp/Portable/SpellCheck/CSharpSpellcheckCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/SpellCheck/CSharpSpellcheckCodeFixProvider.cs @@ -18,6 +18,11 @@ internal partial class CSharpSpellCheckCodeFixProvider : AbstractSpellCheckCodeF private const string CS0426 = nameof(CS0426); // The type name '0' does not exist in the type '1' private const string CS1520 = nameof(CS1520); // Method must have a return type + [ImportingConstructor] + public CSharpSpellCheckCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = AddImportDiagnosticIds.FixableDiagnosticIds.Concat( GenerateMethodDiagnosticIds.FixableDiagnosticIds).Concat( diff --git a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpIfLikeStatementGenerator.cs b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpIfLikeStatementGenerator.cs index da5c36bbc142a..9bb75ba48d422 100644 --- a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpIfLikeStatementGenerator.cs +++ b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpIfLikeStatementGenerator.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements [ExportLanguageService(typeof(IIfLikeStatementGenerator), LanguageNames.CSharp), Shared] internal sealed class CSharpIfLikeStatementGenerator : IIfLikeStatementGenerator { + [ImportingConstructor] + public CSharpIfLikeStatementGenerator() + { + } + public bool IsIfOrElseIf(SyntaxNode node) => node is IfStatementSyntax; public bool IsCondition(SyntaxNode expression, out SyntaxNode ifOrElseIf) diff --git a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider.cs index 64280d9c5ad0c..25678c20efb53 100644 --- a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements internal sealed class CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider : AbstractMergeConsecutiveIfStatementsCodeRefactoringProvider { + [ImportingConstructor] + public CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider() + { + } + protected override bool IsApplicableSpan(SyntaxNode node, TextSpan span, out SyntaxNode ifOrElseIf) { if (node is IfStatementSyntax ifStatement) diff --git a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeNestedIfStatementsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeNestedIfStatementsCodeRefactoringProvider.cs index eb66b61b37451..b6671dcce3ec5 100644 --- a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeNestedIfStatementsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpMergeNestedIfStatementsCodeRefactoringProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements internal sealed class CSharpMergeNestedIfStatementsCodeRefactoringProvider : AbstractMergeNestedIfStatementsCodeRefactoringProvider { + [ImportingConstructor] + public CSharpMergeNestedIfStatementsCodeRefactoringProvider() + { + } + protected override bool IsApplicableSpan(SyntaxNode node, TextSpan span, out SyntaxNode ifOrElseIf) { if (node is IfStatementSyntax ifStatement) diff --git a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.cs index c295c7cdc5c06..ff3c10e4f341f 100644 --- a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.cs @@ -11,5 +11,9 @@ namespace Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements internal sealed class CSharpSplitIntoConsecutiveIfStatementsCodeRefactoringProvider : AbstractSplitIntoConsecutiveIfStatementsCodeRefactoringProvider { + [ImportingConstructor] + public CSharpSplitIntoConsecutiveIfStatementsCodeRefactoringProvider() + { + } } } diff --git a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoNestedIfStatementsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoNestedIfStatementsCodeRefactoringProvider.cs index f47c061664212..131f2744af2bd 100644 --- a/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoNestedIfStatementsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/SplitOrMergeIfStatements/CSharpSplitIntoNestedIfStatementsCodeRefactoringProvider.cs @@ -11,5 +11,9 @@ namespace Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements internal sealed class CSharpSplitIntoNestedIfStatementsCodeRefactoringProvider : AbstractSplitIntoNestedIfStatementsCodeRefactoringProvider { + [ImportingConstructor] + public CSharpSplitIntoNestedIfStatementsCodeRefactoringProvider() + { + } } } diff --git a/src/Features/CSharp/Portable/Structure/CSharpBlockStructureService.cs b/src/Features/CSharp/Portable/Structure/CSharpBlockStructureService.cs index fb9d7def46cf8..20a5c714e1acb 100644 --- a/src/Features/CSharp/Portable/Structure/CSharpBlockStructureService.cs +++ b/src/Features/CSharp/Portable/Structure/CSharpBlockStructureService.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Structure [ExportLanguageServiceFactory(typeof(BlockStructureService), LanguageNames.CSharp), Shared] internal class CSharpBlockStructureServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpBlockStructureServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) { return new CSharpBlockStructureService(languageServices.WorkspaceServices.Workspace); diff --git a/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs index bd56ae4ff2c77..737355d2608fb 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs @@ -19,7 +19,8 @@ protected override void CollectBlockSpans( CSharpStructureHelpers.CollectCommentBlockSpans(eventDeclaration, spans); // fault tolerance - if (eventDeclaration.AccessorList.IsMissing || + if (eventDeclaration.AccessorList == null || + eventDeclaration.AccessorList.IsMissing || eventDeclaration.AccessorList.OpenBraceToken.IsMissing || eventDeclaration.AccessorList.CloseBraceToken.IsMissing) { diff --git a/src/Features/CSharp/Portable/TodoComments/CSharpTodoCommentIncrementalAnalyzerProvider.cs b/src/Features/CSharp/Portable/TodoComments/CSharpTodoCommentIncrementalAnalyzerProvider.cs index a2fca9fda9b74..5c3b6438e82de 100644 --- a/src/Features/CSharp/Portable/TodoComments/CSharpTodoCommentIncrementalAnalyzerProvider.cs +++ b/src/Features/CSharp/Portable/TodoComments/CSharpTodoCommentIncrementalAnalyzerProvider.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.CSharp.TodoComments [ExportLanguageServiceFactory(typeof(ITodoCommentService), LanguageNames.CSharp), Shared] internal class CSharpTodoCommentServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpTodoCommentServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) => new CSharpTodoCommentService(languageServices.WorkspaceServices.Workspace); } diff --git a/src/Features/CSharp/Portable/TypeStyle/UseExplicitTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/TypeStyle/UseExplicitTypeCodeFixProvider.cs index f48aab7cffe29..ebd0494552fe6 100644 --- a/src/Features/CSharp/Portable/TypeStyle/UseExplicitTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/TypeStyle/UseExplicitTypeCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.TypeStyle [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.UseExplicitType), Shared] internal class UseExplicitTypeCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseExplicitTypeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseExplicitTypeDiagnosticId); diff --git a/src/Features/CSharp/Portable/TypeStyle/UseImplicitTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/TypeStyle/UseImplicitTypeCodeFixProvider.cs index af52f04483104..139a533ceb185 100644 --- a/src/Features/CSharp/Portable/TypeStyle/UseImplicitTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/TypeStyle/UseImplicitTypeCodeFixProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.CSharp.TypeStyle [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.UseImplicitType), Shared] internal class UseImplicitTypeCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseImplicitTypeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseImplicitTypeDiagnosticId); diff --git a/src/Features/CSharp/Portable/UnsealClass/CSharpUnsealClassCodeFixProvider.cs b/src/Features/CSharp/Portable/UnsealClass/CSharpUnsealClassCodeFixProvider.cs index d5435e72b2c54..5548a093a4dd3 100644 --- a/src/Features/CSharp/Portable/UnsealClass/CSharpUnsealClassCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UnsealClass/CSharpUnsealClassCodeFixProvider.cs @@ -12,6 +12,11 @@ internal sealed class CSharpUnsealClassCodeFixProvider : AbstractUnsealClassCode { private const string CS0509 = nameof(CS0509); // 'D': cannot derive from sealed type 'C' + [ImportingConstructor] + public CSharpUnsealClassCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS0509); diff --git a/src/Features/CSharp/Portable/UpdateProjectToAllowUnsafe/CSharpUpdateProjectToAllowUnsafeCodeFixProvider.cs b/src/Features/CSharp/Portable/UpdateProjectToAllowUnsafe/CSharpUpdateProjectToAllowUnsafeCodeFixProvider.cs index 10bf91346e3a4..ee710c39c5852 100644 --- a/src/Features/CSharp/Portable/UpdateProjectToAllowUnsafe/CSharpUpdateProjectToAllowUnsafeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UpdateProjectToAllowUnsafe/CSharpUpdateProjectToAllowUnsafeCodeFixProvider.cs @@ -13,6 +13,11 @@ internal class CSharpUpdateProjectToAllowUnsafeCodeFixProvider : CodeFixProvider { private const string CS0227 = nameof(CS0227); // error CS0227: Unsafe code may only appear if compiling with /unsafe + [ImportingConstructor] + public CSharpUpdateProjectToAllowUnsafeCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS0227); diff --git a/src/Features/CSharp/Portable/UpgradeProject/CSharpUpgradeProjectCodeFixProvider.cs b/src/Features/CSharp/Portable/UpgradeProject/CSharpUpgradeProjectCodeFixProvider.cs index 4f684288f0c14..bd1915ee82161 100644 --- a/src/Features/CSharp/Portable/UpgradeProject/CSharpUpgradeProjectCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UpgradeProject/CSharpUpgradeProjectCodeFixProvider.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UpgradeProject [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpUpgradeProjectCodeFixProvider : AbstractUpgradeProjectCodeFixProvider { + [ImportingConstructor] + public CSharpUpgradeProjectCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create( new[] { diff --git a/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs b/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs index 8ef9f5219821b..4ddd9408655f7 100644 --- a/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseAutoProperty internal class CSharpUseAutoPropertyCodeFixProvider : AbstractUseAutoPropertyCodeFixProvider { + [ImportingConstructor] + public CSharpUseAutoPropertyCodeFixProvider() + { + } + protected override SyntaxNode GetNodeToRemove(VariableDeclaratorSyntax declarator) { var fieldDeclaration = (FieldDeclarationSyntax)declarator.Parent.Parent; diff --git a/src/Features/CSharp/Portable/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs b/src/Features/CSharp/Portable/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs index d798c172c834c..36e334b955d15 100644 --- a/src/Features/CSharp/Portable/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs @@ -24,6 +24,11 @@ internal class CSharpUseCollectionInitializerCodeFixProvider : ExpressionStatementSyntax, VariableDeclaratorSyntax> { + [ImportingConstructor] + public CSharpUseCollectionInitializerCodeFixProvider() + { + } + protected override StatementSyntax GetNewStatement( StatementSyntax statement, ObjectCreationExpressionSyntax objectCreation, diff --git a/src/Features/CSharp/Portable/UseCompoundAssignment/CSharpUseCompoundAssignmentCodeFixProvider.cs b/src/Features/CSharp/Portable/UseCompoundAssignment/CSharpUseCompoundAssignmentCodeFixProvider.cs index f70f71fdf8708..1cf88d9baa5e7 100644 --- a/src/Features/CSharp/Portable/UseCompoundAssignment/CSharpUseCompoundAssignmentCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseCompoundAssignment/CSharpUseCompoundAssignmentCodeFixProvider.cs @@ -11,6 +11,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UseCompoundAssignment internal class CSharpUseCompoundAssignmentCodeFixProvider : AbstractUseCompoundAssignmentCodeFixProvider { + [ImportingConstructor] public CSharpUseCompoundAssignmentCodeFixProvider() : base(Utilities.Kinds) { diff --git a/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeRefactoringProvider.cs index e24ebaf077a18..4321d2e03b290 100644 --- a/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeRefactoringProvider.cs @@ -16,6 +16,11 @@ internal partial class CSharpUseConditionalExpressionForAssignmentCodeRefactorin : AbstractUseConditionalExpressionForAssignmentCodeFixProvider< StatementSyntax, IfStatementSyntax, LocalDeclarationStatementSyntax, VariableDeclaratorSyntax, ExpressionSyntax, ConditionalExpressionSyntax> { + [ImportingConstructor] + public CSharpUseConditionalExpressionForAssignmentCodeRefactoringProvider() + { + } + protected override AbstractFormattingRule GetMultiLineFormattingRule() => MultiLineConditionalExpressionFormattingRule.Instance; diff --git a/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForReturnCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForReturnCodeRefactoringProvider.cs index 814984276acf3..338b3a5fa1337 100644 --- a/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForReturnCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/UseConditionalExpression/CSharpUseConditionalExpressionForReturnCodeRefactoringProvider.cs @@ -14,6 +14,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseConditionalExpression internal partial class CSharpUseConditionalExpressionForReturnCodeRefactoringProvider : AbstractUseConditionalExpressionForReturnCodeFixProvider { + [ImportingConstructor] + public CSharpUseConditionalExpressionForReturnCodeRefactoringProvider() + { + } + protected override bool IsRef(IReturnOperation returnOperation) => returnOperation.Syntax is ReturnStatementSyntax statement && statement.Expression is RefExpressionSyntax; diff --git a/src/Features/CSharp/Portable/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs b/src/Features/CSharp/Portable/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs index b4bebf79ebbb7..553689c3d839a 100644 --- a/src/Features/CSharp/Portable/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseDeconstruction [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpUseDeconstructionCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpUseDeconstructionCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseDeconstructionDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs b/src/Features/CSharp/Portable/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs index 17879c2b03d40..0fa1a5cd79d3a 100644 --- a/src/Features/CSharp/Portable/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseDefaultLiteral [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal partial class CSharpUseDefaultLiteralCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpUseDefaultLiteralCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseDefaultLiteralDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseExplicitTypeForConst/UseExplicitTypeForConstCodeFixProvider.cs b/src/Features/CSharp/Portable/UseExplicitTypeForConst/UseExplicitTypeForConstCodeFixProvider.cs index ce35b43a9ff12..c5629ca4989ce 100644 --- a/src/Features/CSharp/Portable/UseExplicitTypeForConst/UseExplicitTypeForConstCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseExplicitTypeForConst/UseExplicitTypeForConstCodeFixProvider.cs @@ -18,6 +18,11 @@ internal sealed class UseExplicitTypeForConstCodeFixProvider : CodeFixProvider { private const string CS0822 = nameof(CS0822); // Implicitly-typed variables cannot be constant + [ImportingConstructor] + public UseExplicitTypeForConstCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(CS0822); public override FixAllProvider GetFixAllProvider() diff --git a/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs b/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs index 69722d125e187..ef810da526082 100644 --- a/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs @@ -25,6 +25,7 @@ internal partial class UseExpressionBodyCodeFixProvider : SyntaxEditorBasedCodeF private static readonly ImmutableArray _helpers = UseExpressionBodyHelper.Helpers; + [ImportingConstructor] public UseExpressionBodyCodeFixProvider() { FixableDiagnosticIds = _helpers.SelectAsArray(h => h.DiagnosticId); diff --git a/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs index fa5457e26038a..4e82267a5c168 100644 --- a/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs @@ -21,6 +21,7 @@ internal class UseExpressionBodyCodeRefactoringProvider : CodeRefactoringProvide { private static readonly ImmutableArray _helpers = UseExpressionBodyHelper.Helpers; + [ImportingConstructor] public UseExpressionBodyCodeRefactoringProvider() { } diff --git a/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs b/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs index b3649cfa2413c..2f09adb2332b8 100644 --- a/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseExpressionBodyForLambda [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal sealed partial class UseExpressionBodyForLambdaCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseExpressionBodyForLambdaCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseExpressionBodyForLambdaExpressionsDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeRefactoringProvider.cs index eb3aa0aaf4540..79830a39f8a3d 100644 --- a/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeRefactoringProvider.cs @@ -19,6 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UseExpressionBodyForLambda Name = PredefinedCodeRefactoringProviderNames.UseExpressionBody), Shared] internal sealed class UseExpressionBodyForLambdaCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] public UseExpressionBodyForLambdaCodeRefactoringProvider() { } diff --git a/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs b/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs index c12fc1c52d2ec..9e6e7c37157a6 100644 --- a/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIndexOrRangeOperator [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpUseIndexOperatorCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpUseIndexOperatorCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseIndexOperatorDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs b/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs index fd214c264186a..490baca16d754 100644 --- a/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs @@ -26,6 +26,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIndexOrRangeOperator [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpUseRangeOperatorCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpUseRangeOperatorCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseRangeOperatorDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseInferredMemberName/CSharpUseInferredMemberNameCodeFixProvider.cs b/src/Features/CSharp/Portable/UseInferredMemberName/CSharpUseInferredMemberNameCodeFixProvider.cs index 5c8fd42fa06c1..ce776bf1e3090 100644 --- a/src/Features/CSharp/Portable/UseInferredMemberName/CSharpUseInferredMemberNameCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseInferredMemberName/CSharpUseInferredMemberNameCodeFixProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseInferredMemberName [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal sealed class CSharpUseInferredMemberNameCodeFixProvider : AbstractUseInferredMemberNameCodeFixProvider { + [ImportingConstructor] + public CSharpUseInferredMemberNameCodeFixProvider() + { + } + protected override void LanguageSpecificRemoveSuggestedNode(SyntaxEditor editor, SyntaxNode node) { editor.RemoveNode(node, SyntaxRemoveOptions.KeepExteriorTrivia | SyntaxRemoveOptions.AddElasticMarker); diff --git a/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs b/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs index 6b6c52b26083a..f0aba6a5c59dd 100644 --- a/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIsNullCheck [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseIsNullCheckDiagnosticId); @@ -69,10 +74,13 @@ private static ExpressionSyntax Rewrite(BinaryExpressionSyntax binary) return isPattern; } - // convert: (object)expr != null to !(expr is null) - return SyntaxFactory.PrefixUnaryExpression( - SyntaxKind.LogicalNotExpression, - SyntaxFactory.ParenthesizedExpression(isPattern.WithoutTrivia())).WithTriviaFrom(isPattern); + // convert: (object)expr != null to expr is object + return SyntaxFactory + .BinaryExpression( + SyntaxKind.IsExpression, + isPattern.Expression, + SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword))) + .WithTriviaFrom(isPattern); } private static IsPatternExpressionSyntax RewriteWorker(BinaryExpressionSyntax binary) diff --git a/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider.cs b/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider.cs index 38ea693b6e378..9956af9d989de 100644 --- a/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseIsNullCheck/CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider.cs @@ -11,15 +11,20 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIsNullCheck [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal class CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider : AbstractUseIsNullCheckForReferenceEqualsCodeFixProvider { + [ImportingConstructor] + public CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider() + { + } + protected override string GetIsNullTitle() => CSharpFeaturesResources.Use_is_null_check; protected override string GetIsNotNullTitle() => GetIsNullTitle(); - private static SyntaxNode CreateEqualsNullCheck(SyntaxNode argument, SyntaxKind comparisonOperator) + private static SyntaxNode CreateEqualsNullCheck(SyntaxNode argument) => SyntaxFactory.BinaryExpression( - comparisonOperator, + SyntaxKind.EqualsExpression, (ExpressionSyntax)argument, SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)).Parenthesize(); @@ -28,17 +33,22 @@ private static SyntaxNode CreateIsNullCheck(SyntaxNode argument) (ExpressionSyntax)argument, SyntaxFactory.ConstantPattern(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression))).Parenthesize(); - private static SyntaxNode CreateIsNotNullCheck(SyntaxNode notExpression, SyntaxNode argument) - => ((PrefixUnaryExpressionSyntax)notExpression).WithOperand((ExpressionSyntax)CreateIsNullCheck(argument)); + private static SyntaxNode CreateIsNotNullCheck(SyntaxNode argument) + { + return SyntaxFactory + .BinaryExpression( + SyntaxKind.IsExpression, + (ExpressionSyntax)argument, + SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword))) + .Parenthesize(); + } protected override SyntaxNode CreateNullCheck(SyntaxNode argument, bool isUnconstrainedGeneric) => isUnconstrainedGeneric - ? CreateEqualsNullCheck(argument, SyntaxKind.EqualsExpression) + ? CreateEqualsNullCheck(argument) : CreateIsNullCheck(argument); - protected override SyntaxNode CreateNotNullCheck(SyntaxNode notExpression, SyntaxNode argument, bool isUnconstrainedGeneric) - => isUnconstrainedGeneric - ? CreateEqualsNullCheck(argument, SyntaxKind.NotEqualsExpression) - : CreateIsNotNullCheck(notExpression, argument); + protected override SyntaxNode CreateNotNullCheck(SyntaxNode argument) + => CreateIsNotNullCheck(argument); } } diff --git a/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs b/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs index 80ab1c155fa64..8259dacfe9c33 100644 --- a/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs @@ -26,6 +26,11 @@ internal class CSharpUseLocalFunctionCodeFixProvider : SyntaxEditorBasedCodeFixP { private static readonly TypeSyntax s_objectType = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)); + [ImportingConstructor] + public CSharpUseLocalFunctionCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseLocalFunctionDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseNamedArguments/CSharpUseNamedArgumentsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/UseNamedArguments/CSharpUseNamedArgumentsCodeRefactoringProvider.cs index 8b0315133e27c..66f5ebf60ba1b 100644 --- a/src/Features/CSharp/Portable/UseNamedArguments/CSharpUseNamedArgumentsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/UseNamedArguments/CSharpUseNamedArgumentsCodeRefactoringProvider.cs @@ -66,6 +66,7 @@ protected override AttributeArgumentSyntax WithName(AttributeArgumentSyntax argu => argument.WithNameColon(SyntaxFactory.NameColon(name.ToIdentifierName())); } + [ImportingConstructor] public CSharpUseNamedArgumentsCodeRefactoringProvider() : base(new ArgumentAnalyzer(), new AttributeArgumentAnalyzer()) { diff --git a/src/Features/CSharp/Portable/UseNullPropagation/CSharpUseNullPropagationCodeFixProvider.cs b/src/Features/CSharp/Portable/UseNullPropagation/CSharpUseNullPropagationCodeFixProvider.cs index e9edecd24c33b..aa03a9dd037d3 100644 --- a/src/Features/CSharp/Portable/UseNullPropagation/CSharpUseNullPropagationCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseNullPropagation/CSharpUseNullPropagationCodeFixProvider.cs @@ -18,5 +18,9 @@ internal class CSharpUseNullPropagationCodeFixProvider : AbstractUseNullPropagat ConditionalAccessExpressionSyntax, ElementAccessExpressionSyntax> { + [ImportingConstructor] + public CSharpUseNullPropagationCodeFixProvider() + { + } } } diff --git a/src/Features/CSharp/Portable/UseObjectInitializer/CSharpUseObjectInitializerCodeFixProvider.cs b/src/Features/CSharp/Portable/UseObjectInitializer/CSharpUseObjectInitializerCodeFixProvider.cs index 6749081cd242f..2544dabf1c898 100644 --- a/src/Features/CSharp/Portable/UseObjectInitializer/CSharpUseObjectInitializerCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseObjectInitializer/CSharpUseObjectInitializerCodeFixProvider.cs @@ -20,6 +20,11 @@ internal class CSharpUseObjectInitializerCodeFixProvider : ExpressionStatementSyntax, VariableDeclaratorSyntax> { + [ImportingConstructor] + public CSharpUseObjectInitializerCodeFixProvider() + { + } + protected override StatementSyntax GetNewStatement( StatementSyntax statement, ObjectCreationExpressionSyntax objectCreation, ImmutableArray> matches) diff --git a/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs b/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs index 51f166ba0a5a1..b63a39ba5132e 100644 --- a/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs @@ -23,6 +23,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UsePatternMatching [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal partial class CSharpAsAndNullCheckCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpAsAndNullCheckCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.InlineAsTypeCheckId); diff --git a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs index 96e96035478ee..9032b445baaaf 100644 --- a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UsePatternMatching [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal partial class CSharpIsAndCastCheckCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public CSharpIsAndCastCheckCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.InlineIsTypeCheckId); diff --git a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs index c8a4db93415e6..287d1b6523c77 100644 --- a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs @@ -20,6 +20,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UsePatternMatching [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal partial class CSharpIsAndCastCheckWithoutNameCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] public CSharpIsAndCastCheckWithoutNameCodeFixProvider() : base(supportsFixAll: false) { diff --git a/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs b/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs index a8e0ceb8b6a0d..fe053ec24c9f4 100644 --- a/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs @@ -21,6 +21,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UseSimpleUsingStatement [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(UseSimpleUsingStatementCodeFixProvider)), Shared] internal class UseSimpleUsingStatementCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseSimpleUsingStatementCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseSimpleUsingStatementDiagnosticId); diff --git a/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementDiagnosticAnalyzer.cs index 17983c11dfe1b..a68cc8ce6afaf 100644 --- a/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/UseSimpleUsingStatement/UseSimpleUsingStatementDiagnosticAnalyzer.cs @@ -1,11 +1,14 @@ // 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.Immutable; +using System.Linq; +using System.Threading; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.UseSimpleUsingStatement { @@ -96,6 +99,18 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) } var cancellationToken = context.CancellationToken; + + // Converting a using-statement to a using-variable-declaration will cause the using's + // variables to now be pushed up to the parent block's scope. This is also true for any + // local variables in the innermost using's block. These may then collide with other + // variables in the block, causing an error. Check for that and bail if this happens. + if (CausesVariableCollision( + context.SemanticModel, parentBlock, + outermostUsing, innermostUsing, cancellationToken)) + { + return; + } + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); if (optionSet == null) { @@ -117,6 +132,36 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) properties: null)); } + private bool CausesVariableCollision( + SemanticModel semanticModel, BlockSyntax parentBlock, + UsingStatementSyntax outermostUsing, UsingStatementSyntax innermostUsing, + CancellationToken cancellationToken) + { + var symbolNameToExistingSymbol = semanticModel.GetExistingSymbols(parentBlock, cancellationToken).ToLookup(s => s.Name); + + for (var current = outermostUsing; current != null; current = current.Statement as UsingStatementSyntax) + { + // Check if the using statement itself contains variables that will collide + // with other variables in the block. + var usingOperation = (IUsingOperation)semanticModel.GetOperation(current, cancellationToken); + if (DeclaredLocalCausesCollision(symbolNameToExistingSymbol, usingOperation.Locals)) + { + return true; + } + } + + var innerUsingOperation = (IUsingOperation)semanticModel.GetOperation(innermostUsing, cancellationToken); + if (innerUsingOperation.Body is IBlockOperation innerUsingBlock) + { + return DeclaredLocalCausesCollision(symbolNameToExistingSymbol, innerUsingBlock.Locals); + } + + return false; + } + + private static bool DeclaredLocalCausesCollision(ILookup symbolNameToExistingSymbol, ImmutableArray locals) + => locals.Any(local => symbolNameToExistingSymbol[local.Name].Any(otherLocal => !local.Equals(otherLocal))); + private static bool PreservesSemantics( BlockSyntax parentBlock, UsingStatementSyntax outermostUsing, @@ -132,7 +177,6 @@ private static bool PreservesSemantics( private static bool UsingStatementDoesNotInvolveJumps( SyntaxList parentStatements, int index, UsingStatementSyntax innermostUsing) { - // Jumps are not allowed to cross a using declaration in the forward direction, // and can't go back unless there is a curly brace between the using and the label. // diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf index a44ce681814ae..eacae31b947ec 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf @@ -62,6 +62,11 @@ Použít předvolby kvalifikace this. + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Převést na metodu @@ -122,6 +127,11 @@ Odebrat nepotřebné direktivy using + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Seřadit modifikátory dostupnosti @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified Příkaz if lze zjednodušit. diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf index 780f66dfa189f..e65edc9d75eea 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf @@ -62,6 +62,11 @@ Einstellungen zur Qualifikation "this." anwenden + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method In Methode konvertieren @@ -122,6 +127,11 @@ Nicht benötigte Using-Direktiven entfernen + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Zugriffsmodifizierer sortieren @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified Die If-Anweisung kann vereinfacht werden. diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf index ad8b06c964f57..07beda0e355f1 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf @@ -62,6 +62,11 @@ Aplicar preferencias de calificación “this.” + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Convertir al método @@ -122,6 +127,11 @@ Eliminar instrucciones Using innecesarias + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Ordenar modificadores de accesibilidad @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified La instrucción "if" se puede simplificar diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf index c77a277063491..ee0f4d1b98ed9 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf @@ -62,6 +62,11 @@ Appliquer les préférences de qualification 'this.' + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Convertir en méthode @@ -122,6 +127,11 @@ Supprimer les Usings inutiles + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Trier les modificateurs d'accessibilité @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified L'instruction 'if' peut être simplifiée diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf index 723544c88d076..b65ed5d8810f8 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf @@ -62,6 +62,11 @@ Applica le preferenze relative alla qualificazione 'this.' + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Converti in metodo @@ -122,6 +127,11 @@ Rimuovi istruzioni using non necessarie + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Ordina i modificatori di accessibilità @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified L'istruzione 'If' può essere semplificata diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf index 09ab8e156d788..1f97a41f75c14 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf @@ -62,6 +62,11 @@ 'this.' 修飾の基本設定を適用します + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method メソッドに変換 @@ -122,6 +127,11 @@ 不要な using の削除 + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers アクセシビリティ修飾子を並べ替える @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified 'if' ステートメントは簡素化できます diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf index 9d9a090323ad4..7b977e329b669 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf @@ -62,6 +62,11 @@ 'this.' 한정자 기본 설정 적용 + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method 메서드로 변환 @@ -122,6 +127,11 @@ 불필요한 Using 제거 + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers 접근성 한정자 정렬 @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified 'if' 문을 간단하게 줄일 수 있습니다. diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf index 14b9c895f36d5..f3eb6e748a176 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf @@ -62,6 +62,11 @@ Zastosuj preferencje kwalifikacji „this.” + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Konwertuj na metodę @@ -122,6 +127,11 @@ Usuń niepotrzebne użycia + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Sortuj modyfikatory dostępności @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified Instrukcja „if” może zostać uproszczona diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf index 742252ce350da..ef316ffb2b2e8 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf @@ -62,6 +62,11 @@ Aplicar as preferências de qualificação 'this.' + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Converter em método @@ -122,6 +127,11 @@ Remover Usos Desnecessários + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Classificar modificadores de acessibilidade @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified A instrução 'if' pode ser simplificada diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf index 5ace9c21b1407..d6914e564006d 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf @@ -62,6 +62,11 @@ Применять предпочтения для квалификации this. + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Преобразовать в метод @@ -122,6 +127,11 @@ Удалить ненужные директивы using + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Сортировать модификаторы доступности @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified Оператор if можно упростить diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf index 76627f2e25e4b..5ddc3984fede0 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf @@ -62,6 +62,11 @@ 'this.' nitelemesi tercihlerini uygula + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method Yönteme dönüştür @@ -122,6 +127,11 @@ Gereksiz Kullanımları Kaldır + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers Erişilebilirlik değiştiricilerini sırala @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified 'If' deyimi basitleştirilebilir diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf index ef8dfbaa00ef1..cfc3f30a61c34 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf @@ -62,6 +62,11 @@ 应用 “this.” 资格首选项 + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method 转换为方法 @@ -122,6 +127,11 @@ 删除不必要的 Using + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers 对可访问性修饰符排序 @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified 可简化“If”语句 diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf index a3d6fa8926700..0145ee5674053 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf @@ -62,6 +62,11 @@ 套用 'this.' 資格喜好設定 + + Convert switch statement to expression + Convert switch statement to expression + + Convert to method 轉換為方法 @@ -122,6 +127,11 @@ 移除不必要的 Using + + &Sort Usings + &Sort Usings + + Sort accessibility modifiers 排序協助工具修飾詞 @@ -132,6 +142,11 @@ Unseal class '{0}' + + Use 'switch' expression + Use 'switch' expression + + 'if' statement can be simplified 'if' 陳述式可簡化 diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs index f37d917c34ee1..d930012aa2a6e 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs @@ -22,6 +22,11 @@ namespace Microsoft.CodeAnalysis.AddConstructorParametersFromMembers Before = PredefinedCodeRefactoringProviderNames.GenerateOverrides)] internal partial class AddConstructorParametersFromMembersCodeRefactoringProvider : AbstractGenerateFromMembersCodeRefactoringProvider { + [ImportingConstructor] + public AddConstructorParametersFromMembersCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs index 3dac27625c03e..284e3320aae1e 100644 --- a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs @@ -317,7 +317,7 @@ private ImmutableArray PrepareCreationOfCodeActions( var methodToUpdate = argumentInsertPositionData.MethodToUpdate; var argumentToInsert = argumentInsertPositionData.ArgumentToInsert; - var cascadingFix = HasCascadingDeclarations(methodToUpdate) + var cascadingFix = AddParameterService.Instance.HasCascadingDeclarations(methodToUpdate) ? new Func>(c => FixAsync(document, methodToUpdate, argumentToInsert, arguments, fixAllReferences: true, c)) : null; @@ -332,52 +332,6 @@ private ImmutableArray PrepareCreationOfCodeActions( return builder.ToImmutableAndFree(); } - /// - /// Checks if there are indications that there might be more than one declarations that need to be fixed. - /// The check does not look-up if there are other declarations (this is done later in the CodeAction). - /// - private bool HasCascadingDeclarations(IMethodSymbol method) - { - // Don't cascade constructors - if (method.IsConstructor()) - { - return false; - } - - // Virtual methods of all kinds might have overrides somewhere else that need to be fixed. - if (method.IsVirtual || method.IsOverride || method.IsAbstract) - { - return true; - } - - // If interfaces are involved we will fix those too - // Explicit interface implementations are easy to detect - if (method.ExplicitInterfaceImplementations.Length > 0) - { - return true; - } - - // For implicit interface implementations lets check if the characteristic of the method - // allows it to implicit implement an interface member. - if (method.DeclaredAccessibility != Accessibility.Public) - { - return false; - } - - if (method.IsStatic) - { - return false; - } - - // Now check if the method does implement an interface member - if (method.ExplicitOrImplicitInterfaceImplementations().Length > 0) - { - return true; - } - - return false; - } - private static string GetCodeFixTitle(string resourceString, IMethodSymbol methodToUpdate, bool includeParameters) { var methodDisplay = methodToUpdate.ToDisplayString(new SymbolDisplayFormat( @@ -404,7 +358,6 @@ private async Task FixAsync( bool fixAllReferences, CancellationToken cancellationToken) { - var solution = invocationDocument.Project.Solution; var (argumentType, refKind) = await GetArgumentTypeAndRefKindAsync(invocationDocument, argument, cancellationToken).ConfigureAwait(false); // The argumentNameSuggestion is the base for the parameter name. @@ -412,66 +365,16 @@ private async Task FixAsync( var (argumentNameSuggestion, isNamedArgument) = await GetNameSuggestionForArgumentAsync( invocationDocument, argument, cancellationToken).ConfigureAwait(false); - var referencedSymbols = fixAllReferences - ? await FindMethodDeclarationReferences(invocationDocument, method, cancellationToken).ConfigureAwait(false) - : method.GetAllMethodSymbolsOfPartialParts(); - - var anySymbolReferencesNotInSource = referencedSymbols.Any(symbol => !symbol.IsFromSource()); - var locationsInSource = referencedSymbols.Where(symbol => symbol.IsFromSource()); - - // Indexing Locations[0] is valid because IMethodSymbols have one location at most - // and IsFromSource() tests if there is at least one location. - var locationsByDocument = locationsInSource.ToLookup(declarationLocation - => solution.GetDocument(declarationLocation.Locations[0].SourceTree)); - - foreach (var documentLookup in locationsByDocument) - { - var document = documentLookup.Key; - var syntaxFacts = document.GetLanguageService(); - var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var editor = new SyntaxEditor(syntaxRoot, solution.Workspace); - var generator = editor.Generator; - foreach (var methodDeclaration in documentLookup) - { - var methodNode = syntaxRoot.FindNode(methodDeclaration.Locations[0].SourceSpan); - var existingParameters = generator.GetParameters(methodNode); - var insertionIndex = isNamedArgument - ? existingParameters.Count - : argumentList.IndexOf(argument); - - // if the preceding parameter is optional, the new parameter must also be optional - // see also BC30202 and CS1737 - var parameterMustBeOptional = insertionIndex > 0 && - syntaxFacts.GetDefaultOfParameter(existingParameters[insertionIndex - 1]) != null; - - var parameterSymbol = CreateParameterSymbol( - methodDeclaration, argumentType, refKind, parameterMustBeOptional, argumentNameSuggestion); - - var argumentInitializer = parameterMustBeOptional ? generator.DefaultExpression(argumentType) : null; - var parameterDeclaration = generator.ParameterDeclaration(parameterSymbol, argumentInitializer) - .WithAdditionalAnnotations(Formatter.Annotation); - if (anySymbolReferencesNotInSource && methodDeclaration == method) - { - parameterDeclaration = parameterDeclaration.WithAdditionalAnnotations( - ConflictAnnotation.Create(FeaturesResources.Related_method_signatures_found_in_metadata_will_not_be_updated)); - } - - - if (method.MethodKind == MethodKind.ReducedExtension) - { - insertionIndex++; - } - - AddParameter( - syntaxFacts, editor, methodNode, argument, - insertionIndex, parameterDeclaration, cancellationToken); - } - - var newRoot = editor.GetChangedRoot(); - solution = solution.WithDocumentSyntaxRoot(document.Id, newRoot); - } - - return solution; + var newParameterIndex = isNamedArgument ? (int?)null : argumentList.IndexOf(argument); + return await AddParameterService.Instance.AddParameterAsync( + invocationDocument, + method, + argumentType, + refKind, + argumentNameSuggestion, + newParameterIndex, + fixAllReferences, + cancellationToken).ConfigureAwait(false); } private static async Task<(ITypeSymbol, RefKind)> GetArgumentTypeAndRefKindAsync(Document invocationDocument, TArgumentSyntax argument, CancellationToken cancellationToken) @@ -484,25 +387,6 @@ private async Task FixAsync( return (argumentType, refKind); } - private static async Task> FindMethodDeclarationReferences( - Document invocationDocument, IMethodSymbol method, CancellationToken cancellationToken) - { - var progress = new StreamingProgressCollector(StreamingFindReferencesProgress.Instance); - - await SymbolFinder.FindReferencesAsync( - symbolAndProjectId: SymbolAndProjectId.Create(method, invocationDocument.Project.Id), - solution: invocationDocument.Project.Solution, - documents: null, - progress: progress, - options: FindReferencesSearchOptions.Default, - cancellationToken: cancellationToken).ConfigureAwait(false); - var referencedSymbols = progress.GetReferencedSymbols(); - return referencedSymbols.Select(referencedSymbol => referencedSymbol.Definition) - .OfType() - .Distinct() - .ToImmutableArray(); - } - private async Task<(string argumentNameSuggestion, bool isNamed)> GetNameSuggestionForArgumentAsync( Document invocationDocument, TArgumentSyntax argument, CancellationToken cancellationToken) { @@ -524,178 +408,6 @@ await SymbolFinder.FindReferencesAsync( } } - private IParameterSymbol CreateParameterSymbol( - IMethodSymbol method, - ITypeSymbol parameterType, - RefKind refKind, - bool isOptional, - string argumentNameSuggestion) - { - var uniqueName = NameGenerator.EnsureUniqueness(argumentNameSuggestion, method.Parameters.Select(p => p.Name)); - var newParameterSymbol = CodeGenerationSymbolFactory.CreateParameterSymbol( - attributes: default, refKind: refKind, isOptional: isOptional, isParams: false, type: parameterType, name: uniqueName); - return newParameterSymbol; - } - - private static void AddParameter( - ISyntaxFactsService syntaxFacts, - SyntaxEditor editor, - SyntaxNode declaration, - TArgumentSyntax argument, - int insertionIndex, - SyntaxNode parameterDeclaration, - CancellationToken cancellationToken) - { - var sourceText = declaration.SyntaxTree.GetText(cancellationToken); - var generator = editor.Generator; - - var existingParameters = generator.GetParameters(declaration); - var placeOnNewLine = ShouldPlaceParametersOnNewLine(existingParameters, cancellationToken); - - if (!placeOnNewLine) - { - // Trivial case. Just let the stock editor impl handle this for us. - editor.InsertParameter(declaration, insertionIndex, parameterDeclaration); - return; - } - - if (insertionIndex == existingParameters.Count) - { - // Placing the last parameter on its own line. Get the indentation of the - // curent last parameter and give the new last parameter the same indentation. - var leadingIndentation = GetDesiredLeadingIndentation( - generator, syntaxFacts, existingParameters[existingParameters.Count - 1], includeLeadingNewLine: true); - parameterDeclaration = parameterDeclaration.WithPrependedLeadingTrivia(leadingIndentation) - .WithAdditionalAnnotations(Formatter.Annotation); - - editor.AddParameter(declaration, parameterDeclaration); - } - else if (insertionIndex == 0) - { - // Inserting into the start of the list. The existing first parameter might - // be on the same line as the parameter list, or it might be on the next line. - var firstParameter = existingParameters[0]; - var previousToken = firstParameter.GetFirstToken().GetPreviousToken(); - - if (sourceText.AreOnSameLine(previousToken, firstParameter.GetFirstToken())) - { - // First parameter is on hte same line as the method. - - // We want to insert the parameter at the front of the exsiting parameter - // list. That means we need to move the current first parameter to a new - // line. Give the current first parameter the indentation of the second - // parameter in the list. - editor.InsertParameter(declaration, insertionIndex, parameterDeclaration); - var nextParameter = existingParameters[insertionIndex]; - - var nextLeadingIndentation = GetDesiredLeadingIndentation( - generator, syntaxFacts, existingParameters[insertionIndex + 1], includeLeadingNewLine: true); - editor.ReplaceNode( - nextParameter, - nextParameter.WithPrependedLeadingTrivia(nextLeadingIndentation) - .WithAdditionalAnnotations(Formatter.Annotation)); - } - else - { - // First parameter is on its own line. No need to adjust its indentation. - // Just copy its indentation over to the parameter we're inserting, and - // make sure the current first parameter gets a newline so it stays on - // its own line. - - // We want to insert the parameter at the front of the exsiting parameter - // list. That means we need to move the current first parameter to a new - // line. Give the current first parameter the indentation of the second - // parameter in the list. - var firstLeadingIndentation = GetDesiredLeadingIndentation( - generator, syntaxFacts, existingParameters[0], includeLeadingNewLine: false); - - editor.InsertParameter(declaration, insertionIndex, - parameterDeclaration.WithLeadingTrivia(firstLeadingIndentation)); - var nextParameter = existingParameters[insertionIndex]; - - editor.ReplaceNode( - nextParameter, - nextParameter.WithPrependedLeadingTrivia(generator.ElasticCarriageReturnLineFeed) - .WithAdditionalAnnotations(Formatter.Annotation)); - } - } - else - { - // We're inserting somewhere after the start (but not at the end). Because - // we've set placeOnNewLine, we know that the current comma we'll be placed - // after already have a newline following it. So all we need for this new - // parameter is to get the indentation of the following parameter. - // Because we're going to 'steal' the existing comma from that parameter, - // ensure that the next parameter has a new-line added to it so that it will - // still stay on a new line. - var nextParameter = existingParameters[insertionIndex]; - var leadingIndentation = GetDesiredLeadingIndentation( - generator, syntaxFacts, existingParameters[insertionIndex], includeLeadingNewLine: false); - parameterDeclaration = parameterDeclaration.WithPrependedLeadingTrivia(leadingIndentation); - - editor.InsertParameter(declaration, insertionIndex, parameterDeclaration); - editor.ReplaceNode( - nextParameter, - nextParameter.WithPrependedLeadingTrivia(generator.ElasticCarriageReturnLineFeed) - .WithAdditionalAnnotations(Formatter.Annotation)); - } - } - - private static List GetDesiredLeadingIndentation( - SyntaxGenerator generator, ISyntaxFactsService syntaxFacts, - SyntaxNode node, bool includeLeadingNewLine) - { - var triviaList = new List(); - if (includeLeadingNewLine) - { - triviaList.Add(generator.ElasticCarriageReturnLineFeed); - } - - var lastWhitespace = default(SyntaxTrivia); - foreach (var trivia in node.GetLeadingTrivia().Reverse()) - { - if (syntaxFacts.IsWhitespaceTrivia(trivia)) - { - lastWhitespace = trivia; - } - else if (syntaxFacts.IsEndOfLineTrivia(trivia)) - { - break; - } - } - - if (lastWhitespace.RawKind != 0) - { - triviaList.Add(lastWhitespace); - } - - return triviaList; - } - - private static bool ShouldPlaceParametersOnNewLine( - IReadOnlyList parameters, CancellationToken cancellationToken) - { - if (parameters.Count <= 1) - { - return false; - } - - var text = parameters[0].SyntaxTree.GetText(cancellationToken); - for (int i = 1, n = parameters.Count; i < n; i++) - { - var lastParameter = parameters[i - 1]; - var thisParameter = parameters[i]; - - if (text.AreOnSameLine(lastParameter.GetLastToken(), thisParameter.GetFirstToken())) - { - return false; - } - } - - // All parameters are on different lines. Place the new parameter on a new line as well. - return true; - } - private static readonly SymbolDisplayFormat SimpleFormat = new SymbolDisplayFormat( typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly, diff --git a/src/Features/Core/Portable/AddParameter/AddParameterService.cs b/src/Features/Core/Portable/AddParameter/AddParameterService.cs new file mode 100644 index 0000000000000..57d09044a81d9 --- /dev/null +++ b/src/Features/Core/Portable/AddParameter/AddParameterService.cs @@ -0,0 +1,329 @@ +// 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.Collections.Immutable; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.LanguageServices; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.Utilities; + +namespace Microsoft.CodeAnalysis.AddParameter +{ + internal class AddParameterService : IAddParameterService + { + private AddParameterService() + { + } + + public static AddParameterService Instance = new AddParameterService(); + + public bool HasCascadingDeclarations(IMethodSymbol method) + { + // Don't cascade constructors + if (method.IsConstructor()) + { + return false; + } + + // Virtual methods of all kinds might have overrides somewhere else that need to be fixed. + if (method.IsVirtual || method.IsOverride || method.IsAbstract) + { + return true; + } + + // If interfaces are involved we will fix those too + // Explicit interface implementations are easy to detect + if (method.ExplicitInterfaceImplementations.Length > 0) + { + return true; + } + + // For implicit interface implementations lets check if the characteristic of the method + // allows it to implicit implement an interface member. + if (method.DeclaredAccessibility != Accessibility.Public) + { + return false; + } + + if (method.IsStatic) + { + return false; + } + + // Now check if the method does implement an interface member + if (method.ExplicitOrImplicitInterfaceImplementations().Length > 0) + { + return true; + } + + return false; + } + + public async Task AddParameterAsync( + Document invocationDocument, + IMethodSymbol method, + ITypeSymbol newParamaterType, + RefKind refKind, + string parameterName, + int? newParameterIndex, + bool fixAllReferences, + CancellationToken cancellationToken) + { + var solution = invocationDocument.Project.Solution; + + var referencedSymbols = fixAllReferences + ? await FindMethodDeclarationReferences(invocationDocument, method, cancellationToken).ConfigureAwait(false) + : method.GetAllMethodSymbolsOfPartialParts(); + + var anySymbolReferencesNotInSource = referencedSymbols.Any(symbol => !symbol.IsFromSource()); + var locationsInSource = referencedSymbols.Where(symbol => symbol.IsFromSource()); + + // Indexing Locations[0] is valid because IMethodSymbols have one location at most + // and IsFromSource() tests if there is at least one location. + var locationsByDocument = locationsInSource.ToLookup(declarationLocation + => solution.GetDocument(declarationLocation.Locations[0].SourceTree)); + + foreach (var documentLookup in locationsByDocument) + { + var document = documentLookup.Key; + var syntaxFacts = document.GetLanguageService(); + var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var editor = new SyntaxEditor(syntaxRoot, solution.Workspace); + var generator = editor.Generator; + foreach (var methodDeclaration in documentLookup) + { + var methodNode = syntaxRoot.FindNode(methodDeclaration.Locations[0].SourceSpan); + var existingParameters = generator.GetParameters(methodNode); + var insertionIndex = newParameterIndex ?? existingParameters.Count; + + // if the preceding parameter is optional, the new parameter must also be optional + // see also BC30202 and CS1737 + var parameterMustBeOptional = insertionIndex > 0 && + syntaxFacts.GetDefaultOfParameter(existingParameters[insertionIndex - 1]) != null; + + var parameterSymbol = CreateParameterSymbol( + methodDeclaration, newParamaterType, refKind, parameterMustBeOptional, parameterName); + + var argumentInitializer = parameterMustBeOptional ? generator.DefaultExpression(newParamaterType) : null; + var parameterDeclaration = generator.ParameterDeclaration(parameterSymbol, argumentInitializer) + .WithAdditionalAnnotations(Formatter.Annotation); + if (anySymbolReferencesNotInSource && methodDeclaration == method) + { + parameterDeclaration = parameterDeclaration.WithAdditionalAnnotations( + ConflictAnnotation.Create(FeaturesResources.Related_method_signatures_found_in_metadata_will_not_be_updated)); + } + + + if (method.MethodKind == MethodKind.ReducedExtension) + { + insertionIndex++; + } + + AddParameter(syntaxFacts, editor, methodNode, insertionIndex, parameterDeclaration, cancellationToken); + } + + var newRoot = editor.GetChangedRoot(); + solution = solution.WithDocumentSyntaxRoot(document.Id, newRoot); + } + + return solution; + } + + private static async Task> FindMethodDeclarationReferences( + Document invocationDocument, IMethodSymbol method, CancellationToken cancellationToken) + { + var progress = new StreamingProgressCollector(StreamingFindReferencesProgress.Instance); + + await SymbolFinder.FindReferencesAsync( + symbolAndProjectId: SymbolAndProjectId.Create(method, invocationDocument.Project.Id), + solution: invocationDocument.Project.Solution, + documents: null, + progress: progress, + options: FindReferencesSearchOptions.Default, + cancellationToken: cancellationToken).ConfigureAwait(false); + var referencedSymbols = progress.GetReferencedSymbols(); + return referencedSymbols.Select(referencedSymbol => referencedSymbol.Definition) + .OfType() + .Distinct() + .ToImmutableArray(); + } + + private IParameterSymbol CreateParameterSymbol( + IMethodSymbol method, + ITypeSymbol parameterType, + RefKind refKind, + bool isOptional, + string argumentNameSuggestion) + { + var uniqueName = NameGenerator.EnsureUniqueness(argumentNameSuggestion, method.Parameters.Select(p => p.Name)); + var newParameterSymbol = CodeGenerationSymbolFactory.CreateParameterSymbol( + attributes: default, refKind: refKind, isOptional: isOptional, isParams: false, type: parameterType, name: uniqueName); + return newParameterSymbol; + } + + private static void AddParameter( + ISyntaxFactsService syntaxFacts, + SyntaxEditor editor, + SyntaxNode declaration, + int insertionIndex, + SyntaxNode parameterDeclaration, + CancellationToken cancellationToken) + { + var sourceText = declaration.SyntaxTree.GetText(cancellationToken); + var generator = editor.Generator; + + var existingParameters = generator.GetParameters(declaration); + var placeOnNewLine = ShouldPlaceParametersOnNewLine(existingParameters, cancellationToken); + + if (!placeOnNewLine) + { + // Trivial case. Just let the stock editor impl handle this for us. + editor.InsertParameter(declaration, insertionIndex, parameterDeclaration); + return; + } + + if (insertionIndex == existingParameters.Count) + { + // Placing the last parameter on its own line. Get the indentation of the + // curent last parameter and give the new last parameter the same indentation. + var leadingIndentation = GetDesiredLeadingIndentation( + generator, syntaxFacts, existingParameters[existingParameters.Count - 1], includeLeadingNewLine: true); + parameterDeclaration = parameterDeclaration.WithPrependedLeadingTrivia(leadingIndentation) + .WithAdditionalAnnotations(Formatter.Annotation); + + editor.AddParameter(declaration, parameterDeclaration); + } + else if (insertionIndex == 0) + { + // Inserting into the start of the list. The existing first parameter might + // be on the same line as the parameter list, or it might be on the next line. + var firstParameter = existingParameters[0]; + var previousToken = firstParameter.GetFirstToken().GetPreviousToken(); + + if (sourceText.AreOnSameLine(previousToken, firstParameter.GetFirstToken())) + { + // First parameter is on hte same line as the method. + + // We want to insert the parameter at the front of the exsiting parameter + // list. That means we need to move the current first parameter to a new + // line. Give the current first parameter the indentation of the second + // parameter in the list. + editor.InsertParameter(declaration, insertionIndex, parameterDeclaration); + var nextParameter = existingParameters[insertionIndex]; + + var nextLeadingIndentation = GetDesiredLeadingIndentation( + generator, syntaxFacts, existingParameters[insertionIndex + 1], includeLeadingNewLine: true); + editor.ReplaceNode( + nextParameter, + nextParameter.WithPrependedLeadingTrivia(nextLeadingIndentation) + .WithAdditionalAnnotations(Formatter.Annotation)); + } + else + { + // First parameter is on its own line. No need to adjust its indentation. + // Just copy its indentation over to the parameter we're inserting, and + // make sure the current first parameter gets a newline so it stays on + // its own line. + + // We want to insert the parameter at the front of the exsiting parameter + // list. That means we need to move the current first parameter to a new + // line. Give the current first parameter the indentation of the second + // parameter in the list. + var firstLeadingIndentation = GetDesiredLeadingIndentation( + generator, syntaxFacts, existingParameters[0], includeLeadingNewLine: false); + + editor.InsertParameter(declaration, insertionIndex, + parameterDeclaration.WithLeadingTrivia(firstLeadingIndentation)); + var nextParameter = existingParameters[insertionIndex]; + + editor.ReplaceNode( + nextParameter, + nextParameter.WithPrependedLeadingTrivia(generator.ElasticCarriageReturnLineFeed) + .WithAdditionalAnnotations(Formatter.Annotation)); + } + } + else + { + // We're inserting somewhere after the start (but not at the end). Because + // we've set placeOnNewLine, we know that the current comma we'll be placed + // after already have a newline following it. So all we need for this new + // parameter is to get the indentation of the following parameter. + // Because we're going to 'steal' the existing comma from that parameter, + // ensure that the next parameter has a new-line added to it so that it will + // still stay on a new line. + var nextParameter = existingParameters[insertionIndex]; + var leadingIndentation = GetDesiredLeadingIndentation( + generator, syntaxFacts, existingParameters[insertionIndex], includeLeadingNewLine: false); + parameterDeclaration = parameterDeclaration.WithPrependedLeadingTrivia(leadingIndentation); + + editor.InsertParameter(declaration, insertionIndex, parameterDeclaration); + editor.ReplaceNode( + nextParameter, + nextParameter.WithPrependedLeadingTrivia(generator.ElasticCarriageReturnLineFeed) + .WithAdditionalAnnotations(Formatter.Annotation)); + } + } + + private static List GetDesiredLeadingIndentation( + SyntaxGenerator generator, ISyntaxFactsService syntaxFacts, + SyntaxNode node, bool includeLeadingNewLine) + { + var triviaList = new List(); + if (includeLeadingNewLine) + { + triviaList.Add(generator.ElasticCarriageReturnLineFeed); + } + + var lastWhitespace = default(SyntaxTrivia); + foreach (var trivia in node.GetLeadingTrivia().Reverse()) + { + if (syntaxFacts.IsWhitespaceTrivia(trivia)) + { + lastWhitespace = trivia; + } + else if (syntaxFacts.IsEndOfLineTrivia(trivia)) + { + break; + } + } + + if (lastWhitespace.RawKind != 0) + { + triviaList.Add(lastWhitespace); + } + + return triviaList; + } + + private static bool ShouldPlaceParametersOnNewLine( + IReadOnlyList parameters, CancellationToken cancellationToken) + { + if (parameters.Count <= 1) + { + return false; + } + + var text = parameters[0].SyntaxTree.GetText(cancellationToken); + for (int i = 1, n = parameters.Count; i < n; i++) + { + var lastParameter = parameters[i - 1]; + var thisParameter = parameters[i]; + + if (text.AreOnSameLine(lastParameter.GetLastToken(), thisParameter.GetFirstToken())) + { + return false; + } + } + + // All parameters are on different lines. Place the new parameter on a new line as well. + return true; + } + } +} diff --git a/src/Features/Core/Portable/AddParameter/IAddParameterService.cs b/src/Features/Core/Portable/AddParameter/IAddParameterService.cs new file mode 100644 index 0000000000000..ebaf7eb7772e5 --- /dev/null +++ b/src/Features/Core/Portable/AddParameter/IAddParameterService.cs @@ -0,0 +1,29 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.CodeAnalysis.AddParameter +{ + internal interface IAddParameterService + { + /// + /// Checks if there are indications that there might be more than one declarations that need to be fixed. + /// The check does not look-up if there are other declarations (this is done later in the CodeAction). + /// + bool HasCascadingDeclarations(IMethodSymbol method); + + /// + /// Adds a parameter to a method. + /// + /// to add as the final parameter + /// + Task AddParameterAsync( + Document invocationDocument, + IMethodSymbol method, + ITypeSymbol newParamaterType, + RefKind refKind, + string parameterName, + int? newParameterIndex, + bool fixAllReferences, + CancellationToken cancellationToken); + } +} diff --git a/src/Features/Core/Portable/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs b/src/Features/Core/Portable/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs index c51df1edb88e4..392250f1ae0b7 100644 --- a/src/Features/Core/Portable/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.AddRequiredParentheses [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared] internal class AddRequiredParenthesesCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public AddRequiredParenthesesCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.AddRequiredParenthesesDiagnosticId); diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs index dcd6d5eec9573..e6de8462aa35e 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.ChangeSignature Name = PredefinedCodeRefactoringProviderNames.ChangeSignature), Shared] internal class ChangeSignatureCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public ChangeSignatureCodeRefactoringProvider() + { + } + public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { if (context.Span.IsEmpty) diff --git a/src/Features/Core/Portable/CodeFixes/NamingStyle/NamingStyleCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/NamingStyle/NamingStyleCodeFixProvider.cs index 86fd3f317bad7..16ca2d8f8175c 100644 --- a/src/Features/Core/Portable/CodeFixes/NamingStyle/NamingStyleCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/NamingStyle/NamingStyleCodeFixProvider.cs @@ -23,6 +23,11 @@ namespace Microsoft.CodeAnalysis.CodeFixes.NamingStyles Name = PredefinedCodeFixProviderNames.ApplyNamingStyle), Shared] internal class NamingStyleCodeFixProvider : CodeFixProvider { + [ImportingConstructor] + public NamingStyleCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.NamingRuleId); diff --git a/src/Features/Core/Portable/CodeLens/CodeLensReferencesServiceFactory.cs b/src/Features/Core/Portable/CodeLens/CodeLensReferencesServiceFactory.cs index e3d2b6fec6a6e..53b35cfc85175 100644 --- a/src/Features/Core/Portable/CodeLens/CodeLensReferencesServiceFactory.cs +++ b/src/Features/Core/Portable/CodeLens/CodeLensReferencesServiceFactory.cs @@ -11,6 +11,11 @@ internal sealed class CodeLensReferencesServiceFactory : IWorkspaceServiceFactor { public static readonly ICodeLensReferencesService Instance = new CodeLensReferencesService(); + [ImportingConstructor] + public CodeLensReferencesServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return Instance; diff --git a/src/Features/Core/Portable/CodeQuality/AbstractCodeQualityDiagnosticAnalyzer.cs b/src/Features/Core/Portable/CodeQuality/AbstractCodeQualityDiagnosticAnalyzer.cs index 6ff64070bcb0c..8774f8dd3211a 100644 --- a/src/Features/Core/Portable/CodeQuality/AbstractCodeQualityDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/CodeQuality/AbstractCodeQualityDiagnosticAnalyzer.cs @@ -41,12 +41,14 @@ protected static DiagnosticDescriptor CreateDescriptor( bool isUnneccessary, bool isEnabledByDefault = true, bool isConfigurable = true, + LocalizableString description = null, params string[] customTags) => new DiagnosticDescriptor( id, title, messageFormat, DiagnosticCategory.CodeQuality, DiagnosticSeverity.Info, isEnabledByDefault, + description, customTags: DiagnosticCustomTags.Create(isUnneccessary, isConfigurable, customTags)); } } diff --git a/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs index 2f561f53d92d2..46f66cd9693d3 100644 --- a/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.CodeRefactorings.ExtractMethod Name = PredefinedCodeRefactoringProviderNames.ExtractMethod), Shared] internal class ExtractMethodCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public ExtractMethodCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { // Don't bother if there isn't a selection diff --git a/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs index 18d9d82fb09ef..bf4840ea9c379 100644 --- a/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.CodeRefactorings.MoveType Name = PredefinedCodeRefactoringProviderNames.MoveTypeToFile), Shared] internal class MoveTypeCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public MoveTypeCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/CodeRefactorings/ServicesLayerCodeActionHelpersService.cs b/src/Features/Core/Portable/CodeRefactorings/ServicesLayerCodeActionHelpersService.cs index 47a8b69d77788..8c01afc3f6146 100644 --- a/src/Features/Core/Portable/CodeRefactorings/ServicesLayerCodeActionHelpersService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/ServicesLayerCodeActionHelpersService.cs @@ -9,6 +9,11 @@ namespace Microsoft.CodeAnalysis.CodeRefactorings [ExportWorkspaceServiceFactory(typeof(ICodeRefactoringHelpersService), ServiceLayer.Default), Shared] internal class ServicesLayerCodeActionHelpersService : IWorkspaceServiceFactory { + [ImportingConstructor] + public ServicesLayerCodeActionHelpersService() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return new CodeActionHelpersService(); diff --git a/src/Features/Core/Portable/Completion/CompletionHelperServiceFactory.cs b/src/Features/Core/Portable/Completion/CompletionHelperServiceFactory.cs index 9d76d69c441a9..f8d5da53f95a0 100644 --- a/src/Features/Core/Portable/Completion/CompletionHelperServiceFactory.cs +++ b/src/Features/Core/Portable/Completion/CompletionHelperServiceFactory.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.Completion [ExportWorkspaceServiceFactory(typeof(ICompletionHelperService)), Shared] internal class CompletionHelperServiceFactory : IWorkspaceServiceFactory { + [ImportingConstructor] + public CompletionHelperServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return new Service(workspaceServices.Workspace); diff --git a/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs b/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs index 80399689dc1b9..42317ebc34b18 100644 --- a/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs +++ b/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Completion [ExportOptionProvider, Shared] internal class CompletionOptionsProvider : IOptionProvider { + [ImportingConstructor] + public CompletionOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( CompletionOptions.HideAdvancedMembers, CompletionOptions.TriggerOnTyping, diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs index d4c1b85520cdd..57ba21a5d612d 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs @@ -66,7 +66,11 @@ protected override CompletionItem CreateItem( var matchPriority = preselect ? ComputeSymbolMatchPriority(symbols[0]) : MatchPriority.Default; rules = rules.WithMatchPriority(matchPriority); - if (preselect) + if (context.IsRightSideOfNumericType) + { + rules = rules.WithSelectionBehavior(CompletionItemSelectionBehavior.SoftSelection); + } + else if (preselect) { rules = rules.WithSelectionBehavior(PreselectedItemSelectionBehavior); } diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs index 6ba8c638be510..314acf02e3312 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs @@ -267,8 +267,9 @@ protected virtual CompletionItem CreateItem( contextPosition: context.Position, symbols: symbols, supportedPlatforms: supportedPlatformData, - rules: GetCompletionItemRules(symbols).WithMatchPriority( - preselect ? MatchPriority.Preselect : MatchPriority.Default)); + rules: GetCompletionItemRules(symbols) + .WithMatchPriority(preselect ? MatchPriority.Preselect : MatchPriority.Default) + .WithSelectionBehavior(context.IsRightSideOfNumericType ? CompletionItemSelectionBehavior.SoftSelection : CompletionItemSelectionBehavior.Default)); } protected virtual string GetFilterText(ISymbol symbol, string displayText, SyntaxContext context) @@ -314,10 +315,12 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) using (Logger.LogBlock(FunctionId.Completion_SymbolCompletionProvider_GetItemsWorker, cancellationToken)) { - var regularItems = await GetItemsWorkerAsync(document, position, options, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false); + var syntaxContext = await GetOrCreateContext(document, position, cancellationToken).ConfigureAwait(false); + + var regularItems = await GetItemsWorkerAsync(syntaxContext, document, position, options, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false); context.AddItems(regularItems); - var preselectedItems = await GetItemsWorkerAsync(document, position, options, preselect: true, cancellationToken: cancellationToken).ConfigureAwait(false); + var preselectedItems = await GetItemsWorkerAsync(syntaxContext, document, position, options, preselect: true, cancellationToken: cancellationToken).ConfigureAwait(false); context.AddItems(preselectedItems); } } @@ -328,11 +331,10 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) } private async Task> GetItemsWorkerAsync( - Document document, int position, OptionSet options, bool preselect, CancellationToken cancellationToken) + SyntaxContext context, Document document, int position, OptionSet options, bool preselect, CancellationToken cancellationToken) { var relatedDocumentIds = GetRelatedDocumentIds(document, position); - var context = await GetOrCreateContext(document, position, cancellationToken).ConfigureAwait(false); options = GetUpdatedRecommendationOptions(options, document.Project.Language); var typeInferenceService = document.GetLanguageService(); diff --git a/src/Features/Core/Portable/Completion/Providers/TypeImportCompletionService.cs b/src/Features/Core/Portable/Completion/Providers/TypeImportCompletionService.cs index 224fb2b2d3d97..6face83fda29a 100644 --- a/src/Features/Core/Portable/Completion/Providers/TypeImportCompletionService.cs +++ b/src/Features/Core/Portable/Completion/Providers/TypeImportCompletionService.cs @@ -56,6 +56,11 @@ private readonly ConcurrentDictionary _peItemsCache private readonly ConcurrentDictionary _projectItemsCache = new ConcurrentDictionary(); + [ImportingConstructor] + public TypeImportCompletionService() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { var workspace = workspaceServices.Workspace; diff --git a/src/Features/Core/Portable/Diagnostics/Analyzers/IDEDiagnosticIds.cs b/src/Features/Core/Portable/Diagnostics/Analyzers/IDEDiagnosticIds.cs index a42770a665f62..44ea5b25a86ce 100644 --- a/src/Features/Core/Portable/Diagnostics/Analyzers/IDEDiagnosticIds.cs +++ b/src/Features/Core/Portable/Diagnostics/Analyzers/IDEDiagnosticIds.cs @@ -109,6 +109,12 @@ internal static class IDEDiagnosticIds public const string MoveMisplacedUsingDirectivesDiagnosticId = "IDE0065"; + public const string ConvertSwitchStatementToExpressionDiagnosticId = "IDE0066"; + + public const string DisposeObjectsBeforeLosingScopeDiagnosticId = "IDE0067"; + public const string UseRecommendedDisposePatternDiagnosticId = "IDE0068"; + public const string DisposableFieldsShouldBeDisposedDiagnosticId = "IDE0069"; + // Analyzer error Ids public const string AnalyzerChangedId = "IDE1001"; public const string AnalyzerDependencyConflictId = "IDE1002"; diff --git a/src/Features/Core/Portable/Diagnostics/InternalDiagnosticsOptionsProvider.cs b/src/Features/Core/Portable/Diagnostics/InternalDiagnosticsOptionsProvider.cs index b100358b82e2d..2126b56fdfeb3 100644 --- a/src/Features/Core/Portable/Diagnostics/InternalDiagnosticsOptionsProvider.cs +++ b/src/Features/Core/Portable/Diagnostics/InternalDiagnosticsOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Diagnostics [ExportOptionProvider, Shared] internal class InternalDiagnosticsOptionsProvider : IOptionProvider { + [ImportingConstructor] + public InternalDiagnosticsOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( InternalDiagnosticsOptions.BlueSquiggleForBuildDiagnostic, InternalDiagnosticsOptions.CompilationEndCodeFix, diff --git a/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs b/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs new file mode 100644 index 0000000000000..c780f3f50c607 --- /dev/null +++ b/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs @@ -0,0 +1,275 @@ +// 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.Concurrent; +using System.Collections.Immutable; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading; +using Microsoft.CodeAnalysis.CodeQuality; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.FlowAnalysis; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.DisposeAnalysis; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.PointsToAnalysis; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.DisposeAnalysis +{ + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + internal sealed class DisposableFieldsShouldBeDisposedDiagnosticAnalyzer + : AbstractCodeQualityDiagnosticAnalyzer + { + private static readonly DiagnosticDescriptor s_disposableFieldsShouldBeDisposedRule = CreateDescriptor( + IDEDiagnosticIds.DisposableFieldsShouldBeDisposedDiagnosticId, + title: new LocalizableResourceString(nameof(FeaturesResources.Disposable_fields_should_be_disposed), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + messageFormat: new LocalizableResourceString(nameof(FeaturesResources.Disposable_field_0_is_never_disposed), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + description: new LocalizableResourceString(nameof(FeaturesResources.DisposableFieldsShouldBeDisposedDescription), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + isUnneccessary: false); + + public DisposableFieldsShouldBeDisposedDiagnosticAnalyzer() + : base(ImmutableArray.Create(s_disposableFieldsShouldBeDisposedRule), GeneratedCodeAnalysisFlags.Analyze) + { + } + + public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticDocumentAnalysis; + + protected override void InitializeWorker(AnalysisContext context) + { + context.RegisterCompilationStartAction(compilationContext => + { + if (!DisposeAnalysisHelper.TryCreate(compilationContext.Compilation, out var disposeAnalysisHelper)) + { + return; + } + + // Register a symbol start action to analyze all named types. + compilationContext.RegisterSymbolStartAction( + symbolStartContext => SymbolAnalyzer.OnSymbolStart(symbolStartContext, disposeAnalysisHelper), + SymbolKind.NamedType); + }); + } + + private sealed class SymbolAnalyzer + { + private readonly ImmutableHashSet _disposableFields; + private readonly ConcurrentDictionary _fieldDisposeValueMap; + private readonly DisposeAnalysisHelper _disposeAnalysisHelper; + + public SymbolAnalyzer(ImmutableHashSet disposableFields, DisposeAnalysisHelper disposeAnalysisHelper) + { + Debug.Assert(!disposableFields.IsEmpty); + + _disposableFields = disposableFields; + _disposeAnalysisHelper = disposeAnalysisHelper; + _fieldDisposeValueMap = new ConcurrentDictionary(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void OnSymbolStart(SymbolStartAnalysisContext symbolStartContext, DisposeAnalysisHelper disposeAnalysisHelper) + { + // We only want to analyze types which are disposable (implement System.IDisposable directly or indirectly) + // and have at least one disposable field. + var namedType = (INamedTypeSymbol)symbolStartContext.Symbol; + if (!namedType.IsDisposable(disposeAnalysisHelper.IDisposableType)) + { + return; + } + + var disposableFields = disposeAnalysisHelper.GetDisposableFields(namedType); + if (disposableFields.IsEmpty) + { + return; + } + + var analyzer = new SymbolAnalyzer(disposableFields, disposeAnalysisHelper); + + // Register an operation block action to analyze disposable assignments and dispose invocations for fields. + symbolStartContext.RegisterOperationBlockStartAction(analyzer.OnOperationBlockStart); + + // Register symbol end action for containing type to report non-disposed fields. + // We report fields that have disposable type (implement System.IDisposable directly or indirectly) + // and were assigned a disposable object within this containing type, but were not disposed in + // containing type's Dispose method. + symbolStartContext.RegisterSymbolEndAction(analyzer.OnSymbolEnd); + } + + private void AddOrUpdateFieldDisposedValue(IFieldSymbol field, bool disposed) + { + Debug.Assert(_disposableFields.Contains(field)); + Debug.Assert(!field.IsStatic); + Debug.Assert(field.Type.IsDisposable(_disposeAnalysisHelper.IDisposableType)); + + // Update the dispose value for the field. + // Update value factory delegate ensures that fields for which we have + // already seen dispose invocations, i.e. currentValue = true, continue to be marked as disposed. + _fieldDisposeValueMap.AddOrUpdate(field, + addValue: disposed, + updateValueFactory: (f, currentValue) => currentValue || disposed); + } + + private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext) + { + foreach (var kvp in _fieldDisposeValueMap) + { + IFieldSymbol field = kvp.Key; + bool disposed = kvp.Value; + if (!disposed) + { + // Disposable field '{0}' is never disposed + var diagnostic = Diagnostic.Create(s_disposableFieldsShouldBeDisposedRule, field.Locations[0], field.Name); + symbolEndContext.ReportDiagnostic(diagnostic); + } + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void OnOperationBlockStart(OperationBlockStartAnalysisContext operationBlockStartContext) + { + switch (operationBlockStartContext.OwningSymbol) + { + case IFieldSymbol _: + // Field initializer. + if (operationBlockStartContext.OperationBlocks.Length == 1 && + operationBlockStartContext.OperationBlocks[0] is IFieldInitializerOperation fieldInitializer) + { + foreach (var field in fieldInitializer.InitializedFields) + { + if (!field.IsStatic && _disposableFields.Contains(field)) + { + // Instance field initialized with a disposable object is considered a candidate. + AddOrUpdateFieldDisposedValue(field, disposed: false); + } + } + } + + break; + + case IMethodSymbol containingMethod: + // Method body. + OnMethodOperationBlockStart(operationBlockStartContext, containingMethod); + break; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void OnMethodOperationBlockStart(OperationBlockStartAnalysisContext operationBlockStartContext, IMethodSymbol containingMethod) + { + // Shared PointsTo dataflow analysis result for all the callbacks to AnalyzeFieldReference + // for this method's executable code. + PointsToAnalysisResult lazyPointsToAnalysisResult = null; + + // If we have any potential disposable object creation descendant within the operation blocks, + // register an operation action to analyze field references where field might be assigned a disposable object. + if (_disposeAnalysisHelper.HasAnyDisposableCreationDescendant(operationBlockStartContext.OperationBlocks, containingMethod)) + { + operationBlockStartContext.RegisterOperationAction(AnalyzeFieldReference, OperationKind.FieldReference); + } + + // If this is a Dispose method, then analyze dispose invocations for fields within this method. + if (_disposeAnalysisHelper.IsAnyDisposeMethod(containingMethod)) + { + AnalyzeDisposeMethod(); + } + + return; + + // Local function + void AnalyzeFieldReference(OperationAnalysisContext operationContext) + { + var fieldReference = (IFieldReferenceOperation)operationContext.Operation; + var field = fieldReference.Field; + + // Check if this is a Disposable field that is not currently being tracked. + if (_fieldDisposeValueMap.ContainsKey(field) || + !_disposableFields.Contains(field)) + { + return; + } + + // Only track instance fields on the current instance. + if (field.IsStatic || fieldReference.Instance?.Kind != OperationKind.InstanceReference) + { + return; + } + + // We have a field reference for a disposable field. + // Check if it is being assigned a locally created disposable object. + if (fieldReference.Parent is ISimpleAssignmentOperation simpleAssignmentOperation && + simpleAssignmentOperation.Target == fieldReference) + { + if (lazyPointsToAnalysisResult == null) + { + if (_disposeAnalysisHelper.TryGetOrComputeResult( + operationBlockStartContext, containingMethod, + s_disposableFieldsShouldBeDisposedRule, + trackInstanceFields: false, + out _, out var pointsToAnalysisResult) && + pointsToAnalysisResult != null) + { + Interlocked.CompareExchange(ref lazyPointsToAnalysisResult, pointsToAnalysisResult, null); + } + } + + PointsToAbstractValue assignedPointsToValue = lazyPointsToAnalysisResult[simpleAssignmentOperation.Value.Kind, simpleAssignmentOperation.Value.Syntax]; + foreach (var location in assignedPointsToValue.Locations) + { + if (_disposeAnalysisHelper.IsDisposableCreationOrDisposeOwnershipTransfer(location, containingMethod)) + { + AddOrUpdateFieldDisposedValue(field, disposed: false); + break; + } + } + } + } + + void AnalyzeDisposeMethod() + { + // Perform dataflow analysis to compute dispose value of disposable fields at the end of dispose method. + if (_disposeAnalysisHelper.TryGetOrComputeResult(operationBlockStartContext, containingMethod, + s_disposableFieldsShouldBeDisposedRule, trackInstanceFields: true, + disposeAnalysisResult: out var disposeAnalysisResult, + pointsToAnalysisResult: out var pointsToAnalysisResult)) + { + BasicBlock exitBlock = disposeAnalysisResult.ControlFlowGraph.GetExit(); + foreach (var fieldWithPointsToValue in disposeAnalysisResult.TrackedInstanceFieldPointsToMap) + { + IFieldSymbol field = fieldWithPointsToValue.Key; + PointsToAbstractValue pointsToValue = fieldWithPointsToValue.Value; + + if (!_disposableFields.Contains(field)) + { + continue; + } + + ImmutableDictionary disposeDataAtExit = disposeAnalysisResult.ExitBlockOutput.Data; + var disposed = false; + foreach (var location in pointsToValue.Locations) + { + if (disposeDataAtExit.TryGetValue(location, out DisposeAbstractValue disposeValue)) + { + switch (disposeValue.Kind) + { + // For MaybeDisposed, conservatively mark the field as disposed as we don't support path sensitive analysis. + case DisposeAbstractValueKind.MaybeDisposed: + case DisposeAbstractValueKind.Unknown: + case DisposeAbstractValueKind.Escaped: + case DisposeAbstractValueKind.Disposed: + disposed = true; + AddOrUpdateFieldDisposedValue(field, disposed); + break; + } + } + + if (disposed) + { + break; + } + } + } + } + } + } + } + } +} diff --git a/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs b/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs new file mode 100644 index 0000000000000..92e4ab753599c --- /dev/null +++ b/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs @@ -0,0 +1,322 @@ +// 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.Concurrent; +using System.Collections.Immutable; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.DisposeAnalysis; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.PointsToAnalysis; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.DisposeAnalysis +{ + /// + /// Helper for DisposeAnalysis. + /// + internal sealed class DisposeAnalysisHelper + { + private static readonly string[] s_disposeOwnershipTransferLikelyTypes = new string[] + { + "System.IO.Stream", + "System.IO.TextReader", + "System.IO.TextWriter", + "System.Resources.IResourceReader", + }; + private static readonly ImmutableHashSet s_DisposableCreationKinds = ImmutableHashSet.Create( + OperationKind.ObjectCreation, + OperationKind.TypeParameterObjectCreation, + OperationKind.DynamicObjectCreation, + OperationKind.Invocation); + + private readonly ImmutableHashSet _disposeOwnershipTransferLikelyTypes; + private ConcurrentDictionary> _lazyDisposableFieldsMap; + public INamedTypeSymbol IDisposableType { get; } + public INamedTypeSymbol TaskType { get; } + + private DisposeAnalysisHelper(INamedTypeSymbol disposableType, INamedTypeSymbol taskType, ImmutableHashSet disposeOwnershipTransferLikelyTypes) + { + IDisposableType = disposableType; + TaskType = taskType; + _disposeOwnershipTransferLikelyTypes = disposeOwnershipTransferLikelyTypes; + } + + public static bool TryCreate(Compilation compilation, out DisposeAnalysisHelper disposeHelper) + { + var disposableType = compilation.SystemIDisposableType(); + if (disposableType == null) + { + disposeHelper = null; + return false; + } + + var taskType = compilation.TaskType(); + var disposeOwnershipTransferLikelyTypes = GetDisposeOwnershipTransferLikelyTypes(compilation); + disposeHelper = new DisposeAnalysisHelper(disposableType, taskType, disposeOwnershipTransferLikelyTypes); + return true; + } + + private static ImmutableHashSet GetDisposeOwnershipTransferLikelyTypes(Compilation compilation) + { + var builder = PooledHashSet.GetInstance(); + try + { + foreach (var typeName in s_disposeOwnershipTransferLikelyTypes) + { + INamedTypeSymbol typeSymbol = compilation.GetTypeByMetadataName(typeName); + if (typeSymbol != null) + { + builder.Add(typeSymbol); + } + } + + return builder.ToImmutableHashSet(); + } + finally + { + builder.Free(); + } + } + + private void EnsureDisposableFieldsMap() + { + if (_lazyDisposableFieldsMap == null) + { + Interlocked.CompareExchange(ref _lazyDisposableFieldsMap, new ConcurrentDictionary>(), null); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public bool TryGetOrComputeResult( + OperationBlockAnalysisContext context, + IMethodSymbol containingMethod, + DiagnosticDescriptor rule, + bool trackInstanceFields, + out DisposeAnalysisResult disposeAnalysisResult, + out PointsToAnalysisResult pointsToAnalysisResult, + InterproceduralAnalysisPredicate interproceduralAnalysisPredicateOpt = null) + { + // Compute the dispose analysis result - skip Attribute blocks (OperationKind.None) + foreach (var operationBlock in context.OperationBlocks.Where(o => o.Kind != OperationKind.None)) + { + var cfg = context.GetControlFlowGraph(operationBlock); + if (cfg != null) + { + var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation); + disposeAnalysisResult = FlowAnalysis.DataFlow.DisposeAnalysis.DisposeAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, + context.Options, rule, _disposeOwnershipTransferLikelyTypes, trackInstanceFields, + exceptionPathsAnalysis: false, context.CancellationToken, out pointsToAnalysisResult, + interproceduralAnalysisPredicateOpt: interproceduralAnalysisPredicateOpt, + defaultDisposeOwnershipTransferAtConstructor: true); + return true; + } + } + + disposeAnalysisResult = null; + pointsToAnalysisResult = null; + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public bool TryGetOrComputeResult( + OperationBlockStartAnalysisContext context, + IMethodSymbol containingMethod, + DiagnosticDescriptor rule, + bool trackInstanceFields, + out DisposeAnalysisResult disposeAnalysisResult, + out PointsToAnalysisResult pointsToAnalysisResult, + InterproceduralAnalysisPredicate interproceduralAnalysisPredicateOpt = null) + { + // Compute the dispose analysis result - skip Attribute blocks (OperationKind.None) + foreach (var operationBlock in context.OperationBlocks.Where(o => o.Kind != OperationKind.None)) + { + var cfg = context.GetControlFlowGraph(operationBlock); + if (cfg != null) + { + var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation); + disposeAnalysisResult = FlowAnalysis.DataFlow.DisposeAnalysis.DisposeAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, + context.Options, rule, _disposeOwnershipTransferLikelyTypes, trackInstanceFields, + exceptionPathsAnalysis: false, context.CancellationToken, out pointsToAnalysisResult, + interproceduralAnalysisPredicateOpt: interproceduralAnalysisPredicateOpt, + defaultDisposeOwnershipTransferAtConstructor: true); + return true; + } + } + + disposeAnalysisResult = null; + pointsToAnalysisResult = null; + return false; + } + + private bool HasDisposableOwnershipTransferForConstructorParameter(IMethodSymbol containingMethod) => + containingMethod.MethodKind == MethodKind.Constructor && + containingMethod.Parameters.Any(p => _disposeOwnershipTransferLikelyTypes.Contains(p.Type)); + + private bool IsDisposableCreation(IOperation operation) + => (s_DisposableCreationKinds.Contains(operation.Kind) || + operation.Parent is IArgumentOperation argument && argument.Parameter.RefKind == RefKind.Out) && + operation.Type?.IsDisposable(IDisposableType) == true; + + public bool HasAnyDisposableCreationDescendant(ImmutableArray operationBlocks, IMethodSymbol containingMethod) + { + return operationBlocks.HasAnyOperationDescendant(IsDisposableCreation) || + HasDisposableOwnershipTransferForConstructorParameter(containingMethod); + } + + public ImmutableHashSet GetDisposableFields(INamedTypeSymbol namedType) + { + EnsureDisposableFieldsMap(); + if (_lazyDisposableFieldsMap.TryGetValue(namedType, out ImmutableHashSet disposableFields)) + { + return disposableFields; + } + + if (!namedType.IsDisposable(IDisposableType)) + { + disposableFields = ImmutableHashSet.Empty; + } + else + { + disposableFields = namedType.GetMembers() + .OfType() + .Where(f => f.Type.IsDisposable(IDisposableType) && !f.Type.InheritsFromOrEquals(TaskType)) + .ToImmutableHashSet(); + } + + return _lazyDisposableFieldsMap.GetOrAdd(namedType, disposableFields); + } + + /// + /// Returns true if the given was created for an allocation in the + /// or represents a location created for a constructor parameter whose type indicates dispose ownership transfer. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + public bool IsDisposableCreationOrDisposeOwnershipTransfer(AbstractLocation location, IMethodSymbol containingMethod) + { + if (location.CreationOpt == null) + { + return location.SymbolOpt?.Kind == SymbolKind.Parameter && + HasDisposableOwnershipTransferForConstructorParameter(containingMethod); + } + + return IsDisposableCreation(location.CreationOpt); + } + + /// + /// Checks if the given method implements or overrides an implementation of . + /// + private bool IsDisposeImplementation(IMethodSymbol method) + { + if (method == null) + { + return false; + } + + if (method.IsOverride) + { + return IsDisposeImplementation(method.OverriddenMethod); + } + + // Identify the implementor of IDisposable.Dispose in the given method's containing type and check + // if it is the given method. + return method.ReturnsVoid && + method.Parameters.Length == 0 && + IsImplementationOfInterfaceMethod(method, typeArgument: null, IDisposableType, nameof(IDisposable.Dispose)); + } + + /// + /// Returns true if this method is any Dispose method responsible for disposing the disposable fields + /// of a disposable named type. For example, "void Dispose()", "void Dispose(bool)", "Task DisposeAsync()", etc. + /// + public bool IsAnyDisposeMethod(IMethodSymbol method) + { + if (!method.ContainingType.IsDisposable(IDisposableType)) + { + return false; + } + + return IsDisposeImplementation(method) || + (Equals(method.ContainingType, IDisposableType) && HasDisposeMethodSignature(method)) || + HasDisposeBoolMethodSignature(method) || + HasDisposeAsyncMethodSignature(method) || + HasOverriddenDisposeCoreAsyncMethodSignature(method) || + HasDisposeCloseMethodSignature(method); + } + + /// + /// Checks if the given method has the signature "void Dispose()". + /// + private static bool HasDisposeMethodSignature(IMethodSymbol method) + { + return method.Name == nameof(IDisposable.Dispose) && method.MethodKind == MethodKind.Ordinary && + method.ReturnsVoid && method.Parameters.IsEmpty; + } + + /// + /// Checks if the given method has the signature "void Dispose(bool)". + /// + public static bool HasDisposeBoolMethodSignature(IMethodSymbol method) + { + if (method.Name == nameof(IDisposable.Dispose) && method.MethodKind == MethodKind.Ordinary && + method.ReturnsVoid && method.Parameters.Length == 1) + { + IParameterSymbol parameter = method.Parameters[0]; + return parameter.Type != null && + parameter.Type.SpecialType == SpecialType.System_Boolean && + parameter.RefKind == RefKind.None; + } + + return false; + } + + /// + /// Checks if the given method has the signature "void Close()". + /// + private static bool HasDisposeCloseMethodSignature(IMethodSymbol method) + { + return method.Name == "Close" && method.MethodKind == MethodKind.Ordinary && + method.ReturnsVoid && method.Parameters.IsEmpty; + } + + /// + /// Checks if the given method has the signature "Task DisposeAsync()". + /// + private bool HasDisposeAsyncMethodSignature(IMethodSymbol method) + { + return method.Name == "DisposeAsync" && + method.MethodKind == MethodKind.Ordinary && + method.ReturnType.Equals(TaskType) && + method.Parameters.IsEmpty; + } + + /// + /// Checks if the given method has the signature "override Task DisposeCoreAsync(bool)". + /// + private bool HasOverriddenDisposeCoreAsyncMethodSignature(IMethodSymbol method) + { + return method.Name == "DisposeCoreAsync" && + method.MethodKind == MethodKind.Ordinary && + method.IsOverride && + method.ReturnType.Equals(TaskType) && + method.Parameters.Length == 1 && + method.Parameters[0].Type.SpecialType == SpecialType.System_Boolean; + } + + /// + /// Checks if the given method is an implementation of the given interface method + /// Substituted with the given typeargument. + /// + private static bool IsImplementationOfInterfaceMethod(IMethodSymbol method, ITypeSymbol typeArgument, INamedTypeSymbol interfaceType, string interfaceMethodName) + { + INamedTypeSymbol constructedInterface = typeArgument != null ? interfaceType?.Construct(typeArgument) : interfaceType; + + return constructedInterface?.GetMembers(interfaceMethodName).Single() is IMethodSymbol interfaceMethod && method.Equals(method.ContainingType.FindImplementationForInterfaceMember(interfaceMethod)); + } + } +} diff --git a/src/Features/Core/Portable/DisposeAnalysis/DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer.cs b/src/Features/Core/Portable/DisposeAnalysis/DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer.cs new file mode 100644 index 0000000000000..655233c3e1542 --- /dev/null +++ b/src/Features/Core/Portable/DisposeAnalysis/DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer.cs @@ -0,0 +1,219 @@ +// 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.Concurrent; +using System.Collections.Immutable; +using System.Linq; +using System.Runtime.CompilerServices; +using Microsoft.CodeAnalysis.CodeQuality; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.FlowAnalysis; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.DisposeAnalysis; +using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.PointsToAnalysis; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.DisposeAnalysis +{ + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + internal sealed class DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer + : AbstractCodeQualityDiagnosticAnalyzer + { + private static readonly DiagnosticDescriptor s_disposeObjectsBeforeLosingScopeRule = CreateDescriptor( + IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, + title: new LocalizableResourceString(nameof(FeaturesResources.Dispose_objects_before_losing_scope), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + messageFormat: new LocalizableResourceString(nameof(FeaturesResources.Disposable_object_created_by_0_is_never_disposed), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + description: new LocalizableResourceString(nameof(FeaturesResources.UseRecommendedDisposePatternDescription), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + isUnneccessary: false); + + private static readonly DiagnosticDescriptor s_useRecommendedDisposePatternRule = CreateDescriptor( + IDEDiagnosticIds.UseRecommendedDisposePatternDiagnosticId, + title: new LocalizableResourceString(nameof(FeaturesResources.Use_recommended_dispose_pattern), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + messageFormat: new LocalizableResourceString(nameof(FeaturesResources.Use_recommended_dispose_pattern_to_ensure_that_object_created_by_0_is_disposed_on_all_paths_using_statement_declaration_or_try_finally), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + description: new LocalizableResourceString(nameof(FeaturesResources.UseRecommendedDisposePatternDescription), FeaturesResources.ResourceManager, typeof(FeaturesResources)), + isUnneccessary: false); + + public DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer() + : base(ImmutableArray.Create(s_disposeObjectsBeforeLosingScopeRule, s_useRecommendedDisposePatternRule), GeneratedCodeAnalysisFlags.None) + { + } + + public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticDocumentAnalysis; + + protected override void InitializeWorker(AnalysisContext context) + { + context.RegisterCompilationStartAction(compilationContext => + { + if (!DisposeAnalysisHelper.TryCreate(compilationContext.Compilation, out DisposeAnalysisHelper disposeAnalysisHelper)) + { + return; + } + + // Avoid reporting duplicate diagnostics from interprocedural analysis. + var reportedLocations = new ConcurrentDictionary(); + + compilationContext.RegisterOperationBlockAction( + operationBlockContext => AnalyzeOperationBlock(operationBlockContext, disposeAnalysisHelper, reportedLocations)); + }); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AnalyzeOperationBlock( + OperationBlockAnalysisContext operationBlockContext, + DisposeAnalysisHelper disposeAnalysisHelper, + ConcurrentDictionary reportedLocations) + { + // We are only intersted in analyzing method bodies that have at least one disposable object creation. + if (!(operationBlockContext.OwningSymbol is IMethodSymbol containingMethod) || + !disposeAnalysisHelper.HasAnyDisposableCreationDescendant(operationBlockContext.OperationBlocks, containingMethod)) + { + return; + } + + PerformFlowAnalysisOnOperationBlock(operationBlockContext, disposeAnalysisHelper, reportedLocations, containingMethod); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void PerformFlowAnalysisOnOperationBlock( + OperationBlockAnalysisContext operationBlockContext, + DisposeAnalysisHelper disposeAnalysisHelper, + ConcurrentDictionary reportedLocations, + IMethodSymbol containingMethod) + { + // We can skip interprocedural analysis for certain invocations. + var interproceduralAnalysisPredicateOpt = new InterproceduralAnalysisPredicate( + skipAnalysisForInvokedMethodPredicateOpt: SkipInterproceduralAnalysis, + skipAnalysisForInvokedLambdaOrLocalFunctionPredicateOpt: null, + skipAnalysisForInvokedContextPredicateOpt: null); + + // Compute dispose dataflow analysis result for the operation block. + if (disposeAnalysisHelper.TryGetOrComputeResult(operationBlockContext, containingMethod, + s_disposeObjectsBeforeLosingScopeRule, trackInstanceFields: false, + out var disposeAnalysisResult, out var pointsToAnalysisResult, + interproceduralAnalysisPredicateOpt)) + { + var notDisposedDiagnostics = ArrayBuilder.GetInstance(); + var mayBeNotDisposedDiagnostics = ArrayBuilder.GetInstance(); + try + { + // Compute diagnostics for undisposed objects at exit block. + var exitBlock = disposeAnalysisResult.ControlFlowGraph.GetExit(); + var disposeDataAtExit = disposeAnalysisResult.ExitBlockOutput.Data; + ComputeDiagnostics(disposeDataAtExit, notDisposedDiagnostics, mayBeNotDisposedDiagnostics, + disposeAnalysisResult, pointsToAnalysisResult); + + // Report diagnostics preferring *not* disposed diagnostics over may be not disposed diagnostics + // and avoiding duplicates. + foreach (var diagnostic in notDisposedDiagnostics.Concat(mayBeNotDisposedDiagnostics)) + { + if (reportedLocations.TryAdd(diagnostic.Location, true)) + { + operationBlockContext.ReportDiagnostic(diagnostic); + } + } + } + finally + { + notDisposedDiagnostics.Free(); + mayBeNotDisposedDiagnostics.Free(); + } + } + + return; + + // Local functions. + bool SkipInterproceduralAnalysis(IMethodSymbol invokedMethod) + { + // Skip interprocedural analysis if we are invoking a method and not passing any disposable object as an argument + // and not receiving a disposable object as a return value. + // We also check that we are not passing any object type argument which might hold disposable object + // and also check that we are not passing delegate type argument which can + // be a lambda or local function that has access to disposable object in current method's scope. + + if (CanBeDisposable(invokedMethod.ReturnType)) + { + return false; + } + + foreach (var p in invokedMethod.Parameters) + { + if (CanBeDisposable(p.Type)) + { + return false; + } + } + + return true; + + bool CanBeDisposable(ITypeSymbol type) + => type.SpecialType == SpecialType.System_Object || + type.IsDisposable(disposeAnalysisHelper.IDisposableType) || + type.TypeKind == TypeKind.Delegate; + } + + void ComputeDiagnostics( + ImmutableDictionary disposeData, + ArrayBuilder notDisposedDiagnostics, + ArrayBuilder mayBeNotDisposedDiagnostics, + DisposeAnalysisResult disposeAnalysisResult, + PointsToAnalysisResult pointsToAnalysisResult) + { + foreach (var kvp in disposeData) + { + AbstractLocation location = kvp.Key; + DisposeAbstractValue disposeValue = kvp.Value; + + // Ignore non-disposable locations and locations without a Creation operation. + if (disposeValue.Kind == DisposeAbstractValueKind.NotDisposable || + location.CreationOpt == null) + { + continue; + } + + // Check if the disposable creation is definitely not disposed or may be not disposed. + var isNotDisposed = disposeValue.Kind == DisposeAbstractValueKind.NotDisposed || + (disposeValue.DisposingOrEscapingOperations.Count > 0 && + disposeValue.DisposingOrEscapingOperations.All(d => d.IsInsideCatchRegion(disposeAnalysisResult.ControlFlowGraph) && !location.CreationOpt.IsInsideCatchRegion(disposeAnalysisResult.ControlFlowGraph))); + var isMayBeNotDisposed = !isNotDisposed && + (disposeValue.Kind == DisposeAbstractValueKind.MaybeDisposed || disposeValue.Kind == DisposeAbstractValueKind.NotDisposedOrEscaped); + + if (isNotDisposed || isMayBeNotDisposed) + { + var syntax = location.TryGetNodeToReportDiagnostic(pointsToAnalysisResult); + if (syntax == null) + { + continue; + } + + var rule = isNotDisposed ? s_disposeObjectsBeforeLosingScopeRule : s_useRecommendedDisposePatternRule; + + // Ensure that we do not include multiple lines for the object creation expression in the diagnostic message. + var objectCreationText = syntax.ToString(); + var indexOfNewLine = objectCreationText.IndexOf(Environment.NewLine); + if (indexOfNewLine > 0) + { + objectCreationText = objectCreationText.Substring(0, indexOfNewLine); + } + + var diagnostic = Diagnostic.Create( + rule, + syntax.GetLocation(), + additionalLocations: null, + properties: null, + objectCreationText); + + if (isNotDisposed) + { + notDisposedDiagnostics.Add(diagnostic); + } + else + { + mayBeNotDisposedDiagnostics.Add(diagnostic); + } + } + } + } + } + } +} diff --git a/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs b/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs index 9646b7efc99b8..7b8533210eeec 100644 --- a/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs +++ b/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.EncapsulateField Name = PredefinedCodeRefactoringProviderNames.EncapsulateField), Shared] internal class EncapsulateFieldRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public EncapsulateFieldRefactoringProvider() + { + } + public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var service = context.Document.GetLanguageService(); diff --git a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs index 624fcdc3d77c6..6e949c9f9bc4e 100644 --- a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.CodeAnalysis.ExtractInterface Name = PredefinedCodeRefactoringProviderNames.ExtractInterface), Shared] internal class ExtractInterfaceCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public ExtractInterfaceCodeRefactoringProvider() + { + } + public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var service = context.Document.GetLanguageService(); diff --git a/src/Features/Core/Portable/ExtractMethod/ExtractMethodOptionsProvider.cs b/src/Features/Core/Portable/ExtractMethod/ExtractMethodOptionsProvider.cs index 3f3c6f3854f6a..f3c7cdefbabea 100644 --- a/src/Features/Core/Portable/ExtractMethod/ExtractMethodOptionsProvider.cs +++ b/src/Features/Core/Portable/ExtractMethod/ExtractMethodOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.ExtractMethod [ExportOptionProvider, Shared] internal class ExtractMethodOptionsProvider : IOptionProvider { + [ImportingConstructor] + public ExtractMethodOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( ExtractMethodOptions.AllowBestEffort, ExtractMethodOptions.DontPutOutOrRefOnStruct, diff --git a/src/Features/Core/Portable/FeaturesResources.Designer.cs b/src/Features/Core/Portable/FeaturesResources.Designer.cs index 042b47f493e71..94df12e3d7c54 100644 --- a/src/Features/Core/Portable/FeaturesResources.Designer.cs +++ b/src/Features/Core/Portable/FeaturesResources.Designer.cs @@ -1182,6 +1182,51 @@ internal static string Deleting_captured_variable_0_will_prevent_the_debug_sessi } } + /// + /// Looks up a localized string similar to Disposable field '{0}' is never disposed. + /// + internal static string Disposable_field_0_is_never_disposed { + get { + return ResourceManager.GetString("Disposable_field_0_is_never_disposed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disposable fields should be disposed. + /// + internal static string Disposable_fields_should_be_disposed { + get { + return ResourceManager.GetString("Disposable_fields_should_be_disposed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disposable object created by '{0}' is never disposed. + /// + internal static string Disposable_object_created_by_0_is_never_disposed { + get { + return ResourceManager.GetString("Disposable_object_created_by_0_is_never_disposed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field.. + /// + internal static string DisposableFieldsShouldBeDisposedDescription { + get { + return ResourceManager.GetString("DisposableFieldsShouldBeDisposedDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dispose objects before losing scope. + /// + internal static string Dispose_objects_before_losing_scope { + get { + return ResourceManager.GetString("Dispose_objects_before_losing_scope", resourceCulture); + } + } + /// /// Looks up a localized string similar to Document. /// @@ -1695,6 +1740,24 @@ internal static string Generate_overrides { } } + /// + /// Looks up a localized string similar to Generate parameter '{0}'. + /// + internal static string Generate_parameter_0 { + get { + return ResourceManager.GetString("Generate_parameter_0", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate parameter '{0}' (and overrides/implementations). + /// + internal static string Generate_parameter_0_and_overrides_implementations { + get { + return ResourceManager.GetString("Generate_parameter_0_and_overrides_implementations", resourceCulture); + } + } + /// /// Looks up a localized string similar to Generate property '{1}.{0}'. /// @@ -4397,6 +4460,25 @@ internal static string Use_range_operator { } } + /// + /// Looks up a localized string similar to Use recommended dispose pattern. + /// + internal static string Use_recommended_dispose_pattern { + get { + return ResourceManager.GetString("Use_recommended_dispose_pattern", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally. + /// + internal static string Use_recommended_dispose_pattern_to_ensure_that_object_created_by_0_is_disposed_on_all_paths_using_statement_declaration_or_try_finally { + get { + return ResourceManager.GetString("Use_recommended_dispose_pattern_to_ensure_that_object_created_by_0_is_disposed_on" + + "_all_paths_using_statement_declaration_or_try_finally", resourceCulture); + } + } + /// /// Looks up a localized string similar to Use simple 'using' statement. /// @@ -4424,6 +4506,15 @@ internal static string User_Diagnostic_Analyzer_Failure { } } + /// + /// Looks up a localized string similar to Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object [rest of string was truncated]";. + /// + internal static string UseRecommendedDisposePatternDescription { + get { + return ResourceManager.GetString("UseRecommendedDisposePatternDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Using readonly references will prevent the debug session from continuing.. /// diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx index 4da1ef01c3e66..a104b906f8526 100644 --- a/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/Features/Core/Portable/FeaturesResources.resx @@ -1623,6 +1623,12 @@ This version used in: {2} Target type matches + + Generate parameter '{0}' + + + Generate parameter '{0}' (and overrides/implementations) + in Source (attribute) @@ -1632,4 +1638,29 @@ This version used in: {2} {0} must return a stream that supports read and seek operations. + + Dispose objects before losing scope + + + Disposable object created by '{0}' is never disposed + + + Use recommended dispose pattern + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + + Disposable fields should be disposed + + + Disposable field '{0}' is never disposed + + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + \ No newline at end of file diff --git a/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs b/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs index 06474b8512c14..69dfd0830ef63 100644 --- a/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs +++ b/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs @@ -16,6 +16,11 @@ namespace Microsoft.CodeAnalysis.Formatting [Shared] internal class FormattingCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public FormattingCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.FormattingDiagnosticId); diff --git a/src/Features/Core/Portable/GenerateConstructorFromMembers/GenerateConstructorFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateConstructorFromMembers/GenerateConstructorFromMembersCodeRefactoringProvider.cs index d1c1a4362a8ac..e92ba4473b3cf 100644 --- a/src/Features/Core/Portable/GenerateConstructorFromMembers/GenerateConstructorFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateConstructorFromMembers/GenerateConstructorFromMembersCodeRefactoringProvider.cs @@ -39,6 +39,7 @@ internal partial class GenerateConstructorFromMembersCodeRefactoringProvider : A private readonly IPickMembersService _pickMembersService_forTesting; + [ImportingConstructor] public GenerateConstructorFromMembersCodeRefactoringProvider() : this(null) { } diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs index 809f282aaf02d..60ab67e5da3fb 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs @@ -24,6 +24,11 @@ namespace Microsoft.CodeAnalysis.GenerateDefaultConstructors Name = PredefinedCodeRefactoringProviderNames.GenerateDefaultConstructors), Shared] internal class GenerateDefaultConstructorsCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public GenerateDefaultConstructorsCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs index 0c479d3b74880..67a71055e8d6b 100644 --- a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs @@ -33,6 +33,7 @@ internal partial class GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringPro private readonly IPickMembersService _pickMembersService_forTestingPurposes; + [ImportingConstructor] public GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider() : this(pickMembersService: null) { diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateParameterCodeAction.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateParameterCodeAction.cs new file mode 100644 index 0000000000000..b5ea0582333c1 --- /dev/null +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateParameterCodeAction.cs @@ -0,0 +1,53 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.AddParameter; +using Microsoft.CodeAnalysis.CodeActions; + +namespace Microsoft.CodeAnalysis.GenerateMember.GenerateVariable +{ + internal partial class AbstractGenerateVariableService + { + private class GenerateParameterCodeAction : CodeAction + { + private readonly Document _document; + private readonly State _state; + private readonly bool _includeOverridesAndImplementations; + + public GenerateParameterCodeAction(Document document, State state, bool includeOverridesAndImplementations) + { + _document = document; + _state = state; + _includeOverridesAndImplementations = includeOverridesAndImplementations; + } + + public override string Title + { + get + { + var text = _includeOverridesAndImplementations + ? FeaturesResources.Generate_parameter_0_and_overrides_implementations + : FeaturesResources.Generate_parameter_0; + + return string.Format( + text, + _state.IdentifierToken.ValueText); + } + } + + protected override Task GetChangedSolutionAsync(CancellationToken cancellationToken) + { + return AddParameterService.Instance.AddParameterAsync( + _document, + _state.ContainingMethod, + _state.LocalType, + RefKind.None, + _state.IdentifierToken.ValueText, + newParameterIndex: null, + _includeOverridesAndImplementations, + cancellationToken); + } + } + } +} diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs index 47856f9983e11..b7f6aee0c575a 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs @@ -21,6 +21,7 @@ private partial class State { public INamedTypeSymbol ContainingType { get; private set; } public INamedTypeSymbol TypeToGenerateIn { get; private set; } + public IMethodSymbol ContainingMethod { get; private set; } public bool IsStatic { get; private set; } public bool IsConstant { get; private set; } public bool IsIndexer { get; private set; } @@ -133,9 +134,16 @@ private async Task TryInitializeAsync( internal bool CanGenerateLocal() { + // !this.IsInMemberContext prevents us offering this fix for `x.goo` where `goo` does not exist return !this.IsInMemberContext && this.IsInExecutableBlock; } + internal bool CanGenerateParameter() + { + // !this.IsInMemberContext prevents us offering this fix for `x.goo` where `goo` does not exist + return this.ContainingMethod != null && !this.IsInMemberContext && !this.IsConstant; + } + private bool TryInitializeExplicitInterface( TService service, SemanticDocument document, @@ -261,6 +269,8 @@ private bool TryInitializeSimpleName( this.IsInMemberContext = this.SimpleNameOpt != this.SimpleNameOrMemberAccessExpressionOpt || syntaxFacts.IsObjectInitializerNamedAssignmentIdentifier(this.SimpleNameOrMemberAccessExpressionOpt); + this.ContainingMethod = semanticModel.GetEnclosingSymbol(this.IdentifierToken.SpanStart, cancellationToken); + CheckSurroundingContext(semanticDocument, SymbolKind.Field, cancellationToken); CheckSurroundingContext(semanticDocument, SymbolKind.Property, cancellationToken); diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs index f3d54fc2b2260..c3e789f9536d2 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.AddParameter; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Internal.Log; @@ -49,30 +50,27 @@ public async Task> GenerateVariableAsync( var canGenerateMember = CodeGenerator.CanAdd(document.Project.Solution, state.TypeToGenerateIn, cancellationToken); - // prefer fields over properties (and vice versa) depending on the casing of the member. - // lowercase -> fields. title case -> properties. - var name = state.IdentifierToken.ValueText; - if (char.IsUpper(name.ToCharArray().FirstOrDefault())) + if (canGenerateMember) { - if (canGenerateMember) + // prefer fields over properties (and vice versa) depending on the casing of the member. + // lowercase -> fields. title case -> properties. + var name = state.IdentifierToken.ValueText; + if (char.IsUpper(name.ToCharArray().FirstOrDefault())) { AddPropertyCodeActions(actions, semanticDocument, state); AddFieldCodeActions(actions, semanticDocument, state); } - - AddLocalCodeActions(actions, document, state); - } - else - { - if (canGenerateMember) + else { + AddFieldCodeActions(actions, semanticDocument, state); AddPropertyCodeActions(actions, semanticDocument, state); } - - AddLocalCodeActions(actions, document, state); } + AddLocalCodeActions(actions, document, state); + AddParameterCodeActions(actions, document, state); + if (actions.Count > 1) { // Wrap the generate variable actions into a single top level suggestion @@ -177,6 +175,17 @@ private void AddLocalCodeActions(ArrayBuilder result, Document docum } } + private void AddParameterCodeActions(ArrayBuilder result, Document document, State state) + { + if (state.CanGenerateParameter()) + { + result.Add(new GenerateParameterCodeAction(document, state, includeOverridesAndImplementations: false)); + + if (AddParameterService.Instance.HasCascadingDeclarations(state.ContainingMethod)) + result.Add(new GenerateParameterCodeAction(document, state, includeOverridesAndImplementations: true)); + } + } + private RefKind GetRefKindFromContext(State state) { if (state.IsInRefContext) diff --git a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs index 47750bbc36343..88e00378c7e21 100644 --- a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs @@ -17,6 +17,7 @@ internal partial class GenerateOverridesCodeRefactoringProvider : CodeRefactorin { private readonly IPickMembersService _pickMembersService_forTestingPurposes; + [ImportingConstructor] public GenerateOverridesCodeRefactoringProvider() : this(null) { } diff --git a/src/Features/Core/Portable/ImplementType/ImplementTypeOptionsProvider.cs b/src/Features/Core/Portable/ImplementType/ImplementTypeOptionsProvider.cs index a61f01976c06a..839406400aff8 100644 --- a/src/Features/Core/Portable/ImplementType/ImplementTypeOptionsProvider.cs +++ b/src/Features/Core/Portable/ImplementType/ImplementTypeOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.ImplementType [ExportOptionProvider, Shared] internal class ImplementTypeOptionsProvider : IOptionProvider { + [ImportingConstructor] + public ImplementTypeOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( ImplementTypeOptions.InsertionBehavior); } diff --git a/src/Features/Core/Portable/IncrementalCaches/SymbolTreeInfoIncrementalAnalyzerProvider.cs b/src/Features/Core/Portable/IncrementalCaches/SymbolTreeInfoIncrementalAnalyzerProvider.cs index b596d031fa616..4fb0bdc78d1bf 100644 --- a/src/Features/Core/Portable/IncrementalCaches/SymbolTreeInfoIncrementalAnalyzerProvider.cs +++ b/src/Features/Core/Portable/IncrementalCaches/SymbolTreeInfoIncrementalAnalyzerProvider.cs @@ -37,6 +37,11 @@ namespace Microsoft.CodeAnalysis.IncrementalCaches [ExportWorkspaceServiceFactory(typeof(ISymbolTreeInfoCacheService))] internal class SymbolTreeInfoIncrementalAnalyzerProvider : IIncrementalAnalyzerProvider, IWorkspaceServiceFactory { + [ImportingConstructor] + public SymbolTreeInfoIncrementalAnalyzerProvider() + { + } + private readonly struct MetadataInfo { /// diff --git a/src/Features/Core/Portable/IncrementalCaches/SyntaxTreeInfoIncrementalAnalyzerProvider.cs b/src/Features/Core/Portable/IncrementalCaches/SyntaxTreeInfoIncrementalAnalyzerProvider.cs index f85a83bb2c08e..654bff852a565 100644 --- a/src/Features/Core/Portable/IncrementalCaches/SyntaxTreeInfoIncrementalAnalyzerProvider.cs +++ b/src/Features/Core/Portable/IncrementalCaches/SyntaxTreeInfoIncrementalAnalyzerProvider.cs @@ -13,6 +13,11 @@ namespace Microsoft.CodeAnalysis.IncrementalCaches [ExportIncrementalAnalyzerProvider(nameof(SyntaxTreeInfoIncrementalAnalyzerProvider), new[] { WorkspaceKind.Host, WorkspaceKind.RemoteWorkspace }), Shared] internal class SyntaxTreeInfoIncrementalAnalyzerProvider : IIncrementalAnalyzerProvider { + [ImportingConstructor] + public SyntaxTreeInfoIncrementalAnalyzerProvider() + { + } + public IIncrementalAnalyzer CreateIncrementalAnalyzer(Workspace workspace) { return new IncrementalAnalyzer(); diff --git a/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs b/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs index 81ee37aa1b4e4..c8a8274f60b01 100644 --- a/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis.IntroduceVariable Name = PredefinedCodeRefactoringProviderNames.IntroduceVariable), Shared] internal class IntroduceVariableCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public IntroduceVariableCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj index 6a1141814d1bb..baeafaa817c12 100644 --- a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj +++ b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj @@ -125,6 +125,7 @@ + diff --git a/src/Features/Core/Portable/MoveDeclarationNearReference/MoveDeclarationNearReferenceCodeRefactoringProvider.cs b/src/Features/Core/Portable/MoveDeclarationNearReference/MoveDeclarationNearReferenceCodeRefactoringProvider.cs index f56946933d478..45e6471d2ba12 100644 --- a/src/Features/Core/Portable/MoveDeclarationNearReference/MoveDeclarationNearReferenceCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/MoveDeclarationNearReference/MoveDeclarationNearReferenceCodeRefactoringProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.MoveDeclarationNearReference [ExtensionOrder(After = PredefinedCodeRefactoringProviderNames.InlineTemporary)] internal sealed class MoveDeclarationNearReferenceCodeRefactoringProvider : CodeRefactoringProvider { + [ImportingConstructor] + public MoveDeclarationNearReferenceCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs b/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs index 90ced6202074b..9114a166f4a24 100644 --- a/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs +++ b/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs @@ -12,6 +12,11 @@ namespace Microsoft.CodeAnalysis.MoveToNamespace [ExtensionOrder(After = PredefinedCodeRefactoringProviderNames.MoveTypeToFile)] internal class MoveToNamespaceCodeActionProvider : CodeRefactoringProvider { + [ImportingConstructor] + public MoveToNamespaceCodeActionProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var service = context.Document.GetLanguageService(); diff --git a/src/Features/Core/Portable/Navigation/DefaultDocumentNavigationServiceFactory.cs b/src/Features/Core/Portable/Navigation/DefaultDocumentNavigationServiceFactory.cs index 84831696bccfd..488b4fb8b9fff 100644 --- a/src/Features/Core/Portable/Navigation/DefaultDocumentNavigationServiceFactory.cs +++ b/src/Features/Core/Portable/Navigation/DefaultDocumentNavigationServiceFactory.cs @@ -11,6 +11,11 @@ internal sealed class DefaultDocumentNavigationServiceFactory : IWorkspaceServic { private IDocumentNavigationService _singleton; + [ImportingConstructor] + public DefaultDocumentNavigationServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { if (_singleton == null) diff --git a/src/Features/Core/Portable/Navigation/DefaultSymbolNavigationServiceFactory.cs b/src/Features/Core/Portable/Navigation/DefaultSymbolNavigationServiceFactory.cs index d9fb1e562bb1a..b25aedf3b0d41 100644 --- a/src/Features/Core/Portable/Navigation/DefaultSymbolNavigationServiceFactory.cs +++ b/src/Features/Core/Portable/Navigation/DefaultSymbolNavigationServiceFactory.cs @@ -11,6 +11,11 @@ internal class DefaultSymbolNavigationServiceFactory : IWorkspaceServiceFactory { private ISymbolNavigationService _singleton; + [ImportingConstructor] + public DefaultSymbolNavigationServiceFactory() + { + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { if (_singleton == null) diff --git a/src/Features/Core/Portable/Navigation/NavigationOptionsProvider.cs b/src/Features/Core/Portable/Navigation/NavigationOptionsProvider.cs index e76e95e3bb1b6..7e2659d3700c5 100644 --- a/src/Features/Core/Portable/Navigation/NavigationOptionsProvider.cs +++ b/src/Features/Core/Portable/Navigation/NavigationOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Navigation [ExportOptionProvider, Shared] internal class NavigationOptionsProvider : IOptionProvider { + [ImportingConstructor] + public NavigationOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( NavigationOptions.PreferProvisionalTab); } diff --git a/src/Features/Core/Portable/Notification/SemanticChangeNotificationService.cs b/src/Features/Core/Portable/Notification/SemanticChangeNotificationService.cs index adea4b94e6d13..2f8afc44f162b 100644 --- a/src/Features/Core/Portable/Notification/SemanticChangeNotificationService.cs +++ b/src/Features/Core/Portable/Notification/SemanticChangeNotificationService.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.Notification [ExportIncrementalAnalyzerProvider(nameof(SemanticChangeNotificationService), workspaceKinds: null)] internal class SemanticChangeNotificationService : ISemanticChangeNotificationService, IIncrementalAnalyzerProvider { + [ImportingConstructor] + public SemanticChangeNotificationService() + { + } + public event EventHandler OpenedDocumentSemanticChanged; public IIncrementalAnalyzer CreateIncrementalAnalyzer(Workspace workspace) diff --git a/src/Features/Core/Portable/OrganizeImports/IOrganizeImportsService.cs b/src/Features/Core/Portable/OrganizeImports/IOrganizeImportsService.cs index 3dae50f3038b4..a128c29ecfd9a 100644 --- a/src/Features/Core/Portable/OrganizeImports/IOrganizeImportsService.cs +++ b/src/Features/Core/Portable/OrganizeImports/IOrganizeImportsService.cs @@ -10,6 +10,8 @@ internal interface IOrganizeImportsService : ILanguageService { Task OrganizeImportsAsync(Document document, CancellationToken cancellationToken); + string SortImportsDisplayStringWithAccelerator { get; } + string SortAndRemoveUnusedImportsDisplayStringWithAccelerator { get; } } } diff --git a/src/Features/Core/Portable/PopulateSwitch/PopulateSwitchCodeFixProvider.cs b/src/Features/Core/Portable/PopulateSwitch/PopulateSwitchCodeFixProvider.cs index 29847ce858efa..d0a2b39d1b985 100644 --- a/src/Features/Core/Portable/PopulateSwitch/PopulateSwitchCodeFixProvider.cs +++ b/src/Features/Core/Portable/PopulateSwitch/PopulateSwitchCodeFixProvider.cs @@ -27,6 +27,11 @@ namespace Microsoft.CodeAnalysis.PopulateSwitch [ExtensionOrder(After = PredefinedCodeFixProviderNames.ImplementInterface)] internal class PopulateSwitchCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public PopulateSwitchCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.PopulateSwitchDiagnosticId); diff --git a/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs b/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs index 4241a2851ae74..081a03ace229c 100644 --- a/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs +++ b/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs @@ -18,6 +18,11 @@ namespace Microsoft.CodeAnalysis.PreferFrameworkType Name = PredefinedCodeFixProviderNames.PreferFrameworkType), Shared] internal class PreferFrameworkTypeCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public PreferFrameworkTypeCodeFixProvider() + { + } + public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create( IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId); diff --git a/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs b/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs index 720333ed76f09..6ee853a31e569 100644 --- a/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs +++ b/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs @@ -254,20 +254,26 @@ private static async Task PullMembersIntoClassAsync( var newDestination = codeGenerationService.AddMembers(destinationSyntaxNode, pullUpMembersSymbols, options: options); // Remove some original members since we are pulling members into class. - // Note: If user chooses to make the member abstract, then the original member won't be touched, - // It will just pull a abstract declaration up to destination. + // Note: If the user chooses to make the member abstract, then the original member will be changed to an override, + // and it will pull an abstract declaration up to the destination. // But if the member is abstract itself, it will still be removed. foreach (var analysisResult in result.MemberAnalysisResults) { - if (!analysisResult.MakeMemberDeclarationAbstract) + foreach (var syntax in symbolToDeclarations[analysisResult.Member]) { - foreach (var syntax in symbolToDeclarations[analysisResult.Member]) + var originalMemberEditor = await solutionEditor.GetDocumentEditorAsync( + solution.GetDocumentId(syntax.SyntaxTree), + cancellationToken).ConfigureAwait(false); + + if (!analysisResult.MakeMemberDeclarationAbstract || analysisResult.Member.IsAbstract) { - var originalMemberEditor = await solutionEditor.GetDocumentEditorAsync( - solution.GetDocumentId(syntax.SyntaxTree), - cancellationToken).ConfigureAwait(false); originalMemberEditor.RemoveNode(originalMemberEditor.Generator.GetDeclaration(syntax)); } + else + { + var declarationSyntax = originalMemberEditor.Generator.GetDeclaration(syntax); + originalMemberEditor.ReplaceNode(declarationSyntax, (node, generator) => generator.WithModifiers(node, DeclarationModifiers.Override)); + } } } diff --git a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs index e1fa0f85970e6..02c66bf708ba5 100644 --- a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs @@ -22,6 +22,11 @@ internal class ReplaceMethodWithPropertyCodeRefactoringProvider : CodeRefactorin { private const string GetPrefix = "Get"; + [ImportingConstructor] + public ReplaceMethodWithPropertyCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs index f3fe04418b292..f2bff8caac6d1 100644 --- a/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs @@ -27,6 +27,11 @@ internal class ReplacePropertyWithMethodsCodeRefactoringProvider : CodeRefactori private const string GetPrefix = "Get"; private const string SetPrefix = "Set"; + [ImportingConstructor] + public ReplacePropertyWithMethodsCodeRefactoringProvider() + { + } + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; diff --git a/src/Features/Core/Portable/Shared/IDocumentSupportsFeatureService.cs b/src/Features/Core/Portable/Shared/IDocumentSupportsFeatureService.cs index 8141ed1a9d0f4..0423494f6cd7a 100644 --- a/src/Features/Core/Portable/Shared/IDocumentSupportsFeatureService.cs +++ b/src/Features/Core/Portable/Shared/IDocumentSupportsFeatureService.cs @@ -18,6 +18,11 @@ internal interface IDocumentSupportsFeatureService : IWorkspaceService [ExportWorkspaceService(typeof(IDocumentSupportsFeatureService), ServiceLayer.Default), Shared] internal class DefaultDocumentSupportsFeatureService : IDocumentSupportsFeatureService { + [ImportingConstructor] + public DefaultDocumentSupportsFeatureService() + { + } + public bool SupportsCodeFixes(Document document) => true; diff --git a/src/Features/Core/Portable/Shared/Options/ServiceComponentOnOffOptionsProvider.cs b/src/Features/Core/Portable/Shared/Options/ServiceComponentOnOffOptionsProvider.cs index e437372f85d40..4384af4135fb5 100644 --- a/src/Features/Core/Portable/Shared/Options/ServiceComponentOnOffOptionsProvider.cs +++ b/src/Features/Core/Portable/Shared/Options/ServiceComponentOnOffOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Shared.Options [ExportOptionProvider, Shared] internal class ServiceComponentOnOffOptionsProvider : IOptionProvider { + [ImportingConstructor] + public ServiceComponentOnOffOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( ServiceComponentOnOffOptions.DiagnosticProvider); } diff --git a/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptionsProvider.cs b/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptionsProvider.cs index aa347f5702122..9061a2178fd5d 100644 --- a/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptionsProvider.cs +++ b/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.Shared.Options [ExportOptionProvider, Shared] internal class ServiceFeatureOnOffOptionsProvider : IOptionProvider { + [ImportingConstructor] + public ServiceFeatureOnOffOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( ServiceFeatureOnOffOptions.ClosedFileDiagnostic); } diff --git a/src/Features/Core/Portable/SolutionCrawler/InternalSolutionCrawlerOptionsProvider.cs b/src/Features/Core/Portable/SolutionCrawler/InternalSolutionCrawlerOptionsProvider.cs index cc464e4129187..36d9247b2eef4 100644 --- a/src/Features/Core/Portable/SolutionCrawler/InternalSolutionCrawlerOptionsProvider.cs +++ b/src/Features/Core/Portable/SolutionCrawler/InternalSolutionCrawlerOptionsProvider.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.SolutionCrawler [ExportOptionProvider, Shared] internal class InternalSolutionCrawlerOptionsProvider : IOptionProvider { + [ImportingConstructor] + public InternalSolutionCrawlerOptionsProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( InternalSolutionCrawlerOptions.SolutionCrawler, InternalSolutionCrawlerOptions.ActiveFileWorkerBackOffTimeSpanInMS, diff --git a/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerService.cs b/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerService.cs index 573c37d7ad407..fcdfe5235cc76 100644 --- a/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerService.cs +++ b/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerService.cs @@ -18,6 +18,11 @@ internal partial class SolutionCrawlerRegistrationService : ISolutionCrawlerRegi [ExportWorkspaceService(typeof(ISolutionCrawlerService), ServiceLayer.Default), Shared] internal class SolutionCrawlerService : ISolutionCrawlerService { + [ImportingConstructor] + public SolutionCrawlerService() + { + } + public void Reanalyze(Workspace workspace, IIncrementalAnalyzer analyzer, IEnumerable projectIds = null, IEnumerable documentIds = null, bool highPriority = false) { // if solution crawler doesn't exist for the given workspace. don't do anything diff --git a/src/Features/Core/Portable/SymbolMapping/SymbolMappingServiceFactory.cs b/src/Features/Core/Portable/SymbolMapping/SymbolMappingServiceFactory.cs index a6c29b9bb8d62..001c066ff4f16 100644 --- a/src/Features/Core/Portable/SymbolMapping/SymbolMappingServiceFactory.cs +++ b/src/Features/Core/Portable/SymbolMapping/SymbolMappingServiceFactory.cs @@ -10,6 +10,11 @@ namespace Microsoft.CodeAnalysis.SymbolMapping [ExportWorkspaceService(typeof(ISymbolMappingService), ServiceLayer.Default), Shared] internal class DefaultSymbolMappingService : ISymbolMappingService { + [ImportingConstructor] + public DefaultSymbolMappingService() + { + } + public async Task MapSymbolAsync(Document document, SymbolKey symbolId, CancellationToken cancellationToken) { var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionCodeFixProvider.cs b/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionCodeFixProvider.cs index 5ad96d64582f2..9b8cb622672aa 100644 --- a/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionCodeFixProvider.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis.UseCoalesceExpression [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared] internal class UseCoalesceExpressionCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseCoalesceExpressionCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseCoalesceExpressionDiagnosticId); diff --git a/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionForNullableCodeFixProvider.cs b/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionForNullableCodeFixProvider.cs index 2e289feda9fc5..c65039acb986f 100644 --- a/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionForNullableCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseCoalesceExpression/UseCoalesceExpressionForNullableCodeFixProvider.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.UseCoalesceExpression [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared] internal class UseCoalesceExpressionForNullableCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseCoalesceExpressionForNullableCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseCoalesceExpressionForNullableDiagnosticId); diff --git a/src/Features/Core/Portable/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs b/src/Features/Core/Portable/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs index 99e0c886af628..3c14d2babb64c 100644 --- a/src/Features/Core/Portable/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.UseExplicitTupleName [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared] internal partial class UseExplicitTupleNameCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseExplicitTupleNameCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseExplicitTupleNameDiagnosticId); diff --git a/src/Features/Core/Portable/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs b/src/Features/Core/Portable/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs index 1b009ebb122e3..73a0c292ce4b4 100644 --- a/src/Features/Core/Portable/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs @@ -26,7 +26,7 @@ public override ImmutableArray FixableDiagnosticIds protected abstract string GetIsNullTitle(); protected abstract string GetIsNotNullTitle(); protected abstract SyntaxNode CreateNullCheck(SyntaxNode argument, bool isUnconstrainedGeneric); - protected abstract SyntaxNode CreateNotNullCheck(SyntaxNode notExpression, SyntaxNode argument, bool isUnconstrainedGeneric); + protected abstract SyntaxNode CreateNotNullCheck(SyntaxNode argument); private static bool IsSupportedDiagnostic(Diagnostic diagnostic) => diagnostic.Properties[UseIsNullConstants.Kind] == UseIsNullConstants.ReferenceEqualsKey; @@ -74,7 +74,7 @@ protected override Task FixAllAsync( var toReplace = negate ? invocation.Parent : invocation; var replacement = negate - ? CreateNotNullCheck(invocation.Parent, argument, isUnconstrainedGeneric) + ? CreateNotNullCheck(argument) : CreateNullCheck(argument, isUnconstrainedGeneric); editor.ReplaceNode( diff --git a/src/Features/Core/Portable/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs b/src/Features/Core/Portable/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs index 1aa38558f9948..a846721638add 100644 --- a/src/Features/Core/Portable/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs @@ -19,6 +19,11 @@ namespace Microsoft.CodeAnalysis.UseThrowExpression Name = PredefinedCodeFixProviderNames.UseThrowExpression), Shared] internal partial class UseThrowExpressionCodeFixProvider : SyntaxEditorBasedCodeFixProvider { + [ImportingConstructor] + public UseThrowExpressionCodeFixProvider() + { + } + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseThrowExpressionDiagnosticId); diff --git a/src/Features/Core/Portable/ValidateFormatString/ValidateFormatStringOption.cs b/src/Features/Core/Portable/ValidateFormatString/ValidateFormatStringOption.cs index 33bbf7fcf71fb..8b6f6d28ca62c 100644 --- a/src/Features/Core/Portable/ValidateFormatString/ValidateFormatStringOption.cs +++ b/src/Features/Core/Portable/ValidateFormatString/ValidateFormatStringOption.cs @@ -20,6 +20,11 @@ internal class ValidateFormatStringOption [ExportOptionProvider, Shared] internal class ValidateFormatStringOptionProvider : IOptionProvider { + [ImportingConstructor] + public ValidateFormatStringOptionProvider() + { + } + public ImmutableArray Options { get; } = ImmutableArray.Create( ValidateFormatStringOption.ReportInvalidPlaceholdersInStringDotFormatCalls); } diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index d603975c9e29c..6d61922aaa1ee 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -112,6 +112,31 @@ Převést na řazenou kolekci členů + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used Hodnota výrazu se nikdy nepoužívá. @@ -137,6 +162,16 @@ Formátuje se dokument. + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Odsadit všechny argumenty @@ -407,6 +442,11 @@ Zrušit zalomení seznamu parametrů + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Pro lambda výrazy používat text bloku @@ -457,6 +497,16 @@ Použít operátor rozsahu + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index a139e3dbf9cbb..cb3643eaf9e15 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -112,6 +112,31 @@ In Tupel konvertieren + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used Der Ausdruckswert wird niemals verwendet. @@ -137,6 +162,16 @@ Dokument wird formatiert + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Alle Argumente einrücken @@ -407,6 +442,11 @@ Parameterliste entpacken + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Blockkörper für Lambdaausdrücke verwenden @@ -457,6 +497,16 @@ Bereichsoperator verwenden + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index 7443fabe33067..a6e606f20b4f4 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -112,6 +112,31 @@ Convertir a tupla + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used El valor de la expresión no se utiliza nunca. @@ -137,6 +162,16 @@ Aplicando formato al documento + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Aplicar sangría a todos los argumentos @@ -407,6 +442,11 @@ Desajustar la lista de parámetros + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Usar cuerpo de bloque de expresiones lambda @@ -457,6 +497,16 @@ Usar el operador de intervalo + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index 60ad55fed15d7..a6ddd39b61480 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -112,6 +112,31 @@ Convertir en tuple + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used La valeur d'expression n'est jamais utilisée @@ -137,6 +162,16 @@ Mise en forme du document + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Mettre en retrait tous les arguments @@ -407,6 +442,11 @@ Exclure du wrapper la liste de paramètres + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Utiliser le corps de bloc pour les expressions lambda @@ -457,6 +497,16 @@ Utiliser l'opérateur de plage + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index 060fedb5efa32..94a435d6dc8db 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -112,6 +112,31 @@ Converti in tupla + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used Il valore dell'espressione non viene mai usato @@ -137,6 +162,16 @@ Formattazione del documento + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Imposta rientro per tutti gli argomenti @@ -407,6 +442,11 @@ Annulla ritorno a capo per elenco di parametri + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Usa il corpo del blocco per le espressioni lambda @@ -457,6 +497,16 @@ Usa l'operatore di intervallo + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index 6e6644927b016..3254564ea718b 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -112,6 +112,31 @@ タプルに変換 + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used 式の値が使用されていません @@ -137,6 +162,16 @@ ドキュメントの書式設定 + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments すべての引数にインデントを設定します @@ -407,6 +442,11 @@ パラメーター リストのラップを解除します + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions ラムダ式にブロック本体を使用する @@ -457,6 +497,16 @@ 範囲演算子を使用 + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index 4cfbc64d5b022..21990270e60eb 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -112,6 +112,31 @@ 튜플로 변환 + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used 식 값은 절대 사용되지 않습니다. @@ -137,6 +162,16 @@ 문서 서식을 지정하는 중 + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments 모든 인수 들여쓰기 @@ -407,6 +442,11 @@ 매개 변수 목록 줄 바꿈 조정 + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions 람다 식에 블록 본문 사용 @@ -457,6 +497,16 @@ 범위 연산자 사용 + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index 81c4b76dd9e58..183559246a90c 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -112,6 +112,31 @@ Konwertuj na spójną kolekcję + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used Wartość wyrażenia nie jest nigdy używana. @@ -137,6 +162,16 @@ Trwa formatowanie dokumentu... + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Dodaj wcięcie dla wszystkich argumentów @@ -407,6 +442,11 @@ Odpakuj listę parametrów + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Użyj treści bloku dla wyrażeń lambda @@ -457,6 +497,16 @@ Użyj operatora zakresu + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index 92939e4108098..6c44e6d0fb1dc 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -112,6 +112,31 @@ Converter a tupla + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used O valor da expressão nunca é usado @@ -137,6 +162,16 @@ Formatando documento + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Recuar todos os argumentos @@ -407,6 +442,11 @@ Desencapsular a lista de parâmetros + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Usar o corpo do bloco para expressões lambda @@ -457,6 +497,16 @@ Usar operador de intervalo + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index 73dedfb578e70..6487a3953574b 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -112,6 +112,31 @@ Преобразовать в кортеж + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used Значение выражения никогда не используется @@ -137,6 +162,16 @@ Форматирование документа + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Добавить отступы для всех аргументов @@ -407,6 +442,11 @@ Развернуть список параметров + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Использовать тело блока для лямбда-выражений @@ -457,6 +497,16 @@ Использовать оператор диапазона + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index 77a3a784b6e56..ae1adc066a27d 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -112,6 +112,31 @@ Başlığa dönüştür + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used İfade değeri asla kullanılmaz @@ -137,6 +162,16 @@ Belge biçimlendiriliyor + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments Tüm bağımsız değişkenleri girintile @@ -407,6 +442,11 @@ Parametre listesinin sarmalamasını kaldır + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions Lambda ifadeleri için blok vücut kullanımı @@ -457,6 +497,16 @@ Aralık işleci kullan + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index 00006e1d7bd70..a851dfb7fe079 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -112,6 +112,31 @@ 转换为元组 + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used 永远不会使用表达式值 @@ -137,6 +162,16 @@ 设置文档格式 + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments 缩进所有参数 @@ -407,6 +442,11 @@ 展开参数列表 + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions 对 lambda 表达式使用块正文 @@ -457,6 +497,16 @@ 使用范围运算符 + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index a8b64233b757d..51b79781931fb 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -112,6 +112,31 @@ 轉換為元組 + + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type. To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field. + + + + Disposable field '{0}' is never disposed + Disposable field '{0}' is never disposed + + + + Disposable fields should be disposed + Disposable fields should be disposed + + + + Disposable object created by '{0}' is never disposed + Disposable object created by '{0}' is never disposed + + + + Dispose objects before losing scope + Dispose objects before losing scope + + Expression value is never used 永遠不會使用運算式值 @@ -137,6 +162,16 @@ 正在將文件格式化 + + Generate parameter '{0}' + Generate parameter '{0}' + + + + Generate parameter '{0}' (and overrides/implementations) + Generate parameter '{0}' (and overrides/implementations) + + Indent all arguments 將所有引數縮排 @@ -407,6 +442,11 @@ 將參數清單取消換行 + + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + Use recommended dispose pattern to ensure that locally scoped disposable objects are disposed on all paths. If possible, wrap the creation within a 'using' statement or a 'using' declaration. Otherwise, use a try-finally pattern, with a dedicated local variable declared before the try region and an unconditional Dispose invocation on non-null value in the 'finally' region, say 'x?.Dispose()'. If the object is explicitly disposed within the try region or the dispose ownership is transfered to another object or method, assign 'null' to the local variable just after such an operation to prevent double dispose in 'finally' + + Use block body for lambda expressions 使用 Lambda 運算式的區體主體 @@ -457,6 +497,16 @@ 使用範圍運算子 + + Use recommended dispose pattern + Use recommended dispose pattern + + + + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + Use recommended dispose pattern to ensure that object created by '{0}' is disposed on all paths: using statement/declaration or try/finally + {Locked="using"}{Locked="try"}{Locked="finally"} "using", "try" and "finally" are C# keywords and should not be localized. + Use simple 'using' statement Use simple 'using' statement diff --git a/src/Features/VisualBasic/Portable/AddAccessibilityModifiers/VisualBasicAddAccessibilityModifiersCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AddAccessibilityModifiers/VisualBasicAddAccessibilityModifiersCodeFixProvider.vb index aa86d73420408..0644634abdb74 100644 --- a/src/Features/VisualBasic/Portable/AddAccessibilityModifiers/VisualBasicAddAccessibilityModifiersCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AddAccessibilityModifiers/VisualBasicAddAccessibilityModifiersCodeFixProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddAccessibilityModifiers Friend Class VisualBasicAddAccessibilityModifiersCodeFixProvider Inherits AbstractAddAccessibilityModifiersCodeFixProvider + + Public Sub New() + End Sub + Protected Overrides Function MapToDeclarator(declaration As SyntaxNode) As SyntaxNode If TypeOf declaration Is FieldDeclarationSyntax Then Return DirectCast(declaration, FieldDeclarationSyntax).Declarators(0).Names(0) diff --git a/src/Features/VisualBasic/Portable/AddAnonymousTypeMemberName/VisualBasicAddAnonymousTypeMemberNameCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AddAnonymousTypeMemberName/VisualBasicAddAnonymousTypeMemberNameCodeFixProvider.vb index dbfa4527ddb57..f15df0b1c79b0 100644 --- a/src/Features/VisualBasic/Portable/AddAnonymousTypeMemberName/VisualBasicAddAnonymousTypeMemberNameCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AddAnonymousTypeMemberName/VisualBasicAddAnonymousTypeMemberNameCodeFixProvider.vb @@ -16,6 +16,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddAnonymousTypeMemberName Private Const BC36556 As String = NameOf(BC36556) ' Anonymous type member name can be inferred only from a simple or qualified name with no arguments. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC36556) diff --git a/src/Features/VisualBasic/Portable/AddFileBanner/VisualBasicAddFileBannerCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/AddFileBanner/VisualBasicAddFileBannerCodeRefactoringProvider.vb index 21fe8625934ed..1002314cffec1 100644 --- a/src/Features/VisualBasic/Portable/AddFileBanner/VisualBasicAddFileBannerCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/AddFileBanner/VisualBasicAddFileBannerCodeRefactoringProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddFileBanner Friend Class VisualBasicAddFileBannerCodeRefactoringProvider Inherits AbstractAddFileBannerCodeRefactoringProvider + + Public Sub New() + End Sub + Protected Overrides Function IsCommentStartCharacter(ch As Char) As Boolean Return ch = "'"c End Function diff --git a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportCodeFixProvider.vb index 5a221873f1d09..5791d8d83d95f 100644 --- a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportCodeFixProvider.vb @@ -97,6 +97,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddImport Friend Class VisualBasicAddImportCodeFixProvider Inherits AbstractAddImportCodeFixProvider + Public Sub New() End Sub diff --git a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb index 19e1dcf35d5a3..a81883049a3ed 100644 --- a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb +++ b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddImport Friend Class VisualBasicAddImportFeatureService Inherits AbstractAddImportFeatureService(Of SimpleNameSyntax) + + Public Sub New() + End Sub + Protected Overrides Function CanAddImport(node As SyntaxNode, cancellationToken As CancellationToken) As Boolean If node.GetAncestor(Of ImportsStatementSyntax)() IsNot Nothing Then Return False diff --git a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddMissingImportsFeatureService.vb b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddMissingImportsFeatureService.vb index dc7c6ecf85dcc..2a1371ba45304 100644 --- a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddMissingImportsFeatureService.vb +++ b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddMissingImportsFeatureService.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddMissingImports Friend Class VisualBasicAddMissingImportsFeatureService Inherits AbstractAddMissingImportsFeatureService + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = AddImportDiagnosticIds.FixableDiagnosticIds End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/AddObsoleteAttribute/VisualBasicAddObsoleteAttributeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AddObsoleteAttribute/VisualBasicAddObsoleteAttributeCodeFixProvider.vb index 783e8b027d862..0c031d0d3beeb 100644 --- a/src/Features/VisualBasic/Portable/AddObsoleteAttribute/VisualBasicAddObsoleteAttributeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AddObsoleteAttribute/VisualBasicAddObsoleteAttributeCodeFixProvider.vb @@ -16,6 +16,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddObsoleteAttribute "BC40008" ' 'C' is obsolete. ) + Public Sub New() MyBase.New(VisualBasicSyntaxFactsService.Instance, VBFeaturesResources.Add_Obsolete) End Sub diff --git a/src/Features/VisualBasic/Portable/AddPackage/VisualBasicAddSpecificPackageCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AddPackage/VisualBasicAddSpecificPackageCodeFixProvider.vb index ab0891c44d329..bd29ec5643f61 100644 --- a/src/Features/VisualBasic/Portable/AddPackage/VisualBasicAddSpecificPackageCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AddPackage/VisualBasicAddSpecificPackageCodeFixProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddPackage Private Const BC37267 As String = NameOf(BC37267) ' Predefined type 'ValueTuple(Of ,)' is not defined or imported. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC37267) diff --git a/src/Features/VisualBasic/Portable/AddParameter/VisualBasicAddParameterCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AddParameter/VisualBasicAddParameterCodeFixProvider.vb index b6408414de709..94bcaadd1681a 100644 --- a/src/Features/VisualBasic/Portable/AddParameter/VisualBasicAddParameterCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AddParameter/VisualBasicAddParameterCodeFixProvider.vb @@ -32,6 +32,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddParameter Const BC36582 As String = NameOf(BC36582) ' error BC36582: Too many arguments to extension method 'Public Sub ExtensionM1()' defined in 'Extensions'. Const BC36625 As String = NameOf(BC36625) ' error BC36625: Lambda expression cannot be converted to 'Integer' because 'Integer' is not a delegate type. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(Of String)( IDEDiagnosticIds.UnboundConstructorId, BC30057, BC30272, BC30274, BC30311, BC30389, BC30512, BC32006, BC30387, BC30516, BC36582, BC36625) diff --git a/src/Features/VisualBasic/Portable/AliasAmbiguousType/VisualBasicAliasAmbiguousTypeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/AliasAmbiguousType/VisualBasicAliasAmbiguousTypeCodeFixProvider.vb index 7f57e68a61973..d1a351e89cdb1 100644 --- a/src/Features/VisualBasic/Portable/AliasAmbiguousType/VisualBasicAliasAmbiguousTypeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/AliasAmbiguousType/VisualBasicAliasAmbiguousTypeCodeFixProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AliasAmbiguousType 'BC30561: '' is ambiguous, imported from the namespaces or types '' Private Const BC30561 As String = NameOf(BC30561) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC30561) Protected Overrides Function GetTextPreviewOfChange(aliasName As String, typeSymbol As ITypeSymbol) As String diff --git a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb index 7efa27f4a1b65..69482ea88520a 100644 --- a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb +++ b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb @@ -76,6 +76,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature SyntaxKind.SubNewStatement, SyntaxKind.ConstructorBlock) + + Public Sub New() + End Sub + Public Overrides Async Function GetInvocationSymbolAsync( document As Document, position As Integer, diff --git a/src/Features/VisualBasic/Portable/CodeFixes/AddMissingReference/VisualBasicAddMissingReferenceCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/AddMissingReference/VisualBasicAddMissingReferenceCodeFixProvider.vb index ec5503ec75494..cdb020d4eaf1b 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/AddMissingReference/VisualBasicAddMissingReferenceCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/AddMissingReference/VisualBasicAddMissingReferenceCodeFixProvider.vb @@ -17,6 +17,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddMissingReference Friend Const BC30005 As String = "BC30005" ' ERR_UnreferencedAssemblyEvent3 Friend Const BC30652 As String = "BC30652" ' ERR_UnreferencedAssembly3 + Public Sub New() End Sub diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb index 5a1988f3e6614..1215926dc140a 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb @@ -23,6 +23,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async Friend ReadOnly Ids As ImmutableArray(Of String) = ImmutableArray.Create(BC30311, BC37055, BC42358) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return Ids diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicConvertToAsyncFunctionCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicConvertToAsyncFunctionCodeFixProvider.vb index 08c1f963ff710..4b2710709aad4 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicConvertToAsyncFunctionCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicConvertToAsyncFunctionCodeFixProvider.vb @@ -18,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async Friend ReadOnly Ids As ImmutableArray(Of String) = ImmutableArray.Create(Of String)(BC37001) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return Ids diff --git a/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb index 4ff7a3aa5e8ef..057590bc9e83f 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.CorrectNextControlVariabl Friend Const BC30070 As String = "BC30070" ' Next control variable does not match For loop control variable 'x'. Friend Const BC30451 As String = "BC30451" 'BC30451: 'y' is not declared. It may be inaccessible due to its protection level. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30070, BC30451) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb index b3b978acc3618..3a7c3a05b33fb 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb @@ -40,6 +40,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEndConstruct Friend Const BC31117 As String = "BC31117" ' error BC31117: 'RaiseEvent' declaration must end with a matching 'End RaiseEvent'. Friend Const BC36008 As String = "BC36008" ' error BC36008: 'Using' must end with a matching 'End Using'. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30025, BC30026, BC30027, BC30081, BC30082, BC30083, BC30084, BC30085, BC30185, BC30253, BC30384, BC30481, BC30624, BC30625, diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb index e361197b5770a..636454186da5c 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEnumMember Friend Const BC30456 As String = "BC30456" ' error BC30456: 'Red' is not a member of 'Color'. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30456) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb index da72146c3fcb1..971cced1101b2 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb @@ -21,6 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent Friend Const BC30456 As String = "BC30456" ' error BC30456: 'x' is not a member of 'y'. Friend Const BC30451 As String = "BC30451" ' error BC30451: 'x' is not declared, it may be inaccessible due to its protection level. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30401, BC30590, BC30456, BC30451) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb index 6ea24c9b2f3cf..ef372c5c36d31 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateMethod Friend Const BC30311 As String = "BC30311" ' error BC30311: Cannot convert type 'x' to type 'y' + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30311) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb index 37b903c4f0c77..c326f84c04782 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb @@ -36,6 +36,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateMethod Friend Const BC30110 As String = "BC30110" ' error BC30110: 'Foo' is a structure type and cannot be used as an expression. Friend Const BC30111 As String = "BC30111" ' error BC30111: 'Foo' is an interface type and cannot be used as an expression. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30518, BC30519, BC30520, BC30521, BC30057, BC30112, BC30451, BC30455, BC30456, BC30401, BC30516, BC32016, BC32045, BC32087, BC36625, BC30107, BC30108, BC30109, BC30110, BC30111) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb index 4da4cacbf2749..569304fe7f15c 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb @@ -25,6 +25,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateType Friend Const BC32045 As String = "BC32045" ' error BC32045: 'Goo' has no type parameters and so cannot have type arguments. Friend Const BC40056 As String = "BC40056" ' error BC40056: Namespace or type specified in the Imports 'A' doesn't contain any public member or cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make sure the imported element name doesn't use any aliases. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30002, IDEDiagnosticIds.UnboundIdentifierId, BC30182, BC30451, BC30456, BC32042, BC32043, BC32045, BC40056) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb index d099ab5c5dd83..0e00f23d9bbd7 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb @@ -35,6 +35,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectExitContinue Friend Const BC30689 As String = "BC30689" ' Statement cannot appear outside of a method body. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30781, BC30782, BC30783, BC30784, BC30240, BC30065, BC30066, BC30067, BC30089, BC30096, BC30097, BC30099, BC30393, BC30689) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb index d98e31064ff55..b839bac7dd0c1 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb @@ -18,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectFunctionReturnTy Friend Const BC36938 As String = "BC36938" ' Iterator functions must return either IEnumerable(Of T), or IEnumerator(Of T), or the non-generic forms IEnumerable or IEnumerator. Friend Const BC36945 As String = "BC36945" ' The 'Async' modifier can only be used on Subs, or on Functions that return Task or Task(Of T). + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC36938, BC36945) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/InsertMissingCast/InsertMissingCastCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/InsertMissingCast/InsertMissingCastCodeFixProvider.vb index 48304b34bb035..a53056b7c8bda 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/InsertMissingCast/InsertMissingCastCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/InsertMissingCast/InsertMissingCastCodeFixProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.InsertMissingCast Friend Const BC30512 As String = "BC30512" ' Option Strict On disallows implicit conversions from '{0}' to '{1}'. Friend Const BC42016 As String = "BC42016" ' Implicit conversions from '{0}' to '{1}'. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30512, BC42016) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicChangeToYieldCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicChangeToYieldCodeFixProvider.vb index 3ee6e2d27ccd1..b2a311bc5f23b 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicChangeToYieldCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicChangeToYieldCodeFixProvider.vb @@ -19,6 +19,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Iterator Friend Const BC36942 As String = "BC36942" ' error BC36942 : To return a value from an Iterator function, use 'Yield' rather than 'Return'. Friend Shared ReadOnly Ids As ImmutableArray(Of String) = ImmutableArray.Create(BC36942) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return Ids diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb index 7db26074e779e..918029b05503c 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb @@ -21,6 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Iterator Friend Shared ReadOnly Ids As ImmutableArray(Of String) = ImmutableArray.Create(BC30451) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return Ids diff --git a/src/Features/VisualBasic/Portable/CodeFixes/MoveToTopOfFile/MoveToTopOfFileCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/MoveToTopOfFile/MoveToTopOfFileCodeFixProvider.vb index 3b004e6643b24..813ddac1c7e48 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/MoveToTopOfFile/MoveToTopOfFileCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/MoveToTopOfFile/MoveToTopOfFileCodeFixProvider.vb @@ -20,6 +20,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.MoveToTopOfFile Friend Const BC30637 As String = "BC30637" ' Assembly or Module attribute statements must precede any declarations in a file. Friend Const BC30627 As String = "BC30627" ' 'Option' statements must precede any declarations or 'Imports' statements. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30465, BC30637, BC30627) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb index ef9f5e4394699..c532e8c84731e 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.OverloadBase Friend Const BC40003 As String = "BC40003" ' '{0} '{1}' shadows an overloadable member declared in the base class '{2}'. If you want to overload the base method, this method must be declared 'Overloads'. Friend Const BC40004 As String = "BC40004" ' '{0} '{1}' overloads an overloadable member declared in the base class '{2}'. If you want to shadow the base method, this method must be declared 'Shadows'. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC40003, BC40004) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.vb index 7c56fac071293..41a622eb256fd 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/RemoveUnnecessaryCast/RemoveUnnecessaryCastCodeFixProvider.vb @@ -19,6 +19,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.RemoveUnnecessaryCast Partial Friend Class RemoveUnnecessaryCastCodeFixProvider Inherits SyntaxEditorBasedCodeFixProvider + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(IDEDiagnosticIds.RemoveUnnecessaryCastDiagnosticId) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb index 896a6375b1eb4..d4ab740c814c9 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Suppression Friend Class VisualBasicSuppressionCodeFixProvider Inherits AbstractSuppressionCodeFixProvider + + Public Sub New() + End Sub + Protected Overrides Function CreatePragmaRestoreDirectiveTrivia(diagnostic As Diagnostic, formatNode As Func(Of SyntaxNode, SyntaxNode), needsLeadingEndOfLine As Boolean, needsTrailingEndOfLine As Boolean) As SyntaxTriviaList Dim errorCodes = GetErrorCodes(diagnostic) Dim pragmaDirective = SyntaxFactory.EnableWarningDirectiveTrivia(errorCodes) diff --git a/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb b/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb index 15d040c24175d..186fce5df32a0 100644 --- a/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb +++ b/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb @@ -23,6 +23,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeLens SymbolDisplayKindOptions.None, SymbolDisplayMiscellaneousOptions.UseSpecialTypes) + + Public Sub New() + End Sub + ''' ''' Returns the node that should be displayed ''' diff --git a/src/Features/VisualBasic/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.vb index 57f1ec4361f3d..e4c89291f6f21 100644 --- a/src/Features/VisualBasic/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeRefactorings/AddAwait/AddAwaitCodeRefactoringProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.AddAwait Friend Class VisualBasicAddAwaitCodeRefactoringProvider Inherits AbstractAddAwaitCodeRefactoringProvider(Of ExpressionSyntax, InvocationExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetTitle() As String Return VBFeaturesResources.Add_Await End Function diff --git a/src/Features/VisualBasic/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.vb index d841ca550d969..a03cb7d7bed07 100644 --- a/src/Features/VisualBasic/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.vb @@ -18,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.InlineTemporary Partial Friend Class InlineTemporaryCodeRefactoringProvider Inherits CodeRefactoringProvider + + Public Sub New() + End Sub + Public Overloads Overrides Async Function ComputeRefactoringsAsync(context As CodeRefactoringContext) As Task Dim document = context.Document Dim textSpan = context.Span diff --git a/src/Features/VisualBasic/Portable/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb b/src/Features/VisualBasic/Portable/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb index 0a56c7f6df47c..2e9004e25d854 100644 --- a/src/Features/VisualBasic/Portable/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb +++ b/src/Features/VisualBasic/Portable/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb @@ -10,5 +10,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.MoveType Friend Class VisualBasicMoveTypeService Inherits AbstractMoveTypeService(Of VisualBasicMoveTypeService, TypeBlockSyntax, NamespaceBlockSyntax, MethodBaseSyntax, CompilationUnitSyntax) + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/CodeRefactorings/SyncNamespace/VisualBasicChangeNamespaceService.vb b/src/Features/VisualBasic/Portable/CodeRefactorings/SyncNamespace/VisualBasicChangeNamespaceService.vb index 91cce939c3898..7ec3787453146 100644 --- a/src/Features/VisualBasic/Portable/CodeRefactorings/SyncNamespace/VisualBasicChangeNamespaceService.vb +++ b/src/Features/VisualBasic/Portable/CodeRefactorings/SyncNamespace/VisualBasicChangeNamespaceService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeNamespace Friend Class VisualBasicChangeNamespaceService Inherits AbstractChangeNamespaceService(Of NamespaceStatementSyntax, CompilationUnitSyntax, StatementSyntax) + + Public Sub New() + End Sub + Public Overrides Function TryGetReplacementReferenceSyntax(reference As SyntaxNode, newNamespaceParts As ImmutableArray(Of String), syntaxFacts As ISyntaxFactsService, ByRef old As SyntaxNode, ByRef [new] As SyntaxNode) As Boolean Dim nameRef = TryCast(reference, SimpleNameSyntax) If nameRef IsNot Nothing Then diff --git a/src/Features/VisualBasic/Portable/CommentSelection/VisualBasicCommentSelectionService.vb b/src/Features/VisualBasic/Portable/CommentSelection/VisualBasicCommentSelectionService.vb index 2563303da9f00..fb9fa4c450e31 100644 --- a/src/Features/VisualBasic/Portable/CommentSelection/VisualBasicCommentSelectionService.vb +++ b/src/Features/VisualBasic/Portable/CommentSelection/VisualBasicCommentSelectionService.vb @@ -9,6 +9,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CommentSelection Friend Class VisualBasicCommentSelectionService Inherits AbstractCommentSelectionService + + Public Sub New() + End Sub + Public Overrides ReadOnly Property SingleLineCommentString As String = "'" Public Overrides ReadOnly Property SupportsBlockComment As Boolean = False diff --git a/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb b/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb index cd1c6f9e7e4a8..90e95ec5c5a83 100644 --- a/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb +++ b/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb @@ -19,6 +19,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion Friend Class VisualBasicCompletionServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicCompletionService(languageServices.WorkspaceServices.Workspace) End Function diff --git a/src/Features/VisualBasic/Portable/ConflictMarkerResolution/VisualBasicResolveConflictMarkerCodeFixProvider.vb b/src/Features/VisualBasic/Portable/ConflictMarkerResolution/VisualBasicResolveConflictMarkerCodeFixProvider.vb index 7e6d296a610f5..7f00fcd0c74c0 100644 --- a/src/Features/VisualBasic/Portable/ConflictMarkerResolution/VisualBasicResolveConflictMarkerCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/ConflictMarkerResolution/VisualBasicResolveConflictMarkerCodeFixProvider.vb @@ -11,6 +11,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConflictMarkerResolution Private Const BC37284 As String = NameOf(BC37284) + Public Sub New() MyBase.New(BC37284) End Sub diff --git a/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToClass/VisualBasicConvertAnonymousTypeToClassCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToClass/VisualBasicConvertAnonymousTypeToClassCodeRefactoringProvider.vb index d1a6ea84129fb..c4d0796308ce2 100644 --- a/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToClass/VisualBasicConvertAnonymousTypeToClassCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToClass/VisualBasicConvertAnonymousTypeToClassCodeRefactoringProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertAnonymousTypeToClass AnonymousObjectCreationExpressionSyntax, NamespaceBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides Function CreateObjectCreationExpression( nameNode As NameSyntax, anonymousObject As AnonymousObjectCreationExpressionSyntax) As ObjectCreationExpressionSyntax diff --git a/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToTuple/VisualBasicConvertAnonymousTypeToTupleCodeFixProvider.vb b/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToTuple/VisualBasicConvertAnonymousTypeToTupleCodeFixProvider.vb index 60c3e0472fc4c..ff6f8c7d83b8a 100644 --- a/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToTuple/VisualBasicConvertAnonymousTypeToTupleCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertAnonymousTypeToTuple/VisualBasicConvertAnonymousTypeToTupleCodeFixProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertAnonymousTypeToTuple TupleExpressionSyntax, AnonymousObjectCreationExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function ConvertToTuple(anonCreation As AnonymousObjectCreationExpressionSyntax) As TupleExpressionSyntax Return SyntaxFactory.TupleExpression( SyntaxFactory.Token(SyntaxKind.OpenParenToken).WithTriviaFrom(anonCreation.Initializer.OpenBraceToken), diff --git a/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb b/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb index 41dbde8a6bca3..9525f2ff3f197 100644 --- a/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb +++ b/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertAutoPropertyToFullProperty Private Const Underscore As String = "_" + + Public Sub New() + End Sub + Friend Overrides Function GetProperty(token As SyntaxToken) As SyntaxNode Dim containingProperty = token.Parent.FirstAncestorOrSelf(Of PropertyStatementSyntax) If containingProperty Is Nothing Then diff --git a/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb index 00c2a5dd07960..4cb42ae9fcda3 100644 --- a/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertForEachToFor Friend Class VisualBasicConvertForEachToForCodeRefactoringProvider Inherits AbstractConvertForEachToForCodeRefactoringProvider(Of ForEachBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property Title As String = VBFeaturesResources.Convert_to_For Protected Overrides Function GetForEachStatement(selection As TextSpan, token As SyntaxToken) As ForEachBlockSyntax diff --git a/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb index 94e90d926c849..401f1adbc2c00 100644 --- a/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb @@ -19,6 +19,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertForToForEach TypeSyntax, VariableDeclaratorSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetTitle() As String Return VBFeaturesResources.Convert_to_For_Each End Function diff --git a/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb index 9786a0b4cbd0a..f994f5af9f52c 100644 --- a/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch Partial Friend NotInheritable Class VisualBasicConvertIfToSwitchCodeRefactoringProvider Inherits AbstractConvertIfToSwitchCodeRefactoringProvider + + Public Sub New() + End Sub + Protected Overrides Function CreateAnalyzer(syntaxFacts As ISyntaxFactsService, semanticModel As SemanticModel) As IAnalyzer Return New VisualBasicAnalyzer(syntaxFacts, semanticModel) End Function diff --git a/src/Features/VisualBasic/Portable/ConvertNumericLiteral/VisualBasicConvertNumericLiteralCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertNumericLiteral/VisualBasicConvertNumericLiteralCodeRefactoringProvider.vb index 842e29f60b422..6223bf80c4cc3 100644 --- a/src/Features/VisualBasic/Portable/ConvertNumericLiteral/VisualBasicConvertNumericLiteralCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertNumericLiteral/VisualBasicConvertNumericLiteralCodeRefactoringProvider.vb @@ -9,6 +9,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertNumericLiteral Friend NotInheritable Class VisualBasicConvertNumericLiteralCodeRefactoringProvider Inherits AbstractConvertNumericLiteralCodeRefactoringProvider + + Public Sub New() + End Sub + Protected Overrides Function GetNumericLiteralPrefixes() As (hexPrefix As String, binaryPrefix As String) Return (hexPrefix:="&H", binaryPrefix:="&B") End Function diff --git a/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertConcatenationToInterpolatedStringRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertConcatenationToInterpolatedStringRefactoringProvider.vb index 85746fa6bebd1..0e1c5d8501dd2 100644 --- a/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertConcatenationToInterpolatedStringRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertConcatenationToInterpolatedStringRefactoringProvider.vb @@ -9,6 +9,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertToInterpolatedString Friend Class VisualBasicConvertConcatenationToInterpolatedStringRefactoringProvider Inherits AbstractConvertConcatenationToInterpolatedStringRefactoringProvider + + Public Sub New() + End Sub + Protected Overrides Function CreateInterpolatedStringStartToken(isVerbatim As Boolean) As SyntaxToken Return SyntaxFactory.Token(SyntaxKind.DollarSignDoubleQuoteToken) End Function diff --git a/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertPlaceholderToInterpolatedStringRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertPlaceholderToInterpolatedStringRefactoringProvider.vb index 783dc738ab926..ed3ed6ad1f3f9 100644 --- a/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertPlaceholderToInterpolatedStringRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertToInterpolatedString/VisualBasicConvertPlaceholderToInterpolatedStringRefactoringProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertToInterpolatedString Partial Friend Class VisualBasicConvertPlaceholderToInterpolatedStringRefactoringProvider Inherits AbstractConvertPlaceholderToInterpolatedStringRefactoringProvider(Of InvocationExpressionSyntax, ExpressionSyntax, ArgumentSyntax, LiteralExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetInterpolatedString(text As String) As SyntaxNode Return TryCast(SyntaxFactory.ParseExpression("$" + text), InterpolatedStringExpressionSyntax) End Function diff --git a/src/Features/VisualBasic/Portable/ConvertTupleToStruct/VisualBasicConvertTupleToStructCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertTupleToStruct/VisualBasicConvertTupleToStructCodeRefactoringProvider.vb index d2785da4d0ca2..6b23b32f6d6e7 100644 --- a/src/Features/VisualBasic/Portable/ConvertTupleToStruct/VisualBasicConvertTupleToStructCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertTupleToStruct/VisualBasicConvertTupleToStructCodeRefactoringProvider.vb @@ -21,6 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertTupleToStruct TypeBlockSyntax, NamespaceBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides Function CreateObjectCreationExpression( nameNode As NameSyntax, openParen As SyntaxToken, arguments As SeparatedSyntaxList(Of ArgumentSyntax), closeParen As SyntaxToken) As ObjectCreationExpressionSyntax diff --git a/src/Features/VisualBasic/Portable/DesignerAttributes/BasicDesignerAttributeService.vb b/src/Features/VisualBasic/Portable/DesignerAttributes/BasicDesignerAttributeService.vb index 3f8f5dd793520..58a6265e7b4bf 100644 --- a/src/Features/VisualBasic/Portable/DesignerAttributes/BasicDesignerAttributeService.vb +++ b/src/Features/VisualBasic/Portable/DesignerAttributes/BasicDesignerAttributeService.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.DesignerAttributes Friend Class VisualBasicDesignerAttributeServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New BasicDesignerAttributeService(languageServices.WorkspaceServices.Workspace) End Function diff --git a/src/Features/VisualBasic/Portable/Diagnostics/VisualBasicAnalyzerDriverService.vb b/src/Features/VisualBasic/Portable/Diagnostics/VisualBasicAnalyzerDriverService.vb index 0391cbfc6918f..dbfcd8de32a6f 100644 --- a/src/Features/VisualBasic/Portable/Diagnostics/VisualBasicAnalyzerDriverService.vb +++ b/src/Features/VisualBasic/Portable/Diagnostics/VisualBasicAnalyzerDriverService.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Diagnostics Friend NotInheritable Class VisualBasicAnalyzerDriverService Implements IAnalyzerDriverService + + Public Sub New() + End Sub + Public Sub ComputeDeclarationsInSpan(model As SemanticModel, span As TextSpan, getSymbol As Boolean, diff --git a/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb b/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb index 8df43db355f84..1addb5a1a7d66 100644 --- a/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb +++ b/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb @@ -9,5 +9,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.DocumentHighlighting Friend Class VisualBasicDocumentHighlightsService Inherits AbstractDocumentHighlightsService + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/DocumentationComments/CodeFixes/VisualBasicRemoveDocCommentNodeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/DocumentationComments/CodeFixes/VisualBasicRemoveDocCommentNodeCodeFixProvider.vb index 964cb23fc9a1a..968dbd48abb90 100644 --- a/src/Features/VisualBasic/Portable/DocumentationComments/CodeFixes/VisualBasicRemoveDocCommentNodeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/DocumentationComments/CodeFixes/VisualBasicRemoveDocCommentNodeCodeFixProvider.vb @@ -43,6 +43,10 @@ Namespace Microsoft.CodeAnalysis.DiagnosticComments.CodeFixes Friend ReadOnly Id As ImmutableArray(Of String) = ImmutableArray.Create(BC42305, BC42306, BC42307, BC42313, BC42315, BC42317) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return Id diff --git a/src/Features/VisualBasic/Portable/DocumentationComments/VisualBasicDocumentationCommentFormattingService.vb b/src/Features/VisualBasic/Portable/DocumentationComments/VisualBasicDocumentationCommentFormattingService.vb index f34d8ce37c423..a399eb1c2984d 100644 --- a/src/Features/VisualBasic/Portable/DocumentationComments/VisualBasicDocumentationCommentFormattingService.vb +++ b/src/Features/VisualBasic/Portable/DocumentationComments/VisualBasicDocumentationCommentFormattingService.vb @@ -10,5 +10,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.DocumentationComments Friend Class VisualBasicDocumentationCommentFormattingService Inherits AbstractDocumentationCommentFormattingService + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb index cf425e8f267c2..d83f0e2e0daec 100644 --- a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb +++ b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue Friend NotInheritable Class VisualBasicEditAndContinueAnalyzer Inherits AbstractEditAndContinueAnalyzer + + Public Sub New() + End Sub + #Region "Syntax Analysis" ''' diff --git a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb index 6b0e5f4da669a..b3ac5828c30e8 100644 --- a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb +++ b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb @@ -12,6 +12,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages Public Shared Shadows Instance As New VisualBasicEmbeddedLanguageFeaturesProvider() + Public Sub New() MyBase.New(VisualBasicEmbeddedLanguagesProvider.Info) End Sub diff --git a/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb b/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb index ce35ad3b59133..931fec5292963 100644 --- a/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb +++ b/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EncapsulateField Friend Class VisualBasicEncapsulateFieldService Inherits AbstractEncapsulateFieldService + + Public Sub New() + End Sub + Protected Overrides Async Function RewriteFieldNameAndAccessibility(originalFieldName As String, makePrivate As Boolean, document As Document, diff --git a/src/Features/VisualBasic/Portable/ExtractInterface/VisualBasicExtractInterfaceService.vb b/src/Features/VisualBasic/Portable/ExtractInterface/VisualBasicExtractInterfaceService.vb index 366c9faf0f2f9..939c0a9dd8176 100644 --- a/src/Features/VisualBasic/Portable/ExtractInterface/VisualBasicExtractInterfaceService.vb +++ b/src/Features/VisualBasic/Portable/ExtractInterface/VisualBasicExtractInterfaceService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractInterface Friend Class VisualBasicExtractInterfaceService Inherits AbstractExtractInterfaceService + + Public Sub New() + End Sub + Protected Overrides Async Function GetTypeDeclarationAsync( document As Document, position As Integer, typeDiscoveryRule As TypeDiscoveryRule, diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb index 7043204428b93..c5429052aaaa1 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Friend Class VisualBasicExtractMethodService Inherits AbstractExtractMethodService(Of VisualBasicSelectionValidator, VisualBasicMethodExtractor, VisualBasicSelectionResult) + + Public Sub New() + End Sub + Protected Overrides Function CreateSelectionValidator(document As SemanticDocument, textSpan As TextSpan, options As OptionSet) As VisualBasicSelectionValidator diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSyntaxTriviaServiceFactory.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSyntaxTriviaServiceFactory.vb index 83ac38960ad96..5cf3809c5bde4 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSyntaxTriviaServiceFactory.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSyntaxTriviaServiceFactory.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Friend Class VisualBasicSyntaxTriviaServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(provider As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicSyntaxTriviaService(provider) End Function diff --git a/src/Features/VisualBasic/Portable/FullyQualify/VisualBasicFullyQualifyCodeFixProvider.vb b/src/Features/VisualBasic/Portable/FullyQualify/VisualBasicFullyQualifyCodeFixProvider.vb index e732b6bbfee00..69919c1ecaaa1 100644 --- a/src/Features/VisualBasic/Portable/FullyQualify/VisualBasicFullyQualifyCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/FullyQualify/VisualBasicFullyQualifyCodeFixProvider.vb @@ -42,6 +42,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.FullyQualify ''' Friend Const BC32045 = "BC32045" + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30002, IDEDiagnosticIds.UnboundIdentifierId, BC30451, BC30561, BC40056, BC32045) diff --git a/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb b/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb index 4f330e480e5b0..8635e960db9ca 100644 --- a/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb @@ -34,6 +34,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor Friend Class GenerateConstructorCodeFixProvider Inherits AbstractGenerateMemberCodeFixProvider + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return GenerateConstructorDiagnosticIds.AllDiagnosticIds diff --git a/src/Features/VisualBasic/Portable/GenerateConstructor/VisualBasicGenerateConstructorService.vb b/src/Features/VisualBasic/Portable/GenerateConstructor/VisualBasicGenerateConstructorService.vb index 6a1d973601d48..1da1a379441c6 100644 --- a/src/Features/VisualBasic/Portable/GenerateConstructor/VisualBasicGenerateConstructorService.vb +++ b/src/Features/VisualBasic/Portable/GenerateConstructor/VisualBasicGenerateConstructorService.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor Partial Friend Class VisualBasicGenerateConstructorService Inherits AbstractGenerateConstructorService(Of VisualBasicGenerateConstructorService, ArgumentSyntax, AttributeSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GenerateNameForArgument(semanticModel As SemanticModel, argument As ArgumentSyntax, cancellationToken As CancellationToken) As String Return semanticModel.GenerateNameForArgument(argument, cancellationToken) End Function diff --git a/src/Features/VisualBasic/Portable/GenerateEqualsAndGetHashCodeFromMembers/VisualBasicGenericEqualsAndGetHashCodeService.vb b/src/Features/VisualBasic/Portable/GenerateEqualsAndGetHashCodeFromMembers/VisualBasicGenericEqualsAndGetHashCodeService.vb index a227aaeb0cb1d..4518330db87e1 100644 --- a/src/Features/VisualBasic/Portable/GenerateEqualsAndGetHashCodeFromMembers/VisualBasicGenericEqualsAndGetHashCodeService.vb +++ b/src/Features/VisualBasic/Portable/GenerateEqualsAndGetHashCodeFromMembers/VisualBasicGenericEqualsAndGetHashCodeService.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateEqualsAndGetHashCodeFromMem Friend Class VisualBasicGenericEqualsAndGetHashCodeService Inherits AbstractGenerateEqualsAndGetHashCodeService + + Public Sub New() + End Sub + Protected Overrides Function TryWrapWithUnchecked(statements As ImmutableArray(Of SyntaxNode), ByRef wrappedStatements As ImmutableArray(Of SyntaxNode)) As Boolean ' VB doesn't support 'unchecked' statements. Return False diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateDefaultConstructors/VisualBasicGenerateDefaultConstructorsService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateDefaultConstructors/VisualBasicGenerateDefaultConstructorsService.vb index 713ff5ca5b9f9..7a90eb406e2a5 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateDefaultConstructors/VisualBasicGenerateDefaultConstructorsService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateDefaultConstructors/VisualBasicGenerateDefaultConstructorsService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateDefaultConst Partial Friend Class VisualBasicGenerateDefaultConstructorsService Inherits AbstractGenerateDefaultConstructorsService(Of VisualBasicGenerateDefaultConstructorsService) + + Public Sub New() + End Sub + Protected Overrides Function TryInitializeState( semanticDocument As SemanticDocument, textSpan As TextSpan, cancellationToken As CancellationToken, ByRef classType As INamedTypeSymbol) As Boolean diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateEnumMember/VisualBasicGenerateEnumMemberService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateEnumMember/VisualBasicGenerateEnumMemberService.vb index 6bd7ee9829a2a..63bb5027e3da4 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateEnumMember/VisualBasicGenerateEnumMemberService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateEnumMember/VisualBasicGenerateEnumMemberService.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateEnumMember Partial Friend Class VisualBasicGenerateEnumMemberService Inherits AbstractGenerateEnumMemberService(Of VisualBasicGenerateEnumMemberService, SimpleNameSyntax, ExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsIdentifierNameGeneration(node As SyntaxNode) As Boolean Return TypeOf node Is IdentifierNameSyntax End Function diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb index 37ae312fb2b84..9c4e994443ae1 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Partial Friend Class VisualBasicGenerateConversionService Inherits AbstractGenerateConversionService(Of VisualBasicGenerateConversionService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function AreSpecialOptionsActive(semanticModel As SemanticModel) As Boolean Return VisualBasicCommonGenerationServiceMethods.AreSpecialOptionsActive(semanticModel) End Function diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb index 2c80a75f58bcd..e3ddc33e18ce7 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Partial Friend Class VisualBasicGenerateMethodService Inherits AbstractGenerateMethodService(Of VisualBasicGenerateMethodService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsExplicitInterfaceGeneration(node As SyntaxNode) As Boolean Return TypeOf node Is QualifiedNameSyntax End Function diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateVariable/VisualBasicGenerateVariableService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateVariable/VisualBasicGenerateVariableService.vb index 06cd116d95bd5..10840e812e48b 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateVariable/VisualBasicGenerateVariableService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateVariable/VisualBasicGenerateVariableService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateVariable Partial Friend Class VisualBasicGenerateVariableService Inherits AbstractGenerateVariableService(Of VisualBasicGenerateVariableService, SimpleNameSyntax, ExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsExplicitInterfaceGeneration(node As Microsoft.CodeAnalysis.SyntaxNode) As Boolean Return TypeOf node Is QualifiedNameSyntax End Function diff --git a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb index 13d69c7487cdf..aa386f20a3ac0 100644 --- a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb +++ b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb @@ -25,6 +25,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateType Private Shared ReadOnly s_annotation As SyntaxAnnotation = New SyntaxAnnotation + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property DefaultFileExtension As String Get Return ".vb" diff --git a/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb b/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb index 7c628f2535167..cc7b6cbec0885 100644 --- a/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb @@ -20,6 +20,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateVariable Friend Const BC30451 As String = "BC30451" ' error BC30451: 'xyz' is not declared. It may be inaccessible due to its protection level. Friend Const BC36610 As String = "BC36610" ' error BC36610: Name 'v' is either not declared or not in the current scope. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30456, BC30401, BC30451, BC36610) diff --git a/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassCodeFixProvider.vb b/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassCodeFixProvider.vb index b95edf61c581b..f04cfaf8fcaee 100644 --- a/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassCodeFixProvider.vb @@ -14,6 +14,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementAbstractClass Friend Const BC30610 As String = "BC30610" ' Class 'goo' must either be declared 'MustInherit' or override the following inherited 'MustOverride' member(s): + Public Sub New() MyBase.New(BC30610) End Sub diff --git a/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassService.vb b/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassService.vb index 2c99fe6db0f5e..757c02d4c4ef5 100644 --- a/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassService.vb +++ b/src/Features/VisualBasic/Portable/ImplementAbstractClass/VisualBasicImplementAbstractClassService.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementAbstractClass Partial Friend Class VisualBasicImplementAbstractClassService Inherits AbstractImplementAbstractClassService(Of ClassBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides Function TryInitializeState( document As Document, model As SemanticModel, classBlock As ClassBlockSyntax, cancellationToken As CancellationToken, ByRef classType As INamedTypeSymbol, ByRef abstractClassType As INamedTypeSymbol) As Boolean diff --git a/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb b/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb index 63a0af56b8711..15817e58136b7 100644 --- a/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementInterface Friend Const BC30149 As String = "BC30149" ' Class 'bar' must implement 'Sub goo()' for interface 'igoo'. + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30149) diff --git a/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceService.vb b/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceService.vb index 22662b67192fd..7d5dc2203e4af 100644 --- a/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceService.vb +++ b/src/Features/VisualBasic/Portable/ImplementInterface/VisualBasicImplementInterfaceService.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementInterface Partial Friend Class VisualBasicImplementInterfaceService Inherits AbstractImplementInterfaceService + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property CanImplementImplicitly As Boolean Get Return False diff --git a/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicAddParameterCheckCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicAddParameterCheckCodeRefactoringProvider.vb index 31dbe1d4461a8..642f4638d93d4 100644 --- a/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicAddParameterCheckCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicAddParameterCheckCodeRefactoringProvider.vb @@ -16,6 +16,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InitializeParameter ExpressionSyntax, BinaryExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsFunctionDeclaration(node As SyntaxNode) As Boolean Return InitializeParameterHelpers.IsFunctionDeclaration(node) End Function diff --git a/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicInitializeMemberFromParameterCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicInitializeMemberFromParameterCodeRefactoringProvider.vb index a730cb0839084..c8d6cdecfe0a0 100644 --- a/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicInitializeMemberFromParameterCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/InitializeParameter/VisualBasicInitializeMemberFromParameterCodeRefactoringProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InitializeParameter StatementSyntax, ExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsFunctionDeclaration(node As SyntaxNode) As Boolean Return InitializeParameterHelpers.IsFunctionDeclaration(node) End Function diff --git a/src/Features/VisualBasic/Portable/IntroduceUsingStatement/VisualBasicIntroduceUsingStatementCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/IntroduceUsingStatement/VisualBasicIntroduceUsingStatementCodeRefactoringProvider.vb index 87cde0ae0905b..18538bb4d05b8 100644 --- a/src/Features/VisualBasic/Portable/IntroduceUsingStatement/VisualBasicIntroduceUsingStatementCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/IntroduceUsingStatement/VisualBasicIntroduceUsingStatementCodeRefactoringProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceUsingStatement Friend NotInheritable Class VisualBasicIntroduceUsingStatementCodeRefactoringProvider Inherits AbstractIntroduceUsingStatementCodeRefactoringProvider(Of StatementSyntax, LocalDeclarationStatementSyntax) + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property CodeActionTitle As String = VBFeaturesResources.Introduce_Using_statement Protected Overrides Function CanRefactorToContainBlockStatements(parent As SyntaxNode) As Boolean diff --git a/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService.vb b/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService.vb index a44a164b2bdd8..b9befbe123c6f 100644 --- a/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService.vb +++ b/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable Partial Friend Class VisualBasicIntroduceVariableService Inherits AbstractIntroduceVariableService(Of VisualBasicIntroduceVariableService, ExpressionSyntax, TypeSyntax, TypeBlockSyntax, QueryExpressionSyntax, NameSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetContainingExecutableBlocks(expression As ExpressionSyntax) As IEnumerable(Of SyntaxNode) Return expression.GetContainingExecutableBlocks() End Function diff --git a/src/Features/VisualBasic/Portable/InvertConditional/VisualBasicInvertConditionalCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/InvertConditional/VisualBasicInvertConditionalCodeRefactoringProvider.vb index d0963138f1dd2..25a998bbc6fa0 100644 --- a/src/Features/VisualBasic/Portable/InvertConditional/VisualBasicInvertConditionalCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/InvertConditional/VisualBasicInvertConditionalCodeRefactoringProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InvertConditional Friend Class VisualBasicInvertConditionalCodeRefactoringProvider Inherits AbstractInvertConditionalCodeRefactoringProvider(Of TernaryConditionalExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function ShouldOffer( conditional As TernaryConditionalExpressionSyntax, position As Integer) As Boolean diff --git a/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb b/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb index 02648eb8ebafc..d4a6210c3dee2 100644 --- a/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb +++ b/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InvertIf Friend NotInheritable Class VisualBasicInvertMultiLineIfCodeRefactoringProvider Inherits VisualBasicInvertIfCodeRefactoringProvider(Of MultiLineIfBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetHeaderSpan(ifNode As MultiLineIfBlockSyntax) As TextSpan Return TextSpan.FromBounds( ifNode.IfStatement.IfKeyword.SpanStart, diff --git a/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb b/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb index f5f209dfec581..68cfa6594db90 100644 --- a/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb +++ b/src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InvertIf Friend NotInheritable Class VisualBasicInvertSingleLineIfCodeRefactoringProvider Inherits VisualBasicInvertIfCodeRefactoringProvider(Of SingleLineIfStatementSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetHeaderSpan(ifNode As SingleLineIfStatementSyntax) As TextSpan Return TextSpan.FromBounds( ifNode.IfKeyword.SpanStart, diff --git a/src/Features/VisualBasic/Portable/InvertLogical/VisualBasicInvertLogicalCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/InvertLogical/VisualBasicInvertLogicalCodeRefactoringProvider.vb index 88ca2e1120533..856b73e088147 100644 --- a/src/Features/VisualBasic/Portable/InvertLogical/VisualBasicInvertLogicalCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/InvertLogical/VisualBasicInvertLogicalCodeRefactoringProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InvertLogical Friend Class VisualBasicInvertLogicalCodeRefactoringProvider Inherits AbstractInvertLogicalCodeRefactoringProvider(Of SyntaxKind, ExpressionSyntax, BinaryExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetKind(rawKind As Integer) As SyntaxKind Return CType(rawKind, SyntaxKind) End Function diff --git a/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicAnonymousTypeDisplayService.vb b/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicAnonymousTypeDisplayService.vb index 9529ece6ffcf2..ecda2fa569b5c 100644 --- a/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicAnonymousTypeDisplayService.vb +++ b/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicAnonymousTypeDisplayService.vb @@ -28,6 +28,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LanguageServices SymbolDisplayMiscellaneousOptions.UseSpecialTypes, kindOptions:=SymbolDisplayKindOptions.IncludeNamespaceKeyword Or SymbolDisplayKindOptions.IncludeTypeKeyword Or SymbolDisplayKindOptions.IncludeMemberKeyword) + + Public Sub New() + End Sub + Public Overrides Function GetAnonymousTypeParts(anonymousType As INamedTypeSymbol, semanticModel As SemanticModel, position As Integer, displayService As ISymbolDisplayService) As IEnumerable(Of SymbolDisplayPart) If anonymousType.IsAnonymousDelegateType() Then Return GetDelegateAnonymousType(anonymousType, semanticModel, position, displayService) diff --git a/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicSymbolDisplayServiceFactory.vb b/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicSymbolDisplayServiceFactory.vb index f21bbca94bd6d..031cab78875a2 100644 --- a/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicSymbolDisplayServiceFactory.vb +++ b/src/Features/VisualBasic/Portable/LanguageServices/VisualBasicSymbolDisplayServiceFactory.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LanguageServices Friend Class VisualBasicSymbolDisplayServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(provider As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicSymbolDisplayService(provider) End Function diff --git a/src/Features/VisualBasic/Portable/MakeFieldReadonly/VisualBasicMakeFieldReadonlyCodeFixProvider.vb b/src/Features/VisualBasic/Portable/MakeFieldReadonly/VisualBasicMakeFieldReadonlyCodeFixProvider.vb index a29f8bfd1e2bb..81247ad9e6776 100644 --- a/src/Features/VisualBasic/Portable/MakeFieldReadonly/VisualBasicMakeFieldReadonlyCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/MakeFieldReadonly/VisualBasicMakeFieldReadonlyCodeFixProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MakeFieldReadonly Friend Class VisualBasicMakeFieldReadonlyCodeFixProvider Inherits AbstractMakeFieldReadonlyCodeFixProvider(Of ModifiedIdentifierSyntax, FieldDeclarationSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetVariableDeclarators(declaration As FieldDeclarationSyntax) As ImmutableList(Of ModifiedIdentifierSyntax) Return declaration.Declarators.SelectMany(Function(d) d.Names).ToImmutableListOrEmpty() End Function diff --git a/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb b/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb index 1b3ca34bf0d0f..19bde9112a571 100644 --- a/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/MakeMethodAsynchronous/VisualBasicMakeMethodAsynchronousCodeFixProvider.vb @@ -21,6 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MakeMethodAsynchronous Private Shared ReadOnly s_asyncToken As SyntaxToken = SyntaxFactory.Token(SyntaxKind.AsyncKeyword) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return s_diagnosticIds diff --git a/src/Features/VisualBasic/Portable/MakeMethodSynchronous/VisualBasicMakeMethodSynchronousCodeFixProvider.vb b/src/Features/VisualBasic/Portable/MakeMethodSynchronous/VisualBasicMakeMethodSynchronousCodeFixProvider.vb index bef18f0f4f672..0ffa3393c250b 100644 --- a/src/Features/VisualBasic/Portable/MakeMethodSynchronous/VisualBasicMakeMethodSynchronousCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/MakeMethodSynchronous/VisualBasicMakeMethodSynchronousCodeFixProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MakeMethodSynchronous Private Shared ReadOnly s_diagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC42356) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return s_diagnosticIds diff --git a/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceServiceFactory.vb b/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceServiceFactory.vb index 41a8f911ac5a0..d420f1a61f197 100644 --- a/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceServiceFactory.vb +++ b/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceServiceFactory.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MetadataAsSource Friend Class VisualBasicMetadataAsSourceServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(provider As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicMetadataAsSourceService(provider) End Function diff --git a/src/Features/VisualBasic/Portable/MoveDeclarationNearReference/VisualBasicMoveDeclarationNearReferenceService.vb b/src/Features/VisualBasic/Portable/MoveDeclarationNearReference/VisualBasicMoveDeclarationNearReferenceService.vb index f595c3289e7e3..f0c6cac992315 100644 --- a/src/Features/VisualBasic/Portable/MoveDeclarationNearReference/VisualBasicMoveDeclarationNearReferenceService.vb +++ b/src/Features/VisualBasic/Portable/MoveDeclarationNearReference/VisualBasicMoveDeclarationNearReferenceService.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MoveDeclarationNearReference LocalDeclarationStatementSyntax, VariableDeclaratorSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsMeaningfulBlock(node As SyntaxNode) As Boolean Return TypeOf node Is LambdaExpressionSyntax OrElse TypeOf node Is ForOrForEachBlockSyntax OrElse diff --git a/src/Features/VisualBasic/Portable/NameTupleElement/VisualBasicNameTupleElementCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/NameTupleElement/VisualBasicNameTupleElementCodeRefactoringProvider.vb index 94d31abaedeb8..e420b534f5ef8 100644 --- a/src/Features/VisualBasic/Portable/NameTupleElement/VisualBasicNameTupleElementCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/NameTupleElement/VisualBasicNameTupleElementCodeRefactoringProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.NameTupleElement Friend Class VisualBasicNameTupleElementCodeRefactoringProvider Inherits AbstractNameTupleElementCodeRefactoringProvider(Of SimpleArgumentSyntax, TupleExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function WithName(argument As SimpleArgumentSyntax, name As String) As SimpleArgumentSyntax Return argument.WithNameColonEquals(SyntaxFactory.NameColonEquals(name.ToIdentifierName())) End Function diff --git a/src/Features/VisualBasic/Portable/NavigateTo/VisualBasicNavigateToSearchService.vb b/src/Features/VisualBasic/Portable/NavigateTo/VisualBasicNavigateToSearchService.vb index df770a4640a4f..fdde1ab623caf 100644 --- a/src/Features/VisualBasic/Portable/NavigateTo/VisualBasicNavigateToSearchService.vb +++ b/src/Features/VisualBasic/Portable/NavigateTo/VisualBasicNavigateToSearchService.vb @@ -8,5 +8,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.NavigateTo Friend Class VisualBasicNavigateToSearchService Inherits AbstractNavigateToSearchService + + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/OrderModifiers/VisualBasicOrderModifiersCodeFixProvider.vb b/src/Features/VisualBasic/Portable/OrderModifiers/VisualBasicOrderModifiersCodeFixProvider.vb index bcd512c3b0b10..e64e27b291778 100644 --- a/src/Features/VisualBasic/Portable/OrderModifiers/VisualBasicOrderModifiersCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/OrderModifiers/VisualBasicOrderModifiersCodeFixProvider.vb @@ -11,6 +11,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.OrderModifiers Friend Class VisualBasicOrderModifiersCodeFixProvider Inherits AbstractOrderModifiersCodeFixProvider + Public Sub New() MyBase.New(VisualBasicSyntaxFactsService.Instance, VisualBasicCodeStyleOptions.PreferredModifierOrder, diff --git a/src/Features/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.vb b/src/Features/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.vb index 4a9e9a758d010..dc24153cd51e3 100644 --- a/src/Features/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.vb +++ b/src/Features/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.OrganizeImports Partial Friend Class VisualBasicOrganizeImportsService Implements IOrganizeImportsService + + Public Sub New() + End Sub + Public Async Function OrganizeImportsAsync(document As Document, cancellationToken As CancellationToken) As Task(Of Document) Implements IOrganizeImportsService.OrganizeImportsAsync Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) @@ -24,6 +28,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.OrganizeImports Return document.WithSyntaxRoot(newRoot) End Function + Public ReadOnly Property SortImportsDisplayStringWithAccelerator As String Implements IOrganizeImportsService.SortImportsDisplayStringWithAccelerator + Get + Return VBFeaturesResources.Sort_Imports + End Get + End Property + Public ReadOnly Property SortAndRemoveUnusedImportsDisplayStringWithAccelerator As String Implements IOrganizeImportsService.SortAndRemoveUnusedImportsDisplayStringWithAccelerator Get Return VBFeaturesResources.Remove_and_Sort_Imports diff --git a/src/Features/VisualBasic/Portable/Organizing/Organizers/TypeBlockOrganizer.vb b/src/Features/VisualBasic/Portable/Organizing/Organizers/TypeBlockOrganizer.vb index 3ae0a13e84d02..2893a18266390 100644 --- a/src/Features/VisualBasic/Portable/Organizing/Organizers/TypeBlockOrganizer.vb +++ b/src/Features/VisualBasic/Portable/Organizing/Organizers/TypeBlockOrganizer.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Organizing.Organizers Friend Class TypeBlockOrganizer Inherits AbstractSyntaxNodeOrganizer(Of TypeBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides Function Organize(typeBlock As TypeBlockSyntax, cancellationToken As CancellationToken) As TypeBlockSyntax Dim members = MemberDeclarationsOrganizer.Organize(typeBlock.Members, cancellationToken) diff --git a/src/Features/VisualBasic/Portable/QualifyMemberAccess/VisualBasicQualifyMemberAccessCodeFixProvider.vb b/src/Features/VisualBasic/Portable/QualifyMemberAccess/VisualBasicQualifyMemberAccessCodeFixProvider.vb index 32cb6811b24ba..19e1e3771776e 100644 --- a/src/Features/VisualBasic/Portable/QualifyMemberAccess/VisualBasicQualifyMemberAccessCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/QualifyMemberAccess/VisualBasicQualifyMemberAccessCodeFixProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.QualifyMemberAccess Friend Class VisualBasicQualifyMemberAccessCodeFixProvider Inherits AbstractQualifyMemberAccessCodeFixprovider(Of SimpleNameSyntax, InvocationExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetTitle() As String Return VBFeaturesResources.Add_Me End Function diff --git a/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicQuickInfoService.vb b/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicQuickInfoService.vb index 883c199b84c39..8026a102a642b 100644 --- a/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicQuickInfoService.vb +++ b/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicQuickInfoService.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.QuickInfo Friend Class VisualBasicQuickInfoServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicQuickInfoService(languageServices.WorkspaceServices.Workspace) End Function diff --git a/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicSemanticQuickInfoProvider.vb b/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicSemanticQuickInfoProvider.vb index 62847b15d9d96..bc2a0420a1d00 100644 --- a/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicSemanticQuickInfoProvider.vb +++ b/src/Features/VisualBasic/Portable/QuickInfo/VisualBasicSemanticQuickInfoProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.QuickInfo Friend Class VisualBasicSemanticQuickInfoProvider Inherits CommonSemanticQuickInfoProvider + + Public Sub New() + End Sub + Protected Overrides Async Function BuildQuickInfoAsync( document As Document, token As SyntaxToken, diff --git a/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsCodeFixProvider.vb b/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsCodeFixProvider.vb index f719ae36bd3d3..9e347c2c6f38b 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsCodeFixProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryImports Friend Class VisualBasicRemoveUnnecessaryImportsCodeFixProvider Inherits AbstractRemoveUnnecessaryImportsCodeFixProvider + + Public Sub New() + End Sub + Protected Overrides Function GetTitle() As String Return VBFeaturesResources.Remove_Unnecessary_Imports End Function diff --git a/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsService.vb b/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsService.vb index 180e542549105..005dfece0de8d 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsService.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicRemoveUnnecessaryImportsService.vb @@ -9,5 +9,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryImports Friend Class VisualBasicRemoveUnnecessaryImportsService Inherits AbstractVisualBasicRemoveUnnecessaryImportsService + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicUnnecessaryImportsService.vb b/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicUnnecessaryImportsService.vb index 975ea49d2749e..d306e77c56381 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicUnnecessaryImportsService.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnnecessaryImports/VisualBasicUnnecessaryImportsService.vb @@ -9,5 +9,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryImports Friend Class VisualBasicUnnecessaryImportsService Inherits AbstractVisualBasicRemoveUnnecessaryImportsService + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/RemoveUnnecessaryParentheses/VisualBasicRemoveUnnecessaryParenthesesCodeFixProvider.vb b/src/Features/VisualBasic/Portable/RemoveUnnecessaryParentheses/VisualBasicRemoveUnnecessaryParenthesesCodeFixProvider.vb index 86e55749a5247..da4a77acc65f6 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnnecessaryParentheses/VisualBasicRemoveUnnecessaryParenthesesCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnnecessaryParentheses/VisualBasicRemoveUnnecessaryParenthesesCodeFixProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryParentheses Friend Class VisualBasicRemoveUnnecessaryParenthesesCodeFixProvider Inherits AbstractRemoveUnnecessaryParenthesesCodeFixProvider(Of ParenthesizedExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function CanRemoveParentheses(current As ParenthesizedExpressionSyntax, semanticModel As SemanticModel) As Boolean Return VisualBasicRemoveUnnecessaryParenthesesDiagnosticAnalyzer.CanRemoveParenthesesHelper( current, semanticModel, precedence:=Nothing, clarifiesPrecedence:=Nothing) diff --git a/src/Features/VisualBasic/Portable/RemoveUnusedMembers/VisualBasicRemoveUnusedMembersCodeFixProvider.vb b/src/Features/VisualBasic/Portable/RemoveUnusedMembers/VisualBasicRemoveUnusedMembersCodeFixProvider.vb index 434f302a3724b..9d78e1f83afbf 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnusedMembers/VisualBasicRemoveUnusedMembersCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnusedMembers/VisualBasicRemoveUnusedMembersCodeFixProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnusedMembers Friend Class VisualBasicRemoveUnusedMembersCodeFixProvider Inherits AbstractRemoveUnusedMembersCodeFixProvider(Of FieldDeclarationSyntax) + + Public Sub New() + End Sub + ''' ''' This method adjusts the to remove based on whether or not all variable declarators ''' within a field declaration should be removed, diff --git a/src/Features/VisualBasic/Portable/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb b/src/Features/VisualBasic/Portable/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb index 476700427e665..86ee9b166b7e0 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnusedParametersAndValues ExpressionStatementSyntax, LocalDeclarationStatementSyntax, VariableDeclaratorSyntax, ForEachBlockSyntax, CaseBlockSyntax, CaseClauseSyntax, CatchStatementSyntax, CatchBlockSyntax) + + Public Sub New() + End Sub + Protected Overrides Function WrapWithBlockIfNecessary(statements As IEnumerable(Of StatementSyntax)) As StatementSyntax ' Unreachable code path as VB statements don't need to be wrapped in special BlockSyntax. Throw ExceptionUtilities.Unreachable diff --git a/src/Features/VisualBasic/Portable/RemoveUnusedVariable/VisualBasicRemoveUnusedVariableCodeFixProvider.vb b/src/Features/VisualBasic/Portable/RemoveUnusedVariable/VisualBasicRemoveUnusedVariableCodeFixProvider.vb index ae5ef29e6660d..0f5e4f47caa9c 100644 --- a/src/Features/VisualBasic/Portable/RemoveUnusedVariable/VisualBasicRemoveUnusedVariableCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/RemoveUnusedVariable/VisualBasicRemoveUnusedVariableCodeFixProvider.vb @@ -17,6 +17,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnusedVariable Private Const BC42024 As String = NameOf(BC42024) + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC42024) diff --git a/src/Features/VisualBasic/Portable/ReplaceDocCommentTextWithTag/VisualBasicReplaceDocCommentTextWithTagCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ReplaceDocCommentTextWithTag/VisualBasicReplaceDocCommentTextWithTagCodeRefactoringProvider.vb index 1aa8ff1110daf..73f5748fc53a7 100644 --- a/src/Features/VisualBasic/Portable/ReplaceDocCommentTextWithTag/VisualBasicReplaceDocCommentTextWithTagCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ReplaceDocCommentTextWithTag/VisualBasicReplaceDocCommentTextWithTagCodeRefactoringProvider.vb @@ -24,6 +24,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ReplaceDocCommentTextWithTag SyntaxFacts.GetText(SyntaxKind.AwaitKeyword) } + + Public Sub New() + End Sub + Protected Overrides Function IsXmlTextToken(token As SyntaxToken) As Boolean Return token.Kind() = SyntaxKind.XmlTextLiteralToken OrElse token.Kind() = SyntaxKind.DocumentationCommentLineBreakToken diff --git a/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb b/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb index 2f175f6abfdff..93c60e5d85374 100644 --- a/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb +++ b/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.ReplaceMethodWithP Inherits AbstractReplaceMethodWithPropertyService Implements IReplaceMethodWithPropertyService + + Public Sub New() + End Sub + Public Function GetMethodDeclaration(token As SyntaxToken) As SyntaxNode Implements IReplaceMethodWithPropertyService.GetMethodDeclaration Dim containingMethod = token.Parent.FirstAncestorOrSelf(Of MethodStatementSyntax) If containingMethod Is Nothing Then diff --git a/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb b/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb index 70daaa1a3f4e5..378f6083bc601 100644 --- a/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb +++ b/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.ReplaceMethodWithP Partial Friend Class VisualBasicReplacePropertyWithMethods Inherits AbstractReplacePropertyWithMethodsService(Of IdentifierNameSyntax, ExpressionSyntax, CrefReferenceSyntax, StatementSyntax) + + Public Sub New() + End Sub + Public Overrides Function GetPropertyDeclaration(token As SyntaxToken) As SyntaxNode Dim containingProperty = token.Parent.FirstAncestorOrSelf(Of PropertyStatementSyntax) If containingProperty Is Nothing Then diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/AddRemoveHandlerSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/AddRemoveHandlerSignatureHelpProvider.vb index d4db01e57c1be..b9d0583d85571 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/AddRemoveHandlerSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/AddRemoveHandlerSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Friend Class AddRemoveHandlerSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of AddRemoveHandlerStatementSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetIntrinsicOperatorDocumentationAsync(node As AddRemoveHandlerStatementSyntax, document As Document, cancellationToken As CancellationToken) As ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation)) Select Case node.Kind Case SyntaxKind.AddHandlerStatement diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb index 59e677ac36d83..6a3a06c4c71aa 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class AttributeSignatureHelpProvider Inherits AbstractVisualBasicSignatureHelpProvider + + Public Sub New() + End Sub + Public Overrides Function IsTriggerCharacter(ch As Char) As Boolean Return ch = "("c OrElse ch = ","c End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/CastExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/CastExpressionSignatureHelpProvider.vb index a3cfe73ae0397..9b90a6f2606bd 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/CastExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/CastExpressionSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class CastExpressionSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of CastExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetIntrinsicOperatorDocumentationAsync(node As CastExpressionSyntax, document As Document, cancellationToken As CancellationToken) As ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation)) Select Case node.Kind Case SyntaxKind.CTypeExpression diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/ConditionalExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/ConditionalExpressionSignatureHelpProvider.vb index 7f5c06be4f710..0ed057048bdf1 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/ConditionalExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/ConditionalExpressionSignatureHelpProvider.vb @@ -40,6 +40,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Friend Class BinaryConditionalExpressionSignatureHelpProvider Inherits ConditionalExpressionSignatureHelpProvider(Of BinaryConditionalExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property Kind As SyntaxKind Get Return SyntaxKind.BinaryConditionalExpression @@ -51,6 +55,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Friend Class TernaryConditionalExpressionSignatureHelpProvider Inherits ConditionalExpressionSignatureHelpProvider(Of TernaryConditionalExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides ReadOnly Property Kind As SyntaxKind Get Return SyntaxKind.TernaryConditionalExpression diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb index 20ef7f59312f1..a599aab252bf6 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class FunctionAggregationSignatureHelpProvider Inherits AbstractVisualBasicSignatureHelpProvider + + Public Sub New() + End Sub + Public Overrides Function IsTriggerCharacter(ch As Char) As Boolean Return ch = "("c End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb index ab42d9b97d8ee..d3d6874860891 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class GenericNameSignatureHelpProvider Inherits AbstractVisualBasicSignatureHelpProvider + + Public Sub New() + End Sub + Public Overrides Function IsTriggerCharacter(ch As Char) As Boolean Return ch = " "c OrElse ch = ","c End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/GetTypeExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/GetTypeExpressionSignatureHelpProvider.vb index 22c41d6337ddb..f290433874c72 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/GetTypeExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/GetTypeExpressionSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class GetTypeExpressionSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of GetTypeExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetIntrinsicOperatorDocumentationAsync(node As GetTypeExpressionSyntax, document As Document, cancellationToken As CancellationToken) As ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation)) Return New ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation))({New GetTypeExpressionDocumentation()}) End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/GetXmlNamespaceExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/GetXmlNamespaceExpressionSignatureHelpProvider.vb index 91b358bf5a8ac..62fe38fcfecb1 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/GetXmlNamespaceExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/GetXmlNamespaceExpressionSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class GetXmlNamespaceExpressionSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of GetXmlNamespaceExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetIntrinsicOperatorDocumentationAsync(node As GetXmlNamespaceExpressionSyntax, document As Document, cancellationToken As CancellationToken) As ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation)) Return New ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation))({New GetXmlNamespaceExpressionDocumentation()}) End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb index e45addd512c34..b162a59d21f11 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb @@ -16,6 +16,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class InvocationExpressionSignatureHelpProvider Inherits AbstractVisualBasicSignatureHelpProvider + + Public Sub New() + End Sub + Public Overrides Function IsTriggerCharacter(ch As Char) As Boolean Return ch = "("c OrElse ch = ","c End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/MidAssignmentSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/MidAssignmentSignatureHelpProvider.vb index fde7e5a140a5c..89172e307754c 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/MidAssignmentSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/MidAssignmentSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class MidAssignmentSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of AssignmentStatementSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetIntrinsicOperatorDocumentationAsync(node As AssignmentStatementSyntax, document As Document, cancellationToken As CancellationToken) As ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation)) Return New ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation))({New MidAssignmentDocumentation()}) End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/NameOfExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/NameOfExpressionSignatureHelpProvider.vb index 5d1609b7db7ba..91c23dfc86aa5 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/NameOfExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/NameOfExpressionSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Friend Class NameOfExpressionSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of NameOfExpressionSyntax) + + Public Sub New() + End Sub + Public Overrides Function IsRetriggerCharacter(ch As Char) As Boolean Return ch = ")"c End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb index 8b45db5c7e76d..87b66ac5bbaca 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb @@ -14,6 +14,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class ObjectCreationExpressionSignatureHelpProvider Inherits AbstractVisualBasicSignatureHelpProvider + + Public Sub New() + End Sub + Public Overrides Function IsTriggerCharacter(ch As Char) As Boolean Return ch = "("c OrElse ch = ","c End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/PredefinedCastExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/PredefinedCastExpressionSignatureHelpProvider.vb index 22bbbbc703929..635acf3980950 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/PredefinedCastExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/PredefinedCastExpressionSignatureHelpProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Partial Friend Class PredefinedCastExpressionSignatureHelpProvider Inherits AbstractIntrinsicOperatorSignatureHelpProvider(Of PredefinedCastExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetIntrinsicOperatorDocumentationAsync(node As PredefinedCastExpressionSyntax, document As Document, cancellationToken As CancellationToken) As ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation)) Return New ValueTask(Of IEnumerable(Of AbstractIntrinsicOperatorDocumentation))(GetIntrinsicOperatorDocumentationImplAsync(node, document, cancellationToken)) End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb index b37fc804be454..88e945e9eab49 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Friend Class RaiseEventStatementSignatureHelpProvider Inherits AbstractVisualBasicSignatureHelpProvider + + Public Sub New() + End Sub + Public Overrides Function IsTriggerCharacter(ch As Char) As Boolean Return ch = "("c OrElse ch = ","c End Function diff --git a/src/Features/VisualBasic/Portable/SimplifyThisOrMe/VisualBasicSimplifyThisOrMeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/SimplifyThisOrMe/VisualBasicSimplifyThisOrMeCodeFixProvider.vb index ca6b74dc669af..3f56074e5ac30 100644 --- a/src/Features/VisualBasic/Portable/SimplifyThisOrMe/VisualBasicSimplifyThisOrMeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/SimplifyThisOrMe/VisualBasicSimplifyThisOrMeCodeFixProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyThisOrMe Partial Friend Class VisualBasicSimplifyThisOrMeCodeFixProvider Inherits AbstractSimplifyThisOrMeCodeFixProvider(Of MemberAccessExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetTitle() As String Return VBFeaturesResources.Remove_Me_qualification End Function diff --git a/src/Features/VisualBasic/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.vb b/src/Features/VisualBasic/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.vb index 8c8253b4644ec..c1bcb00a9f797 100644 --- a/src/Features/VisualBasic/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.vb @@ -14,6 +14,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyTypeNames Partial Friend Class SimplifyTypeNamesCodeFixProvider Inherits AbstractSimplifyTypeNamesCodeFixProvider(Of SyntaxKind) + Public Sub New() MyBase.New(New VisualBasicSimplifyTypeNamesDiagnosticAnalyzer()) End Sub diff --git a/src/Features/VisualBasic/Portable/SolutionCrawler/VisualBasicDocumentDifferenceService.vb b/src/Features/VisualBasic/Portable/SolutionCrawler/VisualBasicDocumentDifferenceService.vb index 4f5f17a9c9da4..450ef276ee521 100644 --- a/src/Features/VisualBasic/Portable/SolutionCrawler/VisualBasicDocumentDifferenceService.vb +++ b/src/Features/VisualBasic/Portable/SolutionCrawler/VisualBasicDocumentDifferenceService.vb @@ -9,5 +9,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SolutionCrawler Friend Class VisualBasicDocumentDifferenceService Inherits AbstractDocumentDifferenceService + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/SpellCheck/VisualBasicSpellCheckCodeFixProvider.vb b/src/Features/VisualBasic/Portable/SpellCheck/VisualBasicSpellCheckCodeFixProvider.vb index 55cc3aa158438..7addac3eafe00 100644 --- a/src/Features/VisualBasic/Portable/SpellCheck/VisualBasicSpellCheckCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/SpellCheck/VisualBasicSpellCheckCodeFixProvider.vb @@ -35,6 +35,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SpellCheck ''' Friend Const BC32045 = "BC32045" + + Public Sub New() + End Sub + Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) Get Return ImmutableArray.Create(BC30002, IDEDiagnosticIds.UnboundIdentifierId, BC30451, BC30456, BC32045) diff --git a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicIfLikeStatementGenerator.vb b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicIfLikeStatementGenerator.vb index e09e00d68b988..e72f260351c8c 100644 --- a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicIfLikeStatementGenerator.vb +++ b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicIfLikeStatementGenerator.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SplitOrMergeIfStatements Friend NotInheritable Class VisualBasicIfLikeStatementGenerator Implements IIfLikeStatementGenerator + + Public Sub New() + End Sub + Public Function IsIfOrElseIf(node As SyntaxNode) As Boolean Implements IIfLikeStatementGenerator.IsIfOrElseIf Return TypeOf node Is MultiLineIfBlockSyntax OrElse TypeOf node Is ElseIfBlockSyntax diff --git a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeConsecutiveIfStatementsCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeConsecutiveIfStatementsCodeRefactoringProvider.vb index 4607c8b6e8465..8ab66378c23a4 100644 --- a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeConsecutiveIfStatementsCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeConsecutiveIfStatementsCodeRefactoringProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SplitOrMergeIfStatements Friend NotInheritable Class VisualBasicMergeConsecutiveIfStatementsCodeRefactoringProvider Inherits AbstractMergeConsecutiveIfStatementsCodeRefactoringProvider + + Public Sub New() + End Sub + Protected Overrides Function IsApplicableSpan(node As SyntaxNode, span As TextSpan, ByRef ifOrElseIf As SyntaxNode) As Boolean If TypeOf node Is IfStatementSyntax AndAlso TypeOf node.Parent Is MultiLineIfBlockSyntax Then Dim ifStatement = DirectCast(node, IfStatementSyntax) diff --git a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeNestedIfStatementsCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeNestedIfStatementsCodeRefactoringProvider.vb index 5a6806888af74..ca112eb7a3c12 100644 --- a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeNestedIfStatementsCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicMergeNestedIfStatementsCodeRefactoringProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SplitOrMergeIfStatements Friend NotInheritable Class VisualBasicMergeNestedIfStatementsCodeRefactoringProvider Inherits AbstractMergeNestedIfStatementsCodeRefactoringProvider + + Public Sub New() + End Sub + Protected Overrides Function IsApplicableSpan(node As SyntaxNode, span As TextSpan, ByRef ifOrElseIf As SyntaxNode) As Boolean If TypeOf node Is IfStatementSyntax And TypeOf node.Parent Is MultiLineIfBlockSyntax Then Dim ifStatement = DirectCast(node, IfStatementSyntax) diff --git a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.vb index e6efd6119b9dc..a9f996f3fbbd1 100644 --- a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoConsecutiveIfStatementsCodeRefactoringProvider.vb @@ -9,5 +9,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SplitOrMergeIfStatements Friend NotInheritable Class VisualBasicSplitIntoConsecutiveIfStatementsCodeRefactoringProvider Inherits AbstractSplitIntoConsecutiveIfStatementsCodeRefactoringProvider + + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoNestedIfStatementsCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoNestedIfStatementsCodeRefactoringProvider.vb index 1db25731a7014..b5b0af5f226fb 100644 --- a/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoNestedIfStatementsCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/SplitOrMergeIfStatements/VisualBasicSplitIntoNestedIfStatementsCodeRefactoringProvider.vb @@ -9,5 +9,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SplitOrMergeIfStatements Friend NotInheritable Class VisualBasicSplitIntoNestedIfStatementsCodeRefactoringProvider Inherits AbstractSplitIntoNestedIfStatementsCodeRefactoringProvider + + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/Structure/VisualBasicBlockStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/VisualBasicBlockStructureProvider.vb index 3a7f4641041b9..947dfcc6ef11d 100644 --- a/src/Features/VisualBasic/Portable/Structure/VisualBasicBlockStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/VisualBasicBlockStructureProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Friend Class VisualBasicBlockStructureServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicBlockStructureService(languageServices.WorkspaceServices.Workspace) End Function diff --git a/src/Features/VisualBasic/Portable/TodoComments/BasicTodoCommentIncrementalAnalyzerProvider.vb b/src/Features/VisualBasic/Portable/TodoComments/BasicTodoCommentIncrementalAnalyzerProvider.vb index cca5bb7ea250e..70edc09a91dcd 100644 --- a/src/Features/VisualBasic/Portable/TodoComments/BasicTodoCommentIncrementalAnalyzerProvider.vb +++ b/src/Features/VisualBasic/Portable/TodoComments/BasicTodoCommentIncrementalAnalyzerProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.TodoComments Friend Class VisualBasicTodoCommentServiceFactory Implements ILanguageServiceFactory + + Public Sub New() + End Sub + Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService Return New VisualBasicTodoCommentService(languageServices.WorkspaceServices.Workspace) End Function diff --git a/src/Features/VisualBasic/Portable/UnsealClass/VisualBasicUnsealClassCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UnsealClass/VisualBasicUnsealClassCodeFixProvider.vb index db9628cfc642f..d0b86421df037 100644 --- a/src/Features/VisualBasic/Portable/UnsealClass/VisualBasicUnsealClassCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UnsealClass/VisualBasicUnsealClassCodeFixProvider.vb @@ -12,6 +12,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnsealClass Private Const BC30299 As String = NameOf(BC30299) ' 'D' cannot inherit from class 'C' because 'C' is declared 'NotInheritable'. + + Public Sub New() + End Sub + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC30299) diff --git a/src/Features/VisualBasic/Portable/UseAutoProperty/VisualBasicUseAutoPropertyCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseAutoProperty/VisualBasicUseAutoPropertyCodeFixProvider.vb index 4b9144ea57877..2f348ce738af8 100644 --- a/src/Features/VisualBasic/Portable/UseAutoProperty/VisualBasicUseAutoPropertyCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseAutoProperty/VisualBasicUseAutoPropertyCodeFixProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseAutoProperty Friend Class VisualBasicUseAutoPropertyCodeFixProvider Inherits AbstractUseAutoPropertyCodeFixProvider(Of TypeBlockSyntax, PropertyBlockSyntax, ModifiedIdentifierSyntax, ConstructorBlockSyntax, ExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetNodeToRemove(identifier As ModifiedIdentifierSyntax) As SyntaxNode Return Utilities.GetNodeToRemove(identifier) End Function diff --git a/src/Features/VisualBasic/Portable/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb index ae05d5b870663..1bfc33c2ddde7 100644 --- a/src/Features/VisualBasic/Portable/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb @@ -21,6 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseCollectionInitializer ExpressionStatementSyntax, VariableDeclaratorSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetNewStatement( statement As StatementSyntax, objectCreation As ObjectCreationExpressionSyntax, matches As ImmutableArray(Of ExpressionStatementSyntax)) As StatementSyntax diff --git a/src/Features/VisualBasic/Portable/UseCompoundAssignment/VisualBasicUseCompoundAssignmentCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseCompoundAssignment/VisualBasicUseCompoundAssignmentCodeFixProvider.vb index 5577771984377..cbc98502d51e6 100644 --- a/src/Features/VisualBasic/Portable/UseCompoundAssignment/VisualBasicUseCompoundAssignmentCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseCompoundAssignment/VisualBasicUseCompoundAssignmentCodeFixProvider.vb @@ -11,6 +11,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseCompoundAssignment Friend Class VisualBasicUseCompoundAssignmentCodeFixProvider Inherits AbstractUseCompoundAssignmentCodeFixProvider(Of SyntaxKind, AssignmentStatementSyntax, ExpressionSyntax) + Public Sub New() MyBase.New(Kinds) End Sub diff --git a/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForAssignmentCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForAssignmentCodeRefactoringProvider.vb index 7d8d2e3f1adaf..1f1c70cffa6d0 100644 --- a/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForAssignmentCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForAssignmentCodeRefactoringProvider.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseConditionalExpression Inherits AbstractUseConditionalExpressionForAssignmentCodeFixProvider(Of StatementSyntax, MultiLineIfBlockSyntax, LocalDeclarationStatementSyntax, VariableDeclaratorSyntax, ExpressionSyntax, TernaryConditionalExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetMultiLineFormattingRule() As AbstractFormattingRule Return MultiLineConditionalExpressionFormattingRule.Instance End Function diff --git a/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForReturnCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForReturnCodeRefactoringProvider.vb index dca1698bf80de..f538a29ec2945 100644 --- a/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForReturnCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/UseConditionalExpression/VisualBasicUseConditionalExpressionForReturnCodeRefactoringProvider.vb @@ -13,6 +13,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseConditionalExpression Inherits AbstractUseConditionalExpressionForReturnCodeFixProvider(Of StatementSyntax, MultiLineIfBlockSyntax, ExpressionSyntax, TernaryConditionalExpressionSyntax) + + Public Sub New() + End Sub + Protected Overrides Function IsRef(returnOperation As IReturnOperation) As Boolean ' VB does not have ref returns. Return False diff --git a/src/Features/VisualBasic/Portable/UseInferredMemberName/VisualBasicUseInferredMemberNameCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseInferredMemberName/VisualBasicUseInferredMemberNameCodeFixProvider.vb index 995ce1a6ea5f2..d42c4ba13c2bf 100644 --- a/src/Features/VisualBasic/Portable/UseInferredMemberName/VisualBasicUseInferredMemberNameCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseInferredMemberName/VisualBasicUseInferredMemberNameCodeFixProvider.vb @@ -11,6 +11,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseInferredMemberName Friend Class VisualBasicUseInferredMemberNameCodeFixProvider Inherits AbstractUseInferredMemberNameCodeFixProvider + + Public Sub New() + End Sub + Protected Overrides Sub LanguageSpecificRemoveSuggestedNode(editor As SyntaxEditor, node As SyntaxNode) Select Case node.Kind Case SyntaxKind.NameColonEquals diff --git a/src/Features/VisualBasic/Portable/UseIsNullCheck/VisualBasicUseIsNullCheckForReferenceEqualsCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseIsNullCheck/VisualBasicUseIsNullCheckForReferenceEqualsCodeFixProvider.vb index 9cbe20967b501..6f1c6e71549f8 100644 --- a/src/Features/VisualBasic/Portable/UseIsNullCheck/VisualBasicUseIsNullCheckForReferenceEqualsCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseIsNullCheck/VisualBasicUseIsNullCheckForReferenceEqualsCodeFixProvider.vb @@ -10,6 +10,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseIsNullCheck Friend Class VisualBasicUseIsNullCheckForReferenceEqualsCodeFixProvider Inherits AbstractUseIsNullCheckForReferenceEqualsCodeFixProvider + + Public Sub New() + End Sub + Protected Overrides Function GetIsNullTitle() As String Return VBFeaturesResources.Use_Is_Nothing_check End Function @@ -24,7 +28,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseIsNullCheck SyntaxFactory.NothingLiteralExpression(SyntaxFactory.Token(SyntaxKind.NothingKeyword))).Parenthesize() End Function - Protected Overrides Function CreateNotNullCheck(notExpression As SyntaxNode, argument As SyntaxNode, isUnconstrainedGeneric As Boolean) As SyntaxNode + Protected Overrides Function CreateNotNullCheck(argument As SyntaxNode) As SyntaxNode Return SyntaxFactory.IsNotExpression( DirectCast(argument, ExpressionSyntax).Parenthesize(), SyntaxFactory.NothingLiteralExpression(SyntaxFactory.Token(SyntaxKind.NothingKeyword))).Parenthesize() diff --git a/src/Features/VisualBasic/Portable/UseNamedArguments/VisualBasicUseNamedArgumentsCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/UseNamedArguments/VisualBasicUseNamedArgumentsCodeRefactoringProvider.vb index 8929d725971dd..daf41d5f9a749 100644 --- a/src/Features/VisualBasic/Portable/UseNamedArguments/VisualBasicUseNamedArgumentsCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/UseNamedArguments/VisualBasicUseNamedArgumentsCodeRefactoringProvider.vb @@ -53,6 +53,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseNamedArguments End Function End Class + Public Sub New() MyBase.New(New ArgumentAnalyzer(), attributeArgumentAnalyzer:=Nothing) End Sub diff --git a/src/Features/VisualBasic/Portable/UseNullPropagation/VisualBasicUseNullPropagationCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseNullPropagation/VisualBasicUseNullPropagationCodeFixProvider.vb index d94d07aa2ba00..09704369e97c3 100644 --- a/src/Features/VisualBasic/Portable/UseNullPropagation/VisualBasicUseNullPropagationCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseNullPropagation/VisualBasicUseNullPropagationCodeFixProvider.vb @@ -18,5 +18,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseNullPropagation ConditionalAccessExpressionSyntax, InvocationExpressionSyntax) + + Public Sub New() + End Sub End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/UseObjectInitializer/VisualBasicUseObjectInitializerCodeFixProvider.vb b/src/Features/VisualBasic/Portable/UseObjectInitializer/VisualBasicUseObjectInitializerCodeFixProvider.vb index 4fa8a5c0e872d..ae6d6d1bc4a77 100644 --- a/src/Features/VisualBasic/Portable/UseObjectInitializer/VisualBasicUseObjectInitializerCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/UseObjectInitializer/VisualBasicUseObjectInitializerCodeFixProvider.vb @@ -19,6 +19,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseObjectInitializer AssignmentStatementSyntax, VariableDeclaratorSyntax) + + Public Sub New() + End Sub + Protected Overrides Function GetNewStatement( statement As StatementSyntax, objectCreation As ObjectCreationExpressionSyntax, matches As ImmutableArray(Of Match(Of ExpressionSyntax, StatementSyntax, MemberAccessExpressionSyntax, AssignmentStatementSyntax))) As StatementSyntax diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb index d252ec58b4163..2d8f57a0bfbb7 100644 --- a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb +++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb @@ -22,7 +22,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources ''' ''' A strongly-typed resource class, for looking up localized strings, etc. ''' - _ @@ -2437,6 +2437,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources End Get End Property + ''' + ''' Looks up a localized string similar to &Sort Imports. + ''' + Friend ReadOnly Property Sort_Imports() As String + Get + Return ResourceManager.GetString("Sort_Imports", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Specifies a collection and a range variable to use in a query.. ''' diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx index d9f7949512b8d..8eacc1a5ec3f2 100644 --- a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx +++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx @@ -1278,4 +1278,7 @@ Sub(<parameterList>) <statement> Make '{0}' inheritable + + &Sort Imports + \ No newline at end of file diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf index 881c4ce48f5db..dbb34a103da2a 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf @@ -97,6 +97,11 @@ Odebrat nepotřebné importy + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Sem vložte název, kterým deklarujete novou položku. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf index c0708fe5cd564..d29ee7efac723 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf @@ -97,6 +97,11 @@ Unnötige Import-Direktiven entfernen + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Geben Sie hier einen Namen ein, um ein neues Feld zu deklarieren. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf index 1c5793dbc3730..ed3174b9b82f0 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf @@ -97,6 +97,11 @@ Quitar instrucciones Import innecesarias + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Escriba aquí un nombre para declarar un nuevo campo. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf index 666e727818f44..631f7363733a7 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf @@ -97,6 +97,11 @@ Supprimer les importations superflues + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Tapez un nom ici pour déclarer un nouveau champ. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf index 600a0a4d235c7..32c9b16fb1e19 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf @@ -97,6 +97,11 @@ Rimuovi Import non necessari + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Digitare qui un nome per dichiarare un nuovo campo. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf index 4bc37cd9c9c74..ef65ca51e27e1 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf @@ -97,6 +97,11 @@ 不要なインポートの削除 + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. 新しいフィールドを宣言するには、ここに名前を入力します。 diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf index 224a056feceae..2837946509399 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf @@ -5,409 +5,346 @@ Add Await Await 추가 - Add Await and 'ConfigureAwait(false)' Await 및 'ConfigureAwait(false)' 추가 - Add <Obsolete> <Obsolete> 추가 - Add missing Imports 누락된 Imports 추가 - {Locked="Import"} "Import" is a VB keyword and should not be localized. Add 'Shadows' 'Shadows' 추가 - {Locked="Shadows"} "Shadows" is a VB keyword and should not be localized. 'If' statement can be simplified 'if' 문을 간단하게 줄일 수 있습니다. - Insert '{0}'. {0}'을(를) 삽입합니다. - Delete the '{0}' statement. {0}' 문을 삭제합니다. - Create event {0} in {1} {1}에서 {0} 이벤트를 만들기 - Insert the missing 'End Property' statement. 없는 'End Property' 문을 삽입합니다. - Insert the missing '{0}'. 누락된 '{0}'을(를) 삽입합니다. - Inline temporary variable 인라인 임시 변수 - Conflict(s) detected. 충돌이 감지되었습니다. - Introduce 'Using' statement 'Using' 문 지정 - {Locked="Using"} "Using" is a VB keyword and should not be localized. Make '{0}' inheritable '{0}'을(를) 상속할 수 있게 만들기 - Move the '{0}' statement to line {1}. {0}' 문을 {1} 줄로 이동합니다. - Delete the '{0}' statement. {0}' 문을 삭제합니다. - <Multiple Types> <여러 형식> - Remove Unnecessary Imports 불필요한 Imports 제거 - + + + + &Sort Imports + &Sort Imports Type a name here to declare a new field. 여기에 이름을 입력하여 새 필드를 선언하세요. - Note: Space completion is disabled to avoid potential interference. To insert a name from the list, use tab. 참고: 입력을 방해하지 않으려면 공백 완성 기능을 사용하지 않도록 설정합니다. 목록에서 이름을 삽입하려면 탭을 사용하세요. - <new field> <새 필드> - Type a name here to declare a parameter. If no preceding keyword is used; 'ByVal' will be assumed and the argument will be passed by value. 여기에 이름을 입력하여 매개 변수를 선언하세요. 선행 키워드를 사용하지 않으면 'ByVal'이 가정되고 인수가 값으로 전달됩니다. - <parameter name> <매개 변수 이름> - Type a new name for the column, followed by '='. Otherwise, the original column name with be used. 열의 새 이름을 입력하고 뒤에 '='를 입력하세요. 그렇게 하지 않으면 원래 열 이름이 사용됩니다. - Note: Use tab for automatic completion; space completion is disabled to avoid interfering with a new name. 참고: 자동으로 완성되게 하려면 탭을 사용하세요. 새 이름의 입력을 방해하지 않으려면 공백 완성 기능을 사용하지 않도록 설정합니다. - <result alias> <결과 별칭> - Type a new variable name 새 변수 이름 입력 - Note: Space and '=' completion are disabled to avoid potential interference. To insert a name from the list, use tab. 참고: 입력을 방해하지 않으려면 공백 및 '=' 완성 기능을 사용하지 않도록 설정합니다. 목록에서 이름을 삽입하려면 탭을 사용하세요. - <new resource> <새 리소스> - AddHandler statement AddHandler 문 - RemoveHandler statement RemoveHandler 문 - {0} function {0} 함수 - CType function CType 함수 - DirectCast function DirectCast 함수 - TryCast function TryCast 함수 - GetType function GetType 함수 - GetXmlNamespace function GetXmlNamespace 함수 - Mid statement Mid 문 - Fix Incorrect Function Return Type 잘못된 함수 반환 형식 수정 - Simplify name '{0}' {0}' 이름 단순화 - Simplify member access '{0}' 멤버 액세스 '{0}' 단순화 - Remove 'Me' qualification Me' 한정자 제거 - Name can be simplified 이름은 간단하게 줄일 수 있습니다. - can't determine valid range of statements to extract out 추출할 문에 유효한 범위를 결정할 수 없습니다. - Not all code paths return 일부 코드 경로가 반환됩니다. - contains invalid selection 선택 영역이 잘못되었습니다. - the selection contains syntactic errors 선택 영역에 구문 오류가 포함되어 있습니다. - Selection can't be crossed over preprocessors 선택 영역은 전처리기를 벗어날 수 없습니다. - Selection can't contain throw without enclosing catch block 선택 영역은 바깥쪽 catch 블록 없이 throw를 포함할 수 없습니다. - Selection can't be parts of constant initializer expression 선택 영역은 상수 이니셜라이저 식의 일부일 수 없습니다. - Argument used for ByRef parameter can't be extracted out ByRef 매개 변수에 사용되는 인수는 추출할 수 없습니다. - all static local usages defined in the selection must be included in the selection 선택 영역에 정의된 모든 고정 로컬 사용 내역은 선택 영역에 포함되어야 합니다. - Implicit member access can't be included in the selection without containing statement 문이 없는 선택 영역에 암시적 멤버 액세스를 포함할 수 없습니다. - Selection must be part of executable statements 선택 영역은 실행 가능 문의 일부여야 합니다. - next statement control variable doesn't have matching declaration statement next 문 제어 변수에 일치하는 declaration 문이 없습니다. - Selection doesn't contain any valid node 선택 영역에 유효한 노드가 포함되어 있지 않습니다. - no valid statement range to extract out 추출하는 데 유효한 문 범위가 없습니다. - Invalid selection 잘못된 선택 영역입니다. - Selection doesn't contain any valid token 선택 영역에 유효한 토큰이 포함되어 있지 않습니다. - No valid selection to perform extraction 추출하는 데 유효한 선택 영역이 없습니다. - No common root node for extraction 추출에 필요한 일반 루트 노드가 없습니다. - Deprecated 사용되지 않음 - Extension 확장 - Awaitable 대기 가능 - Awaitable, Extension 대기 가능, 확장 - <new variable> <새 변수> - R&emove and Sort Imports Imports 제거 및 정렬(&E) - @@ -415,13 +352,11 @@ AddressOf <procedureName> 지정한 프로시저를 참조하는 대리자 프로시저 인스턴스를 만듭니다. AddressOf <procedureName> - Indicates that an external procedure has another name in its DLL. 외부 프로시저의 DLL에 다른 이름이 있음을 나타냅니다. - @@ -429,7 +364,6 @@ AddressOf <procedureName> <result> = <expression1> AndAlso <expression2> 두 식의 단락(short-circuit) 논리곱 연산을 수행합니다. 두 피연산자가 모두 True인 경우 True를 반환합니다. 첫 번째 식이 False인 경우 두 번째 식은 계산하지 않습니다. <result> = <expression1> AndAlso <expression2> - @@ -437,79 +371,66 @@ AddressOf <procedureName> <result> = <expression1> And <expression2> 두 Boolean 식의 논리곱 연산을 수행하거나 두 숫자 식의 비트 논리곱 연산을 수행합니다. Boolean 식의 경우 두 피연산자가 모두 True이면 True를 반환합니다. 항상 두 식을 모두 계산합니다. <result> = <expression1> And <expression2> - Used in a Declare statement. The Ansi modifier specifies that Visual Basic should marshal all strings to ANSI values, and should look up the procedure without modifying its name during the search. If no character set is specified, ANSI is the default. Declare 문에 사용됩니다. Ansi 한정자는 Visual Basic에서 모든 문자열을 ANSI 값으로 마샬링하고 프로시저를 검색하는 동안 프로시저 이름을 수정하지 않고 프로시저를 조회하도록 지정합니다. 문자 집합을 지정하지 않으면 ANSI가 기본값으로 사용됩니다. - Specifies a data type in a declaration statement. 선언 문의 데이터 형식을 지정합니다. - Specifies that an attribute at the beginning of a source file applies to the entire assembly. Otherwise the attribute will apply only to an individual programming element, such as a class or property. 소스 파일의 시작 부분에 있는 특성이 전체 어셈블리에 적용되도록 지정합니다. 그렇게 하지 않으면 특성이 클래스나 속성 같은 개별 프로그래밍 요소에만 적용됩니다. - Indicates an asynchronous method that can use the Await operator. Await 연산자를 사용할 수 있는 비동기 메서드를 나타냅니다. - Used in a Declare statement. The Auto modifier specifies that Visual Basic should marshal strings according to .NET Framework rules, and should determine the base character set of the run-time platform and possibly modify the external procedure name if the initial search fails. Declare 문에 사용됩니다. Auto 한정자는 Visual Basic에서 .NET Framework 규칙에 따라 문자열을 마샬링하고 런타임 플랫폼의 기본 문자 집합을 결정하고 초기 검색에 실패할 경우 외부 프로시저 이름을 수정하도록 지정합니다. - Specifies that an argument is passed in such a way that the called procedure can change the underlying value of the argument in the calling code. 호출된 프로시저가 호출 코드의 내부 인수 값을 변경할 수 있는 방식으로 인수가 전달되도록 지정합니다. - Specifies that an argument is passed in such a way that the called procedure or property cannot change the underlying value of the argument in the calling code. 호출된 프로시저 또는 속성이 호출 코드의 내부 인수 값을 변경할 수 없는 방식으로 인수가 전달되도록 지정합니다. - Declares the name of a class and introduces the definitions of the variables, properties, and methods that make up the class. 클래스 이름을 선언하고 클래스를 구성하는 변수, 속성 및 메서드의 정의를 지정합니다. - Generates a string concatenation of two expressions. 두 식의 문자열 연결을 생성합니다. - Declares and defines one or more constants. 하나 이상의 상수를 선언하고 정의합니다. - Use 'In' for a type that will only be used for ByVal arguments to functions. 함수의 ByVal 인수에만 사용되는 형식에 'In'을 사용하세요. - Use 'Out' for a type that will only be used as a return from functions. 함수에서의 반환 형식으로만 사용되는 형식에 'Out'을 사용하세요. - @@ -517,31 +438,26 @@ AddressOf <procedureName> CType(Object As Expression, Object As Type) As Type 식을 지정한 데이터 형식, 개체, 구조체, 클래스 또는 인터페이스로 명시적으로 변환한 결과를 반환합니다. CType(Object As Expression, Object As Type) As Type - Specifies that an event has additional, specialized code for adding handlers, removing handlers, and raising events. 처리기 추가, 처리기 제거, 이벤트 발생 등의 특수화된 추가 코드를 사용하는 이벤트를 지정합니다. - Declares a reference to a procedure implemented in an external file. 외부 파일에 구현된 프로시저에 대한 참조를 선언합니다. - Identifies a property as the default property of its class, structure, or interface. 속성을 클래스, 구조체 또는 인터페이스의 기본 속성으로 식별합니다. - Used to declare a delegate. A delegate is a reference type that refers to a shared method of a type or to an instance method of an object. Any procedure that is convertible, or that has matching parameter types and return type may be used to create an instance of this delegate class. 대리자를 선언하는 데 사용됩니다. 대리자는 형식의 공유 메서드 또는 개체의 인스턴스 메서드를 참조하는 참조 형식입니다. 변환 가능한 프로시저 또는 일치하는 매개 변수 형식과 반환 형식이 있는 프로시저는 이 대리자 클래스의 인스턴스를 만드는 데 사용할 수 있습니다. - @@ -549,205 +465,171 @@ CType(Object As Expression, Object As Type) As Type Dim {<var> [As [New] dataType [(boundList)]][= initializer]}[, var2] 하나 이상의 변수에 사용할 스토리지 공간을 선언하고 할당합니다. Dim {<var> [As [New] dataType [(boundList)]][= initializer]}[, var2] - Divides two numbers and returns a floating-point result. 두 수를 나누고 부동 소수점 결과를 반환합니다. - Terminates a {0} block. {0} 블록을 종료합니다. - Terminates an {0} block. {0} 블록을 종료합니다. - Terminates the definition of a {0} statement. {0} 문의 정의를 종료합니다. - Terminates the definition of an {0} statement. {0} 문의 정의를 종료합니다. - Declares an enumeration and defines the values of its members. 열거형을 선언하고 열거형의 멤버 값을 정의합니다. - Compares two expressions and returns True if they are equal. Otherwise, returns False. 두 식을 비교한 후 같으면 True를 반환하고, 같지 않으면 False를 반환합니다. - Used to release array variables and deallocate the memory used for their elements. 배열 변수를 해제하고 해당 요소에 사용되는 메모리 할당을 해제하는 데 사용됩니다. - Declares a user-defined event. 사용자 정의된 이벤트를 선언합니다. - Exits a Sub procedure and transfers execution immediately to the statement following the call to the Sub procedure. Sub 프로시저를 끝내고 Sub 프로시저 호출 다음에 오는 문으로 실행을 즉시 이동합니다. - Raises a number to the power of another number. 특정 수를 다른 수의 승수로 거듭제곱합니다. - Specifies that the external procedure being referenced in the Declare statement is a Function. Declare 문에서 참조하는 외부 프로시저가 Function임을 지정합니다. - Specifies that the external procedure being referenced in the Declare statement is a Sub. Declare 문에서 참조하는 외부 프로시저가 Sub임을 지정합니다. - Specifies that one or more declared programming elements are accessible only from within the assembly that contains their declaration. 프로그래밍 요소를 선언한 어셈블리에서만 해당 프로그래밍 요소를 하나 이상 액세스할 수 있도록 지정합니다. - Specifies a collection and a range variable to use in a query. 쿼리에 사용할 컬렉션과 범위 변수를 지정합니다. - Declares the name, parameters, and code that define a Function procedure, that is, a procedure that returns a value to the calling code. 호출 코드에 값을 반환하는 Function 프로시저를 정의하는 이름, 매개 변수 및 코드를 선언합니다. - Constrains a generic type parameter to require that any type argument passed to it be a reference type. 제네릭 형식 매개 변수에 전달된 형식 인수가 참조 형식이 되도록 제한합니다. - Specifies a constructor constraint on a generic type parameter. 제네릭 형식 매개 변수에 생성자 제약 조건을 지정합니다. - Constrains a generic type parameter to require that any type argument passed to it be a value type. 제네릭 형식 매개 변수에 전달된 형식 인수가 참조 형식이 되도록 제한합니다. - Declares a Get property procedure that is used to return the current value of a property. 속성의 현재 값을 반환하는 데 사용되는 Get 속성 프로시저를 선언합니다. - Compares two expressions and returns True if the first is greater than the second. Otherwise, returns False. 두 식을 비교한 후 첫 번째 값이 두 번째 값보다 크면 True를 반환하고, 그렇지 않으면 False를 반환합니다. - Compares two expressions and returns True if the first is greater than or equal to the second. Otherwise, returns False. 두 식을 비교한 후 첫 번째 값이 두 번째 값보다 크거나 같으면 True를 반환하고, 그렇지 않으면 False를 반환합니다. - Declares that a procedure handles a specified event. 지정된 이벤트를 처리하는 프로시저를 선언합니다. - Indicates that a class or structure member is providing the implementation for a member defined in an interface. 클래스 또는 구조체 멤버가 인터페이스에 정의된 멤버를 구현함을 나타냅니다. - Specifies one or more interfaces, or interface members, that must be implemented in the class or structure definition in which the Implements statement appears. Implements 문이 표시되는 클래스 또는 구조체 정의에 구현해야 하는 인터페이스 또는 인터페이스 멤버를 하나 이상 지정합니다. - Imports all or specified elements of a namespace into a file. 네임스페이스의 모든 요소 또는 지정한 요소를 파일로 가져옵니다. - Specifies the group that the loop variable in a For Each statement is to traverse. For Each 문에서 루프 변수가 트래버스하는 그룹을 지정합니다. - Specifies the group that the loop variable is to traverse in a For Each statement, or specifies the range variable in a query. For Each 문에서 루프 변수가 트래버스하는 그룹을 지정하거나 쿼리의 범위 변수를 지정합니다. - Causes the current class or interface to inherit the attributes, variables, properties, procedures, and events from another class or set of interfaces. 현재 클래스 또는 인터페이스가 다른 클래스나 인터페이스 집합에서 특성, 변수, 속성, 프로시저 및 이벤트를 상속하도록 합니다. - Specifies the group that the range variable is to traverse in a query. 쿼리에서 범위 변수가 트래버스하는 그룹을 지정합니다. - Divides two numbers and returns an integer result. 두 수를 나누고 정수 결과를 반환합니다. - Declares the name of an interface and the definitions of the members of the interface. 인터페이스 이름과 인터페이스 멤버의 정의를 선언합니다. - Determines whether an expression is false. If instances of any class or structure will be used in an OrElse clause, you must define IsFalse on that class or structure. 식이 false인지 확인합니다. 클래스 또는 구조체의 인스턴스가 OrElse 절에 사용되면 해당 클래스 또는 구조체에서 IsFalse를 정의해야 합니다. - @@ -755,7 +637,6 @@ Dim {<var> [As [New] dataType [(boundList)]][= initializer]}[, var2] 두 개체 참조 변수를 비교하여 개체가 같은 경우 True를 반환합니다. <result> = <object1> Is <object2> - @@ -763,19 +644,16 @@ Dim {<var> [As [New] dataType [(boundList)]][= initializer]}[, var2] 두 개체 참조 변수를 비교하여 개체가 다르면 True를 반환합니다. <result> = <object1> IsNot <object2> - Determines whether an expression is true. If instances of any class or structure will be used in an OrElse clause, you must define IsTrue on that class or structure. 식이 true인지 확인합니다. 클래스 또는 구조체의 인스턴스가 OrElse 절에 사용되면 해당 클래스 또는 구조체에서 IsTrue를 정의해야 합니다. - Indicates an iterator method that can use the Yield statement. Yield 문을 사용할 수 있는 반복기 메서드를 나타냅니다. - @@ -783,31 +661,26 @@ Dim {<var> [As [New] dataType [(boundList)]][= initializer]}[, var2] Yield 문을 사용할 수 있는 반복기 람다 식을 정의합니다. Iterator Function(<parameterList>) As IEnumerable(Of <T>) - Performs an arithmetic left shift on a bit pattern. 비트 패턴의 산술 왼쪽 시프트 연산을 수행합니다. - Compares two expressions and returns True if the first is less than the second. Otherwise, returns False. 두 식을 비교한 후 첫 번째 값이 두 번째 값보다 작으면 True를 반환하고, 그렇지 않으면 False를 반환합니다. - Compares two expressions and returns True if the first is less than or equal to the second. Otherwise, returns False. 두 식을 비교한 후 첫 번째 값이 두 번째 값보다 작거나 같으면 True를 반환하고, 그렇지 않으면 False를 반환합니다. - Introduces a clause that identifies the external file (DLL or code resource) containing an external procedure. 외부 프로시저가 포함된 외부 파일(DLL 또는 코드 리소스)을 식별하는 절을 지정합니다. - @@ -815,13 +688,11 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <result> = <string> Like <pattern> 문자열을 패턴과 비교합니다. 사용 가능한 와일드카드에는 ?(단일 문자와 일치)와 *(0개 이상의 문자와 일치)가 있습니다. <result> = <string> Like <pattern> - Returns the difference between two numeric expressions, or the negative value of a numeric expression. 두 숫자 식의 차이를 반환하거나 숫자 식의 음의 값을 반환합니다. - @@ -829,55 +700,46 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <number1> Mod <number2> 두 숫자를 나누고 나머지만 반환합니다 <number1> Mod <number2> - Specifies that an attribute at the beginning of a source file applies to the entire module. Otherwise the attribute will apply only to an individual programming element, such as a class or property. 소스 파일의 시작 부분에 있는 특성이 전체 모듈에 적용되도록 지정합니다. 그렇게 하지 않으면 특성이 클래스나 속성 같은 개별 프로그래밍 요소에만 적용됩니다. - Multiplies two numbers and returns the product. 두 수를 곱하고 그 결과를 반환합니다. - Specifies that a class can be used only as a base class, and that you cannot create an object directly from it. 클래스를 기본 클래스로만 사용할 수 있고 클래스에서 개체를 직접 만들 수 없도록 지정합니다. - Specifies that a property or procedure is not implemented in the class and must be overridden in a derived class before it can be used. 속성 또는 프로시저가 클래스에서 구현되지 않고 파생 클래스에서 재정의한 후 사용할 수 있도록 지정합니다. - Declares the name of a namespace, and causes the source code following the declaration to be compiled within that namespace. 네임스페이스의 이름을 선언하고 이 선언 뒤에 오는 소스 코드가 해당 네임스페이스에서 컴파일되도록 합니다. - Indicates that a conversion operator (CType) converts a class or structure to a type that might not be able to hold some of the possible values of the original class or structure. 변환 연산자(CType)가 클래스 또는 구조체를 원래 클래스 또는 구조체에서 사용되던 값 중 일부를 보유할 수 없는 형식으로 변환함을 나타냅니다. - Compares two expressions and returns True if they are not equal. Otherwise, returns False. 두 식을 비교한 후 같지 않으면 True를 반환하고, 같으면 False를 반환합니다. - Specifies that a class cannot be used as a base class. 클래스를 기본 클래스로 사용할 수 없도록 지정합니다. - @@ -885,37 +747,31 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <result> = Not <expression> Boolean 식의 논리 부정 연산을 수행하거나 숫자 식의 비트 부정 연산을 수행합니다. <result> = Not <expression> - Specifies that a property or procedure cannot be overridden in a derived class. 속성 또는 프로시저를 파생 클래스에서 재정의할 수 없도록 지정합니다. - Identifies a type parameter on a generic class, structure, interface, delegate, or procedure. 제네릭 클래스, 구조체, 인터페이스, 대리자 또는 프로시저에서 형식 매개 변수를 식별합니다. - Declares the operator symbol, operands, and code that define an operator procedure on a class or structure. 클래스 또는 구조체에서 연산자 프로시저를 정의하는 연산자 기호, 피연산자 및 코드를 선언합니다. - Specifies that a procedure argument can be omitted when the procedure is called. 프로시저를 호출할 때 프로시저 인수를 생략할 수 있도록 지정합니다. - Introduces a statement that specifies a compiler option that applies to the entire source file. 전체 소스 파일에 적용할 컴파일러 옵션을 지정하는 문을 지정합니다. - @@ -923,7 +779,6 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <result> = <expression1> OrElse <expression2> 두 식의 단락(short-circuit) 포함 논리합 연산을 수행합니다. 두 피연산자 중 하나가 True이면 True를 반환합니다. 첫 번째 식이 True이면 두 번째 식을 계산하지 않습니다. <result> = <expression1> OrElse <expression2> - @@ -931,139 +786,116 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <result> = <expression1> Or <expression2> 두 Boolean 식의 포함 논리합 연산을 수행하거나 두 숫자 식의 비트 논리합 연산을 수행합니다. Boolean 식의 경우 하나 이상의 피연산자가 True이면 True를 반환합니다. 항상 두 식을 모두 계산합니다. <result> = <expression1> Or <expression2> - Specifies that a property or procedure re-declares one or more existing properties or procedures with the same name. 속성 또는 프로시저에서 하나 이상의 기존 속성 또는 프로시저를 같은 이름으로 다시 선언할 수 있도록 지정합니다. - Specifies that a property or procedure can be overridden by an identically named property or procedure in a derived class. 속성 또는 프로시저가 파생 클래스의 이름이 같은 속성 또는 프로시저로 재정의될 수 있도록 지정합니다. - Specifies that a property or procedure overrides an identically named property or procedure inherited from a base class. 속성 또는 프로시저가 기본 클래스에서 상속된 이름이 같은 속성 또는 프로시저를 재정의하도록 지정합니다. - Specifies that a procedure parameter takes an optional array of elements of the specified type. 프로시저 매개 변수가 지정된 형식의 선택적인 요소 배열을 사용하도록 지정합니다. - Indicates that a method, class, or structure declaration is a partial definition of the method, class, or structure. 메서드, 클래스 또는 구조체 선언이 메서드, 클래스 또는 구조체의 부분 정의임을 나타냅니다. - Returns the sum of two numbers, or the positive value of a numeric expression. 두 수의 합계를 반환하거나 숫자 식의 양의 값을 반환합니다. - Prevents the contents of an array from being cleared when the dimensions of the array are changed. 배열 차원을 변경할 때 배열 내용이 지워지지 않도록 합니다. - Specifies that one or more declared programming elements are accessible only from within their module, class, or structure. 프로그래밍 요소를 선언한 모듈, 클래스 또는 구조체에서만 해당 프로그래밍 요소를 액세스할 수 있도록 지정합니다. - Declares the name of a property, and the property procedures used to store and retrieve the value of the property. 속성 이름과 속성 값을 저장하고 검색하는 데 사용되는 속성 프로시저를 선언합니다. - Specifies that one or more declared members of a class are accessible from anywhere in the same assembly, their own classes, and derived classes. 키워드 클래스 멤버를 선언한 어셈블리, 해당 어셈블리의 클래스 및 파생 클래스 어디에서나 선언된 클래스 멤버를 액세스할 수 있도록 지정합니다. - Specifies that one or more declared programming elements are accessible only from within their own class or from a derived class. 프로그래밍 요소를 선언한 클래스 또는 파생 클래스에서만 해당 프로그래밍 요소를 액세스할 수 있도록 지정합니다. - Specifies that one or more declared programming elements have no access restrictions. 선언된 프로그래밍 요소에 대한 액세스를 제한하지 않도록 지정합니다. - Specifies that a variable or property can be read but not written to. 변수 또는 속성을 읽을 수 있지만 쓸 수는 없도록 지정합니다. - Reallocates storage space for an array variable. 배열 변수의 스토리지 공간을 다시 할당합니다. - Performs an arithmetic right shift on a bit pattern 비트 패턴의 산술 오른쪽 시프트 연산을 수행합니다. - Declares a Set property procedure that is used to assign a value to a property. 속성에 값을 할당하는 데 사용되는 Set 속성 프로시저를 선언합니다. - Specifies that a declared programming element redeclares and hides an identically named element in a base class. 선언된 프로그래밍 요소가 기본 클래스의 이름이 같은 요소를 다시 선언하고 숨깁니다. - Specifies that one or more declared programming elements are associated with all instances of a class or structure. 선언된 프로그래밍 요소가 클래스 또는 구조체의 모든 인스턴스와 연결되도록 지정합니다. - Specifies that one or more declared local variables are to remain in existence and retain their latest values after the procedure in which they are declared terminates. 지역 변수가 선언된 프로시저가 종료된 후에도 선언된 지역 변수를 하나 이상 유지하고, 최신 값을 그대로 보존하도록 지정합니다. - Declares the name of a structure and introduces the definition of the variables, properties, events, and procedures that make up the structure. 구조체의 이름을 선언하고 해당 구조체를 구성하는 변수, 속성, 이벤트 및 프로시저의 정의를 지정합니다. - Declares the name, parameters, and code that define a Sub procedure, that is, a procedure that does not return a value to the calling code. 호출 코드에 값을 반환하지 않는 프로시저인 Sub 프로시저를 정의하는 이름, 매개 변수 및 코드를 선언합니다. - Separates the beginning and ending values of a loop counter or array bounds or that of a value match range. 루프 카운터나 배열 범위, 범위와 일치하는 값의 시작 값과 끝 값을 구분합니다. - @@ -1071,31 +903,26 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <result> = TypeOf <objectExpression> Is <typeName> 개체 참조 변수의 런타임 형식을 확인한 후 데이터 형식과 비교합니다. 두 형식의 호환 여부에 따라 True 또는 False를 반환합니다. <result> = TypeOf <objectExpression> Is <typeName> - Used in a Declare statement. Specifies that Visual Basic should marshal all strings to Unicode values in a call into an external procedure, and should look up the procedure without modifying its name. Declare 문에 사용됩니다. Visual Basic에서 외부 프로시저 호출 시 모든 문자열을 Unicode 값으로 마샬링하고 프로시저 이름을 수정하지 않고 프로시저를 조회하도록 지정합니다. - Indicates that a conversion operator (CType) converts a class or structure to a type that can hold all possible values of the original class or structure. 변환 연산자(CType)가 클래스 또는 구조체를 원래 클래스 또는 구조체에서 사용되던 모든 값을 보유할 수 있는 형식으로 변환함을 나타냅니다. - Specifies that one or more declared member variables refer to an instance of a class that can raise events 선언된 멤버 변수가 이벤트를 발생시킬 수 있는 클래스의 인스턴스를 참조하도록 지정합니다. - Specifies that a property can be written to but not read. 속성을 쓸 수 있지만 읽을 수 없도록 지정합니다. - @@ -1103,37 +930,31 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) <result> = <expression1> Xor <expression2> 두 Boolean 식의 배타적 논리합 연산을 수행하거나 두 숫자 식의 배타적 비트 연산을 수행합니다. Boolean 식의 경우 두 식 중 하나가 True이면 True를 반환합니다. 항상 두 식을 계산합니다. <result> = <expression1> Xor <expression2> - Applies an aggregation function, such as Sum, Average, or Count to a sequence. Sum, Average, Count 등의 집계 함수를 시퀀스에 적용합니다. - Specifies the sort order for an Order By clause in a query. The smallest element will appear first. 쿼리의 Order By 절에 사용할 정렬 순서를 지정합니다. 가장 작은 요소가 가장 먼저 표시됩니다. - Asynchronously waits for the task to finish. 작업이 완료될 때까지 비동기적으로 기다립니다. - Sets the string comparison method specified in Option Compare to a strict binary sort order. Option Compare에 지정된 문자열 비교 메서드를 엄격한 이진 정렬 순서로 설정합니다. - Specifies the element keys used for grouping (in Group By) or sort order (in Order By). 그룹화(Group By) 또는 정렬 순서(Order By)에 사용할 요소 키를 지정합니다. - @@ -1141,19 +962,16 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) [Call] <procedureName> [(<argumentList>)] Function, Sub 또는 DLL(동적 연결 라이브러리) 프로시저로 실행을 이동합니다. [Call] <procedureName> [(<argumentList>)] - Introduces the statements to run if none of the previous cases in the Select Case statement returns True. Select Case 문에서 이전 조건이 True를 반환하지 않을 경우 실행할 문을 지정합니다. - Followed by a comparison operator and then an expression, Case Is introduces the statements to run if the Select Case expression combined with the Case Is expression evaluates to True. 이 키워드 뒤에는 비교 연산자와 식이 차례로 나옵니다. Case Is는 Case Is 식과 함께 사용하는 Select Case 식이 True인 경우 실행할 문을 지정합니다. - @@ -1161,13 +979,11 @@ Iterator Function(<parameterList>) As IEnumerable(Of <T>) Case {<expression>|<expression1> To <expression2>|[Is] <comparisonOperator> <expression>} Case 문 Select Case 문에서 식의 값을 테스트할 대상 값 또는 값 집합을 지정합니다. Case {<expression>|<expression1> To <expression2>|[Is] <comparisonOperator> <expression>} - Introduces a statement block to be run if the specified exception occurs inside a Try block. 지정한 예외가 Try 블록 안에서 발생할 경우 실행할 문 블록을 지정합니다. - @@ -1175,49 +991,41 @@ Case {<expression>|<expression1> To <expression2>|[Is] <com Option Compare {Binary | Text} 문자열 데이터를 비교할 때 사용할 기본 비교 메서드를 설정합니다. Text로 설정하면 대/소문자를 구분하지 않는 텍스트 정렬 순서를 사용하고, Binary로 설정하면 엄격한 이진 정렬 순서를 사용합니다. Option Compare {Binary | Text} - Defines a conditional compiler constant. Conditional compiler constants are always private to the file in which they appear. The expressions used to initialize them can contain only conditional compiler constants and literals. 조건부 컴파일러 상수를 정의합니다. 조건부 컴파일러 상수는 이 상수가 사용된 파일에 대해 항상 Private입니다. 조건부 컴파일러 상수를 초기화하는 데 사용되는 식에는 조건부 컴파일러 상수와 리터럴만 사용할 수 있습니다. - Transfers execution immediately to the next iteration of the Do loop. Do 루프의 다음 반복으로 실행을 즉시 이동합니다. - Transfers execution immediately to the next iteration of the For loop. For 루프의 다음 반복으로 실행을 즉시 이동합니다. - Transfers execution immediately to the next iteration of the loop. Can be used in a Do loop, a For loop, or a While loop. 루프의 다음 반복으로 실행을 즉시 이동합니다. Do 루프, For 루프 또는 While 루프에 사용할 수 있습니다. - Transfers execution immediately to the next iteration of the While loop. While 루프의 다음 반복으로 실행을 즉시 이동합니다. - Specifies the sort order for an Order By clause in a query. The largest element will appear first. 쿼리의 Order By 절에 사용할 정렬 순서를 지정합니다. 가장 큰 요소가 가장 먼저 표시됩니다. - Restricts the values of a query result to eliminate duplicate values. 쿼리 결과 값을 제한하여 중복 값을 제거합니다. - @@ -1225,7 +1033,6 @@ Option Compare {Binary | Text} Do...Loop {While | Until} <condition> Boolean 조건이 true이거나 조건이 true가 될 때까지 문 블록을 반복합니다. Do...Loop {While | Until} <condition> - @@ -1233,7 +1040,6 @@ Do...Loop {While | Until} <condition> Do Until <condition>...Loop Boolean 조건이 true가 될 때까지 문 블록을 반복합니다. Do Until <condition>...Loop - @@ -1241,73 +1047,61 @@ Do Until <condition>...Loop Do While <condition>...Loop Boolean 조건이 ture인 경우 문 블록을 반복합니다. Do While <condition>...Loop - Introduces a group of statements in an #If statement that is compiled if no previous condition evaluates to True. #If 문에서 이전 조건이 True가 아닌 경우 컴파일할 문 그룹을 지정합니다. - Introduces a condition in an #If statement that is tested if the previous conditional test evaluates to False. #If 문에서 이전 조건 테스트가 False인 경우 테스트할 조건을 지정합니다. - Introduces a condition in an If statement that is to be tested if the previous conditional test fails. If 문에서 이전 조건 테스트가 실패할 경우 테스트할 조건을 지정합니다. - Introduces a group of statements in an If statement that is executed if no previous condition evaluates to True. If 문에서 이전 조건이 True가 아닌 경우 실행할 문 그룹을 지정합니다. - Terminates the definition of an #If block. #If 블록의 정의를 종료합니다. - Stops execution immediately. 바로 실행을 중지합니다. - Terminates a #Region block. #Region 블록을 종료합니다. - Specifies the relationship between element keys to use as the basis of a join operation. 조인 연산의 기준으로 사용할 요소 키 사이의 관계를 지정합니다. - Simulates the occurrence of an error. 오류 항목을 시뮬레이션합니다. - Exits a Do loop and transfers execution immediately to the statement following the Loop statement. Do 루프를 끝내고 Loop 문 다음에 오는 문으로 실행을 즉시 이동합니다. - Exits a For loop and transfers execution immediately to the statement following the Next statement. For 루프를 끝내고 Next 문 다음에 오는 문으로 실행을 즉시 이동합니다. - @@ -1315,25 +1109,21 @@ Do While <condition>...Loop Exit {Do | For | Function | Property | Select | Sub | Try | While} 프로시저 또는 블록을 끝내고 프로시저 호출 또는 블록 정의 다음에 오는 문으로 실행을 즉시 이동합니다. Exit {Do | For | Function | Property | Select | Sub | Try | While} - Exits a Select block and transfers execution immediately to the statement following the End Select statement. Select 블록을 끝내고 End Select 문 다음에 오는 문으로 실행을 즉시 이동합니다. - Exits a Try block and transfers execution immediately to the statement following the End Try statement. Try 블록을 끝내고 End Try 문 다음에 오는 문으로 실행을 즉시 이동합니다. - Exits a While loop and transfers execution immediately to the statement following the End While statement. While 루프를 끝내고 End While 문 다음에 오는 문으로 실행을 즉시 이동합니다. - @@ -1341,79 +1131,66 @@ Exit {Do | For | Function | Property | Select | Sub | Try | While} Option Explicit {On | Off} On으로 설정하면 Dim, Private, Public 또는 ReDim 문을 사용하여 모든 변수를 명시적으로 선언해야 합니다. Option Explicit {On | Off} - Represents a Boolean value that fails a conditional test. 조건 테스트에 실패하는 Boolean 값을 나타냅니다. - Introduces a statement block to be run before exiting a Try structure. Try 구조체를 끝내기 전에 실행할 문 블록을 지정합니다. - Introduces a loop that is repeated for each element in a collection. 컬렉션의 for each 요소에 대해 반복되는 루프를 지정합니다. - Introduces a loop that is iterated a specified number of times. 지정한 횟수만큼 반복되는 루프를 지정합니다. - Identifies a list of values as a collection initializer 값 목록을 컬렉션 이니셜라이저로 식별합니다. - Branches unconditionally to a specified line in a procedure. 프로시저에 지정된 줄로 무조건 분기합니다. - Groups elements that have a common key. 공통 키를 포함된 요소를 그룹화합니다. - Combines the elements of two sequences and groups the results. The join operation is based on matching keys. 두 시퀀스의 요소를 결합하고 결과를 그룹화합니다. 조인 연산은 일치하는 키를 기준으로 합니다. - Use 'Group' to specify that a group named '{0}' should be created. Group'을 사용하여 이름이 '{0}'인 그룹을 만들도록 지정합니다. - Use 'Group' to specify that a group named 'Group' should be created. Group'을 사용하여 이름이 'Group'인 그룹을 만들도록 지정합니다. - Conditionally compiles selected blocks of code, depending on the value of an expression. 식의 값에 따라 선택한 코드 블록을 조건부로 컴파일합니다. - Conditionally executes a group of statements, depending on the value of an expression. 식의 값에 따라 문 그룹을 조건부로 실행합니다. - @@ -1421,37 +1198,31 @@ Option Explicit {On | Off} Option Infer {On | Off} On으로 설정하면 변수를 선언할 때 지역 형식을 유추할 수 있습니다. Option Infer {On | Off} - Specifies an identifier that can serve as a reference to the results of a join or grouping subexpression. 조인 또는 그룹화 하위 식의 결과에 대한 참조로 사용할 수 있는 식별자를 지정합니다. - Combines the elements of two sequences. The join operation is based on matching keys. 두 시퀀스의 요소를 결합합니다. 조인 연산은 일치하는 키를 기준으로 합니다. - Identifies a key field in an anonymous type definition. 익명 형식 정의의 키 필드를 식별합니다. - Computes a value for each item in the query, and assigns the value to a new range variable. 쿼리의 각 항목에 사용할 값을 계산한 후 해당 값을 새 범위 변수에 할당합니다. - Terminates a loop that is introduced with a Do statement. Do 문으로 지정한 루프를 종료합니다. - @@ -1459,7 +1230,6 @@ Option Infer {On | Off} Do...Loop Until <condition> Boolean 조건이 true가 될 때까지 문 블록을 반복합니다. Do...Loop Until <condition> - @@ -1467,49 +1237,41 @@ Do...Loop Until <condition> Do...Loop While <condition> Boolean 조건이 ture인 경우 문 블록을 반복합니다. Do...Loop While <condition> - Provides a way to refer to the current instance of a class or structure, that is, the instance in which the code is running. 코드를 실행 중인 클래스 또는 구조체의 현재 인스턴스를 참조할 수 있도록 합니다. - Provides a way to refer to the base class of the current class instance. You cannot use MyBase to call MustOverride base methods. 현재 클래스 인스턴스의 기본 클래스를 참조할 수 있도록 합니다. MyBase를 사용하여 MustOverride 기본 메서드를 호출할 수 없습니다. - Provides a way to refer to the class instance members as originally implemented, ignoring any derived class overrides. 파생 클래스 재정의를 무시하면서 원래 구현된 클래스 인스턴스 멤버를 참조할 수 있도록 합니다. - Creates a new object instance. 새 개체 인스턴스를 만듭니다. - Terminates a loop that iterates through the values of a loop variable. 루프 변수 값을 통해 반복하는 루프를 종료합니다. - Represents the default value of any data type. 모든 데이터 형식의 기본값을 나타냅니다. - Turns a compiler option off. 컴파일러 옵션을 해제합니다. - @@ -1519,31 +1281,26 @@ On Error GoTo [<label> | 0 | -1] 줄 인수에 지정한 줄에서 시작하는 오류 처리 루틴을 활성화합니다. 지정한 줄은 On Error 문과 같은 프로시저에 있어야 합니다. On Error GoTo [<label> | 0 | -1] - When a run-time error occurs, execution transfers to the statement following the statement or procedure call that resulted in the error. 런타임 오류가 발생하면 오류가 발생한 문 또는 프로시저 호출 다음에 오는 문으로 실행을 이동합니다. - Turns a compiler option on. 컴파일러 옵션을 설정합니다. - Specifies the element keys used to correlate sequences for a join operation. 조인 연산의 시퀀스를 서로 관련시키는 데 사용할 요소 키를 지정합니다. - Specifies the sort order for columns in a query. Can be followed by either the Ascending or the Descending keyword. If neither is specified, Ascending is used. 쿼리에서 열의 정렬 순서를 지정합니다. 뒤에 Ascending 또는 Descending 키워드가 올 수 있습니다. 아무 값도 지정하지 않으면 Ascending이 사용됩니다. - @@ -1551,7 +1308,6 @@ On Error GoTo [<label> | 0 | -1] RaiseEvent(<delegateSignature>)...End RaiseEvent RaiseEvent 문으로 이벤트가 발생될 때 실행할 문을 지정합니다. RaiseEvent(<delegateSignature>)...End RaiseEvent - @@ -1559,13 +1315,11 @@ RaiseEvent(<delegateSignature>)...End RaiseEvent RaiseEvent <eventName> [(<argumentList>)] 클래스, 폼 또는 문서의 모듈 수준에서 선언한 이벤트를 트리거합니다. RaiseEvent <eventName> [(<argumentList>)] - Collapses and hides sections of code in Visual Basic files. Visual Basic 파일에서 코드 섹션을 축소하고 숨깁니다. - @@ -1573,37 +1327,31 @@ RaiseEvent <eventName> [(<argumentList>)] Return -or- Return <expression> Function, Sub, Get, Set, Operator 프로시저 등을 호출한 코드로 실행을 반환합니다. Return -or- Return <expression> - Runs one of several groups of statements, depending on the value of an expression. 식의 값에 따라 여러 문 그룹 중 하나를 실행합니다. - Specifies which columns to include in the result of a query. 쿼리 결과에 포함할 열을 지정합니다. - Skips elements up to a specified position in the collection. 컬렉션에서 지정한 위치까지 요소를 건너뜁니다. - Specifies how much to increment between each loop iteration. 각 루프 반복 간에 증가하는 크기를 지정합니다. - Suspends program execution. 프로그램 실행을 일시 중단합니다. - @@ -1611,7 +1359,6 @@ Return -or- Return <expression> Option Strict {On | Off} On으로 설정하면 암시적 데이터 형식 변환을 확대 변환으로만 제한합니다. Option Strict {On | Off} - @@ -1619,37 +1366,31 @@ Option Strict {On | Off} SyncLock <object>...End Synclock 여러 스레드가 동시에 문 블록을 실행하지 않도록 합니다. SyncLock <object>...End Synclock - Includes elements up to a specified position in the collection. 컬렉션에서 지정한 위치까지 요소를 포함합니다. - Sets the string comparison method specified in Option Compare to a text sort order that is not case sensitive. Option Compare에 지정된 문자열 비교 메서드를 대/소문자를 구분하지 않는 텍스트 정렬 순서로 설정합니다. - Introduces a statement block to be compiled or executed if a tested condition is true. 테스트한 조건이 true일 때 컴파일하거나 실행할 문 블록을 지정합니다. - Throws an exception within a procedure so that you can handle it with structured or unstructured exception-handling code. 구조적 또는 비구조적 예외 처리 코드로 처리할 수 있도록 프로시저에서 에외를 throw합니다. - Represents a Boolean value that passes a conditional test. 조건 테스트를 통과하는 Boolean 값을 나타냅니다. - @@ -1657,7 +1398,6 @@ SyncLock <object>...End Synclock Try...[Catch]...{Catch | Finally}...End Try 코드를 계속 실행하면서 지정한 코드 블록에서 발생할 수 있는 오류의 일부 또는 전체를 처리할 방법을 제공합니다. Try...[Catch]...{Catch | Finally}...End Try - @@ -1665,31 +1405,26 @@ Try...[Catch]...{Catch | Finally}...End Try Using <resource1>[, <resource2>]...End Using Using 블록은 다음과 같은 세 가지 작업을 합니다. 리소스 목록의 변수를 만들어 초기화하고, 블록의 코드를 실행하며, 종료하기 전에 변수를 삭제합니다. Using 블록에 사용되는 리소스는 System.IDisposable을 구현해야 합니다. Using <resource1>[, <resource2>]...End Using - Adds a conditional test to a Catch statement. Exceptions are caught by that Catch statement only when the conditional test that follows the When keyword evaluates to True. 조건 테스트를 Catch 문에 추가합니다. 예외는 When 키워드 다음에 오는 조건 테스트가 True인 경우에만 이 Catch 문에서 catch됩니다. - Specifies the filtering condition for a range variable in a query. 쿼리의 범위 변수에 사용할 필터링 조건을 지정합니다. - Runs a series of statements as long as a given condition is true. 지정한 조건이 true인 동안 일련의 문을 실행합니다. - Specifies a condition for Skip and Take operations. Elements will be bypassed or included as long as the condition is true. Skip 및 Take 작업에 사용할 조건을 지정합니다. 조건이 True인 동안 요소를 건너뛰거나 포함합니다. - @@ -1697,7 +1432,6 @@ Using <resource1>[, <resource2>]...End Using New <typeName> With {[.<property> = <expression>][,...]} 속성 초기화 선언을 개체 이니셜라이저에 지정합니다. New <typeName> With {[.<property> = <expression>][,...]} - @@ -1705,13 +1439,11 @@ New <typeName> With {[.<property> = <expression>][,...]} 단일 개체 또는 구조체를 참조하는 일련의 문을 실행합니다. With <object>...End With - Produces an element of an IEnumerable or IEnumerator. IEnumerable 또는 IEnumerator의 요소를 생성합니다. - @@ -1719,7 +1451,6 @@ With <object>...End With Async Sub/Function(<parameterList>) <expression> Await 연산자를 사용할 수 있는 비동기 람다 식을 정의합니다. 대리자 형식이 필요할 때마다 사용할 수 있습니다. Async Sub/Function(<parameterList>) <expression> - @@ -1727,7 +1458,6 @@ Async Sub/Function(<parameterList>) <expression> Function(<parameterList>) <expression> 단일 값을 계산하고 반환하는 람다 식을 정의합니다. 대리자 형식이 필요한 곳마다 사용할 수 있습니다. Function(<parameterList>) <expression> - @@ -1735,487 +1465,406 @@ Function(<parameterList>) <expression> Sub(<parameterList>) <statement> 문을 실행할 수 있고 값을 반환하지 않는 람다 식을 정의합니다. 대리자 형식이 필요한 곳마다 사용할 수 있습니다. Sub(<parameterList>) <statement> - Disables reporting of specified warnings in the portion of the source file below the current line. 현재 줄 아래의 소스 파일 부분에서 지정한 경고를 보고하지 않습니다. - Enables reporting of specified warnings in the portion of the source file below the current line. 현재 줄 아래의 소스 파일 부분에서 지정한 경고를 보고합니다. - Insert 'Await'. Await'를 삽입합니다. - Make {0} an Async Function. {0}을(를) 비동기 함수로 설정합니다. - Insert Missing Cast 누락된 캐스트 삽입 - Convert {0} to Iterator 반복기로 {0} 변환 - Replace 'Return' with 'Yield Return'을 'Yield'로 바꾸기 - Use the correct control variable 올바른 제어 변수 사용 - NameOf function 함수 이름 - Generate narrowing conversion in '{0}' {0}'에서 축소 변환 생성 - Generate widening conversion in '{0}' {0}'에서 확대 변환 생성 - Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. 이 코드를 변경하지 마세요. 위의 Dispose(disposing As Boolean)에 정리 코드를 입력하세요. - TODO: free unmanaged resources (unmanaged objects) and override Finalize() below. TODO: 관리되지 않는 리소스(관리되지 않는 개체)를 해제하고 아래의 Finalize()를 재정의합니다. - TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources. TODO: 위의 Dispose(disposing As Boolean)에 관리되지 않는 리소스를 해제하기 위한 코드가 있는 경우에만 Finalize()를 재정의합니다. - This code added by Visual Basic to correctly implement the disposable pattern. 삭제 가능한 패턴을 올바르게 구현하기 위해 Visual Basic에서 추가한 코드입니다. - TODO: uncomment the following line if Finalize() is overridden above. TODO: 위의 Finalize()가 재정의된 경우 다음 줄의 주석 처리를 제거합니다. - Imports statement is unnecessary. Imports 문은 필요하지 않습니다. - Try block Try 블록 - {Locked="Try"} "Try" is a VB keyword and should not be localized. Catch clause Catch 절 - {Locked="Catch"} "Catch" is a VB keyword and should not be localized. Finally clause Finally 절 - {Locked="Finally"} "Finally" is a VB keyword and should not be localized. Using statement Using 문 - {Locked="Using"} "Using" is a VB keyword and should not be localized. Using block Using 블록 - {Locked="Using"} "Using" is a VB keyword and should not be localized. With statement With 문 - {Locked="With"} "With" is a VB keyword and should not be localized. With block With 블록 - {Locked="With"} "With" is a VB keyword and should not be localized. SyncLock statement SyncLock 문 - {Locked="SyncLock"} "SyncLock" is a VB keyword and should not be localized. SyncLock block SyncLock 블록 - {Locked="SyncLock"} "SyncLock" is a VB keyword and should not be localized. For Each statement For Each 문 - {Locked="For Each"} "For Each" is a VB keyword and should not be localized. For Each block For Each 블록 - {Locked="For Each"} "For Each" is a VB keyword and should not be localized. On Error statement On Error 문 - {Locked="On Error"} "On Error" is a VB keyword and should not be localized. Resume statement Resume 문 - {Locked="Resume"} "Resume" is a VB keyword and should not be localized. Yield statement Yield 문 - {Locked="Yield"} "Yield" is a VB keyword and should not be localized. Await expression 대기 식 - {Locked="Await"} "Await" is a VB keyword and should not be localized. Lambda 람다 - Where clause Where 절 - {Locked="Where"} "Where" is a VB keyword and should not be localized. Select clause Select 절 - {Locked="Select"} "Select" is a VB keyword and should not be localized. From clause From 절 - {Locked="From"} "From" is a VB keyword and should not be localized. Aggregate clause Aggregate 절 - {Locked="Aggregate"} "Aggregate" is a VB keyword and should not be localized. Let clause Let 절 - {Locked="Let"} "Let" is a VB keyword and should not be localized. Join clause Join 절 - {Locked="Join"} "Join" is a VB keyword and should not be localized. Group Join clause Group Join 절 - {Locked="Group Join"} "Group Join" is a VB keyword and should not be localized. Group By clause Group By 절 - {Locked="Group By"} "Group By" is a VB keyword and should not be localized. Function aggregation 함수 집계 - Take While clause Take While 절 - {Locked="Take While"} "Take While" is a VB keyword and should not be localized. Skip While clause Skip While 절 - {Locked="Skip While"} "Skip While" is a VB keyword and should not be localized. Ordering clause Ordering 절 - {Locked="Ordering"} "Ordering" is a VB keyword and should not be localized. Join condition 조인 조건 - {Locked="Join"} "Join" is a VB keyword and should not be localized. WithEvents field WithEvents 필드 - {Locked="WithEvents"} "WithEvents" is a VB keyword and should not be localized. property accessor 속성 접근자 - as clause as 절 - {Locked="as"} "as" is a VB keyword and should not be localized. type parameters 형식 매개 변수 - parameters 매개 변수 - attributes 특성 - Too many arguments to '{0}'. {0}'에 대한 인수가 너무 많습니다. - Type '{0}' is not defined. {0}' 형식이 정의되지 않았습니다. - Add 'Overloads' 'Overloads' 추가 - {Locked="Overloads"} "Overloads" is a VB keyword and should not be localized. Add a metadata reference to specified assembly and all its dependencies, e.g. #r "myLib.dll". 지정한 어셈블리 및 모든 해당 종속성에 대한 메타데이터 참조를 추가합니다(예: #r "myLib.dll"). - Properties 속성 - <namespace name> <네임스페이스 이름> - Type a name here to declare a namespace. 네임스페이스를 선언하려면 여기에 이름을 입력하세요. - Type a name here to declare a partial class. Partial 클래스를 선언하려면 여기에 이름을 입력하세요. - <class name> <클래스 이름> - <interface name> <인터페이스 이름> - <module name> <모듈 이름> - <structure name> <구조체 이름> - Type a name here to declare a partial interface. Partial 인터페이스를 선언하려면 여기에 이름을 입력하세요. - Type a name here to declare a partial module. Partial 모듈을 선언하려면 여기에 이름을 입력하세요. - Type a name here to declare a partial structure. Partial 구조체를 선언하려면 여기에 이름을 입력하세요. - {0}.add {0}.add - The name of an event add handler where "{0}" is the event name. {0}.remove {0}.remove - The name of an event remove handler where "{0}" is the event name. {0}.get {0}.get - The name of a property getter like "public int MyProperty { get; }" where "{0}" is the property name {0}.set {0}.set - The name of a property setter like "public int MyProperty { set; }" where "{0}" is the property name Make Async Function 비동기 함수로 설정 - Make Async Sub 비동기 Sub로 설정 - Add 'Me.' Me'를 추가하세요. - Use 'Is Nothing' check Is Nothing' 검사 사용 - Use 'IsNot Nothing' check IsNot Nothing' 검사 사용 - Convert to 'Select Case' 'Select Case'로 변환 - Convert to 'For Each' 'For Each'로 변환 - Convert to 'For' 'For'로 변환 - Invert If if 반전 - diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf index 4f7744db4ce82..ebfb770560af4 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf @@ -97,6 +97,11 @@ Usuń niepotrzebne importy + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Wpisz tutaj nazwę, aby utworzyć deklarację nowego pola. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf index a34ad74f2cc7e..9ccc84c072eca 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf @@ -97,6 +97,11 @@ Remover Importações Desnecessárias + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Digite um nome aqui para declarar um novo campo. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf index a678b9515a6c9..e0b84e1f235f8 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf @@ -97,6 +97,11 @@ Удалить ненужные импорты + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Введите здесь имя для объявления нового поля. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf index 2c1c12c683cfb..f62f1b1cecfa3 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf @@ -97,6 +97,11 @@ Gereksiz İçeri Aktarmaları Kaldır + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. Yeni bir alan bildirmek için buraya bir ad yazın. diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf index 014fc04f19dc8..5e590e760c4b9 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf @@ -97,6 +97,11 @@ 删除不必要的导入 + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. 请在此处键入名称以声明新字段。 diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf index ab2c52c59c948..06ab87ddce982 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf @@ -97,6 +97,11 @@ 移除不必要的匯入 + + &Sort Imports + &Sort Imports + + Type a name here to declare a new field. 於此輸入名稱以宣告新的欄位。 diff --git a/src/Interactive/HostTest/InteractiveHostTests.cs b/src/Interactive/HostTest/InteractiveHostTests.cs index 1fa2f5926cacc..f22536c7bc0a6 100644 --- a/src/Interactive/HostTest/InteractiveHostTests.cs +++ b/src/Interactive/HostTest/InteractiveHostTests.cs @@ -1159,7 +1159,7 @@ public void Exception() Assert.Equal("", output); Assert.DoesNotContain("Unexpected", error, StringComparison.OrdinalIgnoreCase); - Assert.True(error.StartsWith(new Exception().Message)); + Assert.True(error.StartsWith($"{new Exception().GetType()}: {new Exception().Message}")); } [Fact, WorkItem(10883, "https://github.com/dotnet/roslyn/issues/10883")] @@ -1173,7 +1173,7 @@ public void PreservingDeclarationsOnException() var error = ReadErrorOutputToEnd(); AssertEx.AssertEqualToleratingWhitespaceDifferences("120", output); - AssertEx.AssertEqualToleratingWhitespaceDifferences("Bang!", error); + AssertEx.AssertEqualToleratingWhitespaceDifferences("System.Exception: Bang!", error); } [Fact] diff --git a/src/NuGet/VisualStudio/VS.ExternalAPIs.Roslyn.Package.csproj b/src/NuGet/VisualStudio/VS.ExternalAPIs.Roslyn.Package.csproj index caabf77549eba..6b7d77b289af3 100644 --- a/src/NuGet/VisualStudio/VS.ExternalAPIs.Roslyn.Package.csproj +++ b/src/NuGet/VisualStudio/VS.ExternalAPIs.Roslyn.Package.csproj @@ -141,6 +141,7 @@ <_File Include="$(ArtifactsBinDir)Roslyn.VisualStudio.Setup\$(Configuration)\net472\Humanizer.dll" TargetDir="" /> + <_File Include="$(ArtifactsBinDir)Roslyn.VisualStudio.Setup\$(Configuration)\net472\Microsoft.CodeAnalysis.FlowAnalysis.Utilities.dll" TargetDir="" /> <_File Include="$(ArtifactsBinDir)Roslyn.VisualStudio.Setup\$(Configuration)\net472\ICSharpCode.Decompiler.dll" TargetDir="" /> <_File Include="$(ArtifactsBinDir)Roslyn.VisualStudio.Setup\$(Configuration)\net472\System.Composition.Hosting.dll" TargetDir="" /> <_File Include="$(ArtifactsBinDir)Roslyn.VisualStudio.Setup\$(Configuration)\net472\System.Composition.TypedParts.dll" TargetDir="" /> diff --git a/src/Scripting/CSharpTest.Desktop/CsiTests.cs b/src/Scripting/CSharpTest.Desktop/CsiTests.cs index 6041081607fd4..c6ee82089e820 100644 --- a/src/Scripting/CSharpTest.Desktop/CsiTests.cs +++ b/src/Scripting/CSharpTest.Desktop/CsiTests.cs @@ -148,7 +148,7 @@ public void LineNumber_Information_On_Exception() Assert.True(result.ContainsErrors); AssertEx.AssertEqualToleratingWhitespaceDifferences("OK", result.Output); AssertEx.AssertEqualToleratingWhitespaceDifferences($@" -Error! +System.Exception: Error! + .MoveNext(){string.Format(ScriptingResources.AtFileLine, $"{cwd}{Path.DirectorySeparatorChar}a.csx", "2")} ", result.Errors); } diff --git a/src/Scripting/CSharpTest/CommandLineRunnerTests.cs b/src/Scripting/CSharpTest/CommandLineRunnerTests.cs index d836d9cbd1d6e..ba634f45e8e5e 100644 --- a/src/Scripting/CSharpTest/CommandLineRunnerTests.cs +++ b/src/Scripting/CSharpTest/CommandLineRunnerTests.cs @@ -248,6 +248,7 @@ public void Exception() "); Assert.Equal(0, runner.RunInteractive()); + var exception = new DivideByZeroException(); Assert.Equal( $@"{LogoAndHelpPrompt} > int div(int a, int b) => a/b; @@ -255,13 +256,13 @@ public void Exception() 5 > div(10, 0) «Red» -{new System.DivideByZeroException().Message} +{exception.GetType()}: {exception.Message} + Submission#0.div(int, int) «Gray» > ", runner.Console.Out.ToString()); Assert.Equal( -$@"{new System.DivideByZeroException().Message} +$@"{exception.GetType()}: {exception.Message} + Submission#0.div(int, int) ", runner.Console.Error.ToString()); } @@ -276,6 +277,7 @@ public void ExceptionInGeneric() "); Assert.Equal(0, runner.RunInteractive()); + var exception = new DivideByZeroException(); Assert.Equal( $@"{LogoAndHelpPrompt} > static class C {{ public static int div(int a, int b) => a/b; }} @@ -283,13 +285,13 @@ public void ExceptionInGeneric() 5 > C.div(10, 0) «Red» -{new System.DivideByZeroException().Message} +{exception.GetType()}: {exception.Message} + Submission#0.C.div(int, int) «Gray» > ", runner.Console.Out.ToString()); Assert.Equal( -$@"{new System.DivideByZeroException().Message} +$@"{exception.GetType()}: {exception.Message} + Submission#0.C.div(int, int) ", runner.Console.Error.ToString()); } @@ -889,7 +891,7 @@ public void PreservingDeclarationsOnException() «Yellow» (1,58): warning CS0162: { CSharpResources.WRN_UnreachableCode } «Red» -Bang! +System.Exception: Bang! «Gray» > i + j + k 120 @@ -897,7 +899,7 @@ public void PreservingDeclarationsOnException() AssertEx.AssertEqualToleratingWhitespaceDifferences( $@"(1,58): warning CS0162: { CSharpResources.WRN_UnreachableCode } -Bang!", +System.Exception: Bang!", runner.Console.Error.ToString()); } diff --git a/src/Scripting/Core/Hosting/ObjectFormatter/CommonObjectFormatter.cs b/src/Scripting/Core/Hosting/ObjectFormatter/CommonObjectFormatter.cs index bab8aa1b68d83..2c555811b7456 100644 --- a/src/Scripting/Core/Hosting/ObjectFormatter/CommonObjectFormatter.cs +++ b/src/Scripting/Core/Hosting/ObjectFormatter/CommonObjectFormatter.cs @@ -65,7 +65,10 @@ public override string FormatException(Exception e) var pooled = PooledStringBuilder.GetInstance(); var builder = pooled.Builder; - builder.AppendLine(e.Message); + builder.Append(e.GetType()); + builder.Append(": "); + builder.Append(e.Message); + builder.Append(Environment.NewLine); var trace = new StackTrace(e, fNeedFileInfo: true); foreach (var frame in trace.GetFrames()) diff --git a/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj b/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj index 0bf918523b6fb..e4b990e07b2a2 100644 --- a/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj +++ b/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj @@ -1,4 +1,4 @@ - + @@ -106,6 +106,9 @@ <_Dependency Remove="Newtonsoft.Json"/> <_Dependency Remove="stdole"/> <_Dependency Remove="StreamJsonRpc"/> + <_Dependency Remove="Nerdbank.Streams"/> + <_Dependency Remove="System.IO.Pipelines"/> + <_Dependency Remove="System.ValueTuple"/> <_Dependency Remove="System.Threading.Tasks.Dataflow"/> <_Dependency Remove="VSLangProj"/> <_Dependency Remove="VSLangProj2"/> @@ -191,7 +194,7 @@ Write a list of assembly names and versions that the insertion tool uses to update assembly versions in DevDiv. --> @@ -215,7 +218,7 @@ Copy NuGet packages to be inserted into VS by the insertion tool. --> diff --git a/src/Test/Utilities/Portable/Compilation/Exceptions.cs b/src/Test/Utilities/Portable/Compilation/Exceptions.cs index 61bb8be358f3b..e8c86d7cdc3d1 100644 --- a/src/Test/Utilities/Portable/Compilation/Exceptions.cs +++ b/src/Test/Utilities/Portable/Compilation/Exceptions.cs @@ -2,13 +2,16 @@ using System; using System.Collections.Generic; +using System.Runtime.Serialization; using Microsoft.CodeAnalysis; using static Roslyn.Test.Utilities.ExceptionHelper; namespace Roslyn.Test.Utilities { + [Serializable] public class EmitException : Exception { + [field: NonSerialized] public IEnumerable Diagnostics { get; } public EmitException(IEnumerable diagnostics, string directory) @@ -16,8 +19,14 @@ public EmitException(IEnumerable diagnostics, string directory) { this.Diagnostics = diagnostics; } + + protected EmitException(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + throw new NotImplementedException(); + } } + [Serializable] public class ExecutionException : Exception { public ExecutionException(string expectedOutput, string actualOutput, string exePath) @@ -25,5 +34,10 @@ public ExecutionException(string expectedOutput, string actualOutput, string exe public ExecutionException(Exception innerException, string exePath) : base(GetMessageFromException(innerException, exePath), innerException) { } + + protected ExecutionException(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + throw new NotImplementedException(); + } } } diff --git a/src/Test/Utilities/Portable/Diagnostics/DiagnosticDescription.cs b/src/Test/Utilities/Portable/Diagnostics/DiagnosticDescription.cs index 38258bd71104f..606dc3a9ba79a 100644 --- a/src/Test/Utilities/Portable/Diagnostics/DiagnosticDescription.cs +++ b/src/Test/Utilities/Portable/Diagnostics/DiagnosticDescription.cs @@ -191,6 +191,7 @@ public DiagnosticDescription WhereSyntax(Func syntaxPredicate) } public object Code => _code; + public bool HasLocation => _startPosition != null; public override bool Equals(object obj) { diff --git a/src/Test/Utilities/Portable/Diagnostics/ThrowingDiagnosticAnalyzer.cs b/src/Test/Utilities/Portable/Diagnostics/ThrowingDiagnosticAnalyzer.cs index 81aea0f652df1..5f48ebedbdf5b 100644 --- a/src/Test/Utilities/Portable/Diagnostics/ThrowingDiagnosticAnalyzer.cs +++ b/src/Test/Utilities/Portable/Diagnostics/ThrowingDiagnosticAnalyzer.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; @@ -17,8 +18,18 @@ namespace Microsoft.CodeAnalysis.Test.Utilities { public class ThrowingDiagnosticAnalyzer : TestDiagnosticAnalyzer where TLanguageKindEnum : struct { + [Serializable] public class DeliberateException : Exception { + public DeliberateException() + { + } + + protected DeliberateException(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + throw new NotImplementedException(); + } + public override string Message { get { return "If this goes unhandled, our diagnostics engine is susceptible to malicious analyzers"; } diff --git a/src/Test/Utilities/Portable/Roslyn.Test.Utilities.csproj b/src/Test/Utilities/Portable/Roslyn.Test.Utilities.csproj index fc82db7d3db7e..2a881bc4ed9d3 100644 --- a/src/Test/Utilities/Portable/Roslyn.Test.Utilities.csproj +++ b/src/Test/Utilities/Portable/Roslyn.Test.Utilities.csproj @@ -96,5 +96,6 @@ + diff --git a/src/Test/Utilities/Portable/Traits/Traits.cs b/src/Test/Utilities/Portable/Traits/Traits.cs index 761e3b71a39ae..f2663c97f1d98 100644 --- a/src/Test/Utilities/Portable/Traits/Traits.cs +++ b/src/Test/Utilities/Portable/Traits/Traits.cs @@ -64,6 +64,7 @@ public static class Features public const string CodeActionsConvertTupleToStruct = "CodeActions.ConvertTupleToStruct"; public const string CodeActionsConvertQueryToForEach = "CodeActions.ConvertQueryToForEach"; public const string CodeActionsConvertForEachToQuery = "CodeActions.ConvertForEachToQuery"; + public const string CodeActionsConvertSwitchStatementToExpression = "CodeActions.ConvertSwitchStatementToExpression"; public const string CodeActionsCorrectExitContinue = "CodeActions.CorrectExitContinue"; public const string CodeActionsCorrectFunctionReturnType = "CodeActions.CorrectFunctionReturnType"; public const string CodeActionsCorrectNextControlVariable = "CodeActions.CorrectNextControlVariable"; @@ -186,6 +187,7 @@ public static class Features public const string DebuggingNameResolver = "Debugging.NameResolver"; public const string DebuggingProximityExpressions = "Debugging.ProximityExpressions"; public const string Diagnostics = nameof(Diagnostics); + public const string DisposeAnalysis = nameof(DisposeAnalysis); public const string DocCommentFormatting = nameof(DocCommentFormatting); public const string DocumentationComments = nameof(DocumentationComments); public const string EditorConfig = nameof(EditorConfig); diff --git a/src/Tools/ExternalAccess/Apex/ApexAsynchronousOperationListenerProviderAccessor.cs b/src/Tools/ExternalAccess/Apex/ApexAsynchronousOperationListenerProviderAccessor.cs new file mode 100644 index 0000000000000..7f34b78baf591 --- /dev/null +++ b/src/Tools/ExternalAccess/Apex/ApexAsynchronousOperationListenerProviderAccessor.cs @@ -0,0 +1,27 @@ +// 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.Composition; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.TestHooks; + +namespace Microsoft.CodeAnalysis.ExternalAccess.Apex +{ + [Export(typeof(IApexAsynchronousOperationListenerProviderAccessor))] + [Shared] + internal sealed class ApexAsynchronousOperationListenerProviderAccessor : IApexAsynchronousOperationListenerProviderAccessor + { + private readonly AsynchronousOperationListenerProvider _implementation; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public ApexAsynchronousOperationListenerProviderAccessor(AsynchronousOperationListenerProvider implementation) + { + _implementation = implementation; + } + + public Task WaitAllAsync(string[] featureNames = null, Action eventProcessingAction = null) + => _implementation.WaitAllAsync(featureNames, eventProcessingAction); + } +} diff --git a/src/Tools/ExternalAccess/Apex/IApexAsynchronousOperationListenerProviderAccessor.cs b/src/Tools/ExternalAccess/Apex/IApexAsynchronousOperationListenerProviderAccessor.cs new file mode 100644 index 0000000000000..f4b0196d6a76d --- /dev/null +++ b/src/Tools/ExternalAccess/Apex/IApexAsynchronousOperationListenerProviderAccessor.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.ExternalAccess.Apex +{ + internal interface IApexAsynchronousOperationListenerProviderAccessor + { + Task WaitAllAsync(string[] featureNames = null, Action eventProcessingAction = null); + } +} diff --git a/src/Tools/ExternalAccess/Apex/Microsoft.CodeAnalysis.ExternalAccess.Apex.csproj b/src/Tools/ExternalAccess/Apex/Microsoft.CodeAnalysis.ExternalAccess.Apex.csproj index 7e026f514c6a4..fe376f49a347f 100644 --- a/src/Tools/ExternalAccess/Apex/Microsoft.CodeAnalysis.ExternalAccess.Apex.csproj +++ b/src/Tools/ExternalAccess/Apex/Microsoft.CodeAnalysis.ExternalAccess.Apex.csproj @@ -24,6 +24,7 @@ + diff --git a/src/Tools/ExternalAccess/FSharp/Editor/FSharpSynchronousIndentationService.cs b/src/Tools/ExternalAccess/FSharp/Editor/FSharpSynchronousIndentationService.cs index 907254f2ec1bc..ff86543602125 100644 --- a/src/Tools/ExternalAccess/FSharp/Editor/FSharpSynchronousIndentationService.cs +++ b/src/Tools/ExternalAccess/FSharp/Editor/FSharpSynchronousIndentationService.cs @@ -3,15 +3,16 @@ using System; using System.Composition; using System.Threading; -using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Indentation; namespace Microsoft.CodeAnalysis.ExternalAccess.FSharp.Internal.Editor { [Shared] - [ExportLanguageService(typeof(ISynchronousIndentationService), LanguageNames.FSharp)] - internal class FSharpSynchronousIndentationService : ISynchronousIndentationService + [ExportLanguageService(typeof(IIndentationService), LanguageNames.FSharp)] + internal class FSharpSynchronousIndentationService : IIndentationService { private readonly IFSharpSynchronousIndentationService _service; @@ -22,17 +23,23 @@ public FSharpSynchronousIndentationService(IFSharpSynchronousIndentationService _service = service; } - public CodeAnalysis.Editor.IndentationResult? GetDesiredIndentation(Document document, int lineNumber, CancellationToken cancellationToken) + public IndentationResult? GetDesiredIndentation(Document document, int lineNumber, CancellationToken cancellationToken) { var result = _service.GetDesiredIndentation(document, lineNumber, cancellationToken); if (result.HasValue) { - return new CodeAnalysis.Editor.IndentationResult(result.Value.BasePosition, result.Value.Offset); + return new IndentationResult(result.Value.BasePosition, result.Value.Offset); } else { return null; } } + + IndentationResult IIndentationService.GetBlankLineIndentation( + Document document, int lineNumber, FormattingOptions.IndentStyle indentStyle, CancellationToken cancellationToken) + { + return default; + } } } diff --git a/src/Tools/ExternalAccess/FSharp/Microsoft.CodeAnalysis.ExternalAccess.FSharp.csproj b/src/Tools/ExternalAccess/FSharp/Microsoft.CodeAnalysis.ExternalAccess.FSharp.csproj index c0599fa40be40..f280b723cf640 100644 --- a/src/Tools/ExternalAccess/FSharp/Microsoft.CodeAnalysis.ExternalAccess.FSharp.csproj +++ b/src/Tools/ExternalAccess/FSharp/Microsoft.CodeAnalysis.ExternalAccess.FSharp.csproj @@ -78,6 +78,7 @@ + \ No newline at end of file diff --git a/src/Tools/ExternalAccess/Xamarin.Remote/Microsoft.CodeAnalysis.ExternalAccess.Xamarin.Remote.csproj b/src/Tools/ExternalAccess/Xamarin.Remote/Microsoft.CodeAnalysis.ExternalAccess.Xamarin.Remote.csproj index 67112eb56d746..6a4b0de2dec25 100644 --- a/src/Tools/ExternalAccess/Xamarin.Remote/Microsoft.CodeAnalysis.ExternalAccess.Xamarin.Remote.csproj +++ b/src/Tools/ExternalAccess/Xamarin.Remote/Microsoft.CodeAnalysis.ExternalAccess.Xamarin.Remote.csproj @@ -22,6 +22,10 @@ + + + + diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs b/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs index d03d85977a081..d7fa22047b418 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs +++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs @@ -1077,6 +1077,15 @@ internal static string Prefer_pattern_matching_over_is_with_cast_check { } } + /// + /// Looks up a localized string similar to Prefer switch expression. + /// + internal static string Prefer_switch_expression { + get { + return ResourceManager.GetString("Prefer_switch_expression", resourceCulture); + } + } + /// /// Looks up a localized string similar to Prefer 'this.'. /// diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx index ed20c1582fad0..3241eba368041 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx +++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx @@ -597,4 +597,7 @@ General Title of the control group on the General Formatting options page + + Prefer switch expression + \ No newline at end of file diff --git a/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelNavigationPointServiceFactory.cs b/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelNavigationPointServiceFactory.cs index 1a44ca162ddd4..3244f89a7ecd3 100644 --- a/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelNavigationPointServiceFactory.cs +++ b/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelNavigationPointServiceFactory.cs @@ -1,7 +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.ComponentModel.Composition; using System.Composition; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor; @@ -16,6 +15,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.CodeModel [ExportLanguageServiceFactory(typeof(ICodeModelNavigationPointService), LanguageNames.CSharp), Shared] internal partial class CSharpCodeModelNavigationPointServiceFactory : ILanguageServiceFactory { + [ImportingConstructor] + public CSharpCodeModelNavigationPointServiceFactory() + { + } + public ILanguageService CreateLanguageService(HostLanguageServices provider) { // This interface is implemented by the ICodeModelService as well, so just grab the other one and return it diff --git a/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelServiceFactory.cs b/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelServiceFactory.cs index f0a8cad450402..85b0ef128b556 100644 --- a/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelServiceFactory.cs +++ b/src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelServiceFactory.cs @@ -18,7 +18,7 @@ internal partial class CSharpCodeModelServiceFactory : ILanguageServiceFactory private readonly IEnumerable _refactorNotifyServices; [ImportingConstructor] - private CSharpCodeModelServiceFactory( + public CSharpCodeModelServiceFactory( IEditorOptionsFactoryService editorOptionsFactoryService, [ImportMany] IEnumerable refactorNotifyServices) { diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpBreakpointResolutionService.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpBreakpointResolutionService.cs index 28b73be41fea0..c8ab935110ee7 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpBreakpointResolutionService.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpBreakpointResolutionService.cs @@ -18,6 +18,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Debugging [ExportLanguageService(typeof(IBreakpointResolutionService), LanguageNames.CSharp), Shared] internal partial class CSharpBreakpointResolutionService : IBreakpointResolutionService { + [ImportingConstructor] + public CSharpBreakpointResolutionService() + { + } + /// /// Returns null if a breakpoint can't be placed at the specified position. /// diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpLanguageDebugInfoService.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpLanguageDebugInfoService.cs index 0e7882d8b2a6e..d8968bc776b81 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpLanguageDebugInfoService.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpLanguageDebugInfoService.cs @@ -13,6 +13,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Debugging [ExportLanguageService(typeof(ILanguageDebugInfoService), LanguageNames.CSharp), Shared] internal partial class CSharpLanguageDebugInfoService : ILanguageDebugInfoService { + [ImportingConstructor] + public CSharpLanguageDebugInfoService() + { + } + public Task GetLocationInfoAsync(Document document, int position, CancellationToken cancellationToken) { return LocationInfoGetter.GetInfoAsync(document, position, cancellationToken); diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.cs index 04308406a657f..338ba80b7c501 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.cs @@ -38,6 +38,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Debugging [ExportLanguageService(typeof(IProximityExpressionsService), LanguageNames.CSharp), Shared] internal partial class CSharpProximityExpressionsService : IProximityExpressionsService { + [ImportingConstructor] + public CSharpProximityExpressionsService() + { + } + public async Task IsValidAsync( Document document, int position, diff --git a/src/VisualStudio/CSharp/Impl/EventHookup/EventHookupSessionManager.cs b/src/VisualStudio/CSharp/Impl/EventHookup/EventHookupSessionManager.cs index 5720a4a90f50f..ee33a49d88f65 100644 --- a/src/VisualStudio/CSharp/Impl/EventHookup/EventHookupSessionManager.cs +++ b/src/VisualStudio/CSharp/Impl/EventHookup/EventHookupSessionManager.cs @@ -28,7 +28,7 @@ internal sealed partial class EventHookupSessionManager : ForegroundThreadAffini [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - internal EventHookupSessionManager(IThreadingContext threadingContext, IToolTipService toolTipService) + public EventHookupSessionManager(IThreadingContext threadingContext, IToolTipService toolTipService) : base(threadingContext) { _toolTipService = toolTipService; diff --git a/src/VisualStudio/CSharp/Impl/LanguageService/CSharpHelpContextService.cs b/src/VisualStudio/CSharp/Impl/LanguageService/CSharpHelpContextService.cs index 740431d058754..1a0669cd33d64 100644 --- a/src/VisualStudio/CSharp/Impl/LanguageService/CSharpHelpContextService.cs +++ b/src/VisualStudio/CSharp/Impl/LanguageService/CSharpHelpContextService.cs @@ -20,6 +20,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService [ExportLanguageService(typeof(IHelpContextService), LanguageNames.CSharp), Shared] internal class CSharpHelpContextService : AbstractHelpContextService { + [ImportingConstructor] + public CSharpHelpContextService() + { + } + public override string Language { get diff --git a/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpLibraryService.cs b/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpLibraryService.cs index 5521f474514be..6834a066bc9bf 100644 --- a/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpLibraryService.cs +++ b/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpLibraryService.cs @@ -22,6 +22,7 @@ internal class CSharpLibraryService : AbstractLibraryService parameterOptions: SymbolDisplayParameterOptions.IncludeType, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + [ImportingConstructor] public CSharpLibraryService() : base(Guids.CSharpLibraryId, __SymbolToolLanguage.SymbolToolLanguage_CSharp, s_typeDisplayFormat, s_memberDisplayFormat) { diff --git a/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpSyncClassViewCommandHandler.cs b/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpSyncClassViewCommandHandler.cs index e9de56218c95d..f0156e7c7e457 100644 --- a/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpSyncClassViewCommandHandler.cs +++ b/src/VisualStudio/CSharp/Impl/ObjectBrowser/CSharpSyncClassViewCommandHandler.cs @@ -18,7 +18,7 @@ internal class CSharpSyncClassViewCommandHandler : AbstractSyncClassViewCommandH { [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - private CSharpSyncClassViewCommandHandler(IThreadingContext threadingContext, SVsServiceProvider serviceProvider) + public CSharpSyncClassViewCommandHandler(IThreadingContext threadingContext, SVsServiceProvider serviceProvider) : base(threadingContext, serviceProvider) { } diff --git a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs index 4c06ee1cf9530..ccfa1e28c4bae 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs @@ -671,6 +671,12 @@ public string Style_PreferConditionalDelegateCall set { SetXmlOption(CSharpCodeStyleOptions.PreferConditionalDelegateCall, value); } } + public string Style_PreferSwitchExpression + { + get { return GetXmlOption(CSharpCodeStyleOptions.PreferSwitchExpression); } + set { SetXmlOption(CSharpCodeStyleOptions.PreferSwitchExpression, value); } + } + public string Style_PreferPatternMatchingOverAsWithNullCheck { get { return GetXmlOption(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck); } diff --git a/src/VisualStudio/CSharp/Impl/Options/Formatting/FormattingOptionPageControl.xaml.cs b/src/VisualStudio/CSharp/Impl/Options/Formatting/FormattingOptionPageControl.xaml.cs index 378a4c2631de0..edff2823c8df1 100644 --- a/src/VisualStudio/CSharp/Impl/Options/Formatting/FormattingOptionPageControl.xaml.cs +++ b/src/VisualStudio/CSharp/Impl/Options/Formatting/FormattingOptionPageControl.xaml.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Options; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.VisualStudio.LanguageServices.Implementation.Options; namespace Microsoft.VisualStudio.LanguageServices.CSharp.Options @@ -24,7 +25,7 @@ public FormattingOptionPageControl(OptionStore optionStore) : base(optionStore) BindToOption(FormatWhenTypingCheckBox, FeatureOnOffOptions.AutoFormattingOnTyping, LanguageNames.CSharp); BindToOption(FormatOnCloseBraceCheckBox, FeatureOnOffOptions.AutoFormattingOnCloseBrace, LanguageNames.CSharp); BindToOption(FormatOnSemicolonCheckBox, FeatureOnOffOptions.AutoFormattingOnSemicolon, LanguageNames.CSharp); - BindToOption(FormatOnReturnCheckBox, FeatureOnOffOptions.AutoFormattingOnReturn, LanguageNames.CSharp); + BindToOption(FormatOnReturnCheckBox, FormattingOptions.AutoFormattingOnReturn, LanguageNames.CSharp); BindToOption(FormatOnPasteCheckBox, FeatureOnOffOptions.FormatOnPaste, LanguageNames.CSharp); } } diff --git a/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs b/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs index 044dae74b8df7..b58affd9b3a8f 100644 --- a/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs +++ b/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs @@ -328,6 +328,36 @@ void M2(object o) //] }} }} +"; + + private static readonly string s_preferSwitchExpression = $@" +class C +{{ + void M1() + {{ +//[ + // {ServicesVSResources.Prefer_colon} + return num switch + {{ + 1 => 1, + _ => 2, + }} +//] + }} + void M2() + {{ +//[ + // {ServicesVSResources.Over_colon} + switch (num) + {{ + case 1: + return 1; + default: + return 2; + }} +//] + }} +}} "; private static readonly string s_preferPatternMatchingOverAsWithNullCheck = $@" @@ -1593,6 +1623,7 @@ internal StyleViewModel(OptionStore optionStore, IServiceProvider serviceProvide // Expression preferences CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferObjectInitializer, ServicesVSResources.Prefer_object_initializer, s_preferObjectInitializer, s_preferObjectInitializer, this, optionStore, expressionPreferencesGroupTitle)); CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferCollectionInitializer, ServicesVSResources.Prefer_collection_initializer, s_preferCollectionInitializer, s_preferCollectionInitializer, this, optionStore, expressionPreferencesGroupTitle)); + CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferSwitchExpression, CSharpVSResources.Prefer_switch_expression, s_preferSwitchExpression, s_preferSwitchExpression, this, optionStore, expressionPreferencesGroupTitle)); CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck, CSharpVSResources.Prefer_pattern_matching_over_is_with_cast_check, s_preferPatternMatchingOverIsWithCastCheck, s_preferPatternMatchingOverIsWithCastCheck, this, optionStore, expressionPreferencesGroupTitle)); CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck, CSharpVSResources.Prefer_pattern_matching_over_as_with_null_check, s_preferPatternMatchingOverAsWithNullCheck, s_preferPatternMatchingOverAsWithNullCheck, this, optionStore, expressionPreferencesGroupTitle)); CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferConditionalExpressionOverAssignment, ServicesVSResources.Prefer_conditional_expression_over_if_with_assignments, s_preferConditionalExpressionOverIfWithAssignments, s_preferConditionalExpressionOverIfWithAssignments, this, optionStore, expressionPreferencesGroupTitle)); diff --git a/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs b/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs index c7ed864fa8009..7d180dca0ef21 100644 --- a/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs +++ b/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs @@ -43,6 +43,11 @@ internal partial class CSharpProgressionLanguageService : IProgressionLanguageSe delegateStyle: SymbolDisplayDelegateStyle.NameAndParameters, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + [ImportingConstructor] + public CSharpProgressionLanguageService() + { + } + public IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken) { // We implement this method lazily so we are able to abort as soon as we need to. diff --git a/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpEntryPointFinderService.cs b/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpEntryPointFinderService.cs index 615cae4bda048..5d5ad4bb7a330 100644 --- a/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpEntryPointFinderService.cs +++ b/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpEntryPointFinderService.cs @@ -11,6 +11,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim [ExportLanguageService(typeof(IEntryPointFinderService), LanguageNames.CSharp), Shared] internal class CSharpEntryPointFinderService : IEntryPointFinderService { + [ImportingConstructor] + public CSharpEntryPointFinderService() + { + } + public IEnumerable FindEntryPoints(INamespaceSymbol symbol, bool findFormsOnly) { return EntryPointFinder.FindEntryPoints(symbol); diff --git a/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpProjectShim.ICSInputSet.cs b/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpProjectShim.ICSInputSet.cs index d61af0a0934a4..30192fca81a54 100644 --- a/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpProjectShim.ICSInputSet.cs +++ b/src/VisualStudio/CSharp/Impl/ProjectSystemShim/CSharpProjectShim.ICSInputSet.cs @@ -3,6 +3,7 @@ using System; using System.IO; using Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim.Interop; +using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim { @@ -45,7 +46,11 @@ public void SetWin32Resource(string filename) public void SetOutputFileName(string filename) { - VisualStudioProject.IntermediateOutputFilePath = filename; + // Some projects like web projects give us just a filename; those aren't really useful (they're just filler) so we'll ignore them for purposes of tracking the path + if (PathUtilities.IsAbsolute(filename)) + { + VisualStudioProject.IntermediateOutputFilePath = filename; + } if (filename != null) { diff --git a/src/VisualStudio/CSharp/Impl/Utilities/CSharpCompilationOptionsChangingService.cs b/src/VisualStudio/CSharp/Impl/Utilities/CSharpCompilationOptionsChangingService.cs index 01e4e8e763d10..e0524c6bb4f97 100644 --- a/src/VisualStudio/CSharp/Impl/Utilities/CSharpCompilationOptionsChangingService.cs +++ b/src/VisualStudio/CSharp/Impl/Utilities/CSharpCompilationOptionsChangingService.cs @@ -12,6 +12,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Utilities [ExportLanguageService(typeof(ICompilationOptionsChangingService), LanguageNames.CSharp), Shared] internal class CSharpCompilationOptionsChangingService : ICompilationOptionsChangingService { + [ImportingConstructor] + public CSharpCompilationOptionsChangingService() + { + } + public bool CanApplyChange(CompilationOptions oldOptions, CompilationOptions newOptions) { var oldCSharpOptions = (CSharpCompilationOptions)oldOptions; diff --git a/src/VisualStudio/CSharp/Impl/Utilities/CSharpParseOptionsChangingService.cs b/src/VisualStudio/CSharp/Impl/Utilities/CSharpParseOptionsChangingService.cs index cc9e6e48b7dae..86e2bf6459146 100644 --- a/src/VisualStudio/CSharp/Impl/Utilities/CSharpParseOptionsChangingService.cs +++ b/src/VisualStudio/CSharp/Impl/Utilities/CSharpParseOptionsChangingService.cs @@ -12,6 +12,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Utilities [ExportLanguageService(typeof(IParseOptionsChangingService), LanguageNames.CSharp), Shared] internal class CSharpParseOptionsChangingService : IParseOptionsChangingService { + [ImportingConstructor] + public CSharpParseOptionsChangingService() + { + } + public bool CanApplyChange(ParseOptions oldOptions, ParseOptions newOptions) { var oldCSharpOptions = (CSharpParseOptions)oldOptions; diff --git a/src/VisualStudio/CSharp/Impl/Venus/CSharpAdditionalFormattingRuleLanguageService.cs b/src/VisualStudio/CSharp/Impl/Venus/CSharpAdditionalFormattingRuleLanguageService.cs index d241482d41524..818686b281ea5 100644 --- a/src/VisualStudio/CSharp/Impl/Venus/CSharpAdditionalFormattingRuleLanguageService.cs +++ b/src/VisualStudio/CSharp/Impl/Venus/CSharpAdditionalFormattingRuleLanguageService.cs @@ -13,6 +13,11 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Venus [ExportLanguageService(typeof(IAdditionalFormattingRuleLanguageService), LanguageNames.CSharp), Shared] internal class CSharpAdditionalFormattingRuleLanguageService : IAdditionalFormattingRuleLanguageService { + [ImportingConstructor] + public CSharpAdditionalFormattingRuleLanguageService() + { + } + public AbstractFormattingRule GetAdditionalCodeGenerationRule() { return BlankLineInGeneratedMethodFormattingRule.Instance; diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf index 7ff6426c1e2ea..c3321440c240a 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf @@ -67,6 +67,11 @@ U kontrol rovnosti odkazů dávat přednost možnosti is null 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf index 77f953590292c..ba5187835c6c0 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf @@ -67,6 +67,11 @@ "is null" für Verweisübereinstimmungsprüfungen vorziehen 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf index 66666349bc635..b5af19d24711e 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf @@ -67,6 +67,11 @@ Preferir “is null” para comprobaciones de igualdad de referencias 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf index bdd1b687fbcf1..ac958b43d331a 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf @@ -67,6 +67,11 @@ Préférer 'is nul' pour les vérifications d'égalité de référence 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf index c8bb34dda7457..a59e88995d481 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf @@ -67,6 +67,11 @@ Preferisci 'is null' per i controlli di uguaglianza dei riferimenti 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf index 63599153f9635..f640835dcdcf2 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf @@ -67,6 +67,11 @@ 参照の等値性のチェックには 'is null' を優先する 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf index 22b1f6754c01f..b29b11e3b690b 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf @@ -67,6 +67,11 @@ 참조 같음 검사에 대해 'is null' 선호 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf index 286f2616cf61e..63a98ec484210 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf @@ -67,6 +67,11 @@ Preferuj wyrażenie „is null” w przypadku sprawdzeń odwołań pod kątem równości 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf index e9894b50554e4..27ec42e61ceb9 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf @@ -67,6 +67,11 @@ Preferir 'is null' para as verificações de igualdade de referência 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf index 502b06898df5b..144057cdb1a9d 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf @@ -67,6 +67,11 @@ Использовать "is null" вместо проверки ссылок на равенство. 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf index 181029db61eb7..28476cae9dc81 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf @@ -67,6 +67,11 @@ Başvuru eşitliği denetimleri için 'is null'ı tercih et 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf index c003ed3fee968..751b248bd6cf2 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf @@ -67,6 +67,11 @@ 引用相等检查偏好 “is null” 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf index 826496173a7c2..d6646c51be6be 100644 --- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf +++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf @@ -67,6 +67,11 @@ 參考相等檢查最好使用 'is null' 'is null' is a C# string and should not be localized. + + Prefer switch expression + Prefer switch expression + + Preferred 'using' directive placement Preferred 'using' directive placement diff --git a/src/VisualStudio/CSharp/Test/Watson/WatsonTests.cs b/src/VisualStudio/CSharp/Test/Watson/WatsonTests.cs index 672f213f9e8e6..98526eae103a6 100644 --- a/src/VisualStudio/CSharp/Test/Watson/WatsonTests.cs +++ b/src/VisualStudio/CSharp/Test/Watson/WatsonTests.cs @@ -59,7 +59,7 @@ public void TestRemoteInvocationException() { var mockFault = new MockFault(); - var exception = new RemoteInvocationException("test", "remoteCallstack", "remoteErrorCode"); + var exception = new RemoteInvocationException("test", errorCode: 100, "remoteErrorData"); mockFault.SetExtraParameters(exception, emptyCallstack: false); Assert.Equal(exception.GetParameterString(), mockFault.Map[7]); @@ -70,7 +70,7 @@ public void TestRemoteInvocationExceptionNull() { var mockFault = new MockFault(); - var exception = new RemoteInvocationException(message: null, remoteStack: null, remoteCode: null); + var exception = new RemoteInvocationException(message: null, errorCode: -1, errorData: null); mockFault.SetExtraParameters(exception, emptyCallstack: false); Assert.Equal(exception.GetParameterString(), mockFault.Map[7]); diff --git a/src/VisualStudio/Core/Def/Commands.vsct b/src/VisualStudio/Core/Def/Commands.vsct index 3b57650a7dee2..03bf54aa4b54e 100644 --- a/src/VisualStudio/Core/Def/Commands.vsct +++ b/src/VisualStudio/Core/Def/Commands.vsct @@ -76,6 +76,19 @@ +