Skip to content

Commit 34dd75d

Browse files
committed
Performance and Debugging improvements
Cleaned up, normalized a bit, and fixed bugs found in integration tests.
1 parent 5387180 commit 34dd75d

File tree

6 files changed

+49
-43
lines changed

6 files changed

+49
-43
lines changed

Source/Private/ConvertToAst.ps1

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function ConvertToAst {
1010
$Code
1111
)
1212
process {
13-
Write-Debug " ENTER: ConvertToAst $Code"
13+
Write-Debug " ENTER: ConvertToAst $(($Code -split "[\r\n]")[0])"
1414
$ParseErrors = $null
1515
$Tokens = $null
1616

@@ -19,12 +19,13 @@ function ConvertToAst {
1919
$AST = [System.Management.Automation.Language.Parser]::ParseInput($Code.Definition, "function:$($Code.Name)", [ref]$Tokens, [ref]$ParseErrors)
2020
} else {
2121
$Provider = $null
22-
try {
23-
[string[]]$Files = $ExecutionContext.SessionState.Path.GetResolvedProviderPathFromPSPath($Code, [ref]$Provider)
24-
} catch {
25-
Write-Debug ("Exception resolving Code as Path " + $_.Exception.Message)
22+
if (@($Code).Count -eq 1 -and $Code -notmatch "\n") {
23+
try {
24+
[string[]]$Files = $ExecutionContext.SessionState.Path.GetResolvedProviderPathFromPSPath($Code, [ref]$Provider)
25+
} catch {
26+
Write-Debug ("Exception resolving Code as Path " + $_.Exception.Message)
27+
}
2628
}
27-
2829
if ($Provider.Name -eq "FileSystem" -and $Files.Count -gt 0) {
2930
Write-Debug " Parse Code as File Path"
3031
$AST = [System.Management.Automation.Language.Parser]::ParseFile(($Files[0] | Convert-Path), [ref]$Tokens, [ref]$ParseErrors)

Source/Public/Add-Parameter.ps1

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ function Add-Parameter {
5656
Get-Date -Format $Format
5757
}
5858
#>
59+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
60+
<#RuleId#>'PSReviewUnusedParameter',
61+
<#ParameterName#>'FunctionName',
62+
Justification = 'This parameter IS used, the rule does not understand scopes'
63+
)]
5964
[CmdletBinding()]
6065
[OutputType([TextReplacement])]
6166
param(
@@ -100,7 +105,7 @@ function Add-Parameter {
100105
Name = $parameter.Name
101106
StartOffset = $parameter.StartOffset
102107
Text = if (($parameter.StartLineNumber - $FirstLine) -ge $NextLine) {
103-
Write-Debug "Extracted parameter $($Parameter.Name) with surrounding lines"
108+
# Write-Debug "Extracted parameter $($Parameter.Name) with surrounding lines"
104109
# Take lines after the last parameter
105110
$Lines = @($Text[$NextLine..($parameter.EndLineNumber - $FirstLine)].Where{ ![string]::IsNullOrWhiteSpace($_) })
106111
# If the last line extends past the end of the parameter, trim that line
@@ -110,7 +115,7 @@ function Add-Parameter {
110115
# Don't return the commas, we'll add them back later
111116
($Lines -join "`n").TrimEnd(",")
112117
} else {
113-
Write-Debug "Extracted parameter $($Parameter.Name) text exactly"
118+
# Write-Debug "Extracted parameter $($Parameter.Name) text exactly"
114119
$parameter.Text.TrimEnd(",")
115120
}
116121
}
@@ -163,7 +168,7 @@ function Add-Parameter {
163168
}
164169
}
165170
process {
166-
Write-Debug "Add-Parameter $InputObject $FunctionName $Boilerplate"
171+
# Write-Debug "Add-Parameter $($InputObject.Extent.File ?? ( "L:" + $InputObject.Extent.StartLineNumber + ".." + $InputObject.Extent.EndLineNumber + " C:" + $InputObject.Extent.StartColumnNumber + ".." + $InputObject.Extent.EndColumnNumber)) $FunctionName $Boilerplate"
167172

168173
$Generator = [ParameterGenerator]@{
169174
FunctionFilter = { $Func = $_; $FunctionName.ForEach({ $Func.Name -like $_ }) -contains $true }.GetNewClosure()

Source/Public/Build-Module.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ function Build-Module {
148148
# Folder paths which don't exist inside the module root are ignored.
149149
# Defaults to a search of: "Boilerplate", "Template", "Generators", "Boilerplates", "Templates"
150150
[Alias("TemplateDirectory")]
151-
[string[]]$BoilerplateDirectory = @("Boilerplate", "Template", "Generators", "Boilerplates", "Templates"),
151+
[string[]]$BoilerplateDirectory = @("[Bb]oilerplate", "[Tt]emplate", "[Gg]enerators", "[Bb]oilerplates", "[Tt]emplates"),
152152

153153
# Output the ModuleInfo of the "built" module
154154
[switch]$Passthru

Source/Public/Invoke-ScriptGenerator.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ function Invoke-ScriptGenerator {
6363
[switch]$Overwrite
6464
)
6565
begin {
66-
Write-Debug "Parsing $Source for $Generator with @{$($Parameters.Keys.ForEach{ $_ } -join ', ')}"
6766
$ParseResults = ConvertToAst $Source
6867
[StringBuilder]$Builder = $ParseResults.Ast.Extent.Text
6968
$File = $ParseResults.Ast.Extent.File
@@ -73,6 +72,7 @@ function Invoke-ScriptGenerator {
7372
$Generator = $Parameters["Generator"]
7473
$null = $Parameters.Remove("Generator")
7574
}
75+
Write-Debug "Invoking $Generator generator for $Source with @{$($Parameters.Keys.ForEach{ $_ } -join ', ')}"
7676

7777
# To make things more usable, resolve paths to "boilerplate" or "template" files based on our BoilerplateDirectory (alias TemplateDirectory)
7878
try {
@@ -83,13 +83,15 @@ function Invoke-ScriptGenerator {
8383
$Parameters.Boilerplate = $BoilerPlate
8484
}
8585
}
86+
Write-Debug "Boilerplate = $($Parameters.Boilerplate)"
8687
} elseif ($Parameters.ContainsKey("Template")) {
8788
# If there's a Template parameter and it does not point at a file, check in the BoilerplateDirectory, and update it, if we find it.
8889
if ($Parameters.Template -and -not (Test-Path $Parameters.Template)) {
8990
if ($Template = Join-Path $BoilerplateDirectory $Parameters.Template | Where-Object { Test-Path $_ }) {
9091
$Parameters.Template = $Template
9192
}
9293
}
94+
Write-Debug "Template = $($Parameters.Template)"
9395
}
9496
} catch {
9597
Write-Debug "Could not resolve the Boilerplate/Template"
@@ -110,7 +112,7 @@ function Invoke-ScriptGenerator {
110112
continue
111113
}
112114

113-
Write-Verbose "Generating $GeneratorCmd in $Source"
115+
Write-Verbose "Generating $GeneratorCmd in $Source $(if($Parameters.Count){"`n with $($Parameters.GetEnumerator().ForEach{ $_.Key + ' = ' + ($_.Value -join ", ") } -join "`n and ")"})"
114116
#! Process replacements from the bottom up, so the line numbers work
115117
foreach ($Replacement in $ParseResults | & $GeneratorCmd @Parameters | Sort-Object StartOffset -Descending) {
116118
$Builder = $Builder.Remove($replacement.StartOffset, ($replacement.EndOffset - $replacement.StartOffset)).Insert($replacement.StartOffset, $replacement.Text)

Source/Public/Merge-ScriptBlock.ps1

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -90,51 +90,49 @@ filter Merge-ScriptBlock {
9090
hidden [NamedBlockAst]$EndBlockTemplate
9191

9292
[string] GetExtentText([NamedBlockAst]$Ast) {
93-
if ($ast.UnNamed -and $ast.Parent.ParamBlock.Extent.Text) {
93+
if ($Ast.UnNamed -and $Ast.Parent.ParamBlock.Extent.Text) {
9494
# Trim the paramBlock out of the what we're injecting into the boilerplate template
95-
return $ast.Extent.Text.Remove(
96-
$ast.Parent.ParamBlock.Extent.StartOffset - $ast.Extent.StartOffset,
97-
$ast.Parent.ParamBlock.Extent.EndOffset - $ast.Parent.ParamBlock.Extent.StartOffset).Trim("`r`n").TrimEnd("`r`n ")
95+
return $Ast.Extent.Text.Remove(
96+
$Ast.Parent.ParamBlock.Extent.StartOffset - $Ast.Extent.StartOffset,
97+
$Ast.Parent.ParamBlock.Extent.EndOffset - $Ast.Parent.ParamBlock.Extent.StartOffset).Trim("`r`n").TrimEnd("`r`n ")
9898
} else {
9999
# Trim the `end {` ... `}` off if they're there
100-
return ($ast.Extent.Text -replace "^$($ast.BlockKind)[\s\r\n]*{|}[\s\r\n]*$", "`n").Trim("`r`n").TrimEnd("`r`n ")
100+
return ($Ast.Extent.Text -replace "^$($Ast.BlockKind)[\s\r\n]*{|}[\s\r\n]*$", "`n").Trim("`r`n").TrimEnd("`r`n ")
101101
}
102102
}
103103

104104
Replace([NamedBlockAst]$Template, [NamedBlockAst]$Ast) {
105-
if ($Template) {
106-
if ($ast) {
107-
# If there's a ParamBlock, we don't want to replace that
108-
$Extent = $ast.Extent
109-
if ($ast.UnNamed -and $ast.Parent.ParamBlock.Extent.Text) {
110-
# Make sure we don't replace the ParamBlock
111-
$StartOffset = $ast.Parent.ParamBlock.Extent.EndOffset
112-
} else {
113-
$StartOffset = $Extent.StartOffset
114-
}
115-
$this.Replacements.Add(@{
116-
StartOffset = $StartOffset
117-
EndOffset = $Extent.EndOffset
118-
Text = $this.GetExtentText($Template).Replace("Use-OriginalBlock", $this.GetExtentText($ast))
119-
})
105+
if ($Template -and $Ast) {
106+
# If there's a ParamBlock, we don't want to replace that
107+
$Extent = $Ast.Extent
108+
if ($Ast.UnNamed -and $Ast.Parent.ParamBlock.Extent.Text) {
109+
# Make sure we don't replace the ParamBlock
110+
$StartOffset = $Ast.Parent.ParamBlock.Extent.EndOffset
120111
} else {
121-
Write-Debug "$($ast.Name) Missing $($Template.BlockKind)"
112+
$StartOffset = $Extent.StartOffset
122113
}
123-
} else {
124-
Write-Debug "Boilerplate Missing $($Template.BlockKind)"
114+
Write-Debug "Adding Boilerplate for $($Ast.BlockKind)"
115+
$this.Replacements.Add(@{
116+
StartOffset = $StartOffset
117+
EndOffset = $Extent.EndOffset
118+
# We end up having to normalize the template to be named blocks...
119+
# Just in case the InputObject has named blocks
120+
Text = "$($Ast.BlockKind) {`n" +
121+
$this.GetExtentText($Template).Replace("Use-OriginalBlock", $this.GetExtentText($Ast)) +
122+
"`n}"
123+
})
125124
}
126125
}
127126

128-
129127
# The [Alias(...)] attribute on functions matters, but we can't export aliases that are defined inside a function
130-
[AstVisitAction] VisitFunctionDefinition([FunctionDefinitionAst]$ast) {
131-
if (!$ast.Where($this.FunctionFilter)) {
128+
[AstVisitAction] VisitFunctionDefinition([FunctionDefinitionAst]$Ast) {
129+
if (!$Ast.Where($this.FunctionFilter)) {
132130
return [AstVisitAction]::SkipChildren
133131
}
134-
135-
$this.Replace($this.BeginBlockTemplate, $ast.Body.BeginBlock)
136-
$this.Replace($this.ProcessBlockTemplate, $ast.Body.ProcessBlock)
137-
$this.Replace($this.EndBlockTemplate, $ast.Body.EndBlock)
132+
Write-Debug "Merging $($Ast.Name) with boilerplate"
133+
$this.Replace($this.BeginBlockTemplate, $Ast.Body.BeginBlock)
134+
$this.Replace($this.ProcessBlockTemplate, $Ast.Body.ProcessBlock)
135+
$this.Replace($this.EndBlockTemplate, $Ast.Body.EndBlock)
138136

139137
return [AstVisitAction]::SkipChildren
140138
}

Source/Public/Update-AliasesToExport.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ function Update-AliasesToExport {
141141
}
142142
}
143143
process {
144-
$Visitor = [AliasVisitor]::new()
144+
$Visitor = [AliasExportGenerator]::new()
145145
$ScriptModule.Visit($Visitor)
146146
Update-Metadata -Path $ModuleManifest -PropertyName AliasesToExport -Value $Visitor.Aliases
147147
}

0 commit comments

Comments
 (0)