-
Notifications
You must be signed in to change notification settings - Fork 3
New-FLowChartGraph throw Object reference not set to an instance of an object. #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Une autre construction dérivé, mais une autre exception : $sb={
$grade = 92
Switch ($Grade)
{
{$grade -ge 90} { "Grade A";Break}
# {$grade -ge 80} { "Grade B";Break}
# {$grade -ge 70} { "Grade C";Break}
# {$grade -ge 60} { "Grade D";Break}
# default { "Grade F" }
}
}
$Result=Find-FLowChartNodes -ScriptBlock $Sb
New-FLowChartGraph $Result > c:\temp\testIfWithSwitch.graph
C:\Tools\Graphviz\bin\dot -Tpng c:\temp\testIfWithSwitch.graph -o c:\temp\testIfWithSwitch.png
ii c:\temp\testIfWithSwitch.png La suivante aboutie, mais la représentation est fausse il me semble: $sb={
$grade = 92
Switch ($Grade)
{
{$grade -ge 90} { "Grade A";Break}
# {$grade -ge 80} { "Grade B";Break}
# {$grade -ge 70} { "Grade C";Break}
# {$grade -ge 60} { "Grade D";Break}
default { "Grade F" }
}
writelog "suite" # !!!!!!!! n'est pas considéré dans le graph !!!!!!!!!!
}
del c:\temp\testIfWithSwitch.graphn, c:\temp\testIfWithSwitch.png -ea ignore
$Result=Find-FLowChartNodes -ScriptBlock $Sb
New-FLowChartGraph $Result > c:\temp\testIfWithSwitch.graph
C:\Tools\Graphviz\bin\dot -Tpng c:\temp\testIfWithSwitch.graph -o c:\temp\testIfWithSwitch.png
ii c:\temp\testIfWithSwitch.png |
Super merci pour les exemple de code qui pose problème! Merci beaucoup pour les issues @LaurentDardenne ! |
Normalement c'est fixé ! |
Ce cas n'est pas géré et déclenche la même exception : $sb={
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 80) { "Grade B"} #;Break}
elseif ($grade -ge 70) { "Grade C"}
elseif ($grade -ge 60) { "Grade D" }
else { "Grade F"}
writeLog "Suite"
break
}
del c:\temp\testWithIF2.graph, c:\temp\testWithIF2.png -ea Ignore
Find-FLowChartNodes -ScriptBlock $Sb|New-FLowChartGraph
#New-FLowChartGraph : La référence d'objet n'est pas définie à une instance d'un objet.
$stacktrace
<#
à FlowChartCore.Graph.BreakBuilder.CreateSpecialEdge()
à FlowChartCore.Graph.BreakBuilder..ctor(BreakNode breaknode)
à FlowChartCore.BreakNode.GenerateGraph(Boolean recursive)
à FlowChartCore.ElseIfNode.GenerateGraph(Boolean recursive)
à FlowChartCore.IfNode.GenerateGraph(Boolean recursive)
à FlowChartCore.Cmdlets.NewFlowChartGraph.ProcessRecord()
à System.Management.Automation.CommandProcessor.ProcessRecord()
#> La présence du break, peut importe sa position, déclenche l'exception. En passant le libellé de fin devrait suivre le nom du paramètre : |
Du coup avec cette version on peut visualiser la comparaison entre les instructions If et Switch : $sb={
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 80) { "Grade B"}
elseif ($grade -ge 70) { "Grade C"}
elseif ($grade -ge 60) { "Grade D" }
else { "Grade F"}
writeLog "Suite"
}
del c:\temp\testWithIF2.graph, c:\temp\testWithIF2.png -ea Ignore
Find-FLowChartNodes -ScriptBlock $Sb|New-FLowChartGraph |Set-Content c:\temp\testIF.graph
C:\Tools\Graphviz\bin\dot -Tpng c:\temp\testIf.graph -o c:\temp\testIf.png
ii c:\temp\testIf.png
$sb={
$grade = 92
Switch ($Grade)
{
{$grade -ge 90} { "Grade A"}
{$grade -ge 80} { "Grade B"}
{$grade -ge 70} { "Grade C"}
{$grade -ge 60} { "Grade D"}
default { "Grade F" }
}
}
$Result=Find-FLowChartNodes -ScriptBlock $Sb
New-FLowChartGraph $Result > c:\temp\testIfWithSwitch.graph
C:\Tools\Graphviz\bin\dot -Tpng c:\temp\testIfWithSwitch.graph -o c:\temp\testIfWithSwitch.png
ii c:\temp\testIfWithSwitch.png Bien que le rendu soit différent, le 'fonctionnement' est identique. |
t as testé le break comme ça pour voir si ça balançait le même message d'erreur: Switch ($Grade)
{
{$grade -ge 90} { "Grade A";break}
{$grade -ge 80} { "Grade B";break}
{$grade -ge 70} { "Grade C";break}
{$grade -ge 60} { "Grade D";break}
default { "Grade F";break}
} je ne pense pas avoir gérer ce cas. je peux éventuellement le gérer si nécessaire, mais en gros ça fait quoi ? ça quitte ? un peu comme exit ou return ? |
Salut,
Oui, mais là il faut créer des fichiers de test pour vérifier les régressions, ça va vite avec ce genre d'outil. Ce cas provoque une exception : $sb={
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 80) { "Grade B"}
elseif ($grade -ge 70) { "Grade C";break}
elseif ($grade -ge 60) { "Grade D" }
else { "Grade F"}
writeLog "Suite"
} Et celui-ci: $sb={
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 80) { "Grade B"} #;Break}
elseif ($grade -ge 70) { "Grade C"}
elseif ($grade -ge 60) { "Grade D" }
else { "Grade F"}
writeLog "Suite"
break
}
Si tu parles bien de l'instruction Break ( j'ai un doute désolé) ?
Ici il peut y avoir 5 ou 6 constructions, avec ou sans sens, mais si le langage les permet, on peut les retrouver dans du code à la six-quatre-deux. |
bon faut que je regarde ces cas .. je crois que je vais écrire des tests ça sera moins relou ... concernant le break ...le code de m... bah je vois 2 possibilités,
|
:-)
hum, tu peux vite te retrouver avec un paquet de code illisible et pour un cas précis tout exécuter et devoir aller chercher l'info.
Tu veux dire on ajoute un noeud 'Break' ou on quitte l'analyse ?
Si l'AST indique que la construction d'un break est syntaxiquement correct, il est au 'bon endroit'. Ce serait à PSSA de dire là c'est du code en vrac, ce que n'est pas ton soft. Ces exemples sont bien évidement du n'importe quoi, mais ton soft ne devrait pas terminer sur une exception. Je peux prendre un peu de temps pour étudier comment automatiser et structurer ce type de test. |
(note to self!) pour les break .. j'ai un fix, mais vu que pour moi ce genre de cas ... n'existait pas .. je n'ai jamais pensé à passer le le fix ne fonctionne pas, car je ne troue pas l index du noeud, quand le type break est de niveau 0, car le root n'est pas présent .. ! |
et celui la:
Modif faite pour Breajk. J'ai prépa le terrain pour ce que j'appelle les "keywords" continue, exit, return ... parce t as raison PS ne l interdit pas, j'aurai juste a implémenter les correction de la generation du graph pour ceux la |
Eh je crois que g pas merge le dernier que g fait hier soir ...! |
Ok, je préfére ça :-) |
Correcting Issue #17, some more works needs to be done for other keywords
done! j'ai testé aussi sur ps5.1 et pareil juste besoin d'importer la flowchartcore.dll |
Merci.
C'est une habitude, je place tout dans un script pour l'initialisation, ensuite je ne crée que le nécessaire. Ensuite on peut créer juste un manifeste (psd1), mais le téléchargement via Github ajoute le stream de sécurité à supprimer, là où l'installation d'un module via PSGallery ne le fait pas. Il y a ( avait ?) une gallery de dev sinon utiliser myget. Je l'utilise pour ne pas polluer la gallery avec des POC et autre outil perso. |
t as forké, tu peux participer à la fête, et ça sera plus simple que de dll le projet :) t auras juste à rebase ou je sais pas ce que c le terme git ! |
Certes, pense à d'autres qui peuvent tester sans devoir creuser le comment du pourquoi.
L'avantage de l'utiliser dés le début est que tu valides la chaîne (ton soft et le build) tout au long du développement. |
c vrai :) mais la vu que c du compilé ^^ tu build et boum ! d'habitude je fais ça aussi |
Autres constructions provoquant le bug : #OK
$sb={
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 70) { "Grade C"}
else { "Grade D"}
}
#NOK
$sb={
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 70) { "Grade C"}
}
#NOK
#if dans une boucle for
$sb={
for ($i = 1; ; ++$i)
{
if ($i * $i -gt 50)
{
dir
}
}
} |
it is corrigé ! |
En direct du doc des spec de PS : $break7=New-CodeUseCase 'Break use a string value as target' @'
$i = 1
while ($true) # infinite loop
{
if ($i * $i -gt 100)
{
break # break out of current while loop
}
++$i
}
$lab = "go_here"
:go_here
for ($i = 1; ; ++$i)
{
if ($i * $i -gt 50)
{
break $lab # use a string value as target
}
}
:labelA
for ($i = 1; $i -le 2; $i++)
{
:labelB
for ($j = 1; $j -le 2; $j++)
{
:labelC
for ($k = 1; $k -le 3; $k++)
{
if ($true) { break labelA }
}
}
}
'@ |
Concernant $sb = {
$lab = "go_here"
:go_here
for ($i = 1; ; ++$i)
{
if ($i * $i -gt 50)
{
break $lab # use a string value as target
}
}
} ça je l'ai pas ... ! le problème c'est que si on regarde l'AST du break et bien la propriété label est vide ... PS > $x = Find-FLowChartNodes -ScriptBlock $sb
PS > $break = $x.findnodes({$args[0] -is [FlowChartCore.BreakNode]},$true)
PS > $break.GetAst()
Label Extent Parent
----- ------ ------
break {…
Du coup si le label est vide, j'ai mis une description "Break from Previous Loop"
J'ai par la même occasion corrigé un bug, sur les label qui était "Break From" au lieu de "Break From TheLabel" |
Oui le niveau de détail est plus important. On peut descendre d'un niveau : 'je trouve ça moins facile en C qu'en C#' |
fix issue #17, break with variable label
le cas que j'ai pas gérer ... c'est si tu réaffectes: et enfait dans ton code tu fais un truc comme ça: $somvar = "lol"
$somevar = "namaisohSerieux?"
...
break $somevar
`` |
Autre cas qui déclenche l'exception : Find-FLowChartNodes
#Find-FLowChartNodes : La référence d'objet n'est pas définie à une instance d'un objet. |
ah ouais rigolo ... hum faut que je regarde comment résoudre ça ... ! edit: c'est fixé PS > Find-FLowChartNodes
Find-FLowChartNodes: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used
together or an insufficient number of parameters were provided. |
Les constructions suivantes déclenchent l'exception sur New-FLowChartGraph : New-CodeUseCase 'Switch -File' {
$IsXml=$False
#$FileName=(get-process -pid $pid).Path #test de syntaxe
switch -file $FileName
{
#Début de la section XML
"<?xml version=`"1.0`" encoding=`"ibm850`"?>" {$IsXml=$True;$_;continue}
#Fin de la section XML
"</response>" {$IsXml=$False;$_;break}
default {if ($IsXml)
#On traite les lignes si on se trouve dans la section XML
{$_}
}
}
}
New-CodeUseCase 'Switch Array' {
switch (1,4,-1,3,"Hello",2,1)
{
{$_ -lt 0} { Continue }
{$_ -isnot [Int32]} { Break }
{$_ % 2} {
"$_ is Odd"
}
{-not ($_ % 2)} {
"$_ is Even"
}
}
}
|
ah c le continue ... ça marche dans un switch ?? ça fait kewa ? |
Cela dépend de la construction, dans un boucle on passe à l'itération suivante, ici comme on a un tableau en entrée d'un switch on passe à la valeur suivante ( ici le comportement est identique à celui dans une boucle) : switch (1,4,-1,3,"Hello",2,1)
{
{$_ -lt 0} { write-warning "continue : $_"; Continue }
{$_ -isnot [Int32]} { write-warning "break : $_ ";Break }
{$_ % 2} {
write-warning "suite : $_ ";"$_ is Odd"
}
{-not ($_ % 2)} {
write-warning "suite : $_ ";"$_ is Even"
}
} Mais l'exemple de code Switch -File n'est pas courante on filtre dans une boucle car switch -file lit tout le fichier $filename: function ParseXml([String] $FileName)
{ #Récupération des lignes de la déclaration XML issu de MsdnMan
#L'extraction XML contient quelques lignes parasites.
$IsXml=$False
switch -file $FileName
{
#Début de la section XML
"<?xml version=`"1.0`" encoding=`"ibm850`"?>" {$IsXml=$True;$_;continue}
#Fin de la section XML
"</response>" {$IsXml=$False;$_;break}
default {if ($IsXml)
#On traite les lignes si on se trouve dans la section XML
{$_}
}
}
}
|
Il semble qu'il y ait une régression sur le foreach : [-] FlowChartCode .When there is no violation.Foreach enhanced. 4ms (3ms|0ms)
Expected no exception to be thrown, but an exception "Object reference not set to an instance of an object." was thrown |
étrange! j'ai rouler les tests hier soir et tout fonctionnait ... ! je check ça ! j'ai testé "manuellemen" en copiant le scriptblock du foreach enahanced, $a = {
[CmdletBinding()]
[OutputType('FunctionPosition')]
param(
[Parameter(Position = 0, Mandatory,
ValueFromPipeline, ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('PSPath')]
[System.String[]]
$Path
)
process {
try {
$filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) {
Write-Verbose "From pipeline"
$_
} else {
Write-Verbose "From parameter, $Path"
Get-Item -Path $Path
}
$parser = [System.Management.Automation.Language.Parser]
Write-Verbose "lets start the foreach loop on `$filesToProcess with $($filesToProcess.count) as count"
foreach ($item in $filesToProcess) {
Write-Verbose "$item"
if ($item.PSIsContainer -or
$item.Extension -notin @('.ps1', '.psm1')) {
continue
}
$tokens = $errors = $null
$parser::ParseFile($item.FullName, ([REF]$tokens),
([REF]$errors)) | Out-Null
if ($errors) {
$msg = "File '{0}' has {1} parser errors." -f $item.FullName,
$errors.Count
Write-Warning $msg
}
:tokenLoop foreach ($token in $tokens) {
if ($token.Kind -ne 'Function') {
continue
}
$position = $token.Extent.StartLineNumber
do {
if (-not $foreach.MoveNext()) {
break tokenLoop
}
$token = $foreach.Current
} until ($token.Kind -in @('Generic', 'Identifier'))
$functionPosition = [pscustomobject]@{
Name = $token.Text
LineNumber = $position
Path = $item.FullName
}
Add-Member -InputObject $functionPosition `
-TypeName FunctionPosition -PassThru
}
}
}
catch {
throw
}
}
}
Find-FlowChartNodes -ScriptBlock $a Et je n'ai pas d'exception ... ! whyyyyy ??? |
La dernière fois, cette situation était due à une initialisation qui n'était pas faite. |
Ok j'ai trouvé je vais corrigé... ! |
Probléme à priori avec la présence du return dans ces constructions :
Même exception que pour le poste d'origine. |
ok c fixé !) |
Merci. |
C est dans la branche feature-dev pour l instant! Si tu as besoin je merge dans master 7000 fichier!!!! Et alors il n y avait pas trop d erreur?? |
Avec PS v7.1 non, sauf celles du return et bcp d'erreur de syntaxe dans les fichiers. |
Tu peux clore je pense. |
The following code based on a test of the switch statement raises an exception :
$stacktrace:
The text was updated successfully, but these errors were encountered: