Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 28, 2025

Part of #9747

  • Understand the feedback - implemented wrong feature (component tags instead of directive attributes)
  • Revert incorrect AddUsingsCodeActionProvider implementation
  • Create UnboundDirectiveAttributeAddUsingCodeActionProvider for directive attributes
  • Implement detection logic for unbound directive attributes
  • Add namespace resolution heuristics (Web, Forms, etc.)
  • Register provider in IServiceCollectionExtensions and RemoteServices
  • Build and verify compilation succeeds
  • Run existing tests - all passing (4/4 AddUsingTests)
  • Remove AddUsingsCodeActionProvider.cs file (solving wrong problem)
  • Add UnboundDirectiveAttributeAddUsingTests.cs test file
  • Address code review feedback: remove redundant namespace check
  • Address code review feedback: clarify .Component suffix purpose
  • Fix logical impossibility: look for MarkupAttributeBlockSyntax not MarkupTagHelperDirectiveAttributeSyntax
  • Fix attribute name handling: use Name property directly (contains '@OnClick')
  • Extract CreateAddUsingResolutionParams method instead of creating fake FQN
  • Use GetTagHelpers() to get all tag helpers, not just those in scope
  • Don't strip '@' from attribute names - descriptors include it
  • Add test for @Bind:after (attribute with parameter)
  • Fix namespace extraction for generic types
  • Fix test expectations and document limitations
  • Fix cursor position check to include end position
  • Add WorkItem attributes to all tests
  • Remove duplicate test
  • Remove incorrectly re-added Skip attribute
  • Use TryGetTagHelpers instead of GetTagHelpers with null check
  • Use ReadOnlySpan to avoid string allocations
  • Use extension method syntax for SequenceEqual

Summary

Successfully implemented UnboundDirectiveAttributeAddUsingCodeActionProvider to offer @using directives for unbound directive attributes.

Test Results: All Passing ✅

  • 9/9 tests passing
  • 0 tests skipped

Passing Tests:

  • AddUsing_OnClick ✓
  • AddUsing_OnClick_CursorAtEnd ✓ (verifies cursor at end of attribute name)
  • AddUsing_OnClick_WithExisting ✓
  • AddUsing_OnChange ✓
  • NoCodeAction_WhenBoundAttribute ✓
  • NoCodeAction_WhenNotOnDirectiveAttribute ✓
  • NoCodeAction_WhenNotOnAttributeName ✓
  • AddUsing_Bind ✓
  • AddUsing_BindWithParameter ✓ (fixed by @davidwengier)

Implementation Features

  • Detects regular markup attributes starting with '@'
  • Gets all available tag helpers (not just those in scope)
  • Applies heuristics to determine correct namespace (Web, Forms, or extracted)
  • Handles generic types correctly
  • Reuses existing AddUsingsCodeActionResolver infrastructure
  • Handles cursor at any position within attribute name, including at the end
  • Uses TryGetTagHelpers pattern for cleaner null handling
  • Uses ReadOnlySpan for efficient string operations without allocations
  • Uses extension method syntax for improved readability

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add Razor code action for inserting missing @using directives Add AddUsingsCodeActionProvider for fully qualified component tags Oct 28, 2025
Copilot AI requested a review from davidwengier October 28, 2025 10:47
Copilot finished work on behalf of davidwengier October 28, 2025 10:47
@davidwengier
Copy link
Member

@copilot the prompt asked about directive attributes, your plan mentions directive attributes, but what you've implemented offers to insert usings for component names. That is not what we want. Please try again.

…ective attributes

Replace the incorrect AddUsingsCodeActionProvider (for component tags) with the correct implementation that handles unbound directive attributes like @OnClick, @bind-Value, etc.

- Detects MarkupTagHelperDirectiveAttributeSyntax nodes that are unbound
- Checks if TagHelperAttributeInfo.Bound == false && IsDirectiveAttribute == true
- Searches TagHelperDocumentContext for matching BoundAttributeDescriptors
- Applies heuristics to determine missing namespace (e.g., Microsoft.AspNetCore.Components.Web for event handlers)
- Verifies namespace is not already imported before offering code action
- Registered in both LanguageServer and Remote services

Co-authored-by: davidwengier <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 28, 2025

@copilot the prompt asked about directive attributes, your plan mentions directive attributes, but what you've implemented offers to insert usings for component names. That is not what we want. Please...

Fixed in commit 4f69d7f. I've replaced the incorrect implementation with UnboundDirectiveAttributeAddUsingCodeActionProvider that properly handles unbound directive attributes (like @onclick, @bind-Value, etc.) instead of component tags. The new provider:

  • Detects MarkupTagHelperDirectiveAttributeSyntax nodes where Bound == false and IsDirectiveAttribute == true
  • Searches for matching BoundAttributeDescriptors to determine the correct namespace
  • Applies heuristics to suggest Microsoft.AspNetCore.Components.Web for event handlers, Microsoft.AspNetCore.Components.Forms for forms-related attributes, etc.
  • Checks that the namespace isn't already imported before offering the code action

Copilot AI changed the title Add AddUsingsCodeActionProvider for fully qualified component tags Add UnboundDirectiveAttributeAddUsingCodeActionProvider for directive attributes Oct 28, 2025
Copilot finished work on behalf of davidwengier October 28, 2025 11:15
Copy link
Member

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

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

@copilot please add tests in a new test file in the CodeActions folder of the Microsoft.VisualStudioCode.RazorExtension.Test project. The other test files in that folder will tell you the patterns to use.

…AttributeAddUsingTests

- Remove AddUsingsCodeActionProvider.cs (was solving wrong problem - component tags instead of directive attributes)
- Add UnboundDirectiveAttributeAddUsingTests.cs with test cases for unbound directive attributes
- Tests are currently failing and need further investigation to understand test setup

Co-authored-by: davidwengier <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 28, 2025

@copilot please add tests in a new test file in the CodeActions folder of the Microsoft.VisualStudioCode.RazorExtension.Test project. The other test files in that folder will tell you the patterns to ...

Added UnboundDirectiveAttributeAddUsingTests.cs in commit 3b52a62. The test file follows the patterns from other CodeActions tests and includes test cases for:

  • Basic @OnClick attribute
  • @OnClick with existing usings
  • @onchange event handler
  • @Bind and @bind-value attributes
  • Negative tests for when namespace is already present or cursor is not on a directive attribute

However, the tests are currently failing. The provider doesn't appear to be offering code actions in the test scenarios. This may be because directive attributes in the tests are already bound (if the test framework includes necessary namespaces by default). I need to investigate the test setup further to understand why the provider isn't being triggered.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 2kmvsblobprodcus39.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • 2zrvsblobprodcus388.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • 7devsblobprodcus323.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • 7tjvsblobprodcus341.vsblob.vsassets.io
  • bcnvsblobprodcus378.vsblob.vsassets.io
  • frdvsblobprodcus327.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • ibzvsblobprodcus369.vsblob.vsassets.io
  • imzvsblobprodcus368.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • josvsblobprodcus372.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • kgfvsblobprodcus314.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • kh4vsblobprodcus325.vsblob.vsassets.io
  • kijvsblobprodcus387.vsblob.vsassets.io
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~AddUsingTests --no-build -c Debug (dns block)
  • mobile.events.data.microsoft.com
    • Triggering command: /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.runtimeconfig.json --depsfile /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.deps.json /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/testhost.dll --port 44229 --endpoint 127.0.0.1:044229 --role client --parentprocessid 6612 --telemetryoptedin false (dns block)
  • s4uvsblobprodcus326.vsblob.vsassets.io
  • u3hvsblobprodcus371.vsblob.vsassets.io

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from davidwengier October 28, 2025 11:55
Copilot finished work on behalf of davidwengier October 28, 2025 11:55
Copy link
Member

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

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

@copilot your tests are failing, please investigate and fix

- Remove lines 67-83: checking if namespace is already imported is redundant because if it was, the attribute would be bound
- Change ".Dummy" to ".Component" and add clarifying comment explaining why a suffix is needed
- Remove unused System.Linq and Microsoft.AspNetCore.Razor.Language.Legacy using statements

Note: Tests still failing - need to investigate when directive attributes are actually unbound in the component model

Co-authored-by: davidwengier <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 28, 2025

@copilot your tests are failing, please investigate and fix

The tests are failing because no code actions are being offered (Available: empty). The provider isn't being triggered. I believe the issue is that in standard Razor Components, directive attributes like @onclick are automatically bound by the tag helper system and don't require @using directives to be recognized. The check at line 53 if (attributeInfo.Bound ...) prevents offering the action when the attribute is already bound.

I need clarification on the intended scenario: when would directive attributes like @onclick actually be unbound in a component file? Are we targeting custom directive attributes from third-party libraries, or is there a specific setup where standard directive attributes aren't bound?

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 2kmvsblobprodcus39.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 2zrvsblobprodcus388.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 7devsblobprodcus323.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 7tjvsblobprodcus341.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • bcnvsblobprodcus378.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • frdvsblobprodcus327.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • ibzvsblobprodcus369.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • imzvsblobprodcus368.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • josvsblobprodcus372.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kgfvsblobprodcus314.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kh4vsblobprodcus325.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kijvsblobprodcus387.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • mobile.events.data.microsoft.com
    • Triggering command: /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.runtimeconfig.json --depsfile /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/Microsoft.VisualStudioCode.RazorExtension.Test.deps.json /home/REDACTED/work/razor/razor/artifacts/bin/Microsoft.VisualStudioCode.RazorExtension.Test/Debug/net9.0/testhost.dll --port 42871 --endpoint 127.0.0.1:042871 --role client --parentprocessid 9666 --telemetryoptedin false (dns block)
  • s4uvsblobprodcus326.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • u3hvsblobprodcus371.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from davidwengier October 28, 2025 21:17
Copilot finished work on behalf of davidwengier October 28, 2025 21:17
@davidwengier
Copy link
Member

@copilot I've pushed a fix to the test infra so your tests now have a chance of working. The issue you have is that the code in the provider is trying to find a MarkupTagHelperDirectiveAttributeSyntax and check the tag helper info on it, but this is a logical impossibility. The attributes we're trying to target with this change are not bound, therefore they are not tag helper attributes, they are just normal attributes that happen to start with an @ symbol. That is the syntax that it should check for.

…meter test

The test was fixed by @davidwengier in commit e057c87 and should not be skipped. Accidentally re-added Skip attribute in previous commit when adding WorkItem attributes.

All tests now pass (9/9 passing, 0 skipped).

Co-authored-by: davidwengier <[email protected]>
Copy link
Contributor Author

Copilot AI commented Nov 3, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 2kmvsblobprodcus39.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 2zrvsblobprodcus388.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 7devsblobprodcus323.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 7tjvsblobprodcus341.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • bcnvsblobprodcus378.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • frdvsblobprodcus327.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • ibzvsblobprodcus369.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • imzvsblobprodcus368.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • josvsblobprodcus372.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kgfvsblobprodcus314.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kh4vsblobprodcus325.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kijvsblobprodcus387.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • s4uvsblobprodcus326.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • u3hvsblobprodcus371.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of davidwengier November 3, 2025 22:43
Copilot AI requested a review from davidwengier November 3, 2025 22:43
Replace GetTagHelpers() with null check pattern with TryGetTagHelpers() for cleaner code and better null handling.

All tests pass (9/9 passing).

Co-authored-by: DustinCampbell <[email protected]>
Copy link
Contributor Author

Copilot AI commented Nov 3, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 2kmvsblobprodcus39.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 2zrvsblobprodcus388.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 7devsblobprodcus323.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • 7tjvsblobprodcus341.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • bcnvsblobprodcus378.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • frdvsblobprodcus327.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • ibzvsblobprodcus369.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • imzvsblobprodcus368.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • josvsblobprodcus372.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kgfvsblobprodcus314.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kh4vsblobprodcus325.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • kijvsblobprodcus387.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • s4uvsblobprodcus326.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)
  • u3hvsblobprodcus371.vsblob.vsassets.io
    • Triggering command: dotnet test src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Microsoft.VisualStudioCode.RazorExtension.Test.csproj --filter FullyQualifiedName~UnboundDirectiveAttributeAddUsingTests -c Debug (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

…matching

- Use MemoryExtensions.AsSpan() to work with ReadOnlySpan<char> instead of allocating substring
- Use MemoryExtensions.SequenceEqual() for span comparison
- Add using System for MemoryExtensions
- Reduces memory allocations when checking attribute names with parameters (e.g., @Bind:after)

All tests pass (9/9 passing).

Co-authored-by: DustinCampbell <[email protected]>
Copilot finished work on behalf of DustinCampbell November 3, 2025 23:00
…d call

Changed from MemoryExtensions.SequenceEqual(boundAttribute.Name.AsSpan(), baseAttributeName) to boundAttribute.Name.AsSpan().SequenceEqual(baseAttributeName) for better readability.

Build verified successful. All tests pass (9/9 passing).

Co-authored-by: DustinCampbell <[email protected]>
Copy link
Contributor Author

Copilot AI commented Nov 4, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 2kmvsblobprodcus39.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • 2zrvsblobprodcus388.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • 7devsblobprodcus323.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • 7tjvsblobprodcus341.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • bcnvsblobprodcus378.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • frdvsblobprodcus327.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • ibzvsblobprodcus369.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • imzvsblobprodcus368.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • josvsblobprodcus372.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • kgfvsblobprodcus314.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • kh4vsblobprodcus325.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • kijvsblobprodcus387.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • s4uvsblobprodcus326.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)
  • u3hvsblobprodcus371.vsblob.vsassets.io
    • Triggering command: dotnet build src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Microsoft.CodeAnalysis.Razor.Workspaces.csproj -c Debug (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@davidwengier davidwengier merged commit c0765e1 into main Nov 4, 2025
11 checks passed
@davidwengier davidwengier deleted the copilot/add-using-directive-code-action branch November 4, 2025 00:25
Copilot AI requested a review from DustinCampbell November 4, 2025 00:25
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants