Skip to content

Extensions: extension grouping type names#79217

Merged
jcouv merged 8 commits intodotnet:mainfrom
jcouv:extensions-metadata
Jul 8, 2025
Merged

Extensions: extension grouping type names#79217
jcouv merged 8 commits intodotnet:mainfrom
jcouv:extensions-metadata

Conversation

@jcouv
Copy link
Member

@jcouv jcouv commented Jul 1, 2025

Relates to test plan #76130

@jcouv jcouv self-assigned this Jul 1, 2025
@jcouv jcouv added Area-Compilers Feature - Extension Everything The extension everything feature labels Jul 1, 2025
@jcouv jcouv force-pushed the extensions-metadata branch from 97be638 to c4c2d1d Compare July 2, 2025 00:24
@jcouv jcouv force-pushed the extensions-metadata branch from c4c2d1d to 21c48a6 Compare July 2, 2025 05:24
@jcouv jcouv marked this pull request as ready for review July 2, 2025 06:34
@jcouv jcouv requested a review from a team as a code owner July 2, 2025 06:34
builder.Append('!');
}

builder.Append('T');
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

builder.Append('T');

Adding this character doesn't look necessary. #Closed

Copy link
Member Author

@jcouv jcouv Jul 2, 2025

Choose a reason for hiding this comment

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

Answered elsewhere. We're trying to conform to valid IL

}

builder.Append('T');
builder.Append(StringExtensions.GetNumeral(typeParameter.Ordinal));
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

builder.Append(StringExtensions.GetNumeral(typeParameter.Ordinal));

Is it really useful to add an ordinal at the end of a declaration? It feels like it is better to have two distinct helpers "add declaration" and "add reference" because they really have nothing in common in terms of behavior. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I can split into two helpers. But both declaration and reference should have "T" and an ordinal, to conform to valid IL

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay. I made a change to deviate from valid IL

{
if (isDefinition)
{
var cciTypeParameter = (Cci.IGenericParameter)typeParameter.GetCciAdapter();
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

GetCciAdapter

It worries me that we start using helpers like this outside of emit layer #Closed

typeConstraintStrings.Sort(StringComparer.Ordinal); // Actual order doesn't matter - just want to be deterministic

builder.Append('(');
for (int i = 0; i < typeConstraintStrings.Count(); i++)
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

Count()

Isn't there a property for that? #Closed

builder.Append('(');
for (int i = 0; i < typeConstraintStrings.Count(); i++)
{
if (i > 0)
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

if (i > 0)

For simplicity, we could always add comma at the end of each type as we add spaces after non-type constraints. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I kept this as-is. The trailing comma just feels ugly and the complexity is minimal

}
else if (type is TypeParameterSymbol typeParameter)
{
appendTypeParameter(typeParameter, builder, isDefinition: false);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

typeParameter

In an error scenario this could be a type parameter of an enclosing type. Right? #Closed

else if (namedType.IsValueType)
{
builder.Append("valuetype ");
}
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

I think we can drop these prefixes otherwise we are going to allow class and struct to conflict by full name. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

Are you thinking we'll use the extension grouping type name directly as the key for purpose of grouping and conflicts?
The reason I included those keywords is to conform to valid IL. There are some places where the IL won't parse without those keywords (illustrated in some tests).

Copy link
Contributor

Choose a reason for hiding this comment

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

The reason I included those keywords is to conform to valid IL.

I do not think it is our goal to produce a proper IL. We certainly use IL grammar as an inspiration, but I think we can drop some aspects of it that are not part of our specification of what should be included into the content-based name of the extension grouping type.

{
appendContainingType(containingType, builder);
builder.Append(containingType.Name);
appendArity(containingType, builder);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

We probably shouldn't include arity this way. We should simply use metadata name. It may or may not include arity, but CLR uses only that name to match types #Closed

{
if (namedType.Arity > 0)
{
builder.Append('`');
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

builder.Append('`');

This suffix is not always present in metadata. #Closed

appendNamespace(namedType.ContainingNamespace, builder);
appendContainingType(namedType, builder);
builder.Append(namedType.Name);
appendArity(namedType, builder);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

Similar comment about arity as for code in appendContainingType #Closed

{
if (i > 0)
{
builder.Append(',');
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

builder.Append(',');

I guess it is fine to not include sizes and lower bounds because:

  1. they cannot be expressed in syntax
  2. Even if they can be non-default, we probably do not want to differentiate the name by them.

Consider adding a comment that we are intentionally ignoring them. #Closed

}
else
{
appendModifiers(functionPointer.Signature.ReturnTypeWithAnnotations.CustomModifiers, builder);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

appendModifiers(functionPointer.Signature.ReturnTypeWithAnnotations.CustomModifiers, builder);

This doesn't look right. There could be ReturnTypeWithAnnotations.CustomModifiers even when functionPointer.Signature.RefKind != RefKind.None #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think that's possible. See logic in FunctionPointerMethodSymbol.CreateFromSource

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think that's possible. See logic in FunctionPointerMethodSymbol.CreateFromSource

I am pretty sure the model can represent this and such a symbol can be imported from metadata. If you are assuming some constraints on the symbols that can come through here, consider adding an assert in the branch above, and, perhaps, a comment explaining the assumption.

if (parameter.RefKind != RefKind.None)
{
builder.Append('&');
appendModifiers(parameter.RefCustomModifiers, builder);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

RefCustomModifiers

I think there could be non-ref custom modifiers #Closed

builder.Append(", ");
}

appendType(typeArguments[i].Type, builder);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

appendType(typeArguments[i].Type, builder);

Should we worry about custom modifiers? #Closed

modifierStrings.Add(modifierBuilder.ToStringAndFree());
}

modifierStrings.Sort(StringComparer.Ordinal); // Actual order doesn't matter - just want to be deterministic
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

modifierStrings.Sort(StringComparer.Ordinal);

In metadata order of custom modifiers is significant. like order of parameters and we are not sorting parameters. #Closed

var modifierBuilder = PooledStringBuilder.GetInstance();
modifierBuilder.Builder.Append(modifier.IsOptional ? " modopt(" : " modreq(");

appendType(((PublicModel.NamedTypeSymbol)modifier.Modifier).UnderlyingTypeSymbol, modifierBuilder.Builder);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 2, 2025

Choose a reason for hiding this comment

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

((PublicModel.NamedTypeSymbol)modifier.Modifier).UnderlyingTypeSymbol

Consider using CSharpCustomModifier.ModifierSymbol instead #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jul 2, 2025

Done with review pass (commit 1), tests are not reviewed. #Closed


static void appendArrayType(ArrayTypeSymbol array, StringBuilder builder)
{
Debug.Assert(array.Sizes.IsEmpty && array.LowerBounds.IsEmpty);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

IsEmpty

IsDefault? #Closed

if (typeParameter.ContainingType.IsExtension)
{
builder.Append("!");
// Note: in valid IL, we would need a valid identifier name
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

// Note: in valid IL, we would need a valid identifier name

This doesn't look accurate. For example, here is a quote from ECMA-335:

Within a generic type definition, its generic parameters are referred to by their index. Generic
parameter zero is referred to as !0, generic parameter one as !1, and so on. Similarly, within the body
of a generic method definition, its generic parameters are referred to by their index; generic parameter
zero is referred to as !!0, generic parameter one as !!1, and so on.

And a simple search for "!0" finds many examples of its usage in type names:

.class …
MultiSet1<T> extends class Set1<!0[]>

Etc. #Closed


appendTypeParameterTypeConstraints(typeParameter, builder);
// Note: in valid IL, we would need a valid identifier name
builder.Append(StringExtensions.GetNumeral(typeParameter.Ordinal));
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

builder.Append(StringExtensions.GetNumeral(typeParameter.Ordinal));

Do we really need the ordinal at this position? #Closed

static void appendModifiers(ImmutableArray<CustomModifier> customModifiers, StringBuilder builder)
{
// Order of modifiers is significant in metadata so we preserve the order.
var modifierStrings = ArrayBuilder<string>.GetInstance(customModifiers.Length);
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

modifierStrings

No longer used #Closed

AssertEx.Equal("extension<0>(!0)", extension.ComputeExtensionGroupingRawName());

// "0" instead of "T0"
var ilSrc = """
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

Consider removing code from here to the end of the test. It looks like a WIP artifact. #Closed

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like there are artifacts like that in other tests too. I do not think we should be testing CompileIL behavior. Even if it changes, I don't think we will need to do anything about it.


if (namedType.SpecialType == SpecialType.System_Void)
{
builder.Append("void");
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

builder.Append("void");

It looks like other special types also have keyword-like names (see I.8.2.2 Built-in value and reference types). Consider using them as well, at least for those types that have a dedicated entry in "II.23.1.16 Element types used in signatures" table. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I considered, tried it that and ended up reverting it as it was not clearly worth extra logic. The reason I kept void is to try to conform to valid IL as a guiding principle
Relevant test is GroupingTypeRawName_10

appendModifiers(functionPointer.Signature.ReturnTypeWithAnnotations.CustomModifiers, builder);
}

builder.Append(" *(");
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

Is the '*' character really necessary? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I've tried to conform to valid IL as a guiding principle. There are some deviations:

  • For "class"/"valuetype" keyword, there was a compelling argument to remove.
  • For named type parameters, there was a compelling reason too (see GroupingTypeRawName_65).

For * and comma logic, we could deviate too but I'd rather not.

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jul 3, 2025

Done with review pass (commit 4) #Closed

AssertEx.Equal("extension<valuetype .ctor (I, System.ValueType modreq(System.Runtime.InteropServices.UnmanagedType))>(!0)",
extension.ComputeExtensionGroupingRawName());

var unmanagedType = """
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

unmanagedType

No longer used. #Closed

var extension = (SourceNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("E").GetTypeMembers().Single();
AssertEx.Equal("extension(method D *(D)[])", extension.ComputeExtensionGroupingRawName());

var dSrc = """
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

dSrc

No longer used #Closed

var extension = (SourceNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("E").GetTypeMembers().Single();
AssertEx.Equal("extension(method D *(D)[])", extension.ComputeExtensionGroupingRawName());

var dSrc = """
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

dSrc

No longer used #Closed

var extension = (SourceNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("E").GetTypeMembers().Single();
AssertEx.Equal("extension<>(method !0 *(!0)[])", extension.ComputeExtensionGroupingRawName());

var dSrc = """
Copy link
Contributor

@AlekseyTs AlekseyTs Jul 3, 2025

Choose a reason for hiding this comment

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

dSrc

No longer used #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jul 3, 2025

Done with review pass (commit 5) #Closed

@jcouv jcouv requested a review from jjonescz July 3, 2025 20:37
Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (commit 7)

builder.Append('[');
for (int i = 0; i < array.Rank; i++)
{
if (i > 0)
Copy link
Member

@jjonescz jjonescz Jul 4, 2025

Choose a reason for hiding this comment

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

nit: this could be simplified by starting the for at i = 1 instead. #Resolved

var src = """
static class E
{
extension((nint, nuint))
Copy link
Member

@jjonescz jjonescz Jul 4, 2025

Choose a reason for hiding this comment

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

Consider testing dynamic #Resolved

comp.VerifyEmitDiagnostics();

var extension = (SourceNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("E").GetTypeMembers().Single();
AssertEx.Equal("extension(method void *(System.Int32, System.String)[])", extension.ComputeExtensionGroupingRawName());
Copy link
Member

@jjonescz jjonescz Jul 4, 2025

Choose a reason for hiding this comment

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

Aren't these going to result in the same raw name?

unsafe static class E
{
    extension(delegate*<@void>) { }
    extension(delegate*<void>) { }
}

class @void;

I guess that's acceptable though. #Resolved

var src = """
static class E
{
extension<T>(T) where T : class, new()
Copy link
Member

@jjonescz jjonescz Jul 4, 2025

Choose a reason for hiding this comment

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

Should variance (in T and out T) be also included in the name? In any case, consider testing that. #Resolved

var extension = (SourceNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("E").GetTypeMembers().Single();
AssertEx.Equal("extension<byreflike>(!0)", extension.ComputeExtensionGroupingRawName());

// Note: IL should have byreflike flag
Copy link
Member

@jjonescz jjonescz Jul 4, 2025

Choose a reason for hiding this comment

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

Should we file an issue for this? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

The ildasm source in runtime repo handles this (that's how I found the correct representation) but we're not using that version yet.

@jcouv jcouv requested a review from jjonescz July 8, 2025 05:50
@jcouv jcouv merged commit c6f7671 into dotnet:main Jul 8, 2025
24 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Jul 8, 2025
return;
}

if (namedType.Name == "void")
Copy link
Member Author

Choose a reason for hiding this comment

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

I realized there's a bug here... I'll fix in upcoming PR

333fred added a commit that referenced this pull request Jul 17, 2025
* Simplify code

* Simplify code

* Ensure server is loaded and unloaded with the solution

* Check that a resulting ternary operator conversion is implicit before removing a cast in one of its branches

* Extract method for handling source generated documents

* Revert "Remove the 'intent' subsystem from roslyn (#79179)"

This reverts commit 4e03ac9, reversing
changes made to 93b1b3e.

* Remove legacy intents that are no longer hooked up

* Remove unnecessary folder in project file

* More cases

* More cases

* remove tests

* Reduce allocations of BoundBinaryOperator.UncommonData (#79200)

* Remove duplicate method

* Extensions: adjust SpecialName on implementation methods (#79068)

* Update azure-pipelines-integration-dartlab.yml (#79206)

* Rename

* Remove obsolete code

* Extract common lexer code into helpers (#79214)

* Improve diagnostic for ambiguous predefined type (#79196)

* Improve diagnostic for ambiguous predefined type

* Update pre-existing tests

* Keep translations

* Revert unnecessary changes

* Add a source package that can be used to connect to the roslyn build server (#78986)

* Add BuildClient package

* Allow sdk passing compiler hash

* Reuse in Replay

* Add a bit how we can and will break the APIs

* Move more files to the shared folder

* Use shared file list in build task

* Address some known functionality gaps for extension operators (#79167)

Related to #78968.
Related to #76130.

* Use spans in low level lexer char array handling code

* Use spans in low level lexer char array handling code

* VB tests

* Remove duplicate code for processing arrays vs strings

* Revert

* Fix test

* Add internal APIs for prototyping

* Share more code

* Remove unused function

* Use spans in low level lexer char array handling code (#79232)

* Remove unused functions (#79234)

* Update src/Compilers/Core/Portable/InternalUtilities/StringTable.cs

* Remove using

* Rename FileBasedProgramsProjectFactory to MiscellaneousFilesWorkspaceProjectFactory

* Don't double register for document sync

* Don't check configuration if the client doesn't support it (ie, tests)

* Extensions: adjust logic related to primary ctor parameter (#79056)

* Address another set of functionality gaps for extension operators (#79227)

Related to #78967
Related to #78968
Related to #76130

* Revert "Use spans in low level lexer char array handling code (#79232)" (#79245)

This reverts commit fb38d6b.

* Use spans in low level lexer char array handling code (part 2) (#79250)

* Allow the Razor extension to report telemetry (and initialize)

* Make the new Workspace.Register*Handler methods public

We're obsoleting the old ones since the expectation going forward is
most users can use the new ones only.

* Do not use a constructed method symbol in a BoundMethodDefIndex (#79211)

* Simplify

* Address follow-up comments for extension operators (#79249)

Closes #79136.

* Use collection expression

* Docs

* ordering

* Initial support for adding obsolete attributes to primary constructors

* Flesh out

* Use raw strings

* File scoped namespaces

* Simplify tests

* in progress

* Simpler approach

* Revert

* Simplify tests

* Working

* Delete file

* Remove file

* Use the miscellaneous files project name for rich misc projects (#79267)

* Update tests

* Inline strings in test code

* Make tests non-async

* Add the "experimental feature" string back

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2453154

* Move telemetry initialization out of our UI-thread bound helper

This isn't needed anymore.

* Update global.json

* Update nuget.config

* Update Arcade

* Use .NET 10  Preview 5 SDK

* Add back dotnet9 feed

* Add back additional feeds

* Add back dotnet6 feed

* The Unix CI build does not need to pack or publish

* Downgrade arcade

* Reapply "Move to .NET 10 Preview 5 (#78906)"

This reverts commit 1ab27c2.

* Use scouting queue for integration tests

* Revert: Use scouting queue for integration tests

* Fix Rename adornment positioning after scrolling

* Fix debugging of build tasks (#78271)

* Fix debugging of build tasks

* Split into a new target

* Fix up tests

* Tweak 'add required parens' to recognize a common C# idiom

* Lint

* Revert compiler change (#79288)

* Extensions: extension grouping type names (#79217)

* Fix ref safety of user-defined increment operators (#79034)

* Fix ref safety of user-defined increment operators

* Update after merge

* Improve code and tests

* Inline test code

* Make tests synchronous

* Remove unnecessary await

* Enable C# classification in more tests

* Fix unit tests

There's two issues here:

1. Some tests of the VS layer didn't have the telemetry service in the
   first place.
2. There was now a circularity between the VisualStudioWorkspace and
   VisualStudioWorkspaceTelemetryService, so a Lazy has been added.

* Use collection expressions

* Explicitly document that ITaggerEventSource.Changed can be on any thread

All subscribers are working in thread-safe manners (they either take
locks to clear caches, or use existing batching/threading primitives to
queue new work).

* Document that LspSolutionChanged may happen on any thread

Subscribers were already thread safe. I've also removed the IMPORTANT
warning since it seems quite stale -- this is already in a delayed queue
so it's not really clear what it meant.

* Remove subscription from WorkspaceChanged in the StackTraceExplorer

I'm unable to figure out what the intent was here -- it clears the list
but only on a SolutionChanged event, which is the type of event
raised if multiple projects are modified at once in a single workspace
change -- any other type of event would have a more specific kind.
I could imagine the intent might have been for solution close, but
then I can imagine scenarios where the user might have pasted a stack
and now needs to switch the solution to navigate from the stack.

Since this likely never ran, I'm just deleting it.

* Avoid checking the CanonicalName each time for the analyzer

If the user expands a node in a CPS project wanting to look at the
diagnostics under an analyzer, but we haven't been told about that
analyzer let, we stick a WorkspaceChanged handler there to find it once
it comes back. We were hopping to the UI thread to see if the
CanonicalName of the item could have changed, but that's not really
going to happen ever for these items, so we can just grab it once
during creation and be done with it.

* Remove thread requirement from CodeAnalysisDiagnosticAnalyzerService

This looks to be safely callable from any thread.

* Reduce probability of stack overflow during exception handling in ModelComputation (#79292)

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2428510

This was previously addressed by adding a Task.Yield to the TransformModelAsync execution, instead this moves that stack size mitigation to the exception handling process. Per #26567, the vast majority of stack size during stack unwinding is due to the unwinding process itself.

* Remove synchronous rename (#78839)

* wip

* wip

* wip

* fix tests

* wip

* remove unused code

* update test impl

* update option test

* add cancel method

* some cleanup

* call CommitAsync in tests instead

* fix some comments and naming

* rename commit to make it more clear it's an async operation

* feedback

* feedback

* fix integration test

* Update

* Add test demonstrating issue

* inline

* fix casing mismatch when using non-unc file paths

* Collection expressions

* Skip failing tests

* Add cookbook section for avoiding inheritance (#79276)

* Add cookbook section for avoiding inheritance

Adds a section to the incremental generators cookbook on why users should avoid inheritance, that goes over a few possible scenarios and how they can hurt IDE responsiveness.

* Update ToC

* Add a small note on preferring FAWMN.

* Make 'convert to raw string' a syntax-only refactoring

* Fix issue with use-raw-string and fix-all

* Fix bad merge

* Use raw strings in tests

* [main] Source code updates from dotnet/dotnet (#79313)

* [VMR] Codeflow 9eec48b-9eec48b

[[ commit created by automation ]]

* Update dependencies from https://github.com/dotnet/dotnet build 274568
No dependency updates to commit

---------

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>

* Fix argument indentation

* REvert

* Simplify initialization of OpenFileTracker

There's only two things here that could potentially need the UI thread:

1. The Running Document Table subscription, but OpenTextBufferProvider
   already abstracted that away.
2. The IEditorOptionsFactoryService usage, which being a MEF component
   shouldn't care, but even then we don't need it right away.

It's easy to clean all this up, so just do so.

* Revert

* revise

* NRT

* Auto prop

* nrt

* Fix

* Update src/Compilers/Core/Portable/AdditionalTextFile.cs

* better fix

* better fix

* better fix

* Set DeployExtension for all the extensions we expect to deploy

* Set RoslynCompilerType=Custom in all toolset package flavors (#79327)

* Fix code gen for some increment/compound assignment scenarios involving constrained calls. (#79293)

Fixes #79268

* In progress

* In progress

* Hook up

* Add work item

* Cleanup

* Simplify

* Update to xunit.runner.visualstudio 3.1.1

Address changes from dotnet/sdk#49248.

* Temporarily increase timeout of helix items to see if it resolves timeouts

* Update resx generator test resources to assert new behavior, and fix generator in one instance

* Revert broken raw string changes in PropertySetAnalysisTests

* Fix 'use var' with spans

* Skip tests affected by dotnet/runtime#117566.

* Disable tests for #79351

* Disable tests for #79352.

* Make tests more consistent

* Fix issue offering to remove nullable cast in a ternary expression

* Fix not offering to remove unnecessary nullable pragmas

* Fix issue with remove unnecessary parens in vb

* Fix crash in replace property with methods

* Fix

* Track assembly names, not counts

* Disable more tests for #79352

* Add test

* Add test showing issue no longer reproes

* Fix issue where typeof/sizeof weren't classified properly in FindRefs

* Allow user to still create a new field/prop when offering to initialize an existing prop

* Ensure generated types come after top level statements

* Null tolerance

* Ensure we collect dumps on hangs/crashes

* nrt

* Update configs for snap

* *** DO NOT MERGE: Revert "Remove most remaining uses of WorkspaceChanged off the UI thread (#78778)" (#79366)

This reverts commit 67cce50, reversing
changes made to aafd6eb.

Going to run a test insertion to see if this is the cause of regressions
flagged in
https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/650773

* Disable Assert that is causing hangs

Will follow up with an issue but disabling for now to see if this unblocks the CoreCLR tests

* Add console logger to ensure helix console log has detailed info

* Replace Assert.False call

This `Assert.False` call was executing directly an a thread pool thread.
That meant when it triggered it was an unhandled exception on a TPT
which crashes the process. The calling code already fails the test when
this happen hence changed this to just output the failure info to the
test logs.

* Fix helix timeout

* Use new dll name for hooking xunit dispose

---------

Co-authored-by: Cyrus Najmabadi <cyrusn@microsoft.com>
Co-authored-by: David Wengier <david.wengier@microsoft.com>
Co-authored-by: DoctorKrolic <mapmyp03@gmail.com>
Co-authored-by: Cyrus Najmabadi <cyrus.najmabadi@gmail.com>
Co-authored-by: AlekseyTs <AlekseyTs@users.noreply.github.com>
Co-authored-by: Julien Couvreur <julien.couvreur@gmail.com>
Co-authored-by: Ankita Khera <40616383+akhera99@users.noreply.github.com>
Co-authored-by: Jan Jones <janjones@microsoft.com>
Co-authored-by: gel@microsoft.com <gel@microsoft.com>
Co-authored-by: Jason Malinowski <jason.malinowski@microsoft.com>
Co-authored-by: Gen Lu <genlu@users.noreply.github.com>
Co-authored-by: Rikki Gibson <rigibson@microsoft.com>
Co-authored-by: Joey Robichaud <joseph.robichaud@microsoft.com>
Co-authored-by: Joey Robichaud <jorobich@microsoft.com>
Co-authored-by: Oleg Tkachenko <olegtk@microsoft.com>
Co-authored-by: Todd Grunke <toddgrun@microsoft.com>
Co-authored-by: David Barbet <dabarbet@microsoft.com>
Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: jaredpar <jared@paranoidcoding.org>
@RikkiGibson RikkiGibson modified the milestones: Next, 18.0 P1 Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Feature - Extension Everything The extension everything feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants