Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to underline variables in the editor that are reassigned. #51889

Merged
merged 73 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
abfa141
Initial stubs
CyrusNajmabadi Mar 15, 2021
c6b24d3
Add option
CyrusNajmabadi Mar 15, 2021
f4788b4
Body of tagger
CyrusNajmabadi Mar 15, 2021
651ab64
Define apoi
CyrusNajmabadi Mar 15, 2021
70c4602
Implement logic for C#
CyrusNajmabadi Mar 15, 2021
95925b8
revert
CyrusNajmabadi Mar 15, 2021
acfb4b0
Switch to a short delay
CyrusNajmabadi Mar 15, 2021
5bf3abe
Less allocations
CyrusNajmabadi Mar 15, 2021
cb00f07
Nullable
CyrusNajmabadi Mar 15, 2021
bf9ca78
Add doc
CyrusNajmabadi Mar 15, 2021
6e2e788
Simplify
CyrusNajmabadi Mar 15, 2021
99cfe68
Basic tests
CyrusNajmabadi Mar 15, 2021
9eb0a5f
Add option
CyrusNajmabadi Mar 15, 2021
dab5ec5
Add option
CyrusNajmabadi Mar 15, 2021
5136f84
Reorder
CyrusNajmabadi Mar 15, 2021
207696f
add vb option
CyrusNajmabadi Mar 15, 2021
d398c43
VBfixes
CyrusNajmabadi Mar 15, 2021
e15714c
build
CyrusNajmabadi Mar 15, 2021
6e05fd7
Do not allocate
CyrusNajmabadi Mar 15, 2021
08c5bc8
More tests
CyrusNajmabadi Mar 15, 2021
aab4f32
Add support for indexers
CyrusNajmabadi Mar 15, 2021
dabbb04
Add more cases
CyrusNajmabadi Mar 15, 2021
6c08cf3
Fix test
CyrusNajmabadi Mar 15, 2021
f4ee084
Add tests
jnm2 Mar 16, 2021
c226cce
Generate VB tests
jnm2 Mar 16, 2021
3586a2a
Merge pull request #13 from jnm2/underlingVariables_tests
CyrusNajmabadi Mar 16, 2021
1a5c7e7
Support pointers
CyrusNajmabadi Mar 16, 2021
6c3a873
Fix test
CyrusNajmabadi Mar 16, 2021
929643a
Fix test
CyrusNajmabadi Mar 16, 2021
d08289a
Improved behavior
CyrusNajmabadi Mar 16, 2021
5b2f4d9
Fix remaining C# issues. unify code.
CyrusNajmabadi Mar 16, 2021
ced10b5
VBside working
CyrusNajmabadi Mar 16, 2021
2593979
Support writes through ref-extension methods.
CyrusNajmabadi Mar 16, 2021
7df5fc9
Cancellation
CyrusNajmabadi Mar 16, 2021
45edf1a
Add test
CyrusNajmabadi Mar 16, 2021
18715f4
Avoid data flow if unnecessary.
CyrusNajmabadi Mar 16, 2021
660bc7b
Add docs
CyrusNajmabadi Mar 16, 2021
eea7716
Simplify
CyrusNajmabadi Mar 16, 2021
4a5e639
Docs
CyrusNajmabadi Mar 16, 2021
0a37922
Fix and tests for global statements
CyrusNajmabadi Mar 16, 2021
0c66a0c
Add tests
CyrusNajmabadi Mar 16, 2021
9775ccf
Add tests
CyrusNajmabadi Mar 16, 2021
3a6e8a7
Doc
CyrusNajmabadi Mar 16, 2021
1522541
Add tests of event accessor parameter reassignment
jnm2 Mar 16, 2021
89d5d78
Misc tests, three failing
jnm2 Mar 16, 2021
9762e74
null ref
CyrusNajmabadi Mar 17, 2021
bd4113f
Merge pull request #14 from jnm2/underlingVariables_tests
CyrusNajmabadi Mar 17, 2021
e73d1c0
Support top level args
CyrusNajmabadi Mar 17, 2021
195af50
Blank line
CyrusNajmabadi Mar 17, 2021
88f6256
Null checks
CyrusNajmabadi Mar 17, 2021
7609e6f
Update src/Features/Core/Portable/ReassignedVariable/ReassignedVariab…
CyrusNajmabadi Mar 18, 2021
aed9847
Merge branch 'master' into underlingVariables
CyrusNajmabadi Mar 22, 2021
e128051
UPdate resxs
CyrusNajmabadi Mar 22, 2021
fa62450
Merge remote-tracking branch 'upstream/main' into underlingVariables
CyrusNajmabadi Apr 1, 2021
43afd6d
Merge remote-tracking branch 'upstream/main' into underlingVariables
CyrusNajmabadi May 18, 2021
d3f8fae
Fix
CyrusNajmabadi May 18, 2021
0e3bfd7
Fix
CyrusNajmabadi May 18, 2021
bc780ce
Switch to being part of the standard classification system
CyrusNajmabadi May 18, 2021
aa63544
Add tests
CyrusNajmabadi May 18, 2021
9143ff7
Add test
CyrusNajmabadi May 18, 2021
3ab4a9f
Make internal
CyrusNajmabadi May 18, 2021
d7ac5aa
MOve options
CyrusNajmabadi May 18, 2021
4b0b59a
Add comment
CyrusNajmabadi May 18, 2021
7a2b25b
Add test
CyrusNajmabadi May 18, 2021
1611f50
Support ref readonly varaibles
CyrusNajmabadi May 18, 2021
41471fc
Add test
CyrusNajmabadi May 18, 2021
c141e47
Fix tagger
CyrusNajmabadi May 18, 2021
ea44fef
Simplify
CyrusNajmabadi May 18, 2021
ed550f7
Merge remote-tracking branch 'upstream/main' into underlingVariables
CyrusNajmabadi May 25, 2021
a6f459f
Add tests
CyrusNajmabadi May 25, 2021
c1f5f86
Add comments
CyrusNajmabadi May 25, 2021
48a60d3
REname method
CyrusNajmabadi May 25, 2021
a62de54
NRTenable
CyrusNajmabadi May 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching
{
internal sealed class ClassificationTypeFormatDefinitions
internal sealed class BraceMatchingTypeFormatDefinitions
{
[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = ClassificationTypeDefinitions.BraceMatchingName)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@
<PublicAPI Include="PublicAPI.Shipped.txt" />
<PublicAPI Include="PublicAPI.Unshipped.txt" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="EditorFeaturesWpfResources.resx" GenerateSource="true" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Implementation.ReassignedVariable
{
internal sealed class ReassignedVariableTypeFormatDefinitions
{
[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = ClassificationTypeNames.ReassignedVariable)]
[Name(ClassificationTypeNames.ReassignedVariable)]
[Order(After = Priority.High)]
[UserVisible(false)]
[ExcludeFromCodeCoverage]
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
private class ReassignedVariableFormatDefinition : ClassificationFormatDefinition
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public ReassignedVariableFormatDefinition()
{
this.DisplayName = EditorFeaturesResources.Reassigned_variable;
this.TextDecorations = System.Windows.TextDecorations.Underline;
}
}
}
}
3 changes: 3 additions & 0 deletions src/EditorFeatures/Core/EditorFeaturesResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -951,4 +951,7 @@ Do you want to proceed?</value>
<data name="Gathering_Suggestions_Waiting_for_the_solution_to_fully_load" xml:space="preserve">
<value>Gathering Suggestions - Waiting for the solution to fully load</value>
</data>
<data name="Reassigned_variable" xml:space="preserve">
<value>Reassigned variable</value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Implementation.ReassignedVariable
{
internal class ReassignedVariableClassificationTypeDefinitions
{
[Export]
[Name(ClassificationTypeNames.ReassignedVariable)]
[BaseDefinition(PredefinedClassificationTypeNames.FormalLanguage)]
internal readonly ClassificationTypeDefinition? ReassignedVariableTypeDefinition;
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Composition;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.Providers;

namespace Microsoft.CodeAnalysis.Editor.Implementation.UnderlineReassignment
{
internal class ReassignedVariableOptions
{
public static PerLanguageOption2<bool> Underline =
new PerLanguageOption2<bool>(nameof(ReassignedVariableOptions), nameof(Underline), defaultValue: true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will likely be set to false when this is submitted. it will be an opt-in option.

storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.ReassignedVariable.Underline"));
}

[ExportOptionProvider, Shared]
internal class ReassignedVariableOptionsProvider : IOptionProvider
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public ReassignedVariableOptionsProvider()
{
}

public ImmutableArray<IOption> Options { get; } = ImmutableArray.Create<IOption>(
ReassignedVariableOptions.Underline);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Editor.Implementation.Classification;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Tagging;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Editor.Tagging;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.ReassignedVariable;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Implementation.UnderlineReassignment
{
[Export(typeof(IViewTaggerProvider))]
[TagType(typeof(ClassificationTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
internal class ReassignedVariableViewTaggerProvider : AsynchronousViewTaggerProvider<ClassificationTag>
{
private readonly ClassificationTypeMap _typeMap;

[ImportingConstructor]
[SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
public ReassignedVariableViewTaggerProvider(
IThreadingContext threadingContext,
IForegroundNotificationService notificationService,
ClassificationTypeMap typeMap,
IAsynchronousOperationListenerProvider listenerProvider)
: base(threadingContext, listenerProvider.GetListener(FeatureAttribute.Classification), notificationService)
{
_typeMap = typeMap;
}

protected override IEnumerable<PerLanguageOption2<bool>> PerLanguageOptions => SpecializedCollections.SingletonEnumerable(ReassignedVariableOptions.Underline);
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved

protected override ITaggerEventSource CreateEventSource(ITextView textView, ITextBuffer subjectBuffer)
{
this.AssertIsForeground();
const TaggerDelay Delay = TaggerDelay.Short;

// Note: we don't listen for OnTextChanged. They'll get reported by the ViewSpan changing and also the
// SemanticChange notification.
//
// Note: when the user scrolls, we will try to reclassify variables as soon as possible. That way we appear
// unclassified for a very short amount of time.
//
// Note: because we use frozen-partial documents for classifying these, we may end up with incomplete
// semantics (esp. during solution load). Because of this, we also register to hear when the full
// compilation is available so that reclassify and bring ourselves up to date.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... when the full compilation is available ...

Which event source is this?

return new CompilationAvailableTaggerEventSource(
subjectBuffer, Delay,
ThreadingContext,
AsyncListener,
TaggerEventSources.OnViewSpanChanged(ThreadingContext, textView, textChangeDelay: Delay, scrollChangeDelay: TaggerDelay.NearImmediate),
TaggerEventSources.OnWorkspaceChanged(subjectBuffer, Delay, this.AsyncListener),
TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer, Delay));
}

protected override IEnumerable<SnapshotSpan> GetSpansToTag(ITextView textView, ITextBuffer subjectBuffer)
{
this.AssertIsForeground();

// Find the visible span some 100 lines +/- what's actually in view. This way
// if the user scrolls up/down, we'll already have the results.
var visibleSpan = textView.GetVisibleLinesSpan(subjectBuffer, extraLines: 100);
if (visibleSpan == null)
{
// Couldn't find anything visible, just fall back to classifying everything.
return base.GetSpansToTag(textView, subjectBuffer);
}

return SpecializedCollections.SingletonEnumerable(visibleSpan.Value);
}
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved

protected override void ProduceTagsSynchronously(TaggerContext<ClassificationTag> context, DocumentSnapshotSpan spanToTag, int? caretPosition)
{
// Assert just so we can find out who is calling this. We should never be used in synchronous scenarios.
Debug.Fail("Unsupported call to ProduceTagsSynchronously");
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
}

protected override async Task ProduceTagsAsync(TaggerContext<ClassificationTag> context, DocumentSnapshotSpan spanToTag, int? caretPosition)
{
var cancellationToken = context.CancellationToken;

var document = spanToTag.Document;
if (document == null)
return;

document = document.WithFrozenPartialSemantics(cancellationToken);
var service = document.GetLanguageService<IReassignedVariableService>();
if (service == null)
return;

var snapshotSpan = spanToTag.SnapshotSpan;
var reassignedVariables = await service.GetReassignedVariablesAsync(
document, snapshotSpan.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false);

var tag = new ClassificationTag(_typeMap.GetClassificationType(ClassificationTypeNames.ReassignedVariable));
foreach (var variable in reassignedVariables)
context.AddTag(new TagSpan<ClassificationTag>(variable.ToSnapshotSpan(snapshotSpan.Snapshot), tag));
}
}
}
5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading