Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

FixTypeName.GetReflectionType() to work when theTypeName instance represents a generic type definition within aGenericTypeName#24985

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
daxian-dbw merged 6 commits intoPowerShell:masterfromdaxian-dbw:getreflectiontype
Mar 17, 2025

Conversation

@daxian-dbw
Copy link
Member

@daxian-dbwdaxian-dbw commentedFeb 11, 2025
edited
Loading

PR Summary

Fix#24982

When a generic type expression is parsed for the second time, the generic type can be found in cache, and hence the symbol resolver won't go through the code path to resolvegenericTypeName.TypeName, which represents the generic type definition. Therefore, unlike the first-time parsing, the cached type forgenericTypeName.TypeName won't be set during the symbol resolving process for the second parsing.

However, the type resolution inTypeName.GetReflectionType() doesn't work for a generic type definition in most cases, for example, when the generic type expression is[System.Collections.Generic.List[string]],genericTypeName.TypeName will be aTypeName instance with the full nameSystem.Collections.Generic.List which will fail to be resolved. That's why the second time you parse the same generic type expression,genericTypeName.TypeName.GetReflectionType() will return null.

WhygenericTypeName.TypeName can be resolved in the first-time resolution ofgenericTypeName, but doesn't work when directly callinggenericTypeName.TypeName.GetReflectionType()? That's because for the former, withinVisitGenericTypeName(...), it uses aTypeResolutionState instance as the resolution context, which is constructed with the information from thegenericTypeName (seecode here). But when directly callinggenericTypeName.TypeName.GetReflectionType(), it doesn't have that information and thus cannot use the same/equivalentTypeResolutionState instance as the context for type resolution.

The fix is to pass the generic argument count toTypeName when constructing aGenericTypeName instance, so that theTypeName instance can try resolving with an alternate name (i.e.typename`<n>) when the original name fails to resolve.

The changes also fix another issue:

Before: assembly-qualified name[System.Collections.Generic.List[string], System.Private.CoreLib] cannot be resolved.
After:[System.Collections.Generic.List[string], System.Private.CoreLib] can be resolved as expected.

PR Checklist

MartinGC94 reacted with thumbs up emoji
Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • test/powershell/Language/Parser/Parsing.Tests.ps1: Language not supported
Comments suppressed due to low confidence (1)

src/System.Management.Automation/engine/parser/SymbolResolver.cs:717

  • Ensure that the new behavior of setting the cached type for 'genericTypeName.TypeName' when 'GetReflectionType()' returns null is covered by tests.
((ISupportsTypeCaching)genericDefinition).CachedType = foundType.GetGenericTypeDefinition();

@daxian-dbw
Copy link
MemberAuthor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@daxian-dbwdaxian-dbw added the CL-GeneralIndicates that a PR should be marked as a general cmdlet change in the Change Log labelFeb 12, 2025
@microsoft-github-policy-servicemicrosoft-github-policy-servicebot added the Review - NeededThe PR is being reviewed labelFeb 19, 2025
@daxian-dbw
Copy link
MemberAuthor

@MartinGC94 Can you please also review this PR? Thank you!

@microsoft-github-policy-servicemicrosoft-github-policy-servicebot removed the Review - NeededThe PR is being reviewed labelFeb 20, 2025
@MartinGC94
Copy link
Contributor

It fixes my real world scenario and the fix itself seems reasonable. Thanks for the quick fix :)

@microsoft-github-policy-servicemicrosoft-github-policy-servicebot added the Review - NeededThe PR is being reviewed labelMar 1, 2025
@daxian-dbwdaxian-dbw changed the titleSet the cached type forGenericTypeName.TypeName as needed when the generic type is found in cacheFixTypeName.GetReflectionType() to work when theTypeName instance represents a generic type definition within aGenericTypeNameMar 14, 2025
@microsoft-github-policy-servicemicrosoft-github-policy-servicebot removed the Review - NeededThe PR is being reviewed labelMar 14, 2025
if(genericArgumentCount>0&&!_name.Contains('`'))
{
_genericArgumentCount=genericArgumentCount;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Usually, we expect a constructor to throw an exception if the argument is unexpected. But here we perform a correction of the argument. It's amazing. I'm afraid this may provoke accidental misuse of this constructor in the future. At the very least, it would be good to add a comment with examples of the scenarios we address and explaining why this correction is needed in this place.
Alternatively, we could perform a check at the call location and pass the correct arguments.
It could be even better to use a template likeprivate static TypeName TypeName.CreateAlternativeGenericTypeName() with a comprehensive description.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

This "try alternate name" thing happens in multiple places, which is common when dealing with generic type resolution. Comments were added in theGetReflectionType() to explain why we only fall back to alternate name even ifgenericArgumentCount is set.

As for the scenario for using this constructor, the XML comment calls it out and it's also easy to understand by looking at where it's used. So, I don't think more comments are needed.

I can add a check to throw whengenericArgumentCount is a negative value.

@iSazonoviSazonov added CL-GeneralIndicates that a PR should be marked as a general cmdlet change in the Change Log and removed CL-GeneralIndicates that a PR should be marked as a general cmdlet change in the Change Log labelsMar 14, 2025
Copy link
Collaborator

@SeeminglyScienceSeeminglyScience left a comment

Choose a reason for hiding this comment

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

LGTM!

@daxian-dbwdaxian-dbw merged commitef64132 intoPowerShell:masterMar 17, 2025
34 checks passed
@daxian-dbwdaxian-dbw deleted the getreflectiontype branchMarch 17, 2025 22:40
@microsoft-github-policy-service
Copy link
Contributor

microsoft-github-policy-servicebot commentedMar 17, 2025
edited by unfurl-linksbot
Loading

📣 Hey@daxian-dbw, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗https://aka.ms/PSRepoFeedback

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

@iSazonoviSazonoviSazonov approved these changes

@SeeminglyScienceSeeminglyScienceSeeminglyScience approved these changes

Labels

CL-GeneralIndicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

GetReflectionType only returns open generic types once per session

4 participants

@daxian-dbw@MartinGC94@iSazonov@SeeminglyScience

[8]ページ先頭

©2009-2025 Movatter.jp