diff --git a/README.md b/README.md
index 376e05f29d80c..74b1b5e1b2949 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ If you want to get started using Roslyn's APIs to analyzer your code take a look
**The latest pre-release builds** are available from the following public NuGet feeds:
- [Compiler](https://dev.azure.com/dnceng/public/_packaging?_a=feed&feed=dotnet-tools): `https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json`
-- [IDE Services](https://devdiv.visualstudio.com/DevDiv/_packaging?_a=feed&feed=vssdk): `https://devdiv.pkgs.visualstudio.com/_packaging/vssdk/nuget/v3/index.json`
+- [IDE Services](https://dev.azure.com/azure-public/vside/_packaging?_a=feed&feed=vssdk): `https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json`
- [.NET SDK](https://dev.azure.com/dnceng/public/_packaging?_a=feed&feed=dotnet5): `https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json`
[//]: # (Begin current test results)
diff --git a/eng/config/test/Core/InstallTraceListener.cs b/eng/config/test/Core/InstallTraceListener.cs
new file mode 100644
index 0000000000000..968c7d0e1a09e
--- /dev/null
+++ b/eng/config/test/Core/InstallTraceListener.cs
@@ -0,0 +1,13 @@
+//
+
+using System.Runtime.CompilerServices;
+using Roslyn.Test.Utilities;
+
+internal sealed class InitializeTestModule
+{
+ [ModuleInitializer]
+ internal static void Initializer()
+ {
+ RuntimeHelpers.RunModuleConstructor(typeof(TestBase).Module.ModuleHandle);
+ }
+}
diff --git a/src/Analyzers/CSharp/Analyzers/CSharpAnalyzers.projitems b/src/Analyzers/CSharp/Analyzers/CSharpAnalyzers.projitems
index 0efeba0ffee6c..de39f449b6d94 100644
--- a/src/Analyzers/CSharp/Analyzers/CSharpAnalyzers.projitems
+++ b/src/Analyzers/CSharp/Analyzers/CSharpAnalyzers.projitems
@@ -74,6 +74,7 @@
+
diff --git a/src/Analyzers/CSharp/Analyzers/CSharpAnalyzersResources.resx b/src/Analyzers/CSharp/Analyzers/CSharpAnalyzersResources.resx
index b9bc8679ff712..6b9e29189414c 100644
--- a/src/Analyzers/CSharp/Analyzers/CSharpAnalyzersResources.resx
+++ b/src/Analyzers/CSharp/Analyzers/CSharpAnalyzersResources.resx
@@ -292,4 +292,11 @@
'typeof' can be converted to 'nameof'
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
+
+ 'new' expression can be simplified
+
\ No newline at end of file
diff --git a/src/Analyzers/CSharp/Analyzers/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationDiagnosticAnalyzer.cs
new file mode 100644
index 0000000000000..69f2daf620033
--- /dev/null
+++ b/src/Analyzers/CSharp/Analyzers/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationDiagnosticAnalyzer.cs
@@ -0,0 +1,126 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#nullable enable
+
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis.CodeStyle;
+using Microsoft.CodeAnalysis.CSharp.CodeStyle;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.CSharp.Utilities;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+
+namespace Microsoft.CodeAnalysis.CSharp.UseImplicitObjectCreation
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ internal class CSharpUseImplicitObjectCreationDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
+ {
+ public CSharpUseImplicitObjectCreationDiagnosticAnalyzer()
+ : base(IDEDiagnosticIds.UseImplicitObjectCreationDiagnosticId,
+ CSharpCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent,
+ LanguageNames.CSharp,
+ new LocalizableResourceString(nameof(CSharpAnalyzersResources.Use_new), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)),
+ new LocalizableResourceString(nameof(CSharpAnalyzersResources.new_expression_can_be_simplified), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)))
+ {
+ }
+
+ public override DiagnosticAnalyzerCategory GetAnalyzerCategory()
+ => DiagnosticAnalyzerCategory.SemanticSpanAnalysis;
+
+ protected override void InitializeWorker(AnalysisContext context)
+ => context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.ObjectCreationExpression);
+
+ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
+ {
+ var options = context.Options;
+ var syntaxTree = context.Node.SyntaxTree;
+ var semanticModel = context.SemanticModel;
+ var cancellationToken = context.CancellationToken;
+
+ // Not available prior to C# 9.
+ if (((CSharpParseOptions)syntaxTree.Options).LanguageVersion < LanguageVersion.CSharp9)
+ return;
+
+ var optionSet = options.GetAnalyzerOptionSet(syntaxTree, cancellationToken);
+ var styleOption = options.GetOption(CSharpCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent, syntaxTree, cancellationToken);
+ if (!styleOption.Value)
+ {
+ // Bail immediately if the user has disabled this feature.
+ return;
+ }
+
+ // type is apparent if we the object creation location is closely tied (spatially) to the explicit type. Specifically:
+ //
+ // 1. Variable declarations. i.e. `List list = new ...`. Note: we will suppress ourselves if this
+ // is a field and the 'var' preferences would lead to preferring this as `var list = ...`
+ // 2. Expression-bodied constructs with an explicit return type. i.e. `List Prop => new ...` or
+ // `List GetValue(...) => ...` The latter doesn't necessarily have the object creation spatially next to
+ // the type. However, the type is always in a very easy to ascertain location in C#, so it is treated as
+ // apparent.
+
+ var objectCreation = (ObjectCreationExpressionSyntax)context.Node;
+
+ TypeSyntax? typeNode;
+
+ if (objectCreation.Parent.IsKind(SyntaxKind.EqualsValueClause) &&
+ objectCreation.Parent.Parent.IsKind(SyntaxKind.VariableDeclarator) &&
+ objectCreation.Parent.Parent.Parent is VariableDeclarationSyntax variableDeclaration &&
+ !variableDeclaration.Type.IsVar)
+ {
+ typeNode = variableDeclaration.Type;
+
+ var helper = CSharpUseImplicitTypeHelper.Instance;
+ if (helper.ShouldAnalyzeVariableDeclaration(variableDeclaration, cancellationToken) &&
+ helper.AnalyzeTypeName(typeNode, semanticModel, optionSet, cancellationToken).IsStylePreferred)
+ {
+ // this is a case where the user would prefer 'var'. don't offer to use an implicit object here.
+ return;
+ }
+ }
+ else if (objectCreation.Parent.IsKind(SyntaxKind.ArrowExpressionClause))
+ {
+ typeNode = objectCreation.Parent.Parent switch
+ {
+ LocalFunctionStatementSyntax localFunction => localFunction.ReturnType,
+ MethodDeclarationSyntax method => method.ReturnType,
+ ConversionOperatorDeclarationSyntax conversion => conversion.Type,
+ OperatorDeclarationSyntax op => op.ReturnType,
+ BasePropertyDeclarationSyntax property => property.Type,
+ AccessorDeclarationSyntax { RawKind: (int)SyntaxKind.GetAccessorDeclaration, Parent: AccessorListSyntax { Parent: BasePropertyDeclarationSyntax baseProperty } } accessor => baseProperty.Type,
+ _ => null,
+ };
+ }
+ else
+ {
+ // more cases can be added here if we discover more cases we think the type is readily apparent from context.
+ return;
+ }
+
+ if (typeNode == null)
+ return;
+
+ // Only offer if the type being constructed is the exact same as the type being assigned into. We don't
+ // want to change semantics by trying to instantiate something else.
+ var leftType = semanticModel.GetTypeInfo(typeNode, cancellationToken).Type;
+ var rightType = semanticModel.GetTypeInfo(objectCreation, cancellationToken).Type;
+
+ if (leftType is null || rightType is null)
+ return;
+
+ if (leftType.IsErrorType() || rightType.IsErrorType())
+ return;
+
+ if (!leftType.Equals(rightType, SymbolEqualityComparer.Default))
+ return;
+
+ context.ReportDiagnostic(DiagnosticHelper.Create(
+ Descriptor,
+ objectCreation.Type.GetLocation(),
+ styleOption.Notification.Severity,
+ ImmutableArray.Create(objectCreation.GetLocation()),
+ properties: null));
+ }
+ }
+}
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.cs.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.cs.xlf
index 74920414d2772..c110e2e319041 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.cs.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.cs.xlf
@@ -202,6 +202,11 @@
Použít lokální funkci
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Použít porovnávání vzorů
@@ -262,6 +267,11 @@
Příkaz if lze zjednodušit.
+
+
+ 'new' expression can be simplified
+
+
typeof se dá převést na nameof.
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.de.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.de.xlf
index 84f56fc7673d1..7d5f77eead9c4 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.de.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.de.xlf
@@ -202,6 +202,11 @@
Lokale Funktion verwenden
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Musterabgleich verwenden
@@ -262,6 +267,11 @@
Die If-Anweisung kann vereinfacht werden.
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.es.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.es.xlf
index dafa96a93b761..dfcad1013fc27 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.es.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.es.xlf
@@ -202,6 +202,11 @@
Usar función local
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Usar coincidencia de patrones
@@ -262,6 +267,11 @@
La instrucción "if" se puede simplificar
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.fr.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.fr.xlf
index d1e988b52f723..7125856887f1a 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.fr.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.fr.xlf
@@ -202,6 +202,11 @@
Utiliser une fonction locale
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Utiliser les critères spéciaux
@@ -262,6 +267,11 @@
L'instruction 'if' peut être simplifiée
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.it.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.it.xlf
index e196b87352318..6d6539304d662 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.it.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.it.xlf
@@ -202,6 +202,11 @@
Usa la funzione locale
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Usa i criteri di ricerca
@@ -262,6 +267,11 @@
L'istruzione 'If' può essere semplificata
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ja.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ja.xlf
index bbffa53596a07..f921c7d68574f 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ja.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ja.xlf
@@ -202,6 +202,11 @@
ローカル関数を使用します
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
パターン マッチングを使用します
@@ -262,6 +267,11 @@
'if' ステートメントは簡素化できます
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ko.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ko.xlf
index 2b5f98b36e0c8..aaaadb7388852 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ko.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ko.xlf
@@ -202,6 +202,11 @@
로컬 함수 사용
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
패턴 일치 사용
@@ -262,6 +267,11 @@
'if' 문을 간단하게 줄일 수 있습니다.
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pl.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pl.xlf
index 0f3b263a9e11f..7eb173f653946 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pl.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pl.xlf
@@ -202,6 +202,11 @@
Użyj funkcji lokalnej
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Użyj dopasowywania wzorców
@@ -262,6 +267,11 @@
Instrukcja „if” może zostać uproszczona
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pt-BR.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pt-BR.xlf
index 2d88d00089774..bf7b815656e8b 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pt-BR.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.pt-BR.xlf
@@ -202,6 +202,11 @@
Usar função local
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Usar a correspondência de padrão
@@ -262,6 +267,11 @@
A instrução 'if' pode ser simplificada
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ru.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ru.xlf
index e8a4616e472f1..e331fa8db6f3a 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ru.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.ru.xlf
@@ -202,6 +202,11 @@
Использовать локальную функцию
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Используйте сопоставление шаблонов
@@ -262,6 +267,11 @@
Оператор if можно упростить
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.tr.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.tr.xlf
index f3918258c54b6..8a03e12cc00eb 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.tr.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.tr.xlf
@@ -202,6 +202,11 @@
Yerel işlev kullan
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
Desen eşleştirme kullan
@@ -262,6 +267,11 @@
'If' deyimi basitleştirilebilir
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hans.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hans.xlf
index 748cbed12afc5..bdbd208956dfb 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hans.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hans.xlf
@@ -202,6 +202,11 @@
使用本地函数
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
使用模式匹配
@@ -262,6 +267,11 @@
可简化“If”语句
+
+
+ 'new' expression can be simplified
+
+
"typeof" 可以转换为 "nameof"
diff --git a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hant.xlf b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hant.xlf
index bccc0489b0adc..1349e543deb3a 100644
--- a/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hant.xlf
+++ b/src/Analyzers/CSharp/Analyzers/xlf/CSharpAnalyzersResources.zh-Hant.xlf
@@ -202,6 +202,11 @@
使用區域函式
+
+
+ Use 'new(...)'
+ {Locked="new(...)"} This is a C# construct and should not be localized.
+
使用模式比對
@@ -262,6 +267,11 @@
'if' 陳述式可簡化
+
+
+ 'new' expression can be simplified
+
+
'typeof' can be converted to 'nameof'
diff --git a/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems b/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems
index 8ba1d0e8aec03..40f5c81727d2b 100644
--- a/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems
+++ b/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems
@@ -48,6 +48,7 @@
+
diff --git a/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs
new file mode 100644
index 0000000000000..b906cf9fee13e
--- /dev/null
+++ b/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs
@@ -0,0 +1,88 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Immutable;
+using System.Composition;
+using System.Diagnostics.CodeAnalysis;
+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.Host.Mef;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Roslyn.Utilities;
+
+namespace Microsoft.CodeAnalysis.CSharp.UseImplicitObjectCreation
+{
+ [ExportCodeFixProvider(LanguageNames.CSharp), Shared]
+ internal class CSharpUseImplicitObjectCreationCodeFixProvider : SyntaxEditorBasedCodeFixProvider
+ {
+ [ImportingConstructor]
+ [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
+ public CSharpUseImplicitObjectCreationCodeFixProvider()
+ {
+ }
+
+ public override ImmutableArray FixableDiagnosticIds
+ => ImmutableArray.Create(IDEDiagnosticIds.UseImplicitObjectCreationDiagnosticId);
+
+ internal sealed override CodeFixCategory CodeFixCategory => CodeFixCategory.CodeStyle;
+
+ protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic)
+ => !diagnostic.IsSuppressed;
+
+ 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 Task FixAllAsync(
+ Document document, ImmutableArray diagnostics,
+ SyntaxEditor editor, CancellationToken cancellationToken)
+ {
+ // process from inside->out so that outer rewrites see the effects of inner changes.
+ foreach (var diagnostic in diagnostics.OrderBy(d => d.Location.SourceSpan.End))
+ FixOne(editor, diagnostic, cancellationToken);
+
+ return Task.CompletedTask;
+ }
+
+ private static void FixOne(SyntaxEditor editor, Diagnostic diagnostic, CancellationToken cancellationToken)
+ {
+ var node = diagnostic.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken);
+ editor.ReplaceNode(node, (current, _) =>
+ {
+ var currentObjectCreation = (ObjectCreationExpressionSyntax)current;
+ return SyntaxFactory.ImplicitObjectCreationExpression(
+ WithoutTrailingWhitespace(currentObjectCreation.NewKeyword),
+ currentObjectCreation.ArgumentList ?? SyntaxFactory.ArgumentList(),
+ currentObjectCreation.Initializer);
+ });
+ }
+
+ private static SyntaxToken WithoutTrailingWhitespace(SyntaxToken newKeyword)
+ {
+ return newKeyword.TrailingTrivia.All(t => t.IsWhitespace())
+ ? newKeyword.WithoutTrailingTrivia()
+ : newKeyword;
+ }
+
+ private class MyCodeAction : CustomCodeActions.DocumentChangeAction
+ {
+ public MyCodeAction(Func> createChangedDocument)
+ : base(CSharpAnalyzersResources.Use_new, createChangedDocument, CSharpAnalyzersResources.Use_new)
+ {
+ }
+ }
+ }
+}
diff --git a/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems b/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems
index 22a2b50061755..3a0e8886c5621 100644
--- a/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems
+++ b/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems
@@ -82,6 +82,7 @@
+
diff --git a/src/Analyzers/CSharp/Tests/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationTests.cs b/src/Analyzers/CSharp/Tests/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationTests.cs
new file mode 100644
index 0000000000000..ef80deb30a6db
--- /dev/null
+++ b/src/Analyzers/CSharp/Tests/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationTests.cs
@@ -0,0 +1,597 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeStyle;
+using Microsoft.CodeAnalysis.CSharp.CodeStyle;
+using Microsoft.CodeAnalysis.CSharp.UseImplicitObjectCreation;
+using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
+using Microsoft.CodeAnalysis.Test.Utilities;
+using Microsoft.CodeAnalysis.Testing;
+using Xunit;
+
+namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseImplicitObjectCreationTests
+{
+ using VerifyCS = CSharpCodeFixVerifier<
+ CSharpUseImplicitObjectCreationDiagnosticAnalyzer,
+ CSharpUseImplicitObjectCreationCodeFixProvider>;
+
+ public class UseImplicitObjectCreationTests
+ {
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestMissingBeforeCSharp9()
+ {
+ var source = @"
+class C
+{
+ C c = new C();
+}";
+ await new VerifyCS.Test
+ {
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp8,
+ TestCode = source,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestAfterCSharp9()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C c = new [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ C c = new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithObjectInitializer()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C c = new [|C|]() { };
+}",
+ FixedCode = @"
+class C
+{
+ C c = new() { };
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithObjectInitializerWithoutArguments()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C c = new [|C|] { };
+}",
+ FixedCode = @"
+class C
+{
+ C c = new() { };
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithTriviaAfterNew()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C c = new /*x*/ [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ C c = new /*x*/ ();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithDifferentTypes()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ object c = new C();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithErrorTypes()
+ {
+ await new VerifyCS.Test
+ {
+ TestState = {
+ Sources =
+ {
+ @"
+class C
+{
+ {|#0:E|} c = new {|#1:E|}();
+}"
+ },
+ ExpectedDiagnostics =
+ {
+ // /0/Test0.cs(4,5): error CS0246: The type or namespace name 'E' could not be found (are you missing a using directive or an assembly reference?)
+ DiagnosticResult.CompilerError("CS0246").WithLocation(0).WithArguments("E"),
+ // /0/Test0.cs(4,15): error CS0246: The type or namespace name 'E' could not be found (are you missing a using directive or an assembly reference?)
+ DiagnosticResult.CompilerError("CS0246").WithLocation(1).WithArguments("E"),
+ }
+ },
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithDynamic()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ dynamic c = new C();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithArrayTypes()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ int[] c = new int[0];
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithTypeParameter()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C where T : new()
+{
+ T t = new [|T|]();
+}",
+ FixedCode = @"
+class C where T : new()
+{
+ T t = new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithLocalWhenUserDoesNotPreferVar()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ void M()
+ {
+ C c = new [|C|]();
+ }
+}",
+ FixedCode = @"
+class C
+{
+ void M()
+ {
+ C c = new();
+ }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ Options =
+ {
+ { CSharpCodeStyleOptions.VarWhenTypeIsApparent, CodeStyleOptions2.FalseWithSuggestionEnforcement },
+ }
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithLocalWhenUserDoesPreferVar()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ void M()
+ {
+ C c = new C();
+ }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ Options =
+ {
+ { CSharpCodeStyleOptions.VarWhenTypeIsApparent, CodeStyleOptions2.TrueWithSuggestionEnforcement },
+ }
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithForVariable()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ void M()
+ {
+ for (C c = new [|C|]();;)
+ {
+ }
+ }
+}",
+ FixedCode = @"
+class C
+{
+ void M()
+ {
+ for (C c = new();;)
+ {
+ }
+ }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithLocalFunctionExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ void M()
+ {
+ C Func() => new [|C|]();
+ }
+}",
+ FixedCode = @"
+class C
+{
+ void M()
+ {
+ C Func() => new();
+ }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithMethodExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C Func() => new [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ C Func() => new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithConversionExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ public static implicit operator C(int i) => new [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ public static implicit operator C(int i) => new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithOperatorExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ public static C operator +(C c1, C c2) => new [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ public static C operator +(C c1, C c2) => new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithPropertyExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C P => new [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ C P => new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithPropertyAccessorExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C P { get => new [|C|](); }
+}",
+ FixedCode = @"
+class C
+{
+ C P { get => new(); }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithPropertySetAccessorExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C P { set => new C(); }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithIndexerExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C this[int i] => new [|C|]();
+}",
+ FixedCode = @"
+class C
+{
+ C this[int i] => new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestWithIndexerAccessorExpressionBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C this[int i] { get => new [|C|](); }
+}",
+ FixedCode = @"
+class C
+{
+ C this[int i] { get => new(); }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotWithMethodBlockBody()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ C Func() { return new C(); }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotInNonApparentCode1()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ void X() => Bar(new C());
+ void Bar(C c) { }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestNotInNonApparentCode2()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+class C
+{
+ void X()
+ {
+ C c;
+ c = new C();
+ }
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestQualifiedUnqualified1()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+using System.Collections.Generic;
+class C
+{
+ List list = new [|System.Collections.Generic.List|]();
+}",
+ FixedCode = @"
+using System.Collections.Generic;
+class C
+{
+ List list = new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestQualifiedUnqualified2()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+using System.Collections.Generic;
+class C
+{
+ System.Collections.Generic.List list = new [|List|]();
+}",
+ FixedCode = @"
+using System.Collections.Generic;
+class C
+{
+ System.Collections.Generic.List list = new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestAlias()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+using System.Collections.Generic;
+using X = System.Collections.Generic.List;
+class C
+{
+ System.Collections.Generic.List list = new [|X|]();
+}",
+ FixedCode = @"
+using System.Collections.Generic;
+using X = System.Collections.Generic.List;
+class C
+{
+ System.Collections.Generic.List list = new();
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitObjectCreation)]
+ public async Task TestFixAll1()
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = @"
+using System;
+class C
+{
+ public C() { }
+ public C(Action action) { }
+
+ C c1 = new [|C|](() =>
+ {
+ C c2 = new [|C|]();
+ });
+}",
+ FixedCode = @"
+using System;
+class C
+{
+ public C() { }
+ public C(Action action) { }
+
+ C c1 = new(() =>
+ {
+ C c2 = new();
+ });
+}",
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9,
+ }.RunAsync();
+ }
+ }
+}
diff --git a/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs b/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs
index d278de0d9c790..164a035682dce 100644
--- a/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs
+++ b/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs
@@ -145,6 +145,8 @@ internal static class IDEDiagnosticIds
public const string UseNotPatternDiagnosticId = "IDE0083";
public const string UseIsNotExpressionDiagnosticId = "IDE0084";
+ public const string UseImplicitObjectCreationDiagnosticId = "IDE0090";
+
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
public const string AnalyzerDependencyConflictId = "IDE1002";
diff --git a/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs b/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
index f2c7682f5a78a..784c381fbf331 100644
--- a/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
+++ b/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
@@ -2784,5 +2784,31 @@ void local(int x, int y, int v)
}
");
}
+
+ [WorkItem(42559, "https://github.com/dotnet/roslyn/issues/42559")]
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
+ public async Task TestAddParameter_TargetTypedNew()
+ {
+ await TestInRegularAndScriptAsync(@"
+class C
+{
+ C(int i) { }
+
+ void M()
+ {
+ C c = [||]new(1, 2);
+ }
+}",
+@"
+class C
+{
+ C(int i, int v) { }
+
+ void M()
+ {
+ C c = new(1, 2);
+ }
+}");
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs
index ed899db3f6b76..a5297805fcbb4 100644
--- a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs
+++ b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs
@@ -13,7 +13,6 @@
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
-using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Remote.Testing;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
@@ -34,12 +33,12 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification
[Trait(Traits.Feature, Traits.Features.Classification)]
public class SemanticClassifierTests : AbstractCSharpClassifierTests
{
- protected override Task> GetClassificationSpansAsync(string code, TextSpan span, ParseOptions options, TestHost testHost)
+ protected override async Task> GetClassificationSpansAsync(string code, TextSpan span, ParseOptions options, TestHost testHost)
{
using var workspace = CreateWorkspace(code, options, testHost);
var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id);
- return GetSemanticClassificationsAsync(document, span);
+ return await GetSemanticClassificationsAsync(document, span);
}
[Theory]
diff --git a/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs
index cc60724ad5cd1..f3ae5a457e2c2 100644
--- a/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs
+++ b/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs
@@ -8,9 +8,7 @@
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
-using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Remote.Testing;
-using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
@@ -20,12 +18,12 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification
{
public partial class SyntacticClassifierTests : AbstractCSharpClassifierTests
{
- protected override Task> GetClassificationSpansAsync(string code, TextSpan span, ParseOptions options, TestHost testHost)
+ protected override async Task> GetClassificationSpansAsync(string code, TextSpan span, ParseOptions options, TestHost testHost)
{
using var workspace = CreateWorkspace(code, options, testHost);
var document = workspace.CurrentSolution.Projects.First().Documents.First();
- return GetSyntacticClassificationsAsync(document, span);
+ return await GetSyntacticClassificationsAsync(document, span);
}
[Theory]
diff --git a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs
index a7af23948433d..0526cfb383a93 100644
--- a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs
+++ b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs
@@ -19,12 +19,12 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification
[Trait(Traits.Feature, Traits.Features.Classification)]
public partial class TotalClassifierTests : AbstractCSharpClassifierTests
{
- protected override Task> GetClassificationSpansAsync(string code, TextSpan span, ParseOptions options, TestHost testHost)
+ protected override async Task> GetClassificationSpansAsync(string code, TextSpan span, ParseOptions options, TestHost testHost)
{
using var workspace = CreateWorkspace(code, options, testHost);
var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id);
- return GetAllClassificationsAsync(document, span);
+ return await GetAllClassificationsAsync(document, span);
}
[Theory]
diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OverrideCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OverrideCompletionProviderTests.cs
index 1777bbf145a2f..642e9136b131d 100644
--- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OverrideCompletionProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OverrideCompletionProviderTests.cs
@@ -4,6 +4,7 @@
using System;
using System.Linq;
+using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
@@ -3044,6 +3045,7 @@ public override bool Bar(Baz baz)
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
+ [WorkItem(47941, "https://github.com/dotnet/roslyn/issues/47941")]
public async Task OverrideInRecordWithoutExplicitOverriddenMember()
{
await VerifyItemExistsAsync(@"record Program
@@ -3053,6 +3055,7 @@ await VerifyItemExistsAsync(@"record Program
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
+ [WorkItem(47941, "https://github.com/dotnet/roslyn/issues/47941")]
public async Task OverrideInRecordWithExplicitOverriddenMember()
{
await VerifyItemIsAbsentAsync(@"record Program
@@ -3062,5 +3065,25 @@ await VerifyItemIsAbsentAsync(@"record Program
override $$
}", "ToString()");
}
+
+ [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
+ [WorkItem(47973, "https://github.com/dotnet/roslyn/issues/47973")]
+ public async Task NoCloneInOverriddenRecord()
+ {
+ // Currently WellKnownMemberNames.CloneMethodName is not public, so we can't reference it directly. We
+ // could hardcode in the value "$", however if the compiler ever changed the name and we somehow
+ // started showing it in completion, this test would continue to pass. So this allows us to at least go
+ // back and explicitly validate this scenario even in that event.
+ var cloneMemberName = (string)typeof(WellKnownMemberNames).GetField("CloneMethodName", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
+ Assert.Equal("$", cloneMemberName);
+
+ await VerifyItemIsAbsentAsync(@"
+record Base();
+
+record Program : Base
+{
+ override $$
+}", cloneMemberName);
+ }
}
}
diff --git a/src/EditorFeatures/Test/Diagnostics/IDEDiagnosticIDConfigurationTests.cs b/src/EditorFeatures/Test/Diagnostics/IDEDiagnosticIDConfigurationTests.cs
index 8195046306ba5..6e558e0c80946 100644
--- a/src/EditorFeatures/Test/Diagnostics/IDEDiagnosticIDConfigurationTests.cs
+++ b/src/EditorFeatures/Test/Diagnostics/IDEDiagnosticIDConfigurationTests.cs
@@ -397,6 +397,9 @@ public void CSharp_VerifyIDEDiagnosticSeveritiesAreConfigurable()
# IDE0083
csharp_style_prefer_not_pattern = true:suggestion
+# IDE0090
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
+
# IDE1005
csharp_style_conditional_delegate_call = true:suggestion
@@ -942,6 +945,9 @@ No editorconfig based code style option
# IDE0083, PreferNotPattern
csharp_style_prefer_not_pattern = true:suggestion
+# IDE0090, ImplicitObjectCreationWhenTypeIsApparent
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
+
# IDE1005, PreferConditionalDelegateCall
csharp_style_conditional_delegate_call = true:suggestion
diff --git a/src/EditorFeatures/VisualBasicTest/Classification/SemanticClassifierTests.vb b/src/EditorFeatures/VisualBasicTest/Classification/SemanticClassifierTests.vb
index 14d9a917110b9..073776aead0e6 100644
--- a/src/EditorFeatures/VisualBasicTest/Classification/SemanticClassifierTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/Classification/SemanticClassifierTests.vb
@@ -5,7 +5,6 @@
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.Classification
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications
-Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Remote.Testing
Imports Microsoft.CodeAnalysis.Text
@@ -14,11 +13,11 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Classification
Public Class SemanticClassifierTests
Inherits AbstractVisualBasicClassifierTests
- Protected Overrides Function GetClassificationSpansAsync(code As String, span As TextSpan, parseOptions As ParseOptions, testHost As TestHost) As Task(Of ImmutableArray(Of ClassifiedSpan))
+ Protected Overrides Async Function GetClassificationSpansAsync(code As String, span As TextSpan, parseOptions As ParseOptions, testHost As TestHost) As Task(Of ImmutableArray(Of ClassifiedSpan))
Using workspace = CreateWorkspace(code, testHost)
Dim document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id)
- Return GetSemanticClassificationsAsync(document, span)
+ Return Await GetSemanticClassificationsAsync(document, span)
End Using
End Function
diff --git a/src/EditorFeatures/VisualBasicTest/Classification/SyntacticClassifierTests.vb b/src/EditorFeatures/VisualBasicTest/Classification/SyntacticClassifierTests.vb
index b0bba682e0bf6..d1bac7587e3de 100644
--- a/src/EditorFeatures/VisualBasicTest/Classification/SyntacticClassifierTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/Classification/SyntacticClassifierTests.vb
@@ -13,10 +13,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Classification
Public Class SyntacticClassifierTests
Inherits AbstractVisualBasicClassifierTests
- Protected Overrides Function GetClassificationSpansAsync(code As String, span As TextSpan, parseOptions As ParseOptions, testHost As TestHost) As Task(Of ImmutableArray(Of ClassifiedSpan))
+ Protected Overrides Async Function GetClassificationSpansAsync(code As String, span As TextSpan, parseOptions As ParseOptions, testHost As TestHost) As Task(Of ImmutableArray(Of ClassifiedSpan))
Using workspace = CreateWorkspace(code, testHost)
Dim document = workspace.CurrentSolution.Projects.First().Documents.First()
- Return GetSyntacticClassificationsAsync(document, span)
+ Return Await GetSyntacticClassificationsAsync(document, span)
End Using
End Function
diff --git a/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs b/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs
index 5932f2488cc89..3c8dffa24af66 100644
--- a/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs
+++ b/src/Features/CSharp/Portable/AddParameter/CSharpAddParameterCodeFixProvider.cs
@@ -23,7 +23,7 @@ internal class CSharpAddParameterCodeFixProvider : AbstractAddParameterCodeFixPr
ArgumentListSyntax,
AttributeArgumentListSyntax,
InvocationExpressionSyntax,
- ObjectCreationExpressionSyntax>
+ BaseObjectCreationExpressionSyntax>
{
private const string CS1501 = nameof(CS1501); // error CS1501: No overload for method 'M' takes 1 arguments
diff --git a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs
index 216146fef2753..96a83511489b2 100644
--- a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs
+++ b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs
@@ -140,15 +140,25 @@ private static RegisterFixData TryGetObjectCreationFixInfo(
{
// Not supported if this is "new { ... }" (as there are no parameters at all.
- var typeNode = syntaxFacts.GetObjectCreationType(objectCreation);
+ var typeNode = syntaxFacts.IsImplicitObjectCreationExpression(node)
+ ? node
+ : syntaxFacts.GetObjectCreationType(objectCreation);
if (typeNode == null)
{
return new RegisterFixData();
}
+ var symbol = semanticModel.GetSymbolInfo(typeNode, cancellationToken).GetAnySymbol();
+ var type = symbol switch
+ {
+ IMethodSymbol methodSymbol => methodSymbol.ContainingType, // Implicit object creation expressions
+ INamedTypeSymbol namedTypeSymbol => namedTypeSymbol, // Standard object creation expressions
+ _ => null,
+ };
+
// If we can't figure out the type being created, or the type isn't in source,
// then there's nothing we can do.
- if (!(semanticModel.GetSymbolInfo(typeNode, cancellationToken).GetAnySymbol() is INamedTypeSymbol type))
+ if (type == null)
{
return new RegisterFixData();
}
diff --git a/src/Test/Utilities/Portable/Traits/Traits.cs b/src/Test/Utilities/Portable/Traits/Traits.cs
index cc5e92b61e5ed..c7983b5117811 100644
--- a/src/Test/Utilities/Portable/Traits/Traits.cs
+++ b/src/Test/Utilities/Portable/Traits/Traits.cs
@@ -178,6 +178,7 @@ public static class Features
public const string CodeActionsUseExplicitTypeForConst = "CodeActions.UseExplicitTypeForConst";
public const string CodeActionsUseExpressionBody = "CodeActions.UseExpressionBody";
public const string CodeActionsUseFrameworkType = "CodeActions.UseFrameworkType";
+ public const string CodeActionsUseImplicitObjectCreation = "CodeActions.UseImplicitObjectCreation";
public const string CodeActionsUseImplicitType = "CodeActions.UseImplicitType";
public const string CodeActionsUseIndexOperator = "CodeActions.UseIndexOperator";
public const string CodeActionsUseInferredMemberName = "CodeActions.UseInferredMemberName";
diff --git a/src/Tools/Source/RunTests/AssemblyScheduler.cs b/src/Tools/Source/RunTests/AssemblyScheduler.cs
index 35c7c4fdd8f26..adbdba3ec4698 100644
--- a/src/Tools/Source/RunTests/AssemblyScheduler.cs
+++ b/src/Tools/Source/RunTests/AssemblyScheduler.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -10,7 +9,6 @@
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
-using System.Threading.Tasks;
namespace RunTests
{
@@ -33,12 +31,12 @@ internal AssemblyInfo(
ExtraArguments = extraArguments;
}
- internal AssemblyInfo(string assemblyPath, string targetFrameworkMoniker, string architecture, bool useHmtl)
+ internal AssemblyInfo(string assemblyPath, string targetFrameworkMoniker, string architecture, bool includeHtml)
{
AssemblyPath = assemblyPath;
DisplayName = Path.GetFileName(assemblyPath);
- var suffix = useHmtl ? "html" : "xml";
+ var suffix = includeHtml ? "html" : "xml";
ResultsFileName = $"{DisplayName}_{targetFrameworkMoniker}_{architecture}.{suffix}";
ExtraArguments = string.Empty;
}
@@ -91,23 +89,23 @@ private sealed class AssemblyInfoBuilder
private readonly StringBuilder _builder = new StringBuilder();
private readonly string _assemblyPath;
private readonly int _methodLimit;
- private readonly bool _useHtml;
+ private readonly bool _includeHtml;
private readonly bool _hasEventListenerGuard;
private int _currentId;
private List _currentTypeInfoList = new List();
- private AssemblyInfoBuilder(string assemblyPath, int methodLimit, bool useHtml, bool hasEventListenerGuard)
+ private AssemblyInfoBuilder(string assemblyPath, int methodLimit, bool includeHtml, bool hasEventListenerGuard)
{
_assemblyPath = assemblyPath;
- _useHtml = useHtml;
+ _includeHtml = includeHtml;
_methodLimit = methodLimit;
_hasEventListenerGuard = hasEventListenerGuard;
}
- internal static void Build(string assemblyPath, int methodLimit, bool useHtml, List typeInfoList, out List partitionList, out List assemblyInfoList)
+ internal static void Build(string assemblyPath, int methodLimit, bool includeHtml, List typeInfoList, out List partitionList, out List assemblyInfoList)
{
var hasEventListenerGuard = typeInfoList.Any(x => x.FullName == EventListenerGuardFullName);
- var builder = new AssemblyInfoBuilder(assemblyPath, methodLimit, useHtml, hasEventListenerGuard);
+ var builder = new AssemblyInfoBuilder(assemblyPath, methodLimit, includeHtml, hasEventListenerGuard);
builder.Build(typeInfoList);
partitionList = builder._partitionList;
assemblyInfoList = builder._assemblyInfoList;
@@ -169,7 +167,7 @@ private void FinishPartition()
{
var assemblyName = Path.GetFileName(_assemblyPath);
var displayName = $"{assemblyName}.{_currentId}";
- var suffix = _useHtml ? "html" : "xml";
+ var suffix = _includeHtml ? "html" : "xml";
var resultsFileName = $"{assemblyName}.{_currentId}.{suffix}";
var assemblyInfo = new AssemblyInfo(
_assemblyPath,
@@ -206,7 +204,7 @@ public IEnumerable Schedule(string assemblyPath, bool force = fals
var typeInfoList = GetTypeInfoList(assemblyPath);
var assemblyInfoList = new List();
var partitionList = new List();
- AssemblyInfoBuilder.Build(assemblyPath, _methodLimit, _options.UseHtml, typeInfoList, out partitionList, out assemblyInfoList);
+ AssemblyInfoBuilder.Build(assemblyPath, _methodLimit, _options.IncludeHtml, typeInfoList, out partitionList, out assemblyInfoList);
// If the scheduling didn't actually produce multiple partition then send back an unpartitioned
// representation.
@@ -233,7 +231,7 @@ public IEnumerable Schedule(string assemblyPath, bool force = fals
public AssemblyInfo CreateAssemblyInfo(string assemblyPath)
{
- return new AssemblyInfo(assemblyPath, _options.TargetFrameworkMoniker, _options.Test64 ? "x64" : "x86", _options.UseHtml);
+ return new AssemblyInfo(assemblyPath, _options.TargetFrameworkMoniker, _options.Test64 ? "x64" : "x86", _options.IncludeHtml);
}
private static List GetTypeInfoList(string assemblyPath)
diff --git a/src/Tools/Source/RunTests/ITestExecutor.cs b/src/Tools/Source/RunTests/ITestExecutor.cs
index fd5e99afef7cc..da5838f7848a4 100644
--- a/src/Tools/Source/RunTests/ITestExecutor.cs
+++ b/src/Tools/Source/RunTests/ITestExecutor.cs
@@ -15,18 +15,18 @@ internal readonly struct TestExecutionOptions
internal string OutputDirectory { get; }
internal string Trait { get; }
internal string NoTrait { get; }
- internal bool UseHtml { get; }
+ internal bool IncludeHtml { get; }
internal bool Test64 { get; }
internal bool TestVsi { get; }
- internal TestExecutionOptions(string xunitPath, ProcDumpInfo? procDumpInfo, string outputDirectory, string trait, string noTrait, bool useHtml, bool test64, bool testVsi)
+ internal TestExecutionOptions(string xunitPath, ProcDumpInfo? procDumpInfo, string outputDirectory, string trait, string noTrait, bool includeHtml, bool test64, bool testVsi)
{
XunitPath = xunitPath;
ProcDumpInfo = procDumpInfo;
OutputDirectory = outputDirectory;
Trait = trait;
NoTrait = noTrait;
- UseHtml = useHtml;
+ IncludeHtml = includeHtml;
Test64 = test64;
TestVsi = testVsi;
}
diff --git a/src/Tools/Source/RunTests/Options.cs b/src/Tools/Source/RunTests/Options.cs
index 11b10e572f7a3..0442b45435b45 100644
--- a/src/Tools/Source/RunTests/Options.cs
+++ b/src/Tools/Source/RunTests/Options.cs
@@ -23,7 +23,7 @@ internal class Options
///
/// Use HTML output files.
///
- public bool UseHtml { get; set; }
+ public bool IncludeHtml { get; set; }
///
/// Use the 64 bit test runner.
@@ -119,7 +119,7 @@ bool isOption(string argument, string optionName, out string value)
return false;
}
- var opt = new Options { XunitPath = args[0], UseHtml = true, TestResultXmlOutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TestResults") };
+ var opt = new Options { XunitPath = args[0], IncludeHtml = true, TestResultXmlOutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TestResults") };
var index = 1;
var allGood = true;
while (index < args.Length)
@@ -137,7 +137,7 @@ bool isOption(string argument, string optionName, out string value)
}
else if (comparer.Equals(current, "-xml"))
{
- opt.UseHtml = false;
+ opt.IncludeHtml = false;
index++;
}
else if (isOption(current, "-tfm", out string targetFrameworkMoniker))
diff --git a/src/Tools/Source/RunTests/ProcessTestExecutor.cs b/src/Tools/Source/RunTests/ProcessTestExecutor.cs
index bc42d74fe8af2..cfe35995f65d0 100644
--- a/src/Tools/Source/RunTests/ProcessTestExecutor.cs
+++ b/src/Tools/Source/RunTests/ProcessTestExecutor.cs
@@ -32,11 +32,17 @@ public string GetCommandLineArguments(AssemblyInfo assemblyInfo)
{
var assemblyName = Path.GetFileName(assemblyInfo.AssemblyPath);
var resultsFilePath = GetResultsFilePath(assemblyInfo);
+ var xmlResultsFilePath = Path.ChangeExtension(resultsFilePath, ".xml");
+ var htmlResultsFilePath = Path.ChangeExtension(resultsFilePath, ".html");
var builder = new StringBuilder();
builder.AppendFormat(@"""{0}""", assemblyInfo.AssemblyPath);
builder.AppendFormat(@" {0}", assemblyInfo.ExtraArguments);
- builder.AppendFormat(@" -{0} ""{1}""", Options.UseHtml ? "html" : "xml", resultsFilePath);
+ builder.AppendFormat($@" -xml ""{xmlResultsFilePath}""");
+
+ if (Options.IncludeHtml)
+ builder.AppendFormat($@" -html ""{htmlResultsFilePath}""");
+
builder.Append(" -noshadow -verbose");
if (!string.IsNullOrWhiteSpace(Options.Trait))
@@ -70,7 +76,7 @@ public async Task RunTestAsync(AssemblyInfo assemblyInfo, Cancellati
var result = await RunTestAsyncInternal(assemblyInfo, retry: false, cancellationToken);
// For integration tests (TestVsi), we make one more attempt to re-run failed tests.
- if (Options.TestVsi && !Options.UseHtml && !result.Succeeded)
+ if (Options.TestVsi && !Options.IncludeHtml && !result.Succeeded)
{
return await RunTestAsyncInternal(assemblyInfo, retry: true, cancellationToken);
}
diff --git a/src/Tools/Source/RunTests/Program.cs b/src/Tools/Source/RunTests/Program.cs
index f1cafabc69808..a96a6c7289f2a 100644
--- a/src/Tools/Source/RunTests/Program.cs
+++ b/src/Tools/Source/RunTests/Program.cs
@@ -328,7 +328,7 @@ private static ProcessTestExecutor CreateTestExecutor(Options options)
outputDirectory: options.TestResultXmlOutputDirectory,
trait: options.Trait,
noTrait: options.NoTrait,
- useHtml: options.UseHtml,
+ includeHtml: options.IncludeHtml,
test64: options.Test64,
testVsi: options.TestVsi);
return new ProcessTestExecutor(testExecutionOptions);
diff --git a/src/Tools/Source/RunTests/TestRunner.cs b/src/Tools/Source/RunTests/TestRunner.cs
index 4f1ef1a0579d4..1fce3fa637aab 100644
--- a/src/Tools/Source/RunTests/TestRunner.cs
+++ b/src/Tools/Source/RunTests/TestRunner.cs
@@ -175,7 +175,7 @@ private void PrintFailedTestResult(TestResult testResult)
}
// If the results are html, use Process.Start to open in the browser.
- if (_options.UseHtml && !string.IsNullOrEmpty(testResult.ResultsFilePath))
+ if (_options.IncludeHtml && !string.IsNullOrEmpty(testResult.ResultsFilePath))
{
Process.Start(testResult.ResultsFilePath);
}
diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx
index 03b35c3d36437..baebad55c8450 100644
--- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx
+++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx
@@ -620,4 +620,7 @@
Edit color scheme
+
+ Prefer implicit object creation when type is apparent
+
\ No newline at end of file
diff --git a/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs b/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs
index e3126ad83364f..16c734fd652c4 100644
--- a/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs
+++ b/src/VisualStudio/CSharp/Impl/Options/Formatting/StyleViewModel.cs
@@ -967,6 +967,22 @@ void M2(int value)
//]
}}
}}
+";
+
+ private static readonly string s_preferImplicitObjectCreationWhenTypeIsApparent = $@"
+using System.Collections.Generic;
+class Order {{}}
+
+//[
+class Customer
+{{
+ // {ServicesVSResources.Prefer_colon}
+ private readonly List orders = new();
+
+ // {ServicesVSResources.Over_colon}
+ private readonly List orders = new List();
+}}
+//]
";
private static readonly string s_preferIndexOperator = $@"
@@ -1738,6 +1754,7 @@ internal StyleViewModel(OptionStore optionStore, IServiceProvider serviceProvide
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CodeStyleOptions2.PreferInferredAnonymousTypeMemberNames, ServicesVSResources.Prefer_inferred_anonymous_type_member_names, s_preferInferredAnonymousTypeMemberName, s_preferInferredAnonymousTypeMemberName, this, optionStore, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferLocalOverAnonymousFunction, ServicesVSResources.Prefer_local_function_over_anonymous_function, s_preferLocalFunctionOverAnonymousFunction, s_preferLocalFunctionOverAnonymousFunction, this, optionStore, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CodeStyleOptions2.PreferCompoundAssignment, ServicesVSResources.Prefer_compound_assignments, s_preferCompoundAssignments, s_preferCompoundAssignments, this, optionStore, expressionPreferencesGroupTitle));
+ CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent, CSharpVSResources.Prefer_implicit_object_creation_when_type_is_apparent, s_preferImplicitObjectCreationWhenTypeIsApparent, s_preferImplicitObjectCreationWhenTypeIsApparent, this, optionStore, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferIndexOperator, ServicesVSResources.Prefer_index_operator, s_preferIndexOperator, s_preferIndexOperator, this, optionStore, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferRangeOperator, ServicesVSResources.Prefer_range_operator, s_preferRangeOperator, s_preferRangeOperator, this, optionStore, expressionPreferencesGroupTitle));
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf
index ff0359160c483..63dae0e011360 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.cs.xlf
@@ -82,6 +82,11 @@
Při formátování provést dodatečné vyčištění kódu
+
+
+ Prefer implicit object creation when type is apparent
+
+
U kontrol rovnosti odkazů dávat přednost možnosti is null
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf
index 98ddb6af57529..16fe049106877 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.de.xlf
@@ -82,6 +82,11 @@
Zusätzliche Codebereinigung während der Formatierung durchführen
+
+
+ Prefer implicit object creation when type is apparent
+
+
"is null" für Verweisübereinstimmungsprüfungen vorziehen
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf
index 10987923c4d52..9e8d8ac940545 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.es.xlf
@@ -82,6 +82,11 @@
Realizar limpieza de código adicional durante la aplicación de formato
+
+
+ Prefer implicit object creation when type is apparent
+
+
Preferir “is null” para comprobaciones de igualdad de referencias
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf
index 69c632775c6c4..e8a904f712ec1 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.fr.xlf
@@ -82,6 +82,11 @@
Effectuer un nettoyage supplémentaire du code pendant la mise en forme
+
+
+ Prefer implicit object creation when type is apparent
+
+
Préférer 'is nul' pour les vérifications d'égalité de référence
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf
index f8c7239ba7db8..be58d03e46eeb 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.it.xlf
@@ -82,6 +82,11 @@
Esegui la pulizia del codice aggiuntiva durante la formattazione
+
+
+ Prefer implicit object creation when type is apparent
+
+
Preferisci 'is null' per i controlli di uguaglianza dei riferimenti
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf
index 9aa52084bf0e1..4b0b935e9e16a 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ja.xlf
@@ -82,6 +82,11 @@
書式設定中に追加のコード クリーンアップを実行
+
+
+ Prefer implicit object creation when type is apparent
+
+
参照の等値性のチェックには 'is null' を優先する
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf
index db3dd360fad3b..4e96246d5f5e5 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ko.xlf
@@ -82,6 +82,11 @@
서식을 지정하는 동안 추가 코드 정리 수행
+
+
+ Prefer implicit object creation when type is apparent
+
+
참조 같음 검사에 대해 'is null' 선호
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf
index 3f6ee507fca9e..7c085f06727a2 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pl.xlf
@@ -82,6 +82,11 @@
Wykonaj dodatkowe oczyszczanie kodu podczas formatowania
+
+
+ Prefer implicit object creation when type is apparent
+
+
Preferuj wyrażenie „is null” w przypadku sprawdzeń odwołań pod kątem równości
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf
index 16a536953ff10..990f0b01a69f0 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.pt-BR.xlf
@@ -82,6 +82,11 @@
Executar limpeza de código adicional durante a formatação
+
+
+ Prefer implicit object creation when type is apparent
+
+
Preferir 'is null' para as verificações de igualdade de referência
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf
index aa039559bb492..82d39d253fe19 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.ru.xlf
@@ -82,6 +82,11 @@
Выполнять при форматировании дополнительную очистку кода
+
+
+ Prefer implicit object creation when type is apparent
+
+
Использовать "is null" вместо проверки ссылок на равенство.
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf
index a42221783ec7d..6c70f26709939 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.tr.xlf
@@ -82,6 +82,11 @@
Biçimlendirme sırasında ek kod temizleme gerçekleştir
+
+
+ Prefer implicit object creation when type is apparent
+
+
Başvuru eşitliği denetimleri için 'is null'ı tercih et
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf
index 60103c6903375..368bf4bb5256f 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hans.xlf
@@ -82,6 +82,11 @@
在格式设置期间执行其他代码清理
+
+
+ Prefer implicit object creation when type is apparent
+
+
引用相等检查偏好 “is null”
diff --git a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf
index 79361ea63e4cf..f45976f52134d 100644
--- a/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf
+++ b/src/VisualStudio/CSharp/Impl/xlf/CSharpVSResources.zh-Hant.xlf
@@ -82,6 +82,11 @@
在格式化期間執行額外程式碼清除
+
+
+ Prefer implicit object creation when type is apparent
+
+
參考相等檢查最好使用 'is null'
diff --git a/src/VisualStudio/Core/Test/Options/CSharpEditorConfigGeneratorTests.vb b/src/VisualStudio/Core/Test/Options/CSharpEditorConfigGeneratorTests.vb
index c380fc6f31c8d..3bb326feab75f 100644
--- a/src/VisualStudio/Core/Test/Options/CSharpEditorConfigGeneratorTests.vb
+++ b/src/VisualStudio/Core/Test/Options/CSharpEditorConfigGeneratorTests.vb
@@ -124,6 +124,7 @@ csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
@@ -342,6 +343,7 @@ csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
diff --git a/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj b/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj
index 09ac561e3492c..4a71e48c8a974 100644
--- a/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj
+++ b/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj
@@ -4,7 +4,7 @@
Library
Microsoft.CodeAnalysis.CSharp.UnitTests
- net472
+ netcoreapp3.1;net472
@@ -25,18 +25,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Workspaces/CoreTest/BatchFixAllProviderTests.cs b/src/Workspaces/CoreTest/BatchFixAllProviderTests.cs
index 7820ad8cf5f56..df5e4e2323ce4 100644
--- a/src/Workspaces/CoreTest/BatchFixAllProviderTests.cs
+++ b/src/Workspaces/CoreTest/BatchFixAllProviderTests.cs
@@ -105,11 +105,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
if (_nested)
{
-#if NETCOREAPP2_0 || NET472
fixes = new List { CodeAction.Create("Container", fixes.ToImmutableArray(), isInlinable: false) };
-#else
- throw new NotSupportedException("Nested code actions are not supported on this framework.");
-#endif
}
foreach (var fix in fixes)
diff --git a/src/Workspaces/CoreTest/CodeCleanup/ReduceTokenTests.cs b/src/Workspaces/CoreTest/CodeCleanup/ReduceTokenTests.cs
index d79c64f68eac0..b41574b0f2e9f 100644
--- a/src/Workspaces/CoreTest/CodeCleanup/ReduceTokenTests.cs
+++ b/src/Workspaces/CoreTest/CodeCleanup/ReduceTokenTests.cs
@@ -18,6 +18,12 @@ namespace Microsoft.CodeAnalysis.UnitTests.CodeCleanup
[UseExportProvider]
public class ReduceTokenTests
{
+#if NETCOREAPP
+ private static bool IsNetCoreApp => true;
+#else
+ private static bool IsNetCoreApp => false;
+#endif
+
[Fact]
[WorkItem(5529, "DevDiv_Projects/Roslyn")]
[Trait(Traits.Feature, Traits.Features.ReduceTokens)]
@@ -225,23 +231,23 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 2: 8 significant digits
' Dev11 and Roslyn behavior are identical: Always rounded off and pretty listed to <= 9 significant digits
Const f_8_1 As Single = 0.14999795F ' Dev11 & Roslyn: 0.14999795F
- Const f_8_2 As Single = 0.149997965F ' Dev11 & Roslyn: 0.149997965F
+ Const f_8_2 As Single = {(IsNetCoreApp ? "0.14999796F" : "0.149997965F")} ' Dev11 & Roslyn: 0.149997965F
Const f_8_3 As Single = 0.1499797F ' Dev11 & Roslyn: Unchanged
- Const f_8_4 As Single = 1.49997938F ' Dev11 & Roslyn: 1.49997938F
- Const f_8_5 As Single = 1.49997973F ' Dev11 & Roslyn: 1.49997973F
+ Const f_8_4 As Single = {(IsNetCoreApp ? "1.4999794F" : "1.49997938F")} ' Dev11 & Roslyn: 1.49997938F
+ Const f_8_5 As Single = {(IsNetCoreApp ? "1.4999797F" : "1.49997973F")} ' Dev11 & Roslyn: 1.49997973F
- Const f_8_6 As Single = 1499.97937F ' Dev11 & Roslyn: 1499.97937F
+ Const f_8_6 As Single = {(IsNetCoreApp ? "1499.9794F" : "1499.97937F")} ' Dev11 & Roslyn: 1499.97937F
- Const f_8_7 As Single = 1499979.75F ' Dev11 & Roslyn: 1499979.75F
+ Const f_8_7 As Single = {(IsNetCoreApp ? "1499979.8F" : "1499979.75F")} ' Dev11 & Roslyn: 1499979.75F
Const f_8_8 As Single = 14999797.0F ' Dev11 & Roslyn: unchanged
@@ -296,23 +302,23 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 2: 8 significant digits
' Dev11 and Roslyn behavior are identical: Always rounded off and pretty listed to <= 9 significant digits
Const f_8_1 As Single = 0.14999795! ' Dev11 & Roslyn: 0.14999795F
- Const f_8_2 As Single = 0.149997965! ' Dev11 & Roslyn: 0.149997965F
+ Const f_8_2 As Single = {(IsNetCoreApp ? "0.14999796!" : "0.149997965!")} ' Dev11 & Roslyn: 0.149997965F
Const f_8_3 As Single = 0.1499797! ' Dev11 & Roslyn: Unchanged
- Const f_8_4 As Single = 1.49997938! ' Dev11 & Roslyn: 1.49997938F
- Const f_8_5 As Single = 1.49997973! ' Dev11 & Roslyn: 1.49997973F
+ Const f_8_4 As Single = {(IsNetCoreApp ? "1.4999794!" : "1.49997938!")} ' Dev11 & Roslyn: 1.49997938F
+ Const f_8_5 As Single = {(IsNetCoreApp ? "1.4999797!" : "1.49997973!")} ' Dev11 & Roslyn: 1.49997973F
- Const f_8_6 As Single = 1499.97937! ' Dev11 & Roslyn: 1499.97937F
+ Const f_8_6 As Single = {(IsNetCoreApp ? "1499.9794!" : "1499.97937!")} ' Dev11 & Roslyn: 1499.97937F
- Const f_8_7 As Single = 1499979.75! ' Dev11 & Roslyn: 1499979.75F
+ Const f_8_7 As Single = {(IsNetCoreApp ? "1499979.8!" : "1499979.75!")} ' Dev11 & Roslyn: 1499979.75F
Const f_8_8 As Single = 14999797.0! ' Dev11 & Roslyn: unchanged
@@ -379,24 +385,24 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 3: > 8 significant digits
' Dev11 and Roslyn behavior are identical: Always rounded off and pretty listed to <= 9 significant digits
' (a) > 8 significant digits overall, but < 8 digits before decimal point.
- Const f_9_1 As Single = 0.149997935F ' Dev11 & Roslyn: 0.149997935F
- Const f_9_2 As Single = 0.149997935F ' Dev11 & Roslyn: 0.149997935F
- Const f_9_3 As Single = 1.49997962F ' Dev11 & Roslyn: 1.49997962F
+ Const f_9_1 As Single = {(IsNetCoreApp ? "0.14999793F" : "0.149997935F")} ' Dev11 & Roslyn: 0.149997935F
+ Const f_9_2 As Single = {(IsNetCoreApp ? "0.14999793F" : "0.149997935F")} ' Dev11 & Roslyn: 0.149997935F
+ Const f_9_3 As Single = {(IsNetCoreApp ? "1.4999796F" : "1.49997962F")} ' Dev11 & Roslyn: 1.49997962F
- Const f_10_1 As Single = 14999.7969F ' Dev11 & Roslyn: 14999.7969F
+ Const f_10_1 As Single = {(IsNetCoreApp ? "14999.797F" : "14999.7969F")} ' Dev11 & Roslyn: 14999.7969F
' (b) > 8 significant digits before decimal point.
- Const f_10_2 As Single = 149997968.0F ' Dev11 & Roslyn: 149997968.0F
- Const f_10_3 As Single = 1.49997965E+9F ' Dev11 & Roslyn: 1.49997965E+9F
+ Const f_10_2 As Single = {(IsNetCoreApp ? "149997970.0F" : "149997968.0F")} ' Dev11 & Roslyn: 149997968.0F
+ Const f_10_3 As Single = {(IsNetCoreApp ? "1.4999796E+9F" : "1.49997965E+9F")} ' Dev11 & Roslyn: 1.49997965E+9F
- Const f_24_1 As Single = 1.11111148E+20F ' Dev11 & Roslyn: 1.11111148E+20F
+ Const f_24_1 As Single = {(IsNetCoreApp ? "1.1111115E+20F" : "1.11111148E+20F")} ' Dev11 & Roslyn: 1.11111148E+20F
' (c) Overflow/Underflow cases for Single: Ensure no pretty listing/round off
' Holds signed IEEE 32-bit (4-byte) single-precision floating-point numbers ranging in value from -3.4028235E+38 through -1.401298E-45 for negative values and
@@ -474,24 +480,24 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 3: > 8 significant digits
' Dev11 and Roslyn behavior are identical: Always rounded off and pretty listed to <= 9 significant digits
' (a) > 8 significant digits overall, but < 8 digits before decimal point.
- Const f_9_1 As Single = 0.149997935! ' Dev11 & Roslyn: 0.149997935F
- Const f_9_2 As Single = 0.149997935! ' Dev11 & Roslyn: 0.149997935F
- Const f_9_3 As Single = 1.49997962! ' Dev11 & Roslyn: 1.49997962F
+ Const f_9_1 As Single = {(IsNetCoreApp ? "0.14999793!" : "0.149997935!")} ' Dev11 & Roslyn: 0.149997935F
+ Const f_9_2 As Single = {(IsNetCoreApp ? "0.14999793!" : "0.149997935!")} ' Dev11 & Roslyn: 0.149997935F
+ Const f_9_3 As Single = {(IsNetCoreApp ? "1.4999796!" : "1.49997962!")} ' Dev11 & Roslyn: 1.49997962F
- Const f_10_1 As Single = 14999.7969! ' Dev11 & Roslyn: 14999.7969F
+ Const f_10_1 As Single = {(IsNetCoreApp ? "14999.797!" : "14999.7969!")} ' Dev11 & Roslyn: 14999.7969F
' (b) > 8 significant digits before decimal point.
- Const f_10_2 As Single = 149997968.0! ' Dev11 & Roslyn: 149997968.0F
- Const f_10_3 As Single = 1.49997965E+9! ' Dev11 & Roslyn: 1.49997965E+9F
+ Const f_10_2 As Single = {(IsNetCoreApp ? "149997970.0!" : "149997968.0!")} ' Dev11 & Roslyn: 149997968.0F
+ Const f_10_3 As Single = {(IsNetCoreApp ? "1.4999796E+9!" : "1.49997965E+9!")} ' Dev11 & Roslyn: 1.49997965E+9F
- Const f_24_1 As Single = 1.11111148E+20! ' Dev11 & Roslyn: 1.11111148E+20F
+ Const f_24_1 As Single = {(IsNetCoreApp ? "1.1111115E+20!" : "1.11111148E+20!")} ' Dev11 & Roslyn: 1.11111148E+20F
' (c) Overflow/Underflow cases for Single: Ensure no pretty listing/round off
' Holds signed IEEE 32-bit (4-byte) single-precision floating-point numbers ranging in value from -3.4028235E+38 through -1.401298E-45 for negative values and
@@ -731,25 +737,25 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 2: 16 significant digits
' Dev11 and Roslyn behavior are identical: Always rounded off and pretty listed to <= 17 significant digits
Const f_16_1 As Double = 0.1499999999799993 ' Dev11 & Roslyn: 0.1499999999799993
- Const f_16_2 As Double = 0.14999999997999969 ' Dev11 & Roslyn: 0.14999999997999969
+ Const f_16_2 As Double = {(IsNetCoreApp ? "0.1499999999799997" : "0.14999999997999969")} ' Dev11 & Roslyn: 0.14999999997999969
Const f_16_3 As Double = 0.149999999799995 ' Dev11 & Roslyn: Unchanged
Const f_16_4 As Double = 1.499999999799994 ' Dev11 & Roslyn: Unchanged
- Const f_16_5 As Double = 1.4999999997999951 ' Dev11 & Roslyn: 1.4999999997999951
+ Const f_16_5 As Double = {(IsNetCoreApp ? "1.499999999799995" : "1.4999999997999951")} ' Dev11 & Roslyn: 1.4999999997999951
Const f_16_6 As Double = 14999999.99799994 ' Dev11 & Roslyn: Unchanged
- Const f_16_7 As Double = 14999999.997999949 ' Dev11 & Roslyn: 14999999.997999949
+ Const f_16_7 As Double = {(IsNetCoreApp ? "14999999.99799995" : "14999999.997999949")} ' Dev11 & Roslyn: 14999999.997999949
- Const f_16_8 As Double = 149999999997999.19 ' Dev11 & Roslyn: 149999999997999.19
- Const f_16_9 As Double = 149999999997999.81 ' Dev11 & Roslyn: 149999999997999.81
+ Const f_16_8 As Double = {(IsNetCoreApp ? "149999999997999.2" : "149999999997999.19")} ' Dev11 & Roslyn: 149999999997999.19
+ Const f_16_9 As Double = {(IsNetCoreApp ? "149999999997999.8" : "149999999997999.81")} ' Dev11 & Roslyn: 149999999997999.81
Const f_16_10 As Double = 1499999999979995.0 ' Dev11 & Roslyn: Unchanged
@@ -810,25 +816,25 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 2: 16 significant digits
' Dev11 and Roslyn behavior are identical: Always rounded off and pretty listed to <= 17 significant digits
Const f_16_1 As Double = 0.1499999999799993R ' Dev11 & Roslyn: 0.1499999999799993
- Const f_16_2 As Double = 0.14999999997999969R ' Dev11 & Roslyn: 0.14999999997999969
+ Const f_16_2 As Double = {(IsNetCoreApp ? "0.1499999999799997R" : "0.14999999997999969R")} ' Dev11 & Roslyn: 0.14999999997999969
Const f_16_3 As Double = 0.149999999799995# ' Dev11 & Roslyn: Unchanged
Const f_16_4 As Double = 1.499999999799994R ' Dev11 & Roslyn: Unchanged
- Const f_16_5 As Double = 1.4999999997999951R ' Dev11 & Roslyn: 1.4999999997999951
+ Const f_16_5 As Double = {(IsNetCoreApp ? "1.499999999799995R" : "1.4999999997999951R")} ' Dev11 & Roslyn: 1.4999999997999951
Const f_16_6 As Double = 14999999.99799994# ' Dev11 & Roslyn: Unchanged
- Const f_16_7 As Double = 14999999.997999949R ' Dev11 & Roslyn: 14999999.997999949
+ Const f_16_7 As Double = {(IsNetCoreApp ? "14999999.99799995R" : "14999999.997999949R")} ' Dev11 & Roslyn: 14999999.997999949
- Const f_16_8 As Double = 149999999997999.19R ' Dev11 & Roslyn: 149999999997999.19
- Const f_16_9 As Double = 149999999997999.81# ' Dev11 & Roslyn: 149999999997999.81
+ Const f_16_8 As Double = {(IsNetCoreApp ? "149999999997999.2R" : "149999999997999.19R")} ' Dev11 & Roslyn: 149999999997999.19
+ Const f_16_9 As Double = {(IsNetCoreApp ? "149999999997999.8#" : "149999999997999.81#")} ' Dev11 & Roslyn: 149999999997999.81
Const f_16_10 As Double = 1499999999979995.0R ' Dev11 & Roslyn: Unchanged
@@ -915,7 +921,7 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 3: > 16 significant digits
@@ -927,7 +933,7 @@ Sub Main(args As String())
Const f_17_3 As Double = 0.14999999997999938 ' Dev11 & Roslyn: 0.14999999997999938
Const f_17_4 As Double = 0.1499999997999957 ' Dev11 & Roslyn: Unchanged
- Const f_17_5 As Double = 0.14999999979999579 ' Dev11 & Roslyn: 0.14999999979999579
+ Const f_17_5 As Double = {(IsNetCoreApp ? "0.1499999997999958" : "0.14999999979999579")} ' Dev11 & Roslyn: 0.14999999979999579
Const f_17_6 As Double = 1.4999999997999947 ' Dev11 & Roslyn: Unchanged
Const f_17_7 As Double = 1.4999999997999944 ' Dev11 & Roslyn: 1.4999999997999944
@@ -938,10 +944,10 @@ Sub Main(args As String())
Const f_18_3 As Double = 14999999.997999946 ' Dev11 & Roslyn: 14999999.997999946
' (b) > 16 significant digits before decimal point.
- Const f_18_4 As Double = 1.4999999999734E+16 ' Dev11 & Roslyn: 1.4999999999734E+16
+ Const f_18_4 As Double = {(IsNetCoreApp ? "14999999999734000.0" : "1.4999999999734E+16")} ' Dev11 & Roslyn: 1.4999999999734E+16
Const f_18_5 As Double = 14999999999379996.0 ' Dev11 & Roslyn: 14999999999379996.0
- Const f_24_1 As Double = 1.1111114999912469E+20 ' Dev11 & Roslyn: 1.1111114999912469E+20
+ Const f_24_1 As Double = {(IsNetCoreApp ? "1.111111499991247E+20" : "1.1111114999912469E+20")} ' Dev11 & Roslyn: 1.1111114999912469E+20
' (c) Overflow/Underflow cases for Double: Ensure no pretty listing/round off
' Holds signed IEEE 64-bit (8-byte) double-precision floating-point numbers ranging in value from -1.79769313486231570E+308 through -4.94065645841246544E-324 for negative values and
@@ -1046,7 +1052,7 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
' CATEGORY 3: > 16 significant digits
@@ -1058,7 +1064,7 @@ Sub Main(args As String())
Const f_17_3 As Double = 0.14999999997999938# ' Dev11 & Roslyn: 0.14999999997999938
Const f_17_4 As Double = 0.1499999997999957R ' Dev11 & Roslyn: Unchanged
- Const f_17_5 As Double = 0.14999999979999579R ' Dev11 & Roslyn: 0.14999999979999579
+ Const f_17_5 As Double = {(IsNetCoreApp ? "0.1499999997999958R" : "0.14999999979999579R")} ' Dev11 & Roslyn: 0.14999999979999579
Const f_17_6 As Double = 1.4999999997999947# ' Dev11 & Roslyn: Unchanged
Const f_17_7 As Double = 1.4999999997999944R ' Dev11 & Roslyn: 1.4999999997999944
@@ -1069,10 +1075,10 @@ Sub Main(args As String())
Const f_18_3 As Double = 14999999.997999946R ' Dev11 & Roslyn: 14999999.997999946
' (b) > 16 significant digits before decimal point.
- Const f_18_4 As Double = 1.4999999999734E+16# ' Dev11 & Roslyn: 1.4999999999734E+16
+ Const f_18_4 As Double = {(IsNetCoreApp ? "14999999999734000.0#" : "1.4999999999734E+16#")} ' Dev11 & Roslyn: 1.4999999999734E+16
Const f_18_5 As Double = 14999999999379996.0R ' Dev11 & Roslyn: 14999999999379996.0
- Const f_24_1 As Double = 1.1111114999912469E+20R ' Dev11 & Roslyn: 1.1111114999912469E+20
+ Const f_24_1 As Double = {(IsNetCoreApp ? "1.111111499991247E+20R" : "1.1111114999912469E+20R")} ' Dev11 & Roslyn: 1.1111114999912469E+20
' (c) Overflow/Underflow cases for Double: Ensure no pretty listing/round off
' Holds signed IEEE 64-bit (8-byte) double-precision floating-point numbers ranging in value from -1.79769313486231570E+308 through -4.94065645841246544E-324 for negative values and
@@ -1502,7 +1508,7 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
@@ -1530,19 +1536,19 @@ Sub Main(args As String())
Const f_4 As Single = 1.234567E-9F ' Change at -9
Const f_5 As Single = 1.234567E-10F
- Const f_6 As Single = 0.00000000123456778F
- Const f_7 As Single = 0.000000000123456786F
- Const f_8 As Single = 1.23456783E-11F ' Change at -11
- Const f_9 As Single = 1.23456779E-12F
+ Const f_6 As Single = {(IsNetCoreApp ? "0.0000000012345678F" : "0.00000000123456778F")}
+ Const f_7 As Single = {(IsNetCoreApp ? "0.00000000012345679F" : "0.000000000123456786F")}
+ Const f_8 As Single = {(IsNetCoreApp ? "1.2345678E-11F" : "1.23456783E-11F")} ' Change at -11
+ Const f_9 As Single = {(IsNetCoreApp ? "1.2345678E-12F" : "1.23456779E-12F")}
Const d_1 As Single = 0.00000000000000123456789012345
Const d_2 As Single = 0.000000000000000123456789012345
Const d_3 As Single = 1.23456789012345E-17 ' Change at -17
Const d_4 As Single = 1.23456789012345E-18
- Const d_5 As Double = 0.000000000000000012345678901234561
+ Const d_5 As Double = {(IsNetCoreApp ? "0.00000000000000001234567890123456" : "0.000000000000000012345678901234561")}
Const d_6 As Double = 0.000000000000000001234567890123456
- Const d_7 As Double = 1.2345678901234561E-19 ' Change at -19
+ Const d_7 As Double = {(IsNetCoreApp ? "1.234567890123456E-19" : "1.2345678901234561E-19")} ' Change at -19
Const d_8 As Double = 1.234567890123456E-20
End Sub
End Module
@@ -1585,7 +1591,7 @@ End Sub
End Module
|]";
- var expected = @"
+ var expected = $@"
Module Program
Sub Main(args As String())
Const f1 As Single = 3.011F ' Dev11 & Roslyn: 3.011F
@@ -1595,9 +1601,9 @@ Sub Main(args As String())
Const f5 As Single = 3.0E+13! ' Dev11 & Roslyn: 3.0E+13!
Const f6 As Single = 3.0E+13F ' Dev11 & Roslyn: 3.0E+13F
Const f7 As Single = 30000.1F ' Dev11 & Roslyn: 30000.1F
- Const f8 As Single = 3.00012337E+13! ' Dev11 & Roslyn: 3.00012337E+13!
- Const f9 As Single = 3.00012337E+13F ' Dev11 & Roslyn: 3.00012337E+13F
- Const f10 As Single = 3000.12354F ' Dev11 & Roslyn: 3000.12354F
+ Const f8 As Single = {(IsNetCoreApp ? "3.0001234E+13!" : "3.00012337E+13!")} ' Dev11 & Roslyn: 3.00012337E+13!
+ Const f9 As Single = {(IsNetCoreApp ? "3.0001234E+13F" : "3.00012337E+13F")} ' Dev11 & Roslyn: 3.00012337E+13F
+ Const f10 As Single = {(IsNetCoreApp ? "3000.1235F" : "3000.12354F")} ' Dev11 & Roslyn: 3000.12354F
Const f11 As Single = 0.0000003! ' Dev11 & Roslyn: 0.0000003!
Console.WriteLine(f1)
@@ -2049,7 +2055,7 @@ private static async Task VerifyAsync(string codeWithMarker, string expectedResu
var cleanDocument = await CodeCleaner.CleanupAsync(document, textSpans[0], codeCleanups);
- Assert.Equal(expectedResult, (await cleanDocument.GetSyntaxRootAsync()).ToFullString());
+ AssertEx.EqualOrDiff(expectedResult, (await cleanDocument.GetSyntaxRootAsync()).ToFullString());
}
private static Document CreateDocument(string code, string language)
diff --git a/src/Workspaces/CoreTest/Microsoft.CodeAnalysis.Workspaces.UnitTests.csproj b/src/Workspaces/CoreTest/Microsoft.CodeAnalysis.Workspaces.UnitTests.csproj
index 397b41952a248..b424acfd40372 100644
--- a/src/Workspaces/CoreTest/Microsoft.CodeAnalysis.Workspaces.UnitTests.csproj
+++ b/src/Workspaces/CoreTest/Microsoft.CodeAnalysis.Workspaces.UnitTests.csproj
@@ -3,7 +3,7 @@
Library
- net472
+ netcoreapp3.1;net472
true
Microsoft.CodeAnalysis.UnitTests
@@ -30,7 +30,6 @@
-
diff --git a/src/Workspaces/CoreTest/UtilityTest/ReferenceHolderTests.cs b/src/Workspaces/CoreTest/UtilityTest/ReferenceHolderTests.cs
index ed94369ffbc11..1bd834e2c498c 100644
--- a/src/Workspaces/CoreTest/UtilityTest/ReferenceHolderTests.cs
+++ b/src/Workspaces/CoreTest/UtilityTest/ReferenceHolderTests.cs
@@ -60,7 +60,7 @@ public void ExpiredValueNotEqualToNull()
{
var strongNull = ReferenceHolder
\ No newline at end of file