Skip to content

Conversation

@MartinGC94
Copy link
Contributor

@MartinGC94 MartinGC94 commented Feb 11, 2023

PR Summary

Fixes a parser error where an invalid namespace would cause the parser to crash when attempting to resolve a type name. For example: using namespace [System];[S
Also made some adjustments in the completion code so namespace completion continues to work for invalid namespaces.

PR Context

Fixes #17113

PR Checklist

@ghost ghost assigned PaulHigin Feb 11, 2023
@ghost ghost added the Review - Needed The PR is being reviewed label Feb 19, 2023
@ghost
Copy link

ghost commented Feb 19, 2023

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Maintainer, please provide feedback and/or mark it as Waiting on Author

@iSazonov
Copy link
Collaborator

What about using namespace !!!.!!!?

@ghost ghost removed the Review - Needed The PR is being reviewed label Feb 22, 2023
@MartinGC94
Copy link
Contributor Author

MartinGC94 commented Feb 22, 2023

What about using namespace !!!.!!!?

I haven't checked, but I'm fairly certain it's still allowed with this change. While it would certainly be nice if the parser prevented every invalid namespace entry, the main purpose of this change is just to fix the exception thrown when specific characters are used, see: https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/parser/ast.cs#L8457

GitHub
PowerShell for every system! Contribute to PowerShell/PowerShell development by creating an account on GitHub.

@iSazonov
Copy link
Collaborator

For this issue, there are 2 potential fixes:

  • make using namespace to error on invalid namespace names
  • make the constructor of TypeName to tolerate invalid namespace names
    It feels to me option 1 is the right one to go with, but it's not trivial to validate if the namespace name is legitimate using the C# identifier definition.

Although @daxian-dbw pointed out that the first solution is preferable I think full solution should include both since it is impossible to manually check whether a string valid namespace without direct test with the constructor.
I'd prefer to do formal notation check on first step (with Regex) and then try constructor. This allows us to make useful error messages and suggestions and block incorrect inputs.

@MartinGC94
Copy link
Contributor Author

MartinGC94 commented Feb 23, 2023

@iSazonov Using statements cannot be so strict during parsing because types can be created on the fly like this:

using namespace DemoNamespace
Add-Type -TypeDefinition @'
namespace DemoNamespace
{
    public class Hello
    {
        public static void World()
        {
            System.Console.WriteLine("Hello World");
        }
    }
}
'@
[Hello]::World()

I agree that the syntax check itself could be made more thorough, but I don't fully understand the naming rules so it's hard for me to write a regex pattern that I'm confident only blocks invalid values.

@iSazonov
Copy link
Collaborator

@MartinGC94 I mean the checks are performed at different times.
As for Regex we could start with simple one. I don't think we should be so strong as C# compiler. Our intention is to make useful error message instead of unexpected exception.

@MartinGC94
Copy link
Contributor Author

MartinGC94 commented Feb 24, 2023

@iSazonov If the intent is just to prevent unintentional exceptions then the current checks should be fine. Invalid namespaces like using namespace !!!.!!! won't throw any errors but they obviously won't do anything useful either.
If you want, I can easily write a more through regex pattern with the rules I think namespace identifiers have, I'm just saying there's a good chance I'll make a mistake because I don't fully understand the spec.

@iSazonov
Copy link
Collaborator

iSazonov commented Feb 24, 2023

You could play with [regex]::IsMatch("a.q.w", "^([\p{L}_][\p{L}\p{Pc}\p{Nd}\p{Cf}\p{M}]*)(\.[\p{L}_][\p{L}\p{Pc}\p{Nd}\p{Cf}\p{M}]*)*$")

For reference https://www.regular-expressions.info/unicode.html

@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Mar 1, 2023
@pull-request-quantifier-deprecated

This PR has 65 quantified lines of changes. In general, a change size of upto 200 lines is ideal for the best PR experience!


Quantification details

Label      : Small
Size       : +47 -18
Percentile : 26%

Total files changed: 3

Change summary by file extension:
.cs : +43 -18
.ps1 : +4 -0

Change counts above are quantified counts, based on the PullRequestQuantifier customizations.

Why proper sizing of changes matters

Optimal pull request sizes drive a better predictable PR flow as they strike a
balance between between PR complexity and PR review overhead. PRs within the
optimal size (typical small, or medium sized PRs) mean:

  • Fast and predictable releases to production:
    • Optimal size changes are more likely to be reviewed faster with fewer
      iterations.
    • Similarity in low PR complexity drives similar review times.
  • Review quality is likely higher as complexity is lower:
    • Bugs are more likely to be detected.
    • Code inconsistencies are more likely to be detected.
  • Knowledge sharing is improved within the participants:
    • Small portions can be assimilated better.
  • Better engineering practices are exercised:
    • Solving big problems by dividing them in well contained, smaller problems.
    • Exercising separation of concerns within the code changes.

What can I do to optimize my changes

  • Use the PullRequestQuantifier to quantify your PR accurately
    • Create a context profile for your repo using the context generator
    • Exclude files that are not necessary to be reviewed or do not increase the review complexity. Example: Autogenerated code, docs, project IDE setting files, binaries, etc. Check out the Excluded section from your prquantifier.yaml context profile.
    • Understand your typical change complexity, drive towards the desired complexity by adjusting the label mapping in your prquantifier.yaml context profile.
    • Only use the labels that matter to you, see context specification to customize your prquantifier.yaml context profile.
  • Change your engineering behaviors
    • For PRs that fall outside of the desired spectrum, review the details and check if:
      • Your PR could be split in smaller, self-contained PRs instead
      • Your PR only solves one particular issue. (For example, don't refactor and code new features in the same PR).

How to interpret the change counts in git diff output

  • One line was added: +1 -0
  • One line was deleted: +0 -1
  • One line was modified: +1 -1 (git diff doesn't know about modified, it will
    interpret that line like one addition plus one deletion)
  • Change percentiles: Change characteristics (addition, deletion, modification)
    of this PR in relation to all other PRs within the repository.


Was this comment helpful? 👍  :ok_hand:  :thumbsdown: (Email)
Customize PullRequestQuantifier for this repository.

@ghost ghost added the Review - Needed The PR is being reviewed label Mar 9, 2023
@ghost
Copy link

ghost commented Mar 9, 2023

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Maintainer, please provide feedback and/or mark it as Waiting on Author

@daxian-dbw daxian-dbw added WG-Engine core PowerShell engine, interpreter, and runtime Needs-Triage The issue is new and needs to be triaged by a work group. labels May 1, 2023
@StevenBucher98 StevenBucher98 added the PowerShell-Docs not needed The PR was reviewed and doesn't appear to require a PowerShell Docs update label May 15, 2023
@daxian-dbw daxian-dbw removed the Needs-Triage The issue is new and needs to be triaged by a work group. label May 15, 2023
@ghost ghost removed the Review - Needed The PR is being reviewed label May 15, 2023
@IISResetMe IISResetMe added the Review - Needed The PR is being reviewed label May 15, 2023
@JamesWTruher
Copy link
Collaborator

while I agree that this is a problem, I'm concerned about this approach. It seems that the issue is that new TypeName is not expected to throw and it clearly will under some circumstances. A simpler approach might be to address that.
I tried this approach and it seems to produce the proper result:

TypeName newTypeName;
try
{
   newTypeName = new TypeName(typeName.Extent, newTypeNameToSearch);
}
catch (Exception e)
{
   exception = e;
   break;
}

this is around line 400 in engine/parser/TypeResolver.cs
here's the error message with this implementation:

PS> using namespace [system];[s                   
ParserError: 
Line |
   1 |  using namespace [system];[s
     |                             ~
     | Missing ] at end of attribute or type literal.

After more consideration, a TypeName.TryCreate might be an even better approach (to enable better inlining) then checking to see if we were able to create it.

Copy link
Collaborator

@JamesWTruher JamesWTruher left a comment

Choose a reason for hiding this comment

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

please see my comments in the conversation

@ghost ghost added Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept and removed Review - Needed The PR is being reviewed labels May 15, 2023
@MartinGC94
Copy link
Contributor Author

@JamesWTruher I agree that adding TypeName.TryCreate could be useful but should it be in place of the existing changes that makes the namespace parsing more strict? Or in addition to it? I think it would be useful to have the parser show an error for invalid namespaces.

@ghost ghost removed the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label May 16, 2023
@ghost ghost added the Review - Needed The PR is being reviewed label May 24, 2023
@ghost
Copy link

ghost commented May 24, 2023

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Maintainer, please provide feedback and/or mark it as Waiting on Author

@daxian-dbw
Copy link
Member

Superseded by #21162. @MartinGC94 and @iSazonov Thanks for your initial investigation! I have called out the thanks to both of you in the new PR.

@daxian-dbw daxian-dbw closed this Jan 31, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot removed the Review - Needed The PR is being reviewed label Jan 31, 2024
@microsoft-github-policy-service
Copy link
Contributor

microsoft-github-policy-service bot commented Jan 31, 2024

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

🔗 https://aka.ms/PSRepoFeedback

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

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log PowerShell-Docs not needed The PR was reviewed and doesn't appear to require a PowerShell Docs update Small WG-Engine core PowerShell engine, interpreter, and runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PSReadLine throws an exception when typing a type name after using namespace [NameSpace]

7 participants