提交 ee130495 编写于 作者: C CyrusNajmabadi

Merge remote-tracking branch 'upstream/master' into findRefsRQNames1

......@@ -11,14 +11,14 @@
<_CopyReferences>false</_CopyReferences>
<_CopyProjectReferences>false</_CopyProjectReferences>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
<OutDir>$(OutDir)Exes\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)Exes\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == 'UnitTest'">
<PropertyGroup>
<_IsAnyUnitTest>true</_IsAnyUnitTest>
<CopyNuGetImplementations>true</CopyNuGetImplementations>
<OutDir>$(OutDir)UnitTests\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)UnitTests\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == 'UnitTestPortable' OR '$(RoslynProjectType)' == 'UnitTestDesktop'">
......@@ -39,21 +39,21 @@
<_IsAnyUnitTest>true</_IsAnyUnitTest>
<_IsAnyPortableUnitTest>true</_IsAnyPortableUnitTest>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
<OutDir>$(OutDir)Dlls\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)Dlls\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == 'CompilerGeneratorTool'">
<PropertyGroup>
<_CopyReferences>false</_CopyReferences>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
<OutDir>$(OutDir)Exes\</OutDir>
<OutputPath>$(OutputPath)Exes\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == 'Vsix'">
<PropertyGroup>
<_CopyReferences>false</_CopyReferences>
<CopyNuGetImplementations>true</CopyNuGetImplementations>
<OutDir>$(OutDir)Vsix\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)Vsix\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == 'DeploymentTest'">
......@@ -62,8 +62,8 @@
<PropertyGroup>
<AllowedReferenceRelatedFileExtensions>$(AllowedReferenceRelatedFileExtensions);.pdb</AllowedReferenceRelatedFileExtensions>
<CopyNuGetImplementations>true</CopyNuGetImplementations>
<OutDir Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable'">$(OutDir)CoreClrTest</OutDir>
<OutDir Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable'">$(OutDir)UnitTests\Portable\</OutDir>
<OutputPath Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable'">$(OutputPath)CoreClrTest</OutputPath>
<OutputPath Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable'">$(OutputPath)UnitTests\Portable\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == 'Custom'">
......@@ -74,19 +74,19 @@
<_CopyReferences>false</_CopyReferences>
<_CopyProjectReferences>false</_CopyProjectReferences>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
<OutDir>$(OutDir)Dlls\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)Dlls\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == '' AND '$(OutputType)' == 'Exe'">
<PropertyGroup>
<CopyNuGetImplementations>true</CopyNuGetImplementations>
<OutDir>$(OutDir)Exes\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)Exes\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
<When Condition="'$(RoslynProjectType)' == '' AND '$(OutputType)' == 'WinExe'">
<PropertyGroup>
<CopyNuGetImplementations>true</CopyNuGetImplementations>
<OutDir>$(OutDir)Exes\$(MSBuildProjectName)\</OutDir>
<OutputPath>$(OutputPath)Exes\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</When>
</Choose>
......@@ -114,7 +114,6 @@
</PropertyGroup>
<PropertyGroup>
<OutputPath>$(OutDir)</OutputPath>
<RoslynPublicKey>0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9</RoslynPublicKey>
<RoslynInternalKey>002400000480000094000000060200000024000052534131000400000100010055e0217eb635f69281051f9a823e0c7edd90f28063eb6c7a742a19b4f6139778ee0af438f47aed3b6e9f99838aa8dba689c7a71ddb860c96d923830b57bbd5cd6119406ddb9b002cf1c723bf272d6acbb7129e9d6dd5a5309c94e0ff4b2c884d45a55f475cd7dba59198086f61f5a8c8b5e601c0edbf269733f6f578fc8579c2</RoslynInternalKey>
......
......@@ -27,7 +27,7 @@
<SignAssembly>true</SignAssembly>
<UseRoslynAnalyzers Condition="'$(UseRoslynAnalyzers)' == ''">true</UseRoslynAnalyzers>
<BaseOutputPath Condition="'$(BaseOutputPath)' == ''">$(RepoRoot)Binaries\</BaseOutputPath>
<OutDir>$(BaseOutputPath)$(Configuration)\</OutDir>
<OutputPath>$(BaseOutputPath)$(Configuration)\</OutputPath>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">$(RepoRoot)Binaries\Obj\</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\$(MSBuildProjectName)\</IntermediateOutputPath>
......@@ -47,7 +47,7 @@
<MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
<!-- Disable AppX packaging for the Roslyn source. Not setting this to false has the side effect
that any builds of portable projects end up in a sub folder of $(OutDir). Search for this flag in
that any builds of portable projects end up in a sub folder of $(OutputPath). Search for this flag in
Microsoft.Common.CurrentVersion.targets to see how it is consumed -->
<WindowsAppContainer>false</WindowsAppContainer>
......
......@@ -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 <path> 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
}
}
......
......@@ -4066,7 +4066,7 @@ public class Test
// TODO...
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/18800")]
[Fact]
public void CS0306ERR_BadTypeArgument01()
{
var source =
......
......@@ -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);
......
......@@ -1552,5 +1552,38 @@ public override void M2<T>(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
......@@ -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
......@@ -42,6 +42,8 @@ private class SuggestedActionsSource : ForegroundThreadAffinitizedObject, ISugge
private Workspace _workspace;
private int _lastSolutionVersionReported;
public event EventHandler<EventArgs> 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<EventArgs> 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<bool> 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<IDocumentSupportsFeatureService>();
......@@ -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
......@@ -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<string> BreakIntoCharacterParts(string identifier)
private static IList<string> 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<TextSpan> 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<PatternMatch> TryMatchMultiWordPattern(string candida
}
}
}
}
}
\ No newline at end of file
......@@ -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
<Fact>
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
<Fact>
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
<Fact>
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
<Fact>
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
......
......@@ -2430,5 +2430,62 @@ End Class")
diagnosticId:=IDEDiagnosticIds.RemoveQualificationDiagnosticId,
diagnosticSeverity:=DiagnosticSeverity.Error)
End Function
<WorkItem(15996, "https://github.com/dotnet/roslyn/issues/15996")>
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)>
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
<WorkItem(15996, "https://github.com/dotnet/roslyn/issues/15996")>
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)>
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
<WorkItem(15996, "https://github.com/dotnet/roslyn/issues/15996")>
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)>
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
......@@ -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
<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 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
......@@ -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
<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 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
......@@ -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;
......
// 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<Document> 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<Document> GetEditAsync(CancellationToken cancellationToken)
memberDefinitions,
new CodeGenerationOptions(
_state.Location.GetLocation(),
autoInsertionLocation: groupMembers,
autoInsertionLocation: groupMembers,
sortMembers: groupMembers),
cancellationToken).ConfigureAwait(false);
}
private ImmutableArray<ISymbol> GenerateMembers(
ImmutableArray<(INamedTypeSymbol type, ImmutableArray<ISymbol> 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<Document> GetEditAsync(CancellationToken cancellationToken)
var syntaxFacts = _document.Project.LanguageServices.GetService<ISyntaxFactsService>();
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<Document> 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<SyntaxGenerator>();
var throwingBody = syntaxFactory.CreateThrowNotImplementedStatementBlock(
_model.Compilation);
var accessorBody = propertyGenerationBehavior == ImplementTypePropertyGenerationBehavior.PreferAutoProperties
? default(ImmutableArray<SyntaxNode>)
: syntaxFactory.CreateThrowNotImplementedStatementBlock(_model.Compilation);
var getMethod = ShouldGenerateAccessor(property.GetMethod)
? CodeGenerationSymbolFactory.CreateAccessorSymbol(
property.GetMethod,
attributes: default(ImmutableArray<AttributeData>),
accessibility: property.GetMethod.ComputeResultantAccessibility(_state.ClassType),
statements: throwingBody)
statements: accessorBody)
: null;
var setMethod = ShouldGenerateAccessor(property.SetMethod)
......@@ -147,7 +154,7 @@ public async Task<Document> GetEditAsync(CancellationToken cancellationToken)
property.SetMethod,
attributes: default(ImmutableArray<AttributeData>),
accessibility: property.SetMethod.ComputeResultantAccessibility(_state.ClassType),
statements: throwingBody)
statements: accessorBody)
: null;
return CodeGenerationSymbolFactory.CreatePropertySymbol(
......@@ -158,7 +165,8 @@ public async Task<Document> 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
......@@ -176,15 +176,15 @@ public Task<Document> 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<Document> GetUpdatedDocumentAsync(CancellationToken cancellationToke
private ImmutableArray<ISymbol> GenerateMembers(
Compilation compilation,
ImmutableArray<(INamedTypeSymbol type, ImmutableArray<ISymbol> 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<Document> 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<ISymbol> implementedVisi
Compilation compilation,
ISymbol member,
List<ISymbol> 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<ISymbol> implementedVisi
var syntaxFacts = Document.GetLanguageService<ISyntaxFactsService>();
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<SyntaxGenerator>();
......@@ -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<AttributeData>),
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<AttributeData>),
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;
......
......@@ -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<SyntaxGenerator>();
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<ISyntaxFactsService>();
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<AttributeData>),
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<AttributeData>),
accessibility: accessibility,
explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property.GetMethod : null,
statements: GetGetAccessorStatements(compilation, property, generateAbstractly, cancellationToken));
statements: GetGetAccessorStatements(
compilation, property, generateAbstractly, propertyGenerationBehavior, cancellationToken));
}
private ImmutableArray<SyntaxNode> 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<SyntaxNode>)
: factory.CreateThrowNotImplementedStatementBlock(compilation);
}
private ImmutableArray<SyntaxNode> 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<SyntaxNode>)
: factory.CreateThrowNotImplementedStatementBlock(compilation);
}
}
}
}
}
\ No newline at end of file
// 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;
......
......@@ -10,6 +10,12 @@ internal enum ImplementTypeInsertionBehavior
AtTheEnd = 1,
}
internal enum ImplementTypePropertyGenerationBehavior
{
PreferThrowingProperties = 0,
PreferAutoProperties = 1,
}
internal static class ImplementTypeOptions
{
public static readonly PerLanguageOption<ImplementTypeInsertionBehavior> 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<ImplementTypePropertyGenerationBehavior> PropertyGenerationBehavior =
new PerLanguageOption<ImplementTypePropertyGenerationBehavior>(
nameof(ImplementTypeOptions),
nameof(PropertyGenerationBehavior),
defaultValue: ImplementTypePropertyGenerationBehavior.PreferThrowingProperties,
storageLocations: new RoamingProfileStorageLocation(
$"TextEditor.%LANGUAGE%.{nameof(ImplementTypeOptions)}.{nameof(PropertyGenerationBehavior)}"));
}
}
\ No newline at end of file
......@@ -5,19 +5,19 @@
<Target Name="Build">
<!-- NuGetPerBuildPreReleaseVersion -->
<Exec Command="$(OutDir)Exes\csi\csi.exe $(MSBuildThisFileDirectory)BuildNuGets.csx $(OutDir) $(NuGetPerBuildPreReleaseVersion) $(OutDir)NuGet\PerBuildPreRelease" Condition="'$(NuGetPerBuildPreReleaseVersion)' != ''" />
<Exec Command="$(OutputPath)Exes\csi\csi.exe $(MSBuildThisFileDirectory)BuildNuGets.csx $(OutputPath) $(NuGetPerBuildPreReleaseVersion) $(OutputPath)NuGet\PerBuildPreRelease" Condition="'$(NuGetPerBuildPreReleaseVersion)' != ''" />
<!-- NuGetPreReleaseVersion -->
<Exec Command="$(OutDir)Exes\csi\csi.exe $(MSBuildThisFileDirectory)BuildNuGets.csx $(OutDir) $(NuGetPreReleaseVersion) $(OutDir)NuGet\PreRelease" Condition="'$(NuGetPreReleaseVersion)' != ''" />
<Exec Command="$(OutputPath)Exes\csi\csi.exe $(MSBuildThisFileDirectory)BuildNuGets.csx $(OutputPath) $(NuGetPreReleaseVersion) $(OutputPath)NuGet\PreRelease" Condition="'$(NuGetPreReleaseVersion)' != ''" />
<!-- NuGetReleaseVersion -->
<Exec Command="$(OutDir)Exes\csi\csi.exe $(MSBuildThisFileDirectory)BuildNuGets.csx $(OutDir) $(NuGetReleaseVersion) $(OutDir)NuGet\Release" Condition="'$(NuGetReleaseVersion)' != ''" />
<Exec Command="$(OutputPath)Exes\csi\csi.exe $(MSBuildThisFileDirectory)BuildNuGets.csx $(OutputPath) $(NuGetReleaseVersion) $(OutputPath)NuGet\Release" Condition="'$(NuGetReleaseVersion)' != ''" />
</Target>
<Target Name="Clean">
<RemoveDir Directories="$(OutDir)NuGet" />
<RemoveDir Directories="$(OutputPath)NuGet" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build">
</Target>
</Project>
\ No newline at end of file
</Project>
......@@ -3,16 +3,16 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\build\Targets\Settings.props" />
<PropertyGroup>
<InsertionFilesDir>$(OutDir)DevDivInsertionFiles</InsertionFilesDir>
<InsertionFilesDir>$(OutputPath)\DevDivInsertionFiles</InsertionFilesDir>
<VsToolsetDir>$(InsertionFilesDir)\VS.Tools.Roslyn</VsToolsetDir>
<PackagesOutDir>$(OutDir)DevDivPackages\Roslyn</PackagesOutDir>
<PackagesOutDir>$(OutputPath)\DevDivPackages\Roslyn</PackagesOutDir>
</PropertyGroup>
<ItemGroup>
<NuSpec Include="$(InsertionFilesDir)\VS.ExternalAPIs.Roslyn.nuspec">
<Version>$(NuGetPerBuildPreReleaseVersion)</Version>
<!-- TFS build number isn't set on CI server -->
<Version Condition="'$(NuGetPerBuildPreReleaseVersion)' == ''">$(NuGetReleaseVersion)-cibuild</Version>
<BaseDir>$(OutDir)</BaseDir>
<BaseDir>$(OutputPath)</BaseDir>
</NuSpec>
<NuSpec Include="$(VsToolsetDir)\VS.Tools.Roslyn.nuspec">
<Version>$(NuGetPerBuildPreReleaseVersion)</Version>
......@@ -30,4 +30,4 @@
<Target Name="Clean">
<RemoveDir Directories="$(PackagesOutDir)" />
</Target>
</Project>
\ No newline at end of file
</Project>
......@@ -6,7 +6,8 @@
<PropertyGroup>
<OutputArchitecture>neutral</OutputArchitecture>
<OutputLocalized>false</OutputLocalized>
<OutputPath>$(OutDir)Insertion</OutputPath>
<RoslynOutputPath>$(OutputPath)</RoslynOutputPath>
<OutputPath>$(OutputPath)\Insertion</OutputPath>
<IsPackage>true</IsPackage>
<OutputType>vsix</OutputType>
</PropertyGroup>
......@@ -14,7 +15,7 @@
<Import Project="$(NuGetPackageRoot)\MicroBuild.Core\$(MicroBuildCoreVersion)\build\MicroBuild.Core.props" />
<PropertyGroup>
<PackagePreprocessorDefinitions>$(PackagePreprocessorDefinitions);Version=$(VsixVersion);OutputPath=$(OutDir)</PackagePreprocessorDefinitions>
<PackagePreprocessorDefinitions>$(PackagePreprocessorDefinitions);Version=$(VsixVersion);OutputPath=$(RoslynOutputPath)</PackagePreprocessorDefinitions>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
......@@ -23,4 +24,4 @@
</ItemGroup>
<Import Project="$(NuGetPackageRoot)\MicroBuild.Core\$(MicroBuildCoreVersion)\build\MicroBuild.Core.targets" />
</Project>
\ No newline at end of file
</Project>
......@@ -6,7 +6,7 @@
<PropertyGroup>
<FinalizeManifest>true</FinalizeManifest>
<FinalizeSkipLayout>true</FinalizeSkipLayout>
<OutputPath>$(OutDir)Insertion\</OutputPath>
<OutputPath>$(OutputPath)Insertion\</OutputPath>
<IsPackage>true</IsPackage>
<FinalizeValidate>false</FinalizeValidate>
<ValidateManifest>false</ValidateManifest>
......@@ -29,4 +29,4 @@
</ItemGroup>
<Target Name="ValidateManifest" />
</Project>
\ No newline at end of file
</Project>
......@@ -6,7 +6,7 @@
<PropertyGroup>
<FinalizeManifest>true</FinalizeManifest>
<FinalizeSkipLayout>true</FinalizeSkipLayout>
<OutputPath>$(OutDir)Insertion</OutputPath>
<OutputPath>$(OutputPath)\Insertion</OutputPath>
<IsPackage>true</IsPackage>
<FinalizeValidate>false</FinalizeValidate>
<ValidateManifest>false</ValidateManifest>
......@@ -38,4 +38,4 @@
</ItemGroup>
<Target Name="ValidateManifest" />
</Project>
\ No newline at end of file
</Project>
......@@ -6,7 +6,7 @@
<PropertyGroup>
<OutputArchitecture>neutral</OutputArchitecture>
<OutputLocalized>false</OutputLocalized>
<OutputPath>$(OutDir)Insertion</OutputPath>
<OutputPath>$(OutputPath)\Insertion</OutputPath>
<IsPackage>true</IsPackage>
<OutputType>vsix</OutputType>
</PropertyGroup>
......@@ -23,4 +23,4 @@
</ItemGroup>
<Import Project="$(NuGetPackageRoot)\MicroBuild.Core\$(MicroBuildCoreVersion)\build\MicroBuild.Core.targets" />
</Project>
\ No newline at end of file
</Project>
......@@ -6,7 +6,7 @@
<PropertyGroup>
<FinalizeManifest>true</FinalizeManifest>
<FinalizeSkipLayout>true</FinalizeSkipLayout>
<OutputPath>$(OutDir)Insertion\</OutputPath>
<OutputPath>$(OutputPath)\Insertion\</OutputPath>
<IsPackage>true</IsPackage>
<FinalizeValidate>false</FinalizeValidate>
<ValidateManifest>false</ValidateManifest>
......@@ -24,4 +24,4 @@
</ItemGroup>
<Target Name="ValidateManifest" />
</Project>
\ No newline at end of file
</Project>
......@@ -25,7 +25,7 @@
where building multiple projects that produce VSIXes larger than 10MB will race against each other -->
<MSBuild Projects="@(Project)" Targets="Build" BuildInParallel="false" />
<Copy SourceFiles="@(PowerShellScriptsToCopy)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(PowerShellScriptsToCopy)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(PowerShellScriptsToCopy)" DestinationFolder="Templates\CSharp\Diagnostic\Analyzer" />
<Copy SourceFiles="@(PowerShellScriptsToCopy)" DestinationFolder="Templates\VisualBasic\Diagnostic\Analyzer\tools" />
......@@ -40,4 +40,4 @@
<Target Name="Rebuild">
<MSBuild Projects="@(Project)" Targets="Rebuild" BuildInParallel="false" />
</Target>
</Project>
\ No newline at end of file
</Project>
......@@ -8,7 +8,7 @@
<!-- Build CoreXT packages for insertion into DevDiv (order of the following actions matters) -->
<MSBuild Projects="DevDivInsertionFiles\DevDivInsertionFiles.sln" />
<Exec Command="&quot;$(OutDir)\Exes\DevDivInsertionFiles\Roslyn.BuildDevDivInsertionFiles.exe&quot; &quot;$(OutDir)\&quot; &quot;$(MSBuildThisFileDirectory)\&quot; &quot;$(NuGetPackageRoot)&quot; $(AssemblyVersion)" LogStandardErrorAsError="true" />
<Exec Command="&quot;$(OutputPath)\Exes\DevDivInsertionFiles\Roslyn.BuildDevDivInsertionFiles.exe&quot; &quot;$(OutputPath)\&quot; &quot;$(MSBuildThisFileDirectory)\&quot; &quot;$(NuGetPackageRoot)&quot; $(AssemblyVersion)" LogStandardErrorAsError="true" />
<MSBuild Projects="DevDivPackages\Roslyn.proj" />
<MSBuild Projects="DevDivVsix\PortableFacades\PortableFacades.vsmanproj" />
<MSBuild Projects="DevDivVsix\CompilersPackage\Microsoft.CodeAnalysis.Compilers.vsmanproj" />
......@@ -23,4 +23,4 @@
<!-- VSIX Gallery -->
<MSBuild Projects="Vsix\Vsix.proj" />
</Target>
</Project>
\ No newline at end of file
</Project>
......@@ -6,7 +6,7 @@
<VsixUploadConfigs Include="myget_org-extensions.config" />
</ItemGroup>
<Target Name="Build">
<Copy SourceFiles="@(VsixUploadConfigs)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(VsixUploadConfigs)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" />
</Target>
<Target Name="Clean" />
</Project>
\ No newline at end of file
</Project>
......@@ -100,6 +100,16 @@
x:Name="at_the_end"
Content="{x:Static local:AdvancedOptionPageStrings.Option_at_the_end}"/>
</StackPanel>
<Label Content="{x:Static local:AdvancedOptionPageStrings.Option_When_generating_properties}"/>
<StackPanel Margin="15, 0, 0, 0">
<RadioButton GroupName="Property_generation_behavior"
x:Name="prefer_throwing_properties"
Content="{x:Static local:AdvancedOptionPageStrings.Option_prefer_throwing_properties}"/>
<RadioButton GroupName="Property_generation_behavior"
x:Name="prefer_auto_properties"
Content="{x:Static local:AdvancedOptionPageStrings.Option_prefer_auto_properties}"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
......
......@@ -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
......@@ -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; }
......
......@@ -1457,6 +1457,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to prefer auto properties.
/// </summary>
internal static string prefer_auto_properties {
get {
return ResourceManager.GetString("prefer_auto_properties", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Prefer braces.
/// </summary>
......@@ -1547,6 +1556,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to prefer throwing properties.
/// </summary>
internal static string prefer_throwing_properties {
get {
return ResourceManager.GetString("prefer_throwing_properties", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Preference.
/// </summary>
......@@ -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 {
}
}
/// <summary>
/// Looks up a localized string similar to When generating properties:.
/// </summary>
internal static string When_generating_properties {
get {
return ResourceManager.GetString("When_generating_properties", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to When inserting properties, events and methods, place them:.
/// </summary>
......
......@@ -873,7 +873,7 @@ Additional information: {1}</value>
<data name="Pick_members" xml:space="preserve">
<value>Pick members</value>
</data>
<data name="Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual Studio" xml:space="preserve">
<data name="Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio" xml:space="preserve">
<value>Unfortunately, a process used by Visual Studio has encountered an unrecoverable error. We recommend saving your work, and then closing and restarting Visual Studio.</value>
</data>
<data name="Add_a_symbol_specification" xml:space="preserve">
......@@ -900,6 +900,15 @@ Additional information: {1}</value>
<data name="VisualStudioWorkspace_TryApplyChanges_cannot_be_called_from_a_background_thread" xml:space="preserve">
<value>VisualStudioWorkspace.TryApplyChanges cannot be called from a background thread.</value>
</data>
<data name="prefer_auto_properties" xml:space="preserve">
<value>prefer auto properties</value>
</data>
<data name="prefer_throwing_properties" xml:space="preserve">
<value>prefer throwing properties</value>
</data>
<data name="When_generating_properties" xml:space="preserve">
<value>When generating properties:</value>
</data>
<data name="Options" xml:space="preserve">
<value>Options</value>
</data>
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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");
......
......@@ -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);
......
......@@ -110,6 +110,16 @@
x:Name="at_the_end"
Content="{x:Static local:AdvancedOptionPageStrings.Option_at_the_end}"/>
</StackPanel>
<Label Content="{x:Static local:AdvancedOptionPageStrings.Option_When_generating_properties}"/>
<StackPanel Margin="15, 0, 0, 0">
<RadioButton GroupName="Property_generation_behavior"
x:Name="prefer_throwing_properties"
Content="{x:Static local:AdvancedOptionPageStrings.Option_prefer_throwing_properties}"/>
<RadioButton GroupName="Property_generation_behavior"
x:Name="prefer_auto_properties"
Content="{x:Static local:AdvancedOptionPageStrings.Option_prefer_auto_properties}"/>
</StackPanel>
</StackPanel>
</GroupBox>
......
......@@ -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
......@@ -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
......
......@@ -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.
/// </remarks>
/// <param name="candidate">The word being tested.</param>
/// <param name="inludeMatchSpans">Whether or not the matched spans should be included with results</param>
/// <param name="includeMatchSpans">Whether or not the matched spans should be included with results</param>
/// <returns>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.</returns>
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;
}
/// <summary>
......@@ -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
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册