Skip to content

Generic Extension Method PoC #10

@fMichaleczek

Description

@fMichaleczek

It's a standalone sample tested on PowerShell 7.4 with an existant generic extension method present in the PowerShell assemblies.

I don't measure the AST overhead, there is some bug with wrap and unwrap for $this
I have a helper class that do the same as this module but scoped to limited features.

So I post here this code, so you are able to integrate easily the idea if you ever need it

<#
[Markdig.MarkdownExtensions]::Use

OverloadDefinitions
-------------------
static Markdig.MarkdownPipelineBuilder Use[TExtension](Markdig.MarkdownPipelineBuilder pipeline)
static Markdig.MarkdownPipelineBuilder Use[TExtension](Markdig.MarkdownPipelineBuilder pipeline, TExtension extension)

#>
$builder = [Markdig.MarkdownPipelineBuilder]::new()
$builder | Add-Member -MemberType ScriptMethod -Name Use -Value {
       
    $type = [Markdig.MarkdownExtensions]
    $methodName = 'Use'
    
    $parameters = @($this.psobject.ImmediateBaseObject) + $args
    $parametersCount = $args.Length + 1

    $method = $type.GetMethods().Where{ $_.Name -eq $methodName -and $_.GetParameters().Count -eq $parametersCount }[0]
    
    $invocationAst = [System.Management.Automation.Language.Parser]::ParseInput($MyInvocation.Statement, [ref] $null, [ref] $null)
    $invokeMemberAst = $invocationAst.FindAll({ $args[0] -is [System.Management.Automation.Language.InvokeMemberExpressionAst]}, $false)
    
    if ($invokeMemberAst.GenericTypeArguments)
    {
        $genericTypeArguments = $invokeMemberAst.GenericTypeArguments.ForEach{ $_.GetReflectionType() }
        $genericMethod = $method.MakeGenericMethod($genericTypeArguments)
        $genericMethod.Invoke($null, $parameters)
    }
    else
    {
        $method.Invoke($null, $parameters)
    }
    
} -Force 

$emojiExt = [Markdig.Extensions.Emoji.EmojiExtension]::new($null)

# Extension Method
# [Markdig.MarkdownExtensions]::Use[Markdig.Extensions.Emoji.EmojiExtension]($builder, $emojiExt)

# ETS with AST
$builder.Use[Markdig.Extensions.Emoji.EmojiExtension]($emojiExt)

# ETS with crazy AST
$builder. ("U" + 'se')<# test #> [ Markdig.Extensions.Emoji.EmojiExtension ]( $emojiExt)

# KO, but not related to ETS
# [Markdig.MarkdownExtensions]::Use[Markdig.Extensions.Emoji.EmojiExtension]($builder) 
# $builder.Use[Markdig.Extensions.Emoji.EmojiExtension]()

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions