Skip to content

Instantly share code, notes, and snippets.

@eosfor
Last active May 11, 2017 10:51
Show Gist options
  • Save eosfor/783d8efcdd1996df56ece5154fa3a6da to your computer and use it in GitHub Desktop.
Save eosfor/783d8efcdd1996df56ece5154fa3a6da to your computer and use it in GitHub Desktop.
quick and dirty graph of functions
function Find-ASTItem {
param(
[string[]]$FullName,
[ScriptBlock]$FindAll
)
Process {
$Ast = [System.Management.Automation.Language.Parser]::ParseFile( (Resolve-Path $FullName) , [ref]$null, [ref]$null)
foreach($item in $ast.FindAll($FindAll, $true)) {
[PSCustomObject]@{
FileName = Split-Path -Leaf $item.Extent.File
Name = (ASTNameLookup $item.GetType().Name $Item)
Line = $item.Extent.Text
StartLineNumber = $item.Extent.StartLineNumber
StartColumnNumber = $item.Extent.StartColumnNumber
EndLineNumber = $item.Extent.EndLineNumber
EndColumnNumber = $item.Extent.EndColumnNumber
FullName = $item.Extent.File
}
}
}
}
function ASTNameLookup {
param($targetType)
switch ($targetType) {
AssignmentStatementAst {$args[0].Left}
ParameterAst {$args[0].Name}
CommandAst {$args[0].CommandElements[0].Value}
ForEachStatementAst {"ForEach"}
FunctionDefinitionAst {$args[0].Name}
default {$_}
}
}
function Find-ASTItemByType {
param(
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]$Fullname,
$ASTType
)
Begin {
$ASTType = "System.Management.Automation.Language.$($ASTType)" -as [Type]
}
Process {
Find-ASTItem -FullName $Fullname -FindAll {
param($ast)
if($ast -is $ASTType) {
$ast
}
} | Where Name -Match $Name
}
}
function Find-VariableAssignment {
param(
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]$Fullname
)
Process { Find-ASTItemByType $Name $Fullname AssignmentStatementAst }
}
function Find-Function {
param(
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]$Fullname
)
Process { Find-ASTItemByType $Name $Fullname FunctionDefinitionAst }
}
function Find-Expression {
param(
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]$Fullname
)
Process { Find-ASTItemByType $Name $Fullname CommandAst }
}
function Find-Parameter {
param(
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]$Fullname
)
Process { Find-ASTItemByType $Name $Fullname ParameterAst }
}
$g = New-Graph -Type AdjacencyGraph
$f = dir "E:\Repo\Public\AzureCalc\AzureCalc.psm1" | Find-Function
$f.name | % { Add-Vertex -Vertex $_ -Graph $g}
$f | % {
$fName = $_.name
$tmpFile = New-TemporaryFile
$_.line >> ($tmpFile.fullname)
$expr = Find-Expression -Fullname $tmpFile.fullname
$expr.name | ? {$_} | % { Add-Edge -From $fName -to $_ -Graph $g}
}
#Export graph
$graphFile = "c:\temp\ps.gv"
$svgOutFile = "c:\temp\ps.svg"
$pngOutFile = "c:\temp\ps.png"
Export-Graph -Graph $g -Format Graphviz -Path $graphFile
$tempFile = Get-Content $graphFile
$tempFile[0] += "`r`n" + "rankdir = LR"
$tempFile | Out-File $graphFile -Encoding ascii
pushd
cd c:\temp\graphviz\release\bin
.\dot.exe -Tsvg $graphFile -o $svgOutFile
.\dot.exe -Tpng $graphFile -o $pngOutFile
popd
start $pngOutFile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment