diff --git a/build/Targets/Imports.targets b/build/Targets/Imports.targets
index 48f8965adce1f06f2e7fcc36da3fcf19f597ebb9..a41f3d1d7df7e9d2e40d22dc0f8b2e88006ffa5f 100644
--- a/build/Targets/Imports.targets
+++ b/build/Targets/Imports.targets
@@ -11,14 +11,14 @@
<_CopyReferences>false
<_CopyProjectReferences>false
false
- $(OutDir)Exes\$(MSBuildProjectName)\
+ $(OutputPath)Exes\$(MSBuildProjectName)\
<_IsAnyUnitTest>true
true
- $(OutDir)UnitTests\$(MSBuildProjectName)\
+ $(OutputPath)UnitTests\$(MSBuildProjectName)\
@@ -39,21 +39,21 @@
<_IsAnyUnitTest>true
<_IsAnyPortableUnitTest>true
false
- $(OutDir)Dlls\$(MSBuildProjectName)\
+ $(OutputPath)Dlls\$(MSBuildProjectName)\
<_CopyReferences>false
false
- $(OutDir)Exes\
+ $(OutputPath)Exes\
<_CopyReferences>false
true
- $(OutDir)Vsix\$(MSBuildProjectName)\
+ $(OutputPath)Vsix\$(MSBuildProjectName)\
@@ -62,8 +62,8 @@
$(AllowedReferenceRelatedFileExtensions);.pdb
true
- $(OutDir)CoreClrTest
- $(OutDir)UnitTests\Portable\
+ $(OutputPath)CoreClrTest
+ $(OutputPath)UnitTests\Portable\
@@ -74,19 +74,19 @@
<_CopyReferences>false
<_CopyProjectReferences>false
false
- $(OutDir)Dlls\$(MSBuildProjectName)\
+ $(OutputPath)Dlls\$(MSBuildProjectName)\
true
- $(OutDir)Exes\$(MSBuildProjectName)\
+ $(OutputPath)Exes\$(MSBuildProjectName)\
true
- $(OutDir)Exes\$(MSBuildProjectName)\
+ $(OutputPath)Exes\$(MSBuildProjectName)\
@@ -114,7 +114,6 @@
- $(OutDir)
0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
002400000480000094000000060200000024000052534131000400000100010055e0217eb635f69281051f9a823e0c7edd90f28063eb6c7a742a19b4f6139778ee0af438f47aed3b6e9f99838aa8dba689c7a71ddb860c96d923830b57bbd5cd6119406ddb9b002cf1c723bf272d6acbb7129e9d6dd5a5309c94e0ff4b2c884d45a55f475cd7dba59198086f61f5a8c8b5e601c0edbf269733f6f578fc8579c2
diff --git a/build/Targets/Settings.props b/build/Targets/Settings.props
index a702d4dd7508d0b750deae80ce422e0dfa77ee06..db50ab1d7abc9b38598dac62c3e39c9df0089edd 100644
--- a/build/Targets/Settings.props
+++ b/build/Targets/Settings.props
@@ -27,7 +27,7 @@
true
true
$(RepoRoot)Binaries\
- $(BaseOutputPath)$(Configuration)\
+ $(BaseOutputPath)$(Configuration)\
$(RepoRoot)Binaries\Obj\
$(BaseIntermediateOutputPath)$(Configuration)\$(MSBuildProjectName)\
@@ -47,7 +47,7 @@
$(VisualStudioVersion)
false
diff --git a/build/scripts/build.ps1 b/build/scripts/build.ps1
index 4df62deb017bf5366a39bd0ee65ea0d06079300e..0c53de2ab25be81e0af290c3ddbbefc22b52df7b 100644
--- a/build/scripts/build.ps1
+++ b/build/scripts/build.ps1
@@ -4,6 +4,7 @@ param (
[switch]$build = $false,
[switch]$restore = $false,
[switch]$test = $false,
+ [switch]$test64 = $false,
[switch]$clean = $false,
[switch]$clearPackageCache = $false,
[string]$project = "",
@@ -17,7 +18,8 @@ function Print-Usage() {
Write-Host "Build.ps1"
Write-Host "`t-build Run a build operation (default false)"
Write-Host "`t-restore Run a restore operation (default false)"
- Write-Host "`t-test Run tests (default false)"
+ Write-Host "`t-test Run unit tests (default false)"
+ Write-Host "`t-test64 Run unit tests in 64 bit mode"
Write-Host "`t-clean Do a clean build / restore (default false)"
Write-Host "`t-clearPackageCache Clear package cache before restoring"
Write-Host "`t-project Project the build or restore should target"
@@ -38,7 +40,11 @@ function Run-Build() {
function Run-Test() {
$proj = Join-Path $repoDir "BuildAndTest.proj"
- Exec-Command $msbuild "/v:m /p:SkipCoreClr=true /t:Test $proj" | Out-Host
+ $args = "/v:m /p:SkipCoreClr=true /p:ManualTest=true /t:Test $proj"
+ if ($test64) {
+ $args += " /p:Test64=true"
+ }
+ Exec-Command $msbuild $args | Out-Host
}
try {
@@ -68,7 +74,7 @@ try {
Run-Build
}
- if ($test) {
+ if ($test -or $test64) {
Run-Test
}
}
diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
index 074bcaa3900f01b6c30307c6e82323f0d4268a2b..4b704f208a0b8a4e58f1a246ff0b4387916a1d4f 100644
--- a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
@@ -4066,7 +4066,7 @@ public class Test
// TODO...
}
- [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18800")]
+ [Fact]
public void CS0306ERR_BadTypeArgument01()
{
var source =
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.cs
index 58641db39f307bed91384d40c32d0dbaa891e385..5125d16bbb921fade20fadea53a2ad6f0a5d06ad 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.cs
@@ -3820,6 +3820,81 @@ static void G(out object o)
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6));
}
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)]
+ [WorkItem(15996, "https://github.com/dotnet/roslyn/issues/15996")]
+ public async Task TestMemberOfBuiltInType1()
+ {
+ await TestAsync(
+@"using System;
+class C
+{
+ void Main()
+ {
+ [|UInt32|] value = UInt32.MaxValue;
+ }
+}",
+@"using System;
+class C
+{
+ void Main()
+ {
+ uint value = UInt32.MaxValue;
+ }
+}",
+ parseOptions: CSharpParseOptions.Default,
+ options: PreferIntrinsicTypeInDeclaration);
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)]
+ [WorkItem(15996, "https://github.com/dotnet/roslyn/issues/15996")]
+ public async Task TestMemberOfBuiltInType2()
+ {
+ await TestAsync(
+@"using System;
+class C
+{
+ void Main()
+ {
+ UInt32 value = [|UInt32|].MaxValue;
+ }
+}",
+@"using System;
+class C
+{
+ void Main()
+ {
+ UInt32 value = uint.MaxValue;
+ }
+}",
+ parseOptions: CSharpParseOptions.Default,
+ options: PreferIntrinsicTypeInMemberAccess);
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)]
+ [WorkItem(15996, "https://github.com/dotnet/roslyn/issues/15996")]
+ public async Task TestMemberOfBuiltInType3()
+ {
+ await TestAsync(
+@"using System;
+class C
+{
+ void Main()
+ {
+ [|UInt32|].Parse(""foo"");
+ }
+}",
+@"using System;
+class C
+{
+ void Main()
+ {
+ uint.Parse(""foo"");
+ }
+}",
+ parseOptions: CSharpParseOptions.Default,
+ options: PreferIntrinsicTypeInMemberAccess);
+ }
+
private async Task TestWithPredefinedTypeOptionsAsync(string code, string expected, int index = 0)
{
await TestInRegularAndScriptAsync(code, expected, index: index, options: PreferIntrinsicTypeEverywhere);
diff --git a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs
index 9354b3d36a16bd20c4ce1b7bb15cd1ec4be1f9d3..594148a084bee36ffc524e4d4e07d802c7b463a1 100644
--- a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs
+++ b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs
@@ -1552,5 +1552,38 @@ public override void M2(T? i = null)
}
}");
}
+
+ [WorkItem(13932, "https://github.com/dotnet/roslyn/issues/13932")]
+ [WorkItem(5898, "https://github.com/dotnet/roslyn/issues/5898")]
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
+ public async Task TestAutoProperties()
+ {
+ await TestInRegularAndScript1Async(
+@"abstract class AbstractClass
+{
+ public abstract int ReadOnlyProp { get; }
+ public abstract int ReadWriteProp { get; set; }
+ public abstract int WriteOnlyProp { set; }
+}
+
+class [|C|] : AbstractClass
+{
+}",
+@"abstract class AbstractClass
+{
+ public abstract int ReadOnlyProp { get; }
+ public abstract int ReadWriteProp { get; set; }
+ public abstract int WriteOnlyProp { set; }
+}
+
+class C : AbstractClass
+{
+ public override int ReadOnlyProp { get; }
+ public override int ReadWriteProp { get; set; }
+ public override int WriteOnlyProp { set => throw new System.NotImplementedException(); }
+}", parameters: new TestParameters(options: Option(
+ ImplementTypeOptions.PropertyGenerationBehavior,
+ ImplementTypePropertyGenerationBehavior.PreferAutoProperties)));
+ }
}
}
\ No newline at end of file
diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs
index 8c65728e7fc13a1b5cd3353e371e72e5e89e27d4..bf80853e2d6174b741c1dba1d02a62467aa5a5c6 100644
--- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs
+++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs
@@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
-using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.ImplementInterface;
@@ -6705,5 +6704,40 @@ class C : I
}
}");
}
+
+ [WorkItem(13932, "https://github.com/dotnet/roslyn/issues/13932")]
+ [WorkItem(5898, "https://github.com/dotnet/roslyn/issues/5898")]
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
+ public async Task TestAutoProperties()
+ {
+ await TestInRegularAndScript1Async(
+@"interface IInterface
+{
+ int ReadOnlyProp { get; }
+ int ReadWriteProp { get; set; }
+ int WriteOnlyProp { set; }
+}
+
+class Class : [|IInterface|]
+{
+}",
+@"interface IInterface
+{
+ int ReadOnlyProp { get; }
+ int ReadWriteProp { get; set; }
+ int WriteOnlyProp { set; }
+}
+
+class Class : IInterface
+{
+ public int ReadOnlyProp { get; }
+
+ public int ReadWriteProp { get; set; }
+
+ public int WriteOnlyProp { set => throw new System.NotImplementedException(); }
+}", parameters: new TestParameters(options: Option(
+ ImplementTypeOptions.PropertyGenerationBehavior,
+ ImplementTypePropertyGenerationBehavior.PreferAutoProperties)));
+ }
}
}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSource.cs b/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSource.cs
index 2c65683e1aea07bf5e885e6a048592e0018d1847..460cec8a319a4e01a8b37eeb108285c15ef32ba6 100644
--- a/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSource.cs
+++ b/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSource.cs
@@ -42,6 +42,8 @@ private class SuggestedActionsSource : ForegroundThreadAffinitizedObject, ISugge
private Workspace _workspace;
private int _lastSolutionVersionReported;
+ public event EventHandler SuggestedActionsChanged;
+
public SuggestedActionsSource(SuggestedActionsSourceProvider owner, ITextView textView, ITextBuffer textBuffer)
{
_owner = owner;
@@ -64,7 +66,37 @@ public SuggestedActionsSource(SuggestedActionsSourceProvider owner, ITextView te
_registration.WorkspaceChanged += OnWorkspaceChanged;
}
- public event EventHandler SuggestedActionsChanged;
+ public void Dispose()
+ {
+ if (_owner != null)
+ {
+ var updateSource = (IDiagnosticUpdateSource)_owner._diagnosticService;
+ updateSource.DiagnosticsUpdated -= OnDiagnosticsUpdated;
+ }
+
+ if (_workspace != null)
+ {
+ _workspace.DocumentActiveContextChanged -= OnActiveContextChanged;
+ }
+
+ if (_registration != null)
+ {
+ _registration.WorkspaceChanged -= OnWorkspaceChanged;
+ }
+
+ if (_textView != null)
+ {
+ _textView.Closed -= OnTextViewClosed;
+ }
+
+ _owner = null;
+ _workspace = null;
+ _registration = null;
+ _textView = null;
+ _subjectBuffer = null;
+ }
+
+ private bool IsDisposed => _subjectBuffer == null;
public bool TryGetTelemetryId(out Guid telemetryId)
{
@@ -111,6 +143,11 @@ public bool TryGetTelemetryId(out Guid telemetryId)
{
AssertIsForeground();
+ if (IsDisposed)
+ {
+ return null;
+ }
+
using (Logger.LogBlock(FunctionId.SuggestedActions_GetSuggestedActions, cancellationToken))
{
var document = range.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
@@ -529,7 +566,7 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring))
{
// Get the selection while on the UI thread.
- var selection = TryGetCodeRefactoringSelection(_subjectBuffer, _textView, range);
+ var selection = TryGetCodeRefactoringSelection(range);
if (!selection.HasValue)
{
// this is here to fail test and see why it is failed.
@@ -593,20 +630,60 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
SnapshotSpan range,
CancellationToken cancellationToken)
{
- // Explicitly hold onto below fields in locals and use these locals throughout this code path to avoid crashes
- // if these fields happen to be cleared by Dispose() below. This is required since this code path involves
- // code that can run asynchronously from background thread.
- var view = _textView;
- var buffer = _subjectBuffer;
var provider = _owner;
- if (view == null || buffer == null || provider == null)
+ if (IsDisposed)
{
+ // We've already been disposed. No point in continuing.
return false;
}
- using (var asyncToken = provider.OperationListener.BeginAsyncOperation("HasSuggestedActionsAsync"))
- {
+ using (var asyncToken = _owner.OperationListener.BeginAsyncOperation("HasSuggestedActionsAsync"))
+ {
+ // Acquire the user's selection up front, before we do any async work, so that we can
+ // directly grab it when we're on the UI thread. That way we don't have any reentrancy
+ // blocking concerns if VS wants to block on this call (for example, if the user
+ // explicitly invokes the 'show smart tag' command).
+ //
+ // This work must happen on the UI thread as it needs to access the _textView's mutable
+ // state.
+ //
+ // Note: we may be called in one of two VS scenarios:
+ // 1) User has moved caret to a new line. In this case VS will call into us in the
+ // bg to see if we have any suggested actions for this line. In order to figure
+ // this out, we need to see what selectoin the user has (for refactorings), which
+ // necessitates going back to the fg.
+ //
+ // 2) User moves to a line and immediately hits ctrl-dot. In this case, on the UI
+ // thread VS will kick us off and then immediately block to get the results so
+ // that they can expand the lightbulb. In this case we cannot do BG work first,
+ // then call back into the UI thread to try to get the user selection. This will
+ // deadlock as the UI thread is blocked on us.
+ //
+ // There are two solution to '2'. Either introduce reentrancy (which we really don't
+ // like to do), or just ensure that we acquire and get the users selection up front.
+ // This means that when we're called from the UI therad, we never try to go back to the
+ // UI thread.
+ TextSpan? selection = null;
+ if (IsForeground())
+ {
+ selection = TryGetCodeRefactoringSelection(range);
+ }
+ else
+ {
+ await InvokeBelowInputPriority(() =>
+ {
+ // Make sure we were not disposed between kicking off this work and getting
+ // to this point.
+ if (IsDisposed)
+ {
+ return;
+ }
+
+ selection = TryGetCodeRefactoringSelection(range);
+ }).ConfigureAwait(false);
+ }
+
var document = range.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
@@ -617,7 +694,7 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
return
await HasFixesAsync(provider, document, range, cancellationToken).ConfigureAwait(false) ||
- await HasRefactoringsAsync(provider, document, buffer, view, range, cancellationToken).ConfigureAwait(false);
+ await HasRefactoringsAsync(provider, document, selection, cancellationToken).ConfigureAwait(false);
}
}
@@ -658,11 +735,16 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
private async Task HasRefactoringsAsync(
SuggestedActionsSourceProvider provider,
Document document,
- ITextBuffer buffer,
- ITextView view,
- SnapshotSpan range,
+ TextSpan? selection,
CancellationToken cancellationToken)
{
+ if (!selection.HasValue)
+ {
+ // this is here to fail test and see why it is failed.
+ Trace.WriteLine("given range is not current");
+ return false;
+ }
+
var workspace = document.Project.Solution.Workspace;
var supportsFeatureService = workspace.Services.GetService();
@@ -670,28 +752,6 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
provider._codeRefactoringService != null &&
supportsFeatureService.SupportsRefactorings(document))
{
- TextSpan? selection = null;
- if (IsForeground())
- {
- // This operation needs to happen on UI thread because it needs to access textView.Selection.
- selection = TryGetCodeRefactoringSelection(buffer, view, range);
- }
- else
- {
- await InvokeBelowInputPriority(() =>
- {
- // This operation needs to happen on UI thread because it needs to access textView.Selection.
- selection = TryGetCodeRefactoringSelection(buffer, view, range);
- }).ConfigureAwait(false);
- }
-
- if (!selection.HasValue)
- {
- // this is here to fail test and see why it is failed.
- Trace.WriteLine("given range is not current");
- return false;
- }
-
return await Task.Run(
() => provider._codeRefactoringService.HasRefactoringsAsync(
document, selection.Value, cancellationToken),
@@ -701,11 +761,14 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
return false;
}
- private static TextSpan? TryGetCodeRefactoringSelection(ITextBuffer buffer, ITextView view, SnapshotSpan range)
+ private TextSpan? TryGetCodeRefactoringSelection(SnapshotSpan range)
{
- var selectedSpans = view.Selection.SelectedSpans
- .SelectMany(ss => view.BufferGraph.MapDownToBuffer(ss, SpanTrackingMode.EdgeExclusive, buffer))
- .Where(ss => !view.IsReadOnlyOnSurfaceBuffer(ss))
+ this.AssertIsForeground();
+ Debug.Assert(!this.IsDisposed);
+
+ var selectedSpans = _textView.Selection.SelectedSpans
+ .SelectMany(ss => _textView.BufferGraph.MapDownToBuffer(ss, SpanTrackingMode.EdgeExclusive, _subjectBuffer))
+ .Where(ss => !_textView.IsReadOnlyOnSurfaceBuffer(ss))
.ToList();
// We only support refactorings when there is a single selection in the document.
@@ -796,39 +859,6 @@ private void OnSuggestedActionsChanged(Workspace currentWorkspace, DocumentId cu
Volatile.Write(ref _lastSolutionVersionReported, solutionVersion);
}
-
- public void Dispose()
- {
- if (_owner != null)
- {
- var updateSource = (IDiagnosticUpdateSource)_owner._diagnosticService;
- updateSource.DiagnosticsUpdated -= OnDiagnosticsUpdated;
- _owner = null;
- }
-
- if (_workspace != null)
- {
- _workspace.DocumentActiveContextChanged -= OnActiveContextChanged;
- _workspace = null;
- }
-
- if (_registration != null)
- {
- _registration.WorkspaceChanged -= OnWorkspaceChanged;
- _registration = null;
- }
-
- if (_textView != null)
- {
- _textView.Closed -= OnTextViewClosed;
- _textView = null;
- }
-
- if (_subjectBuffer != null)
- {
- _subjectBuffer = null;
- }
- }
}
}
}
\ No newline at end of file
diff --git a/src/EditorFeatures/Test/Utilities/PatternMatcherTests.cs b/src/EditorFeatures/Test/Utilities/PatternMatcherTests.cs
index 7a481d5702a8d0b18176f35eb5d2ab0eafc1d6f1..0b4005470aafe123a019adc4b65c106260a74c7a 100644
--- a/src/EditorFeatures/Test/Utilities/PatternMatcherTests.cs
+++ b/src/EditorFeatures/Test/Utilities/PatternMatcherTests.cs
@@ -182,6 +182,8 @@ private void VerifyBreakIntoCharacterParts(string original, params string[] part
[InlineData("[|Fog|]Bar", "fog", PatternMatchKind.Prefix, CaseInsensitive)]
[InlineData("[|fog|]BarFoo", "Fog", PatternMatchKind.Prefix, CaseInsensitive)]
+ [InlineData("[|system.ref|]lection", "system.ref", PatternMatchKind.Prefix, CaseSensitive)]
+
[InlineData("Fog[|B|]ar", "b", PatternMatchKind.Substring, CaseInsensitive)]
[InlineData("_[|my|]Button", "my", PatternMatchKind.Substring, CaseSensitive)]
@@ -234,10 +236,10 @@ private void VerifyBreakIntoCharacterParts(string original, params string[] part
[InlineData("my[|_b|]utton", "_B", PatternMatchKind.CamelCase, CaseInsensitive, PatternMatcher.CamelCaseContiguousBonus)]
[InlineData("[|_|]my_[|b|]utton", "_B", PatternMatchKind.CamelCase, CaseInsensitive, PatternMatcher.CamelCaseMatchesFromStartBonus)]
- public void TryMatchSingleWordPattern(
+ public void TestNonFuzzyMatch(
string candidate, string pattern, int matchKindInt, bool isCaseSensitive, int? camelCaseWeight = null)
{
- var match = TryMatchSingleWordPattern(candidate, pattern);
+ var match = TestNonFuzzyMatch(candidate, pattern);
Assert.NotNull(match);
var matchKind = (PatternMatchKind)matchKindInt;
@@ -269,9 +271,10 @@ private void VerifyBreakIntoCharacterParts(string original, params string[] part
[InlineData("FogBarBaz", "FZ")]
[InlineData("_mybutton", "myB")]
[InlineData("FogBarChangedEventArgs", "changedeventarrrgh")]
- public void TryMatchSingleWordPattern_NoMatch(string candidate, string pattern)
+ [InlineData("runtime.native.system", "system.reflection")]
+ public void TestNonFuzzyMatch_NoMatch(string candidate, string pattern)
{
- var match = TryMatchSingleWordPattern(candidate, pattern);
+ var match = TestNonFuzzyMatch(candidate, pattern);
Assert.Null(match);
}
@@ -470,7 +473,7 @@ public void TryMatchSingleWordPattern_CultureAwareSingleWordPreferCaseSensitiveE
try
{
- var match = TryMatchSingleWordPattern("[|ioo|]", "\u0130oo"); // u0130 = Capital I with dot
+ var match = TestNonFuzzyMatch("[|ioo|]", "\u0130oo"); // u0130 = Capital I with dot
Assert.Equal(PatternMatchKind.Exact, match.Value.Kind);
Assert.False(match.Value.IsCaseSensitive);
@@ -499,11 +502,15 @@ private static IList BreakIntoCharacterParts(string identifier)
private static IList BreakIntoWordParts(string identifier)
=> PartListToSubstrings(identifier, StringBreaker.BreakIntoWordParts(identifier));
- private static PatternMatch? TryMatchSingleWordPattern(string candidate, string pattern)
+ private static PatternMatch? TestNonFuzzyMatch(string candidate, string pattern)
{
MarkupTestFile.GetSpans(candidate, out candidate, out ImmutableArray spans);
- var match = new PatternMatcher(pattern).MatchSingleWordPattern_ForTestingOnly(candidate);
+ var match = new PatternMatcher(pattern).GetFirstMatch(candidate, includeMatchSpans: true);
+ if (match?.Kind == PatternMatchKind.Fuzzy)
+ {
+ match = null;
+ }
if (match == null)
{
@@ -536,4 +543,4 @@ private static IEnumerable TryMatchMultiWordPattern(string candida
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/EditorFeatures/Test2/IntelliSense/CompletionRulesTests.vb b/src/EditorFeatures/Test2/IntelliSense/CompletionRulesTests.vb
index a270b6cf50ba6e5069ec95ba24c86c5029fca646..fb1571ec4853bbc5e0059b5fff1f9e0017fe9a48 100644
--- a/src/EditorFeatures/Test2/IntelliSense/CompletionRulesTests.vb
+++ b/src/EditorFeatures/Test2/IntelliSense/CompletionRulesTests.vb
@@ -3,6 +3,7 @@
Imports System.Globalization
Imports Microsoft.CodeAnalysis.Completion
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
+Imports Microsoft.CodeAnalysis.Text
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
' These tests adapted from David Kean's table at
@@ -10,7 +11,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Public Class CompletionRulesTests
Public Sub TestMatchLowerCaseEnglishI()
- Dim wordsToMatch = {"index", "Index", "işte", "İşte"}
+ Dim wordsToMatch = {"[|i|]ndex", "[|I|]ndex", "[|i|]şte", "[|İ|]şte"}
Dim wordsToNotMatch = {"ırak"}
TestMatches("i", wordsToMatch)
@@ -19,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Public Sub TestMatchDottedUpperTurkishI()
- Dim wordsToMatch = {"index", "işte", "İşte"}
+ Dim wordsToMatch = {"[|i|]ndex", "[|i|]şte", "[|İ|]şte"}
Dim wordsToNotMatch = {"ırak", "Irak", "Index"}
TestMatches("İ", wordsToMatch)
@@ -28,7 +29,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Public Sub TestMatchNonDottedLowerTurkishI()
- Dim wordsToMatch = {"ırak", "Irak"}
+ Dim wordsToMatch = {"[|ı|]rak", "[|I|]rak"}
Dim wordsToNotMatch = {"index", "işte", "İşte"}
TestMatches("ı", wordsToMatch)
@@ -37,31 +38,48 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Public Sub TestMatchEnglishUpperI()
- Dim wordsToMatch = {"Index", "index", "ırak", "Irak"}
+ ' In turkish-culture "I" will not match "index". However, we want to verify that
+ ' the underlying completion helper will fallback to doing an en-us check if the
+ ' tr-tr check fails, and that it properly also returns the matched spans in this case.
+
+ Dim wordsToMatch = {"[|I|]ndex", "[|i|]ndex", "[|ı|]rak", "[|I|]rak"}
Dim wordsToNotMatch = {"İşte"}
TestMatches("I", wordsToMatch)
TestNotMatches("I", wordsToNotMatch)
End Sub
- Private Sub TestMatches(v As String, wordsToMatch() As String)
+ Private Sub TestMatches(pattern As String, wordsToMatch() As String)
Dim culture = New CultureInfo("tr-TR", useUserOverride:=False)
Dim workspace = New TestWorkspace
Dim helper = CompletionHelper.GetHelper(workspace, LanguageNames.CSharp)
- For Each word In wordsToMatch
+
+ For Each wordMarkup In wordsToMatch
+ Dim word As String = Nothing
+ Dim wordMatchSpan As TextSpan = Nothing
+ MarkupTestFile.GetSpan(wordMarkup, word, wordMatchSpan)
+
Dim item = CompletionItem.Create(word)
- Assert.True(helper.MatchesPattern(item.FilterText, v, culture), $"Expected item {word} does not match {v}")
+ Assert.True(helper.MatchesPattern(item.FilterText, pattern, culture), $"Expected item {word} does not match {pattern}")
+
+ Dim highlightedSpans = helper.GetHighlightedSpans(item.FilterText, pattern, culture)
+ Assert.NotEmpty(highlightedSpans)
+ Assert.Equal(1, highlightedSpans.Length)
+ Assert.Equal(wordMatchSpan, highlightedSpans(0))
Next
End Sub
- Private Sub TestNotMatches(v As String, wordsToNotMatch() As String)
+ Private Sub TestNotMatches(pattern As String, wordsToNotMatch() As String)
Dim culture = New CultureInfo("tr-TR", useUserOverride:=False)
Dim workspace = New TestWorkspace
Dim helper = CompletionHelper.GetHelper(workspace, LanguageNames.CSharp)
For Each word In wordsToNotMatch
Dim item = CompletionItem.Create(word)
- Assert.False(helper.MatchesPattern(item.FilterText, v, culture), $"Unexpected item {word} matches {v}")
+ Assert.False(helper.MatchesPattern(item.FilterText, pattern, culture), $"Unexpected item {word} matches {pattern}")
+
+ Dim highlightedSpans = helper.GetHighlightedSpans(item.FilterText, pattern, culture)
+ Assert.Empty(highlightedSpans)
Next
End Sub
End Class
diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.vb
index 5ee61c03636f79171ade3ad932d0914665ac3dd2..9e9732a845bf8bfaeae3027073e2c30c69eded6d 100644
--- a/src/EditorFeatures/VisualBasicTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/SimplifyTypeNames/SimplifyTypeNamesTests.vb
@@ -2430,5 +2430,62 @@ End Class")
diagnosticId:=IDEDiagnosticIds.RemoveQualificationDiagnosticId,
diagnosticSeverity:=DiagnosticSeverity.Error)
End Function
+
+
+
+ Public Async Function TestMemberOfBuiltInType1() As Task
+ Await TestInRegularAndScriptAsync(
+"Imports System
+Module Module1
+ Sub Main()
+ Dim var As [|UInt32|] = UInt32.MinValue
+ End Sub
+End Module",
+"Imports System
+Module Module1
+ Sub Main()
+ Dim var As UInteger = UInt32.MinValue
+ End Sub
+End Module",
+ options:=PreferIntrinsicPredefinedTypeInDeclaration())
+ End Function
+
+
+
+ Public Async Function TestMemberOfBuiltInType2() As Task
+ Await TestInRegularAndScriptAsync(
+"Imports System
+Module Module1
+ Sub Main()
+ Dim var As UInt32 = [|UInt32|].MinValue
+ End Sub
+End Module",
+"Imports System
+Module Module1
+ Sub Main()
+ Dim var As UInt32 = UInteger.MinValue
+ End Sub
+End Module",
+ options:=PreferIntrinsicTypeInMemberAccess())
+ End Function
+
+
+
+ Public Async Function TestMemberOfBuiltInType3() As Task
+ Await TestInRegularAndScriptAsync(
+"Imports System
+Module Module1
+ Sub Main()
+ [|UInt32|].Parse(""Foo"")
+ End Sub
+End Module",
+"Imports System
+Module Module1
+ Sub Main()
+ UInteger.Parse(""Foo"")
+ End Sub
+End Module",
+ options:=PreferIntrinsicTypeInMemberAccess())
+ End Function
End Class
End Namespace
\ No newline at end of file
diff --git a/src/EditorFeatures/VisualBasicTest/ImplementAbstractClass/ImplementAbstractClassTests.vb b/src/EditorFeatures/VisualBasicTest/ImplementAbstractClass/ImplementAbstractClassTests.vb
index 68036de39b15f4ff7064c5337a0bb0a0dbe97396..0060c89b6c5ec788235926865dc709822d1a1bef 100644
--- a/src/EditorFeatures/VisualBasicTest/ImplementAbstractClass/ImplementAbstractClassTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/ImplementAbstractClass/ImplementAbstractClassTests.vb
@@ -3,6 +3,7 @@
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
+Imports Microsoft.CodeAnalysis.ImplementType
Imports Microsoft.CodeAnalysis.VisualBasic.ImplementAbstractClass
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ImplementAbstractClass
@@ -574,5 +575,42 @@ Class x
End Function
End Class")
End Function
+
+
+
+
+ Public Async Function TestAutoProperties() As Task
+ Await TestInRegularAndScript1Async(
+"MustInherit Class AbstractClass
+ MustOverride ReadOnly Property ReadOnlyProp As Integer
+ MustOverride Property ReadWriteProp As Integer
+ MustOverride WriteOnly Property WriteOnlyProp As Integer
+End Class
+
+Class [|C|]
+ Inherits AbstractClass
+
+End Class",
+"MustInherit Class AbstractClass
+ MustOverride ReadOnly Property ReadOnlyProp As Integer
+ MustOverride Property ReadWriteProp As Integer
+ MustOverride WriteOnly Property WriteOnlyProp As Integer
+End Class
+
+Class C
+ Inherits AbstractClass
+
+ Public Overrides ReadOnly Property ReadOnlyProp As Integer
+ Public Overrides Property ReadWriteProp As Integer
+
+ Public Overrides WriteOnly Property WriteOnlyProp As Integer
+ Set(value As Integer)
+ Throw New System.NotImplementedException()
+ End Set
+ End Property
+End Class", parameters:=New TestParameters(options:=[Option](
+ ImplementTypeOptions.PropertyGenerationBehavior,
+ ImplementTypePropertyGenerationBehavior.PreferAutoProperties)))
+ End Function
End Class
End Namespace
\ No newline at end of file
diff --git a/src/EditorFeatures/VisualBasicTest/ImplementInterface/ImplementInterfaceTests.vb b/src/EditorFeatures/VisualBasicTest/ImplementInterface/ImplementInterfaceTests.vb
index 4d211574599c0e8e3421f35ac84b8a2ec88f6c40..66e9ce5fc2865378052983d6b0144aecc7213155 100644
--- a/src/EditorFeatures/VisualBasicTest/ImplementInterface/ImplementInterfaceTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/ImplementInterface/ImplementInterfaceTests.vb
@@ -3,6 +3,7 @@
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
+Imports Microsoft.CodeAnalysis.ImplementType
Imports Microsoft.CodeAnalysis.VisualBasic.ImplementInterface
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ImplementInterface
@@ -4518,5 +4519,41 @@ Namespace System
End Structure
End Namespace")
End Function
+
+
+
+
+ Public Async Function TestAutoProperties() As Task
+ Await TestInRegularAndScript1Async(
+"interface IInterface
+ readonly property ReadOnlyProp as integer
+ property ReadWriteProp as integer
+ writeonly property WriteOnlyProp as integer
+end interface
+
+class Class
+ implements [|IInterface|]
+end class",
+"interface IInterface
+ readonly property ReadOnlyProp as integer
+ property ReadWriteProp as integer
+ writeonly property WriteOnlyProp as integer
+end interface
+
+class Class
+ implements IInterface
+
+ Public ReadOnly Property ReadOnlyProp As Integer Implements IInterface.ReadOnlyProp
+ Public Property ReadWriteProp As Integer Implements IInterface.ReadWriteProp
+
+ Public WriteOnly Property WriteOnlyProp As Integer Implements IInterface.WriteOnlyProp
+ Set(value As Integer)
+ Throw New System.NotImplementedException()
+ End Set
+ End Property
+end class", parameters:=New TestParameters(options:=[Option](
+ ImplementTypeOptions.PropertyGenerationBehavior,
+ ImplementTypePropertyGenerationBehavior.PreferAutoProperties)))
+ End Function
End Class
End Namespace
\ No newline at end of file
diff --git a/src/Features/Core/Portable/Completion/CompletionHelper.cs b/src/Features/Core/Portable/Completion/CompletionHelper.cs
index 2ad6c674d19326786a8b55f49fa84fe166a19fa1..f98f9b1d3b6e784c0c427aa6c2e10b30256898f9 100644
--- a/src/Features/Core/Portable/Completion/CompletionHelper.cs
+++ b/src/Features/Core/Portable/Completion/CompletionHelper.cs
@@ -112,7 +112,7 @@ public bool MatchesPattern(string text, string pattern, CultureInfo culture)
if (!culture.Equals(EnUSCultureInfo))
{
patternMatcher = this.GetPatternMatcher(pattern, EnUSCultureInfo);
- match = patternMatcher.GetFirstMatch(completionItemText);
+ match = patternMatcher.GetFirstMatch(completionItemText, includeMatchSpans);
if (match != null)
{
return match;
diff --git a/src/Features/Core/Portable/ImplementAbstractClass/AbstractImplementAbstractClassService.Editor.cs b/src/Features/Core/Portable/ImplementAbstractClass/AbstractImplementAbstractClassService.Editor.cs
index d3a42a80ee5b51285af2953936c2b0a70061a914..49e68b7e242663d3a950d103d729771e9c046aea 100644
--- a/src/Features/Core/Portable/ImplementAbstractClass/AbstractImplementAbstractClassService.Editor.cs
+++ b/src/Features/Core/Portable/ImplementAbstractClass/AbstractImplementAbstractClassService.Editor.cs
@@ -1,7 +1,5 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System;
-using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
@@ -37,11 +35,12 @@ public async Task GetEditAsync(CancellationToken cancellationToken)
{
var unimplementedMembers = _state.UnimplementedMembers;
+ var options = await _document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
+ var propertyGenerationBehavior = options.GetOption(ImplementTypeOptions.PropertyGenerationBehavior);
+
var memberDefinitions = GenerateMembers(
- unimplementedMembers,
- cancellationToken);
+ unimplementedMembers, propertyGenerationBehavior, cancellationToken);
- var options = await _document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var insertionBehavior = options.GetOption(ImplementTypeOptions.InsertionBehavior);
var groupMembers = insertionBehavior == ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind;
@@ -51,23 +50,25 @@ public async Task GetEditAsync(CancellationToken cancellationToken)
memberDefinitions,
new CodeGenerationOptions(
_state.Location.GetLocation(),
- autoInsertionLocation: groupMembers,
+ autoInsertionLocation: groupMembers,
sortMembers: groupMembers),
cancellationToken).ConfigureAwait(false);
}
private ImmutableArray GenerateMembers(
ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> unimplementedMembers,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
return unimplementedMembers.SelectMany(t => t.members)
- .Select(m => GenerateMember(m, cancellationToken))
+ .Select(m => GenerateMember(m, propertyGenerationBehavior, cancellationToken))
.WhereNotNull()
.ToImmutableArray();
}
private ISymbol GenerateMember(
ISymbol member,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -76,32 +77,29 @@ public async Task GetEditAsync(CancellationToken cancellationToken)
var syntaxFacts = _document.Project.LanguageServices.GetService();
var addUnsafe = member.IsUnsafe() && !syntaxFacts.IsUnsafeContext(_state.Location);
- return GenerateMember(member, addUnsafe, cancellationToken);
+ return GenerateMember(member, addUnsafe, propertyGenerationBehavior, cancellationToken);
}
private ISymbol GenerateMember(
ISymbol member,
bool addUnsafe,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
var modifiers = new DeclarationModifiers(isOverride: true, isUnsafe: addUnsafe);
var accessibility = member.ComputeResultantAccessibility(_state.ClassType);
- if (member.Kind == SymbolKind.Method)
- {
- return GenerateMethod((IMethodSymbol)member, modifiers, accessibility, cancellationToken);
- }
- else if (member.Kind == SymbolKind.Property)
- {
- return GenerateProperty((IPropertySymbol)member, modifiers, accessibility, cancellationToken);
- }
- else if (member.Kind == SymbolKind.Event)
+ switch (member)
{
- var @event = (IEventSymbol)member;
- return CodeGenerationSymbolFactory.CreateEventSymbol(
- @event,
- accessibility: accessibility,
- modifiers: modifiers);
+ case IMethodSymbol method:
+ return GenerateMethod(method, modifiers, accessibility, cancellationToken);
+
+ case IPropertySymbol property:
+ return GenerateProperty(property, modifiers, accessibility, propertyGenerationBehavior, cancellationToken);
+
+ case IEventSymbol @event:
+ return CodeGenerationSymbolFactory.CreateEventSymbol(
+ @event, accessibility: accessibility, modifiers: modifiers);
}
return null;
@@ -128,18 +126,27 @@ public async Task GetEditAsync(CancellationToken cancellationToken)
IPropertySymbol property,
DeclarationModifiers modifiers,
Accessibility accessibility,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
+ if (property.GetMethod == null)
+ {
+ // Can't generate an auto-prop for a setter-only property.
+ propertyGenerationBehavior = ImplementTypePropertyGenerationBehavior.PreferThrowingProperties;
+ }
+
var syntaxFactory = _document.Project.LanguageServices.GetService();
- var throwingBody = syntaxFactory.CreateThrowNotImplementedStatementBlock(
- _model.Compilation);
+
+ var accessorBody = propertyGenerationBehavior == ImplementTypePropertyGenerationBehavior.PreferAutoProperties
+ ? default(ImmutableArray)
+ : syntaxFactory.CreateThrowNotImplementedStatementBlock(_model.Compilation);
var getMethod = ShouldGenerateAccessor(property.GetMethod)
? CodeGenerationSymbolFactory.CreateAccessorSymbol(
property.GetMethod,
attributes: default(ImmutableArray),
accessibility: property.GetMethod.ComputeResultantAccessibility(_state.ClassType),
- statements: throwingBody)
+ statements: accessorBody)
: null;
var setMethod = ShouldGenerateAccessor(property.SetMethod)
@@ -147,7 +154,7 @@ public async Task GetEditAsync(CancellationToken cancellationToken)
property.SetMethod,
attributes: default(ImmutableArray),
accessibility: property.SetMethod.ComputeResultantAccessibility(_state.ClassType),
- statements: throwingBody)
+ statements: accessorBody)
: null;
return CodeGenerationSymbolFactory.CreatePropertySymbol(
@@ -158,7 +165,8 @@ public async Task GetEditAsync(CancellationToken cancellationToken)
setMethod: setMethod);
}
- private bool ShouldGenerateAccessor(IMethodSymbol method) => method != null && _state.ClassType.FindImplementationForAbstractMember(method) == null;
+ private bool ShouldGenerateAccessor(IMethodSymbol method)
+ => method != null && _state.ClassType.FindImplementationForAbstractMember(method) == null;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs
index 7c3bcba99af707394843a09c789899063a0818e8..4071f72f9680971d1fe5edee3c812ceb1181eca2 100644
--- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs
+++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs
@@ -176,15 +176,15 @@ public Task GetUpdatedDocumentAsync(CancellationToken cancellationToke
var compilation = await result.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var isComImport = unimplementedMembers.Any(t => t.Item1.IsComImport);
+ var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
+ var propertyGenerationBehavior = options.GetOption(ImplementTypeOptions.PropertyGenerationBehavior);
+
var memberDefinitions = GenerateMembers(
- compilation,
- unimplementedMembers,
- cancellationToken);
+ compilation, unimplementedMembers, propertyGenerationBehavior, cancellationToken);
// Only group the members in the destination if the user wants that *and*
// it's not a ComImport interface. Member ordering in ComImport interfaces
// matters, so we don't want to much with them.
- var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var insertionBehavior = options.GetOption(ImplementTypeOptions.InsertionBehavior);
var groupMembers = !isComImport &&
insertionBehavior == ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind;
@@ -203,6 +203,7 @@ public Task GetUpdatedDocumentAsync(CancellationToken cancellationToke
private ImmutableArray GenerateMembers(
Compilation compilation,
ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> unimplementedMembers,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
// As we go along generating members we may end up with conflicts. For example, say
@@ -229,7 +230,9 @@ public Task GetUpdatedDocumentAsync(CancellationToken cancellationToke
foreach (var unimplementedInterfaceMember in unimplementedInterfaceMembers)
{
- var member = GenerateMember(compilation, unimplementedInterfaceMember, implementedVisibleMembers, cancellationToken);
+ var member = GenerateMember(
+ compilation, unimplementedInterfaceMember, implementedVisibleMembers,
+ propertyGenerationBehavior, cancellationToken);
if (member != null)
{
implementedMembers.Add(member);
@@ -272,6 +275,7 @@ private string DetermineMemberName(ISymbol member, List implementedVisi
Compilation compilation,
ISymbol member,
List implementedVisibleMembers,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
// First check if we already generate a member that matches the member we want to
@@ -308,7 +312,9 @@ private string DetermineMemberName(ISymbol member, List implementedVisi
var syntaxFacts = Document.GetLanguageService();
var addUnsafe = member.IsUnsafe() && !syntaxFacts.IsUnsafeContext(State.Location);
- return GenerateMember(compilation, member, memberName, generateInvisibleMember, generateAbstractly, addNew, addUnsafe, cancellationToken);
+ return GenerateMember(
+ compilation, member, memberName, generateInvisibleMember, generateAbstractly,
+ addNew, addUnsafe, propertyGenerationBehavior, cancellationToken);
}
private bool GenerateInvisibleMember(ISymbol member, string memberName)
@@ -376,6 +382,7 @@ private static bool IsUnexpressibleTypeParameter(ITypeParameterSymbol typeParame
bool generateAbstractly,
bool addNew,
bool addUnsafe,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
var factory = this.Document.GetLanguageService();
@@ -386,35 +393,28 @@ private static bool IsUnexpressibleTypeParameter(ITypeParameterSymbol typeParame
? Accessibility.Public
: Accessibility.Private;
- if (member.Kind == SymbolKind.Method)
- {
- var method = (IMethodSymbol)member;
-
- return GenerateMethod(compilation, method, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName, cancellationToken);
- }
- else if (member.Kind == SymbolKind.Property)
- {
- var property = (IPropertySymbol)member;
-
- return GenerateProperty(compilation, property, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName, cancellationToken);
- }
- else if (member.Kind == SymbolKind.Event)
+ switch (member)
{
- var @event = (IEventSymbol)member;
-
- var accessor = CodeGenerationSymbolFactory.CreateAccessorSymbol(
- attributes: default(ImmutableArray),
- accessibility: Accessibility.NotApplicable,
- statements: factory.CreateThrowNotImplementedStatementBlock(compilation));
-
- return CodeGenerationSymbolFactory.CreateEventSymbol(
- @event,
- accessibility: accessibility,
- modifiers: modifiers,
- explicitInterfaceSymbol: useExplicitInterfaceSymbol ? @event : null,
- name: memberName,
- addMethod: GetAddOrRemoveMethod(generateInvisibly, accessor, memberName, factory.AddEventHandler),
- removeMethod: GetAddOrRemoveMethod(generateInvisibly, accessor, memberName, factory.RemoveEventHandler));
+ case IMethodSymbol method:
+ return GenerateMethod(compilation, method, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName, cancellationToken);
+
+ case IPropertySymbol property:
+ return GenerateProperty(compilation, property, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName, propertyGenerationBehavior, cancellationToken);
+
+ case IEventSymbol @event:
+ var accessor = CodeGenerationSymbolFactory.CreateAccessorSymbol(
+ attributes: default(ImmutableArray),
+ accessibility: Accessibility.NotApplicable,
+ statements: factory.CreateThrowNotImplementedStatementBlock(compilation));
+
+ return CodeGenerationSymbolFactory.CreateEventSymbol(
+ @event,
+ accessibility: accessibility,
+ modifiers: modifiers,
+ explicitInterfaceSymbol: useExplicitInterfaceSymbol ? @event : null,
+ name: memberName,
+ addMethod: GetAddOrRemoveMethod(generateInvisibly, accessor, memberName, factory.AddEventHandler),
+ removeMethod: GetAddOrRemoveMethod(generateInvisibly, accessor, memberName, factory.RemoveEventHandler));
}
return null;
diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs
index d0166081792cb0b0c62ec06b267f2f8ec687db6d..c01ac73c953bffb1bbe90d3b47d203fa3c89ab21 100644
--- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs
+++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs
@@ -7,6 +7,7 @@
using System.Threading;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.Editing;
+using Microsoft.CodeAnalysis.ImplementType;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
@@ -25,16 +26,19 @@ internal partial class ImplementInterfaceCodeAction
bool generateAbstractly,
bool useExplicitInterfaceSymbol,
string memberName,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
var factory = this.Document.GetLanguageService();
var attributesToRemove = AttributesToRemove(compilation);
- var getAccessor = GenerateGetAccessor(compilation, property, accessibility, generateAbstractly,
- useExplicitInterfaceSymbol, attributesToRemove, cancellationToken);
+ var getAccessor = GenerateGetAccessor(
+ compilation, property, accessibility, generateAbstractly, useExplicitInterfaceSymbol,
+ propertyGenerationBehavior, attributesToRemove, cancellationToken);
- var setAccessor = GenerateSetAccessor(compilation, property, accessibility,
- generateAbstractly, useExplicitInterfaceSymbol, attributesToRemove, cancellationToken);
+ var setAccessor = GenerateSetAccessor(
+ compilation, property, accessibility, generateAbstractly, useExplicitInterfaceSymbol,
+ propertyGenerationBehavior, attributesToRemove, cancellationToken);
var syntaxFacts = Document.GetLanguageService();
var parameterNames = NameGenerator.EnsureUniqueness(
@@ -73,6 +77,7 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
Accessibility accessibility,
bool generateAbstractly,
bool useExplicitInterfaceSymbol,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
INamedTypeSymbol[] attributesToRemove,
CancellationToken cancellationToken)
{
@@ -81,6 +86,12 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
return null;
}
+ if (property.GetMethod == null)
+ {
+ // Can't have an auto-prop with just a setter.
+ propertyGenerationBehavior = ImplementTypePropertyGenerationBehavior.PreferThrowingProperties;
+ }
+
var setMethod = property.SetMethod.RemoveInaccessibleAttributesAndAttributesOfTypes(
this.State.ClassOrStructType,
attributesToRemove);
@@ -90,7 +101,8 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
attributes: default(ImmutableArray),
accessibility: accessibility,
explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property.SetMethod : null,
- statements: GetSetAccessorStatements(compilation, property, generateAbstractly, cancellationToken));
+ statements: GetSetAccessorStatements(
+ compilation, property, generateAbstractly, propertyGenerationBehavior, cancellationToken));
}
private IMethodSymbol GenerateGetAccessor(
@@ -99,6 +111,7 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
Accessibility accessibility,
bool generateAbstractly,
bool useExplicitInterfaceSymbol,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
INamedTypeSymbol[] attributesToRemove,
CancellationToken cancellationToken)
{
@@ -116,13 +129,15 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
attributes: default(ImmutableArray),
accessibility: accessibility,
explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property.GetMethod : null,
- statements: GetGetAccessorStatements(compilation, property, generateAbstractly, cancellationToken));
+ statements: GetGetAccessorStatements(
+ compilation, property, generateAbstractly, propertyGenerationBehavior, cancellationToken));
}
private ImmutableArray GetSetAccessorStatements(
Compilation compilation,
IPropertySymbol property,
bool generateAbstractly,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
if (generateAbstractly)
@@ -157,13 +172,16 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
return ImmutableArray.Create(factory.ExpressionStatement(expression));
}
- return factory.CreateThrowNotImplementedStatementBlock(compilation);
+ return propertyGenerationBehavior == ImplementTypePropertyGenerationBehavior.PreferAutoProperties
+ ? default(ImmutableArray)
+ : factory.CreateThrowNotImplementedStatementBlock(compilation);
}
private ImmutableArray GetGetAccessorStatements(
Compilation compilation,
IPropertySymbol property,
bool generateAbstractly,
+ ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
CancellationToken cancellationToken)
{
if (generateAbstractly)
@@ -196,8 +214,10 @@ private INamedTypeSymbol[] AttributesToRemove(Compilation compilation)
return ImmutableArray.Create(factory.ReturnStatement(expression));
}
- return factory.CreateThrowNotImplementedStatementBlock(compilation);
+ return propertyGenerationBehavior == ImplementTypePropertyGenerationBehavior.PreferAutoProperties
+ ? default(ImmutableArray)
+ : factory.CreateThrowNotImplementedStatementBlock(compilation);
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.cs
index 660fb901fe65e9bea6b0e41dfe3ca9140a0f3e9f..7af03d954dd68d50cb01a2226415604a121e6a9c 100644
--- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.cs
+++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.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.Collections.Generic;
using System.Linq;
using System.Threading;
diff --git a/src/Features/Core/Portable/ImplementType/ImplementTypeOptions.cs b/src/Features/Core/Portable/ImplementType/ImplementTypeOptions.cs
index 853ba9de2a7018ef55ac25316b4fddf8a60d56fa..3f008ab326e0c4cc6084687bfaebb28257993efe 100644
--- a/src/Features/Core/Portable/ImplementType/ImplementTypeOptions.cs
+++ b/src/Features/Core/Portable/ImplementType/ImplementTypeOptions.cs
@@ -10,6 +10,12 @@ internal enum ImplementTypeInsertionBehavior
AtTheEnd = 1,
}
+ internal enum ImplementTypePropertyGenerationBehavior
+ {
+ PreferThrowingProperties = 0,
+ PreferAutoProperties = 1,
+ }
+
internal static class ImplementTypeOptions
{
public static readonly PerLanguageOption InsertionBehavior =
@@ -19,5 +25,14 @@ internal static class ImplementTypeOptions
defaultValue: ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind,
storageLocations: new RoamingProfileStorageLocation(
$"TextEditor.%LANGUAGE%.{nameof(ImplementTypeOptions)}.{nameof(InsertionBehavior)}"));
+
+ public static readonly PerLanguageOption PropertyGenerationBehavior =
+ new PerLanguageOption(
+ nameof(ImplementTypeOptions),
+ nameof(PropertyGenerationBehavior),
+ defaultValue: ImplementTypePropertyGenerationBehavior.PreferThrowingProperties,
+ storageLocations: new RoamingProfileStorageLocation(
+ $"TextEditor.%LANGUAGE%.{nameof(ImplementTypeOptions)}.{nameof(PropertyGenerationBehavior)}"));
+
}
}
\ No newline at end of file
diff --git a/src/NuGet/NuGet.proj b/src/NuGet/NuGet.proj
index 7c043f413f0e77a5c8b493d9f5e59f91b2b85733..2cf66880af289e0e57d3b14b2702752dc1b4b307 100644
--- a/src/NuGet/NuGet.proj
+++ b/src/NuGet/NuGet.proj
@@ -5,19 +5,19 @@
-
+
-
+
-
+
-
+
-
\ No newline at end of file
+
diff --git a/src/Setup/DevDivPackages/Roslyn.proj b/src/Setup/DevDivPackages/Roslyn.proj
index 7fd9635c5c66ee23ca34362495d72d17ecfbd34a..f7349818e07da336612bf112cea0ae164ae447af 100644
--- a/src/Setup/DevDivPackages/Roslyn.proj
+++ b/src/Setup/DevDivPackages/Roslyn.proj
@@ -3,16 +3,16 @@
- $(OutDir)DevDivInsertionFiles
+ $(OutputPath)\DevDivInsertionFiles
$(InsertionFilesDir)\VS.Tools.Roslyn
- $(OutDir)DevDivPackages\Roslyn
+ $(OutputPath)\DevDivPackages\Roslyn
$(NuGetPerBuildPreReleaseVersion)
$(NuGetReleaseVersion)-cibuild
- $(OutDir)
+ $(OutputPath)
$(NuGetPerBuildPreReleaseVersion)
@@ -30,4 +30,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.swixproj b/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.swixproj
index 03f9fc4b50c60a3a6c24dac2f10da3a10189c6ae..1be98515de706f33cd1dc7398c5e67fd383932f2 100644
--- a/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.swixproj
+++ b/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.swixproj
@@ -6,7 +6,8 @@
neutral
false
- $(OutDir)Insertion
+ $(OutputPath)
+ $(OutputPath)\Insertion
true
vsix
@@ -14,7 +15,7 @@
- $(PackagePreprocessorDefinitions);Version=$(VsixVersion);OutputPath=$(OutDir)
+ $(PackagePreprocessorDefinitions);Version=$(VsixVersion);OutputPath=$(RoslynOutputPath)
$(BaseIntermediateOutputPath)$(Configuration)\
@@ -23,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj b/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj
index d17ac1dd62634d8e2764531c837fcb1844737cad..2436b6d3b4ba01ccc08443b62ea9759760360cfc 100644
--- a/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj
+++ b/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj
@@ -6,7 +6,7 @@
true
true
- $(OutDir)Insertion\
+ $(OutputPath)Insertion\
true
false
false
@@ -29,4 +29,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/DevDivVsix/MicrosoftCodeAnalysisLanguageServices/Microsoft.CodeAnalysis.LanguageServices.vsmanproj b/src/Setup/DevDivVsix/MicrosoftCodeAnalysisLanguageServices/Microsoft.CodeAnalysis.LanguageServices.vsmanproj
index f1e02c279325502c9acef1c6d62d88de1bf2fc69..bd502c3f9e81c606d5b67fb364237f728612bed3 100644
--- a/src/Setup/DevDivVsix/MicrosoftCodeAnalysisLanguageServices/Microsoft.CodeAnalysis.LanguageServices.vsmanproj
+++ b/src/Setup/DevDivVsix/MicrosoftCodeAnalysisLanguageServices/Microsoft.CodeAnalysis.LanguageServices.vsmanproj
@@ -6,7 +6,7 @@
true
true
- $(OutDir)Insertion
+ $(OutputPath)\Insertion
true
false
false
@@ -38,4 +38,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/DevDivVsix/PortableFacades/PortableFacades.swixproj b/src/Setup/DevDivVsix/PortableFacades/PortableFacades.swixproj
index f931f13551c3ff4ab3a078ad5085d678ef69dfc9..9163ec5a36dbcfbacd96b3701e8ceaf564ab84c3 100644
--- a/src/Setup/DevDivVsix/PortableFacades/PortableFacades.swixproj
+++ b/src/Setup/DevDivVsix/PortableFacades/PortableFacades.swixproj
@@ -6,7 +6,7 @@
neutral
false
- $(OutDir)Insertion
+ $(OutputPath)\Insertion
true
vsix
@@ -23,4 +23,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj b/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj
index a6fecdc827d36e390e91965dd3d8386211df2a61..89dc8b22de47e1bf72a01d8d741ad4eeb8975799 100644
--- a/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj
+++ b/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj
@@ -6,7 +6,7 @@
true
true
- $(OutDir)Insertion\
+ $(OutputPath)\Insertion\
true
false
false
@@ -24,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/SetupStep1.proj b/src/Setup/SetupStep1.proj
index 04f418a8306cfe5e2e6ba921188be63a69d81de6..2a5d8d0393e03190f4fa23a1dac1859393811b18 100644
--- a/src/Setup/SetupStep1.proj
+++ b/src/Setup/SetupStep1.proj
@@ -25,7 +25,7 @@
where building multiple projects that produce VSIXes larger than 10MB will race against each other -->
-
+
@@ -40,4 +40,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/SetupStep2.proj b/src/Setup/SetupStep2.proj
index 4f6b35d31de34f538fc3807b6aef21a700c7b1e5..aa04243ae80dd1b60db810f661da63fdab92cf87 100644
--- a/src/Setup/SetupStep2.proj
+++ b/src/Setup/SetupStep2.proj
@@ -8,7 +8,7 @@
-
+
@@ -23,4 +23,4 @@
-
\ No newline at end of file
+
diff --git a/src/Setup/Vsix/Vsix.proj b/src/Setup/Vsix/Vsix.proj
index 1b53f5670354939bbd17732bd38f9b714375312c..21b7f52dfded6ca6035bfd283e746d60a7aa34c8 100644
--- a/src/Setup/Vsix/Vsix.proj
+++ b/src/Setup/Vsix/Vsix.proj
@@ -6,7 +6,7 @@
-
+
-
\ No newline at end of file
+
diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml
index bb02d9d38ec13917d81a2cccc549eafbb86477a2..a365fc75093acacec5c213bb2aee71f04a8884c4 100644
--- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml
+++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml
@@ -100,6 +100,16 @@
x:Name="at_the_end"
Content="{x:Static local:AdvancedOptionPageStrings.Option_at_the_end}"/>
+
+
+
+
+
+
diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs
index 77b0d7d0f70d3d3455e2fe082aaf5137627543b6..54cb686744fd19f79b8ea61fd682945b6d42ae33 100644
--- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs
+++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs
@@ -48,6 +48,9 @@ public AdvancedOptionPageControl(IServiceProvider serviceProvider) : base(servic
BindToOption(with_other_members_of_the_same_kind, ImplementTypeOptions.InsertionBehavior, ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind, LanguageNames.CSharp);
BindToOption(at_the_end, ImplementTypeOptions.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd, LanguageNames.CSharp);
+
+ BindToOption(prefer_throwing_properties, ImplementTypeOptions.PropertyGenerationBehavior, ImplementTypePropertyGenerationBehavior.PreferThrowingProperties, LanguageNames.CSharp);
+ BindToOption(prefer_auto_properties, ImplementTypeOptions.PropertyGenerationBehavior, ImplementTypePropertyGenerationBehavior.PreferAutoProperties, LanguageNames.CSharp);
}
}
}
\ No newline at end of file
diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs
index f6b1e507ddf29656b5c20a2771a9832304e2b237..f80af24135173868abf7fd31d1dc345b5f769d02 100644
--- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs
+++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs
@@ -62,6 +62,15 @@ public static string Option_with_other_members_of_the_same_kind
public static string Option_at_the_end
=> ServicesVSResources.at_the_end;
+ public static string Option_When_generating_properties
+ => ServicesVSResources.When_generating_properties;
+
+ public static string Option_prefer_auto_properties
+ => ServicesVSResources.prefer_auto_properties;
+
+ public static string Option_prefer_throwing_properties
+ => ServicesVSResources.prefer_throwing_properties;
+
public static string Option_GenerateXmlDocCommentsForTripleSlash
{
get { return CSharpVSResources.Generate_XML_documentation_comments_for; }
diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs b/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs
index ed9696771756478e4d2093000a42e37ba4c7661c..f151708ab124c6cf70bb5bae294e3814aa82466e 100644
--- a/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs
+++ b/src/VisualStudio/Core/Def/ServicesVSResources.Designer.cs
@@ -1457,6 +1457,15 @@ internal class ServicesVSResources {
}
}
+ ///
+ /// Looks up a localized string similar to prefer auto properties.
+ ///
+ internal static string prefer_auto_properties {
+ get {
+ return ResourceManager.GetString("prefer_auto_properties", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Prefer braces.
///
@@ -1547,6 +1556,15 @@ internal class ServicesVSResources {
}
}
+ ///
+ /// Looks up a localized string similar to prefer throwing properties.
+ ///
+ internal static string prefer_throwing_properties {
+ get {
+ return ResourceManager.GetString("prefer_throwing_properties", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Preference.
///
@@ -2164,7 +2182,7 @@ internal class ServicesVSResources {
internal static string Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio {
get {
return ResourceManager.GetString("Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_er" +
- "ror_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual Studio", resourceCulture);
+ "ror_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio", resourceCulture);
}
}
@@ -2332,6 +2350,15 @@ internal class ServicesVSResources {
}
}
+ ///
+ /// Looks up a localized string similar to When generating properties:.
+ ///
+ internal static string When_generating_properties {
+ get {
+ return ResourceManager.GetString("When_generating_properties", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to When inserting properties, events and methods, place them:.
///
diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx
index 03a31223fb3d9d96781585912f511f9e47f9e7e1..e23b643793526a8f64a3dea2187780b1c1da2624 100644
--- a/src/VisualStudio/Core/Def/ServicesVSResources.resx
+++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx
@@ -873,7 +873,7 @@ Additional information: {1}
Pick members
-
+
Unfortunately, a process used by Visual Studio has encountered an unrecoverable error. We recommend saving your work, and then closing and restarting Visual Studio.
@@ -900,6 +900,15 @@ Additional information: {1}
VisualStudioWorkspace.TryApplyChanges cannot be called from a background thread.
+
+ prefer auto properties
+
+
+ prefer throwing properties
+
+
+ When generating properties:
+
Options
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs
index 10bf64e7dd8608e739062feb2bf979094afcd6e6..27ed913c8074e485cbe8cf51b9739f9456a6326c 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs
@@ -30,7 +30,7 @@ static void Main(string[] args)
}
}";
- [Fact, Trait(Traits.Feature, Traits.Features.EncapsulateField)]
+ [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18879"), Trait(Traits.Feature, Traits.Features.EncapsulateField)]
public void EncapsulateThroughCommand()
{
SetUpEditor(TestSource);
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpNavigateTo.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpNavigateTo.cs
index e76f870e7dba7fc99e6f442dd1e8d6bf7b03e48f..0b61bb1fb0e70fcf36bb7390a0c9110a17f215f1 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpNavigateTo.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpNavigateTo.cs
@@ -20,7 +20,7 @@ public CSharpNavigateTo(VisualStudioInstanceFactory instanceFactory)
{
}
- [Fact, Trait(Traits.Feature, Traits.Features.SignatureHelp)]
+ [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18870"), Trait(Traits.Feature, Traits.Features.SignatureHelp)]
public void NavigateTo()
{
var project = new ProjectUtils.Project(ProjectName);
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIntellisense.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIntellisense.cs
index 2f7df53f536bf2ebe04bf8662af9081b1bbb8dd5..d37ce11a21f05308746a1619ad18c58c9d1b945f 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIntellisense.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpReplIntellisense.cs
@@ -61,7 +61,7 @@ public void VerifySharpLoadCompletionList()
VisualStudio.InteractiveWindow.Verify.CompletionItemsExist("C:");
}
- [Fact]
+ [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18877")]
public void VerifyNoCrashOnEnter()
{
VisualStudio.Workspace.SetUseSuggestionMode(false);
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpSendToInteractive.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpSendToInteractive.cs
index 4c3c3bb94c53c6f27150c77cb15650fc58e02edc..1d0abb7af76a3789efcc3f39106ef2dfd5fc1d03 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpSendToInteractive.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpSendToInteractive.cs
@@ -214,7 +214,7 @@ public void AddAssemblyReferenceAndTypesToInteractive()
VisualStudio.Workspace.WaitForAsyncOperations(FeatureAttribute.SolutionCrawler);
}
- [Fact]
+ [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18880")]
public void ResetInteractiveFromProjectAndVerify()
{
var assembly = new ProjectUtils.AssemblyReference("System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicNavigateTo.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicNavigateTo.cs
index 4afe5c5204927fd7f0d43101a76f8e4243087d24..f44df3a332cb8728cea90d872edec5500964d2de 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicNavigateTo.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicNavigateTo.cs
@@ -18,7 +18,7 @@ public BasicNavigateTo(VisualStudioInstanceFactory instanceFactory)
{
}
- [Fact, Trait(Traits.Feature, Traits.Features.SignatureHelp)]
+ [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18870"), Trait(Traits.Feature, Traits.Features.SignatureHelp)]
public void NavigateTo()
{
var project = new ProjectUtils.Project(ProjectName);
diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml
index e983f378c28f91d3aa7691063e2f587d65fd91b2..0a2d5fe43a8df29e76dac0bae95c45e811f04643 100644
--- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml
+++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml
@@ -110,6 +110,16 @@
x:Name="at_the_end"
Content="{x:Static local:AdvancedOptionPageStrings.Option_at_the_end}"/>
+
+
+
+
+
+
diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb
index 6e069fc4a36478b5565cac12531788ad1c3422f8..5f210c872d6c3f1a781b4467dccf6f830092db7b 100644
--- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb
+++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb
@@ -45,6 +45,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
BindToOption(with_other_members_of_the_same_kind, ImplementTypeOptions.InsertionBehavior, ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind, LanguageNames.VisualBasic)
BindToOption(at_the_end, ImplementTypeOptions.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd, LanguageNames.VisualBasic)
+
+ BindToOption(prefer_throwing_properties, ImplementTypeOptions.PropertyGenerationBehavior, ImplementTypePropertyGenerationBehavior.PreferThrowingProperties, LanguageNames.VisualBasic)
+ BindToOption(prefer_auto_properties, ImplementTypeOptions.PropertyGenerationBehavior, ImplementTypePropertyGenerationBehavior.PreferAutoProperties, LanguageNames.VisualBasic)
End Sub
End Class
End Namespace
\ No newline at end of file
diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb
index 21e2639bdd9ba4b10a65f3250ba7b2fd6370cd8d..6443bafbed7cd07c6693b9dab3c7db54fa834369 100644
--- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb
+++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb
@@ -84,6 +84,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
Public ReadOnly Property Option_with_other_members_of_the_same_kind As String =
ServicesVSResources.with_other_members_of_the_same_kind
+ Public ReadOnly Property Option_When_generating_properties As String =
+ ServicesVSResources.When_generating_properties
+
+ Public ReadOnly Property Option_prefer_auto_properties As String =
+ ServicesVSResources.prefer_auto_properties
+
+ Public ReadOnly Property Option_prefer_throwing_properties As String =
+ ServicesVSResources.prefer_throwing_properties
+
Public ReadOnly Property Option_at_the_end As String =
ServicesVSResources.at_the_end
diff --git a/src/Workspaces/Core/Portable/PatternMatching/PatternMatcher.cs b/src/Workspaces/Core/Portable/PatternMatching/PatternMatcher.cs
index 6d3aee3ca9eeb2cb1078e00c363a5858178c494c..5629622dc9b6864ccc1e8d7ec1e7c8ba3dbb7d09 100644
--- a/src/Workspaces/Core/Portable/PatternMatching/PatternMatcher.cs
+++ b/src/Workspaces/Core/Portable/PatternMatching/PatternMatcher.cs
@@ -246,18 +246,27 @@ public PatternMatches GetMatches(string candidate, string dottedContainer)
/// so, unless you need to know the full set of matches, use this version.
///
/// The word being tested.
- /// Whether or not the matched spans should be included with results
+ /// Whether or not the matched spans should be included with results
/// If this was a match, the first element of the set of match types that occurred while matching the
/// patterns. If it was not a match, it returns null.
- public PatternMatch? GetFirstMatch(string candidate, bool inludeMatchSpans = false)
+ public PatternMatch? GetFirstMatch(
+ string candidate, bool includeMatchSpans)
{
if (SkipMatch(candidate))
{
return null;
}
- return MatchPatternSegment(candidate, inludeMatchSpans, _fullPatternSegment, wantAllMatches: false, allMatches: out _, fuzzyMatch: false) ??
- MatchPatternSegment(candidate, inludeMatchSpans, _fullPatternSegment, wantAllMatches: false, allMatches: out _, fuzzyMatch: true);
+ return GetFirstMatchWorker(candidate, includeMatchSpans, fuzzyMatch: false) ??
+ GetFirstMatchWorker(candidate, includeMatchSpans, fuzzyMatch: true);
+ }
+
+ private PatternMatch? GetFirstMatchWorker(
+ string candidate, bool includeMatchSpans, bool fuzzyMatch)
+ {
+ return MatchPatternSegment(
+ candidate, includeMatchSpans, _fullPatternSegment,
+ wantAllMatches: false, allMatches: out _, fuzzyMatch: fuzzyMatch);
}
private StringBreaks GetWordSpans(string word)
@@ -268,13 +277,6 @@ private StringBreaks GetWordSpans(string word)
}
}
- internal PatternMatch? MatchSingleWordPattern_ForTestingOnly(string candidate)
- {
- return MatchPatternChunk(candidate, includeMatchSpans: true,
- patternChunk: _fullPatternSegment.TotalTextChunk, punctuationStripped: false,
- fuzzyMatch: false);
- }
-
private static bool ContainsUpperCaseLetter(string pattern)
{
// Expansion of "foreach(char ch in pattern)" to avoid a CharEnumerator allocation
@@ -443,12 +445,10 @@ private static bool ContainsSpaceOrAsterisk(string text)
var singleMatch = MatchPatternSegment(candidate, includeMatchSpans, patternSegment,
wantAllMatches: true, fuzzyMatch: fuzzyMatch, allMatches: out var matches);
- if (singleMatch.HasValue)
- {
- return ImmutableArray.Create(singleMatch.Value);
- }
- return matches;
+ return singleMatch.HasValue
+ ? ImmutableArray.Create(singleMatch.Value)
+ : matches;
}
///
@@ -554,17 +554,18 @@ private static bool ContainsSpaceOrAsterisk(string text)
return null;
}
- if (!wantAllMatches || subWordTextChunks.Length == 1)
- {
- // Stop at the first word
- return result;
- }
-
matches.Add(result.Value);
}
- allMatches = matches.ToImmutable();
- return null;
+ if (wantAllMatches && matches.Count >= 2)
+ {
+ allMatches = matches.ToImmutable();
+ return null;
+ }
+ else
+ {
+ return matches.FirstOrNullable();
+ }
}
finally
{