Skip to content

Type checking in PowerShell class method bodies is not needed #6722

Closed

Description

@rjmholt

#2074 and #3641 and PowerShell/PSScriptAnalyzer#850 discuss type resolution in PowerShell classes.

The examples they use involve types that are required to be known (because they are field/property/method-return types) at compile time (in order to compile the class to IL).

But, we also do type checking in method bodies, even though we don't need to. Example:

> class MyClass { [string] GenStr() { return [Foo]::new().ToString() } }
At line:1 char:45
+ class MyClass { [string] GenStr() { return [Foo]::new().ToString() }  ...
+                                             ~~~
Unable to find type [Foo].
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TypeNotFound

In the above, we don't need to compile against [Foo] at all, so this should be a runtime error. /cc Dongbo Wang (@daxian-dbw).

Activity

  1. BrucePay commented on Apr 24, 2018

    @BrucePay
    Collaborator

    Rob Holt (@rjmholt) Dongbo Wang (@daxian-dbw) Jason Shirk (@lzybkr) The goal with classes is to be substantially more rigorous than normal PowerShell. We wanted to catch as many errors at compile time as possible. If you have an unresolved type in a method at compile time, then add the necessary using module statement so the type resolves. That way you won't have an unresolved type exception at runtime. Dongbo questioned the inconsistency with commands which are resolved at runtime. I don't know - maybe we should make you add using module statements for cmdlets that aren't part of the PowerShell core.

  2. markekraus commented on Apr 24, 2018

    @markekraus
    Contributor

    Bruce Payette (@BrucePay)

    I don't know - maybe we should make you add using module statements for cmdlets that aren't part of the PowerShell core.

    Lets say I have the following MyModule.psm1:

    Enum MyEnum {
        A
        B
    }
    
    class MyClass {
        [MyEnum]$Prop1
    
        MyClass () {
            $This.Prop1 = Get-MyEnumPrivate
        }
    }
    
    function Get-MyClassPublic {
        [CmdletBinding()]
        [OutputType([MyClass])]
        param ()
        end {
            [MyClass]::New()
        }
    }
    Export-ModuleMember -Function Get-MyClassPublic
    
    function Get-MyEnumPrivate {
        [CmdletBinding()]
        [OutputType([MyEnum])]
        param ()
        end {
            [MyEnum]::B
        }
    }

    If checking for unresolved commands and compile time resulted in an error, would that mean module authors would now need to ensure the private functions a method consumes exists or is defined before the class is compiled? That would seem troubling.

  3. BrucePay commented on Apr 25, 2018

    @BrucePay
    Collaborator

    Why? It's already the case for functions i.e. functions must be defined before they can be used. Alternatively we could build the AST for the module, find all the function definitions in the ast and then check the methods to make sure all of the directly called functions are defined, either in the module or through using module statements. And for dynamic dispatches, you could still use the call (&) operator.

  4. markekraus commented on Apr 25, 2018

    @markekraus
    Contributor

    Bruce Payette (@BrucePay)

    It's already the case for functions i.e. functions must be defined before they can be used.

    Perhaps I'm misunderstanding here, but weren't you suggesting with this

    I don't know - maybe we should make you add using module statements for cmdlets that aren't part of the PowerShell core.

    That the PowerShell classes would error at compile time if a method body contained a function that is not already defined? That is a different from a function calling another function at runtime. I can define a function that calls another function that is not yet defined and that will only cause an error at runtime. it does not, however, cause an error at definition time.

    Alternatively we could build the AST for the module, find all the function definitions in the ast and then check the methods [snip]

    Yes. That's where I was going with this, but I just wanted clarity first.

  5. BrucePay commented on Apr 25, 2018

    @BrucePay
    Collaborator

    That the PowerShell classes would error at compile time if a method body contained a function that is not already defined?

    Right. This is different than the dynamic behaviour of functions but we've had a lot of asks for essentially static function resolution at compile time. (I implemented it once to see if it would make dispatch faster - at the time it didn't). Since we've had this idea that classes would exhibit more traditional programming language semantics, having static function resolution seems appropriate.

  6. markekraus commented on Apr 25, 2018

    @markekraus
    Contributor

    So long as the module author doesn't need to care too deeply about the order in which the Classes, Enums, and functions are defined in the module, I'm on board with it being stricter.

  7. added
    WG-Languageparser, language semantics
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    on Apr 25, 2018
  8. vexx32 commented on Aug 14, 2018

    @vexx32
    Collaborator

    Being strict is fine, but if we have to start being incredibly picky about the order of definition it would quickly become nothing more than a nuisance. So... yes go for it.

  9. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  10. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  11. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  12. microsoft-github-policy-service commented on Nov 23, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreWG-Languageparser, language semantics

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions