diff --git a/powershell/ql/lib/powershell.qll b/powershell/ql/lib/powershell.qll index 98746195f9c5..3260ee14b833 100644 --- a/powershell/ql/lib/powershell.qll +++ b/powershell/ql/lib/powershell.qll @@ -79,4 +79,5 @@ import semmle.code.powershell.IndexExpr import semmle.code.powershell.HashTable import semmle.code.powershell.SplitExpr import semmle.code.powershell.CommentEntity -import semmle.code.powershell.Variable \ No newline at end of file +import semmle.code.powershell.Variable +import semmle.code.powershell.internal.Internal::Public \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/Command.qll b/powershell/ql/lib/semmle/code/powershell/Command.qll index 712de75564e3..5617704789e2 100644 --- a/powershell/ql/lib/semmle/code/powershell/Command.qll +++ b/powershell/ql/lib/semmle/code/powershell/Command.qll @@ -65,30 +65,3 @@ class Cmd extends @command, CmdBase { Redirection getARedirection() { result = this.getRedirection(_) } } - -/** - * An argument to a command. - * - * The argument may be named or positional. - */ -class Argument extends Expr { - Cmd cmd; - - Argument() { cmd.getAnArgument() = this } - - Cmd getCmd() { result = cmd } - - int getPosition() { cmd.getPositionalArgument(result) = this } - - string getName() { cmd.getNamedArgument(result) = this } -} - -/** A positional argument to a command. */ -class PositionalArgument extends Argument { - PositionalArgument() { not this instanceof NamedArgument } -} - -/** A named argument to a command. */ -class NamedArgument extends Argument { - NamedArgument() { this = cmd.getNamedArgument(_) } -} diff --git a/powershell/ql/lib/semmle/code/powershell/Function.qll b/powershell/ql/lib/semmle/code/powershell/Function.qll index 402225808815..eff18885ebfe 100644 --- a/powershell/ql/lib/semmle/code/powershell/Function.qll +++ b/powershell/ql/lib/semmle/code/powershell/Function.qll @@ -33,16 +33,28 @@ abstract private class AbstractFunction extends Ast { /** Gets the number of function parameters. */ final int getNumberOfFunctionParameters() { result = count(this.getAFunctionParameter()) } - /** Gets the number of parameters (both function and block). */ + /** + * Gets the number of parameters (both function and block). + * Note: This excludes the `this` parameter. + */ final int getNumberOfParameters() { result = count(this.getAParameter()) } - /** Gets the i'th parameter of this function, if any. */ + /** + * Gets the i'th parameter of this function, if any. + * + * This does not include the `this` parameter. + */ final Parameter getParameter(int i) { result = this.getFunctionParameter(i) or result = this.getBody().getParamBlock().getParameter(i) } + final Parameter getThisParameter() { + result.isThis() and + result.getFunction() = this + } + /** Gets any parameter of this function. */ final Parameter getAParameter() { result = this.getParameter(_) } diff --git a/powershell/ql/lib/semmle/code/powershell/IndexExpr.qll b/powershell/ql/lib/semmle/code/powershell/IndexExpr.qll index 8e69928be5e9..cd31bb36b996 100644 --- a/powershell/ql/lib/semmle/code/powershell/IndexExpr.qll +++ b/powershell/ql/lib/semmle/code/powershell/IndexExpr.qll @@ -1,5 +1,5 @@ import powershell -private import internal.ExplicitWrite +private import internal.ExplicitWrite::Private class IndexExpr extends @index_expression, Expr { override string toString() { result = "...[...]" } diff --git a/powershell/ql/lib/semmle/code/powershell/Variable.qll b/powershell/ql/lib/semmle/code/powershell/Variable.qll index c23e9e237cd1..c155a5f09770 100644 --- a/powershell/ql/lib/semmle/code/powershell/Variable.qll +++ b/powershell/ql/lib/semmle/code/powershell/Variable.qll @@ -1,6 +1,6 @@ private import powershell private import semmle.code.powershell.controlflow.internal.Scope -private import internal.Internal as Internal +private import internal.Parameter::Private as Internal private predicate isFunctionParameterImpl(Internal::Parameter p, Function f, int i) { function_definition_parameter(f, i, p) @@ -42,7 +42,8 @@ private newtype TParameterImpl = TInternalParameter(Internal::Parameter p) or TUnderscore(Scope scope) { exists(VarAccess va | va.getUserPath() = "_" and scope = va.getEnclosingScope()) - } + } or + TThisParameter(Scope scope) { exists(scope.getEnclosingFunction().getDeclaringType()) } private class ParameterImpl extends TParameterImpl { abstract Location getLocation(); @@ -109,9 +110,22 @@ private class Underscore extends ParameterImpl, TUnderscore { final override Scope getEnclosingScope() { result = scope } } +private class ThisParameter extends ParameterImpl, TThisParameter { + Scope scope; + + ThisParameter() { this = TThisParameter(scope) } + + override Location getLocation() { result = scope.getLocation() } + + override string getName() { result = "this" } + + final override Scope getEnclosingScope() { result = scope } +} + private newtype TVariable = TLocalVariable(string name, Scope scope) { not isParameterImpl(name, scope) and + not name = "this" and // This is modeled as a parameter exists(VarAccess va | va.getUserPath() = name and scope = va.getEnclosingScope()) } or TParameter(ParameterImpl p) @@ -186,8 +200,11 @@ class Parameter extends AbstractLocalScopeVariable, TParameter { predicate hasDefaultValue() { exists(this.getDefaultValue()) } + /** Holds if this is the `this` parameter. */ + predicate isThis() { p instanceof ThisParameter } + /** - * Gets the index of this parameter. + * Gets the index of this parameter, if any. * * The parameter may be in a parameter block or a function parameter. */ diff --git a/powershell/ql/lib/semmle/code/powershell/VariableExpression.qll b/powershell/ql/lib/semmle/code/powershell/VariableExpression.qll index 517cffd3efa9..4259ecd79ea7 100644 --- a/powershell/ql/lib/semmle/code/powershell/VariableExpression.qll +++ b/powershell/ql/lib/semmle/code/powershell/VariableExpression.qll @@ -1,5 +1,5 @@ import powershell -private import internal.ExplicitWrite +private import internal.ExplicitWrite::Private private predicate isParameterName(@variable_expression ve) { parameter(_, ve, _, _) } diff --git a/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll b/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll index e5f6185702a8..91c0ff01cd6e 100644 --- a/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll +++ b/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll @@ -217,7 +217,11 @@ module ExprNodes { /** Gets the name of this argument, if any. */ string getName() { result = e.getName() } - StmtNodes::CmdCfgNode getCmd() { result.getAnArgument() = this } + /** Holds if `this` is a qualifier to a call. */ + predicate isQualifier() { e.isQualifier() } + + /** Gets the call for which this is an argument. */ + CallCfgNode getCall() { result.getAnArgument() = this or result.getQualifier() = this } } private class InvokeMemberChildMapping extends ExprChildMapping, InvokeMemberExpr { diff --git a/powershell/ql/lib/semmle/code/powershell/controlflow/internal/Scope.qll b/powershell/ql/lib/semmle/code/powershell/controlflow/internal/Scope.qll index 84b794dbee8f..c1c1fab1c972 100644 --- a/powershell/ql/lib/semmle/code/powershell/controlflow/internal/Scope.qll +++ b/powershell/ql/lib/semmle/code/powershell/controlflow/internal/Scope.qll @@ -36,4 +36,11 @@ class Scope extends Ast, @script_block { * This may be both function paramters and parameter block parameters. */ Parameter getAParameter() { result = this.getParameter(_) } + + Parameter getThisParameter() { + exists(Function func | + func.getBody() = this and + result = func.getThisParameter() + ) + } } diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll index 5da78ee2790f..8a48e03dca84 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll @@ -37,7 +37,7 @@ abstract class LibraryCallable extends string { LibraryCallable() { any() } /** Gets a call to this library callable. */ - Cmd getACall() { none() } + Call getACall() { none() } } /** @@ -222,7 +222,8 @@ private module Cached { cached newtype TArgumentPosition = - TKeywordArgumentPosition(string name) { name = any(CmdParameter p).getName() } or + TThisArgumentPosition() or + TKeywordArgumentPosition(string name) { name = any(Argument p).getName() } or TPositionalArgumentPosition(int pos, NamedSet ns) { exists(CfgNodes::CallCfgNode call | call = ns.getABindingCall() and @@ -232,7 +233,8 @@ private module Cached { cached newtype TParameterPosition = - TKeywordParameter(string name) { name = any(CmdParameter p).getName() } or + TThisParameterPosition() or + TKeywordParameter(string name) { name = any(Argument p).getName() } or TPositionalParameter(int pos, NamedSet ns) { exists(CfgNodes::CallCfgNode call | call = ns.getABindingCall() and @@ -245,6 +247,9 @@ import Cached /** A parameter position. */ class ParameterPosition extends TParameterPosition { + /** Holds if this position represents a `this` parameter. */ + predicate isThis() { this = TThisParameterPosition() } + /** * Holds if this position represents a positional parameter at position `pos` * with function is called with exactly the named parameters from the set `ns` @@ -256,6 +261,8 @@ class ParameterPosition extends TParameterPosition { /** Gets a textual representation of this position. */ string toString() { + this.isThis() and result = "this" + or exists(int pos, NamedSet ns | this.isPositional(pos, ns) and result = "pos(" + pos + ", " + ns.toString() + ")" ) @@ -266,6 +273,9 @@ class ParameterPosition extends TParameterPosition { /** An argument position. */ class ArgumentPosition extends TArgumentPosition { + /** Holds if this position represents a `this` argument. */ + predicate isThis() { this = TThisArgumentPosition() } + /** Holds if this position represents a positional argument at position `pos`. */ predicate isPositional(int pos, NamedSet ns) { this = TPositionalArgumentPosition(pos, ns) } @@ -273,6 +283,8 @@ class ArgumentPosition extends TArgumentPosition { /** Gets a textual representation of this position. */ string toString() { + this.isThis() and result = "this" + or exists(int pos, NamedSet ns | this.isPositional(pos, ns) and result = "pos(" + pos + ", " + ns.toString() + ")" ) @@ -284,6 +296,8 @@ class ArgumentPosition extends TArgumentPosition { /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[nomagic] predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { + ppos.isThis() and apos.isThis() + or exists(string name | ppos.isKeyword(name) and apos.isKeyword(name) diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll index a39c42b21391..d2ed0af64ab3 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll @@ -407,6 +407,9 @@ private module ParameterNodes { override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { parameter.getDeclaringScope() = c.asCfgScope() and ( + pos.isThis() and + parameter.isThis() + or pos.isKeyword(parameter.getName()) or // Given a function f with parameters x, y we map @@ -432,7 +435,9 @@ private module ParameterNodes { ) } - override CfgScope getCfgScope() { result.getAParameter() = parameter } + override CfgScope getCfgScope() { + result.getAParameter() = parameter or result.getThisParameter() = parameter + } override Location getLocationImpl() { result = parameter.getLocation() } @@ -458,7 +463,7 @@ module ArgumentNodes { ExplicitArgumentNode() { this.asExpr() = arg } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - arg.getCmd() = call.asCall() and + arg.getCall() = call.asCall() and ( pos.isKeyword(arg.getName()) or @@ -467,6 +472,9 @@ module ArgumentNodes { ns.getAnExactBindingCall() = call.asCall() and pos.isPositional(i, ns) ) + or + arg.isQualifier() and + pos.isThis() ) } } diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/SsaImpl.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/SsaImpl.qll index 42d4b8433bd2..83faefff825e 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/SsaImpl.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/SsaImpl.qll @@ -69,8 +69,14 @@ predicate uninitializedWrite(Cfg::EntryBasicBlock bb, int i, LocalVariable v) { * function f($a, $b) { ... } * ``` * the inverted index of `$a` is 1, and the inverted index of `$b` is 0. + * + * The inverted index of `$this` is always always the number of + * parameters (excluding `this`). */ private int getInvertedIndex(Parameter p) { + p.isThis() and + result = p.getFunction().getNumberOfParameters() + or exists(int i | p.getIndex() = i or p.hasParameterBlock(_, i) diff --git a/powershell/ql/lib/semmle/code/powershell/internal/Argument.qll b/powershell/ql/lib/semmle/code/powershell/internal/Argument.qll new file mode 100644 index 000000000000..304e2bdb692d --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/internal/Argument.qll @@ -0,0 +1,71 @@ +private import powershell + +module Private { + /** + * An argument to a call. + * + * The argument may be named or positional. + */ + abstract class AbstractArgument extends Expr { + Ast call; + + /** Gets the call that this is an argumnt of. */ + final Ast getCall() { result = call } + + /** Gets the position if this is a positional argument. */ + abstract int getPosition(); + + /** Gets the name if this is a keyword argument. */ + abstract string getName(); + + /** Holds if this is a qualifier of a call */ + abstract predicate isQualifier(); + } + + class CmdArgument extends AbstractArgument { + override Cmd call; + + CmdArgument() { call.getAnArgument() = this } + + override int getPosition() { call.getPositionalArgument(result) = this } + + override string getName() { call.getNamedArgument(result) = this } + + final override predicate isQualifier() { none() } + } + + class InvokeArgument extends AbstractArgument { + override InvokeMemberExpr call; + + InvokeArgument() { call.getAnArgument() = this or call.getQualifier() = this } + + override int getPosition() { call.getArgument(result) = this } + + override string getName() { none() } + + final override predicate isQualifier() { call.getQualifier() = this } + } +} + +private import Private + +module Public { + final class Argument = AbstractArgument; + + /** A positional argument to a command. */ + class PositionalArgument extends Argument { + PositionalArgument() { + not this instanceof NamedArgument and not this instanceof QualifierArgument + } + } + + /** A named argument to a command. */ + class NamedArgument extends Argument { + NamedArgument() { exists(this.getName()) } + } + + /** An argument that is a qualifier to a method. */ + class QualifierArgument extends Argument { + QualifierArgument() { this.isQualifier() } + } +} diff --git a/powershell/ql/lib/semmle/code/powershell/internal/ExplicitWrite.qll b/powershell/ql/lib/semmle/code/powershell/internal/ExplicitWrite.qll index 210a6213420c..ac6c16059046 100644 --- a/powershell/ql/lib/semmle/code/powershell/internal/ExplicitWrite.qll +++ b/powershell/ql/lib/semmle/code/powershell/internal/ExplicitWrite.qll @@ -1,15 +1,19 @@ private import powershell -/** - * Holds if `e` is written to by `assign`. - * - * Note there may be more than one `e` for which `isExplicitWrite(e, assign)` - * holds if the left-hand side is an array literal. - */ -predicate isExplicitWrite(Expr e, AssignStmt assign) { - e = assign.getLeftHandSide() - or - e = any(ConvertExpr convert | isExplicitWrite(convert, assign)).getExpr() - or - e = any(ArrayLiteral array | isExplicitWrite(array, assign)).getAnElement() +module Private { + /** + * Holds if `e` is written to by `assign`. + * + * Note there may be more than one `e` for which `isExplicitWrite(e, assign)` + * holds if the left-hand side is an array literal. + */ + predicate isExplicitWrite(Expr e, AssignStmt assign) { + e = assign.getLeftHandSide() + or + e = any(ConvertExpr convert | isExplicitWrite(convert, assign)).getExpr() + or + e = any(ArrayLiteral array | isExplicitWrite(array, assign)).getAnElement() + } } + +module Public { } diff --git a/powershell/ql/lib/semmle/code/powershell/internal/Internal.qll b/powershell/ql/lib/semmle/code/powershell/internal/Internal.qll index 92beec81a9de..06dbe7ffec81 100644 --- a/powershell/ql/lib/semmle/code/powershell/internal/Internal.qll +++ b/powershell/ql/lib/semmle/code/powershell/internal/Internal.qll @@ -1,2 +1,11 @@ -import Parameter -import ExplicitWrite \ No newline at end of file +module Private { + import Parameter::Private + import ExplicitWrite::Private + import Argument::Private +} + +module Public { + import Parameter::Public + import ExplicitWrite::Public + import Argument::Public +} diff --git a/powershell/ql/lib/semmle/code/powershell/internal/Parameter.qll b/powershell/ql/lib/semmle/code/powershell/internal/Parameter.qll index 85e953f00587..15f4136e22e9 100644 --- a/powershell/ql/lib/semmle/code/powershell/internal/Parameter.qll +++ b/powershell/ql/lib/semmle/code/powershell/internal/Parameter.qll @@ -1,24 +1,28 @@ import powershell -class Parameter extends @parameter, Ast { - override string toString() { result = this.getName().toString() } - - string getName() { - exists(@variable_expression ve | - parameter(this, ve, _, _) and - variable_expression(ve, result, _, _, _, _, _, _, _, _, _, _) - ) - } +module Private { + class Parameter extends @parameter, Ast { + override string toString() { result = this.getName().toString() } + + string getName() { + exists(@variable_expression ve | + parameter(this, ve, _, _) and + variable_expression(ve, result, _, _, _, _, _, _, _, _, _, _) + ) + } - string getStaticType() { parameter(this, _, result, _) } + string getStaticType() { parameter(this, _, result, _) } - int getNumAttributes() { parameter(this, _, _, result) } + int getNumAttributes() { parameter(this, _, _, result) } - AttributeBase getAttribute(int i) { parameter_attribute(this, i, result) } + AttributeBase getAttribute(int i) { parameter_attribute(this, i, result) } - AttributeBase getAnAttribute() { result = this.getAttribute(_) } + AttributeBase getAnAttribute() { result = this.getAttribute(_) } - Expr getDefaultValue() { parameter_default_value(this, result) } + Expr getDefaultValue() { parameter_default_value(this, result) } - override SourceLocation getLocation() { parameter_location(this, result) } + override SourceLocation getLocation() { parameter_location(this, result) } + } } + +module Public { } diff --git a/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected b/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected index ed8fdc6ade61..61dfcc6469d6 100644 --- a/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -1,32 +1,342 @@ conditionals.ps1: +# 1| enter conditionals.ps1 +#-----| -> conditionals.ps1 + +# 1| conditionals.ps1 +#-----| -> {...} + +# 1| enter {...} +#-----| -> {...} + +# 1| {...} +#-----| -> param(...) + +# 11| enter {...} +#-----| -> {...} + +# 11| {...} +#-----| -> param(...) + +# 24| enter {...} +#-----| -> {...} + +# 24| {...} +#-----| -> param(...) + +# 34| enter {...} +#-----| -> {...} + +# 34| {...} +#-----| -> param(...) + +# 47| enter {...} +#-----| -> {...} + +# 47| {...} +#-----| -> param(...) + +# 57| enter {...} +#-----| -> {...} + +# 57| {...} +#-----| -> param(...) + +# 70| enter {...} +#-----| -> {...} + +# 70| {...} +#-----| -> param(...) + +# 84| enter {...} +#-----| -> {...} + +# 84| {...} +#-----| -> param(...) + +# 101| enter {...} +#-----| -> {...} + +# 101| {...} +#-----| -> {...} + +# 110| enter {...} +#-----| -> {...} + +# 110| {...} +#-----| -> {...} + +# 123| enter {...} +#-----| -> {...} + +# 123| {...} +#-----| -> {...} + +functions.ps1: +# 1| enter functions.ps1 +#-----| -> functions.ps1 + +# 1| functions.ps1 +#-----| -> {...} + +# 1| enter {...} +#-----| -> {...} + +# 1| {...} +#-----| -> param(...) + +# 11| enter {...} +#-----| -> {...} + +# 11| {...} +#-----| -> param(...) + +# 13| enter {...} +#-----| -> {...} + +# 13| {...} +#-----| -> 0 + +# 22| enter {...} +#-----| -> {...} + +# 22| {...} +#-----| -> param(...) + +# 36| enter {...} +#-----| -> {...} + +# 36| {...} +#-----| -> param(...) + +global.ps1: +# 1| enter global.ps1 +#-----| -> global.ps1 + +# 1| global.ps1 +#-----| -> {...} + +loops.ps1: +# 1| enter loops.ps1 +#-----| -> loops.ps1 + +# 1| loops.ps1 +#-----| -> {...} + +# 1| enter {...} +#-----| -> {...} + +# 1| {...} +#-----| -> {...} + +# 9| enter {...} +#-----| -> {...} + +# 9| {...} +#-----| -> {...} + +# 17| enter {...} +#-----| -> {...} + +# 17| {...} +#-----| -> {...} + +# 25| enter {...} +#-----| -> {...} + +# 25| {...} +#-----| -> {...} + +# 33| enter {...} +#-----| -> {...} + +# 33| {...} +#-----| -> {...} + +# 41| enter {...} +#-----| -> {...} + +# 41| {...} +#-----| -> {...} + +# 49| enter {...} +#-----| -> {...} + +# 49| {...} +#-----| -> {...} + +# 58| enter {...} +#-----| -> {...} + +# 58| {...} +#-----| -> {...} + +try.ps1: +# 1| enter try.ps1 +#-----| -> try.ps1 + +# 1| try.ps1 +#-----| -> {...} + +# 1| enter {...} +#-----| -> {...} + +# 1| {...} +#-----| -> {...} + +# 10| enter {...} +#-----| -> {...} + +# 10| {...} +#-----| -> {...} + +# 21| enter {...} +#-----| -> {...} + +# 21| {...} +#-----| -> {...} + +# 32| enter {...} +#-----| -> {...} + +# 32| {...} +#-----| -> {...} + +# 43| enter {...} +#-----| -> {...} + +# 43| {...} +#-----| -> {...} + +# 52| enter {...} +#-----| -> {...} + +# 52| {...} +#-----| -> {...} + +# 61| enter {...} +#-----| -> {...} + +# 61| {...} +#-----| -> {...} + +# 72| enter {...} +#-----| -> {...} + +# 72| {...} +#-----| -> {...} + +# 81| enter {...} +#-----| -> {...} + +# 81| {...} +#-----| -> {...} + +# 92| enter {...} +#-----| -> {...} + +# 92| {...} +#-----| -> {...} + +# 105| enter {...} +#-----| -> {...} + +# 105| {...} +#-----| -> {...} + +# 116| enter {...} +#-----| -> {...} + +# 116| {...} +#-----| -> {...} + +# 125| enter {...} +#-----| -> {...} + +# 125| {...} +#-----| -> {...} + +# 136| enter {...} +#-----| -> {...} + +# 136| {...} +#-----| -> {...} + +# 149| enter {...} +#-----| -> {...} + +# 149| {...} +#-----| -> {...} + +# 164| enter {...} +#-----| -> {...} + +# 164| {...} +#-----| -> {...} + +# 179| enter {...} +#-----| -> {...} + +# 179| {...} +#-----| -> {...} + +conditionals.ps1: +# 1| {...} +#-----| -> test-if + # 1| test-if #-----| -> test-if-else -# 1| conditionals.ps1 -#-----| -> {...} +# 11| test-if-else +#-----| -> test-if-conj -# 1| enter conditionals.ps1 -#-----| -> conditionals.ps1 +# 24| test-if-conj +#-----| -> test-if-else-conj -# 1| exit conditionals.ps1 +# 34| test-if-else-conj +#-----| -> test-if-disj + +# 47| test-if-disj +#-----| -> test-if-else-disj + +# 57| test-if-else-disj +#-----| -> test-else-if + +# 70| test-else-if +#-----| -> test-else-if-else + +# 84| test-else-if-else +#-----| -> test-switch + +# 101| test-switch +#-----| -> test-switch-default + +# 110| test-switch-default +#-----| -> test-switch-assign + +# 123| test-switch-assign +#-----| -> exit conditionals.ps1 (normal) # 1| exit conditionals.ps1 (normal) #-----| -> exit conditionals.ps1 -# 1| {...} -#-----| -> test-if - -# 1| enter {...} +# 4| myBool #-----| -> {...} -# 1| exit {...} +# 5| {...} +#-----| -> return ... + +# 6| 10 +#-----| -> return ... + +# 8| return ... +#-----| -> 11 + +# 8| 11 +#-----| -> exit {...} (normal) # 1| exit {...} (normal) #-----| -> exit {...} -# 1| {...} -#-----| -> param(...) - # 2| param(...) #-----| -> {...} @@ -36,46 +346,36 @@ conditionals.ps1: # 4| if (...) {...} #-----| -> myBool -# 4| myBool -#-----| true -> {...} - # 4| myBool #-----| -> myBool -# 5| {...} -#-----| -> return ... - # 6| return ... #-----| -> 10 -# 6| 10 -#-----| -> return ... - # 6| 10 #-----| -> 10 -# 8| return ... -#-----| -> 11 - -# 8| 11 -#-----| -> exit {...} (normal) - # 8| 11 #-----| -> 11 -# 11| test-if-else -#-----| -> test-if-conj - -# 11| enter {...} +# 14| myBool +#-----| -> {...} #-----| -> {...} -# 11| exit {...} +# 15| {...} +#-----| -> return ... + +# 19| {...} +#-----| -> return ... + +# 16| 10 +#-----| -> exit {...} (normal) # 11| exit {...} (normal) #-----| -> exit {...} -# 11| {...} -#-----| -> param(...) +# 20| 11 +#-----| -> exit {...} (normal) # 12| param(...) #-----| -> {...} @@ -86,51 +386,39 @@ conditionals.ps1: # 14| if (...) {...} else {...} #-----| -> myBool -# 14| myBool -#-----| true -> {...} -#-----| false -> {...} - # 14| myBool #-----| -> myBool -# 15| {...} -#-----| -> return ... - # 16| return ... #-----| -> 10 -# 16| 10 -#-----| -> exit {...} (normal) - # 16| 10 #-----| -> 10 -# 19| {...} -#-----| -> return ... - # 20| return ... #-----| -> 11 -# 20| 11 -#-----| -> exit {...} (normal) - # 20| 11 #-----| -> 11 -# 24| test-if-conj -#-----| -> test-if-else-conj - -# 24| enter {...} +# 27| ... -and ... #-----| -> {...} -# 24| exit {...} +# 28| {...} +#-----| -> return ... + +# 29| 10 +#-----| -> return ... + +# 31| return ... +#-----| -> 11 + +# 31| 11 +#-----| -> exit {...} (normal) # 24| exit {...} (normal) #-----| -> exit {...} -# 24| {...} -#-----| -> param(...) - # 25| param(...) #-----| -> {...} @@ -140,52 +428,42 @@ conditionals.ps1: # 27| if (...) {...} #-----| -> ... -and ... -# 27| myBool1 -#-----| false, true -> myBool2 - -# 27| ... -and ... -#-----| true -> {...} - # 27| ... -and ... #-----| -> myBool1 -# 27| myBool2 -#-----| false, true -> ... -and ... +# 27| myBool1 +#-----| -> myBool2 -# 28| {...} -#-----| -> return ... +# 27| myBool2 +#-----| -> ... -and ... # 29| return ... #-----| -> 10 -# 29| 10 -#-----| -> return ... - # 29| 10 #-----| -> 10 -# 31| return ... -#-----| -> 11 - -# 31| 11 -#-----| -> exit {...} (normal) - # 31| 11 #-----| -> 11 -# 34| test-if-else-conj -#-----| -> test-if-disj - -# 34| enter {...} +# 37| ... -and ... +#-----| -> {...} #-----| -> {...} -# 34| exit {...} +# 38| {...} +#-----| -> return ... + +# 42| {...} +#-----| -> return ... + +# 39| 10 +#-----| -> exit {...} (normal) # 34| exit {...} (normal) #-----| -> exit {...} -# 34| {...} -#-----| -> param(...) +# 43| 11 +#-----| -> exit {...} (normal) # 35| param(...) #-----| -> {...} @@ -196,57 +474,45 @@ conditionals.ps1: # 37| if (...) {...} else {...} #-----| -> ... -and ... -# 37| myBool1 -#-----| false, true -> myBool2 - -# 37| ... -and ... -#-----| true -> {...} -#-----| false -> {...} - # 37| ... -and ... #-----| -> myBool1 -# 37| myBool2 -#-----| false, true -> ... -and ... +# 37| myBool1 +#-----| -> myBool2 -# 38| {...} -#-----| -> return ... +# 37| myBool2 +#-----| -> ... -and ... # 39| return ... #-----| -> 10 -# 39| 10 -#-----| -> exit {...} (normal) - # 39| 10 #-----| -> 10 -# 42| {...} -#-----| -> return ... - # 43| return ... #-----| -> 11 -# 43| 11 -#-----| -> exit {...} (normal) - # 43| 11 #-----| -> 11 -# 47| test-if-disj -#-----| -> test-if-else-disj - -# 47| enter {...} +# 50| ... -or ... #-----| -> {...} -# 47| exit {...} +# 51| {...} +#-----| -> return ... + +# 52| 10 +#-----| -> return ... + +# 54| return ... +#-----| -> 11 + +# 54| 11 +#-----| -> exit {...} (normal) # 47| exit {...} (normal) #-----| -> exit {...} -# 47| {...} -#-----| -> param(...) - # 48| param(...) #-----| -> {...} @@ -256,52 +522,42 @@ conditionals.ps1: # 50| if (...) {...} #-----| -> ... -or ... -# 50| myBool1 -#-----| false, true -> myBool2 - -# 50| ... -or ... -#-----| true -> {...} - # 50| ... -or ... #-----| -> myBool1 -# 50| myBool2 -#-----| false, true -> ... -or ... +# 50| myBool1 +#-----| -> myBool2 -# 51| {...} -#-----| -> return ... +# 50| myBool2 +#-----| -> ... -or ... # 52| return ... #-----| -> 10 -# 52| 10 -#-----| -> return ... - # 52| 10 #-----| -> 10 -# 54| return ... -#-----| -> 11 - -# 54| 11 -#-----| -> exit {...} (normal) - # 54| 11 #-----| -> 11 -# 57| test-if-else-disj -#-----| -> test-else-if - -# 57| enter {...} +# 60| ... -or ... +#-----| -> {...} #-----| -> {...} -# 57| exit {...} +# 61| {...} +#-----| -> return ... + +# 65| {...} +#-----| -> return ... + +# 62| 10 +#-----| -> exit {...} (normal) # 57| exit {...} (normal) #-----| -> exit {...} -# 57| {...} -#-----| -> param(...) +# 66| 11 +#-----| -> exit {...} (normal) # 58| param(...) #-----| -> {...} @@ -312,57 +568,45 @@ conditionals.ps1: # 60| if (...) {...} else {...} #-----| -> ... -or ... -# 60| myBool1 -#-----| false, true -> myBool2 - -# 60| ... -or ... -#-----| true -> {...} -#-----| false -> {...} - # 60| ... -or ... #-----| -> myBool1 -# 60| myBool2 -#-----| false, true -> ... -or ... +# 60| myBool1 +#-----| -> myBool2 -# 61| {...} -#-----| -> return ... +# 60| myBool2 +#-----| -> ... -or ... # 62| return ... #-----| -> 10 -# 62| 10 -#-----| -> exit {...} (normal) - -# 62| 10 -#-----| -> 10 - -# 65| {...} -#-----| -> return ... +# 62| 10 +#-----| -> 10 # 66| return ... #-----| -> 11 -# 66| 11 -#-----| -> exit {...} (normal) - # 66| 11 #-----| -> 11 -# 70| test-else-if -#-----| -> test-else-if-else - -# 70| enter {...} +# 73| myBool1 #-----| -> {...} -# 70| exit {...} +# 74| {...} +#-----| -> return ... + +# 75| 10 +#-----| -> return ... + +# 81| return ... +#-----| -> 12 + +# 81| 12 +#-----| -> exit {...} (normal) # 70| exit {...} (normal) #-----| -> exit {...} -# 70| {...} -#-----| -> param(...) - # 71| param(...) #-----| -> {...} @@ -372,46 +616,36 @@ conditionals.ps1: # 73| if (...) {...} #-----| -> myBool1 -# 73| myBool1 -#-----| true -> {...} - # 73| myBool1 #-----| -> myBool1 -# 74| {...} -#-----| -> return ... - # 75| return ... #-----| -> 10 -# 75| 10 -#-----| -> return ... - # 75| 10 #-----| -> 10 -# 81| return ... -#-----| -> 12 - -# 81| 12 -#-----| -> exit {...} (normal) - # 81| 12 #-----| -> 12 -# 84| test-else-if-else -#-----| -> test-switch - -# 84| enter {...} +# 87| myBool1 +#-----| -> {...} #-----| -> {...} -# 84| exit {...} +# 88| {...} +#-----| -> return ... + +# 96| {...} +#-----| -> return ... + +# 89| 10 +#-----| -> exit {...} (normal) # 84| exit {...} (normal) #-----| -> exit {...} -# 84| {...} -#-----| -> param(...) +# 97| 12 +#-----| -> exit {...} (normal) # 85| param(...) #-----| -> {...} @@ -422,189 +656,154 @@ conditionals.ps1: # 87| if (...) {...} else {...} #-----| -> myBool1 -# 87| myBool1 -#-----| true -> {...} -#-----| false -> {...} - # 87| myBool1 #-----| -> myBool1 -# 88| {...} -#-----| -> return ... - # 89| return ... #-----| -> 10 -# 89| 10 -#-----| -> exit {...} (normal) - # 89| 10 #-----| -> 10 -# 96| {...} -#-----| -> return ... - # 97| return ... #-----| -> 12 -# 97| 12 -#-----| -> exit {...} (normal) - # 97| 12 #-----| -> 12 -# 101| test-switch -#-----| -> test-switch-default +# 102| switch(...) {...} +#-----| -> n -# 101| enter {...} +# 102| n +#-----| -> n + +# 102| n +#-----| -> 0: + +# 104| 0: #-----| -> {...} +#-----| -> 1: -# 101| exit {...} +# 104| 0 +#-----| -> exit {...} (normal) # 101| exit {...} (normal) #-----| -> exit {...} -# 101| {...} -#-----| -> {...} +# 105| 1 +#-----| -> exit {...} (normal) -# 102| switch(...) {...} -#-----| -> n +# 106| 2 +#-----| -> exit {...} (normal) # 102| {...} #-----| -> switch(...) {...} -# 102| n -#-----| -> 0: - -# 102| n -#-----| -> n - -# 104| 0: -#-----| true -> {...} -#-----| false -> 1: - # 104| {...} #-----| -> return ... +# 105| 1: +#-----| -> {...} +#-----| -> 2: + # 104| return ... #-----| -> 0 -# 104| 0 -#-----| -> exit {...} (normal) - # 104| 0 #-----| -> 0 -# 105| 1: -#-----| true -> {...} -#-----| false -> 2: - # 105| {...} #-----| -> return ... +# 106| 2: +#-----| -> {...} +#-----| -> exit {...} (normal) + # 105| return ... #-----| -> 1 -# 105| 1 -#-----| -> exit {...} (normal) - # 105| 1 #-----| -> 1 -# 106| 2: -#-----| false -> exit {...} (normal) -#-----| true -> {...} - # 106| {...} #-----| -> return ... # 106| return ... #-----| -> 2 -# 106| 2 -#-----| -> exit {...} (normal) - # 106| 2 #-----| -> 2 -# 110| test-switch-default -#-----| -> test-switch-assign +# 111| switch(...) {...} +#-----| -> n -# 110| enter {...} +# 111| n +#-----| -> n + +# 111| n +#-----| -> 0: + +# 113| 0: #-----| -> {...} +#-----| -> 1: -# 110| exit {...} +# 113| 0 +#-----| -> exit {...} (normal) # 110| exit {...} (normal) #-----| -> exit {...} -# 110| {...} -#-----| -> {...} +# 114| 1 +#-----| -> exit {...} (normal) -# 111| switch(...) {...} -#-----| -> n +# 115| 2 +#-----| -> exit {...} (normal) + +# 118| 3 +#-----| -> exit {...} (normal) # 111| {...} #-----| -> switch(...) {...} -# 111| n -#-----| -> 0: - -# 111| n -#-----| -> n - -# 113| 0: -#-----| true -> {...} -#-----| false -> 1: - # 113| {...} #-----| -> return ... +# 114| 1: +#-----| -> {...} +#-----| -> 2: + # 113| return ... #-----| -> 0 -# 113| 0 -#-----| -> exit {...} (normal) - # 113| 0 #-----| -> 0 -# 114| 1: -#-----| true -> {...} -#-----| false -> 2: - # 114| {...} #-----| -> return ... +# 115| 2: +#-----| -> {...} +#-----| -> default: + # 114| return ... #-----| -> 1 -# 114| 1 -#-----| -> exit {...} (normal) - # 114| 1 #-----| -> 1 -# 115| 2: -#-----| true -> {...} -#-----| false -> default: - # 115| {...} #-----| -> return ... +# 116| default: +#-----| -> {...} +#-----| -> exit {...} (normal) + # 115| return ... #-----| -> 2 -# 115| 2 -#-----| -> exit {...} (normal) - # 115| 2 #-----| -> 2 -# 116| default: -#-----| false -> exit {...} (normal) -#-----| true -> {...} - # 116| {...} #-----| -> Write-Output @@ -614,37 +813,39 @@ conditionals.ps1: # 117| Write-Output #-----| -> return ... -# 117| Error! -#-----| -> Write-Output - # 118| return ... #-----| -> 3 -# 118| 3 -#-----| -> exit {...} (normal) +# 117| Error! +#-----| -> Write-Output # 118| 3 #-----| -> 3 -# 123| test-switch-assign -#-----| -> exit conditionals.ps1 (normal) +# 124| ...=... +#-----| -> a -# 123| enter {...} +# 124| a +#-----| -> switch(...) {...} + +# 124| n +#-----| -> 0: + +# 125| 0: #-----| -> {...} +#-----| -> 1: -# 123| exit {...} +# 125| 0 +#-----| -> exit {...} (normal) # 123| exit {...} (normal) #-----| -> exit {...} -# 123| {...} -#-----| -> {...} - -# 124| a -#-----| -> switch(...) {...} +# 126| 1 +#-----| -> exit {...} (normal) -# 124| ...=... -#-----| -> a +# 127| 2 +#-----| -> exit {...} (normal) # 124| {...} #-----| -> ...=... @@ -652,131 +853,95 @@ conditionals.ps1: # 124| switch(...) {...} #-----| -> n -# 124| n -#-----| -> 0: - # 124| n #-----| -> n -# 125| 0: -#-----| true -> {...} -#-----| false -> 1: - # 125| {...} #-----| -> 0 -# 125| 0 -#-----| -> exit {...} (normal) +# 126| 1: +#-----| -> {...} +#-----| -> 2: # 125| 0 #-----| -> 0 -# 126| 1: -#-----| true -> {...} -#-----| false -> 2: - # 126| {...} #-----| -> 1 -# 126| 1 +# 127| 2: +#-----| -> {...} #-----| -> exit {...} (normal) # 126| 1 #-----| -> 1 -# 127| 2: -#-----| false -> exit {...} (normal) -#-----| true -> {...} - # 127| {...} #-----| -> 2 -# 127| 2 -#-----| -> exit {...} (normal) - # 127| 2 #-----| -> 2 functions.ps1: -# 1| Add-Numbers-Arguments -#-----| -> foo - # 1| {...} #-----| -> Add-Numbers-Arguments -# 1| enter functions.ps1 -#-----| -> functions.ps1 +# 1| Add-Numbers-Arguments +#-----| -> foo -# 1| exit functions.ps1 +# 11| foo +#-----| -> Default-Arguments -# 1| exit functions.ps1 (normal) -#-----| -> exit functions.ps1 +# 13| Default-Arguments +#-----| -> Add-Numbers-From-Array -# 1| functions.ps1 -#-----| -> {...} +# 22| Add-Numbers-From-Array +#-----| -> Add-Numbers-From-Pipeline -# 1| enter {...} -#-----| -> {...} +# 36| Add-Numbers-From-Pipeline +#-----| -> exit functions.ps1 (normal) -# 1| exit {...} +# 1| exit functions.ps1 (normal) +#-----| -> exit functions.ps1 + +# 8| ...+... +#-----| -> exit {...} (normal) # 1| exit {...} (normal) #-----| -> exit {...} -# 1| {...} -#-----| -> param(...) - # 3| param(...) #-----| -> {...} # 3| {...} #-----| -> ...+... -# 8| number1 -#-----| -> number2 - -# 8| ...+... -#-----| -> exit {...} (normal) - # 8| ...+... #-----| -> number1 +# 8| number1 +#-----| -> number2 + # 8| number2 #-----| -> ...+... -# 11| foo -#-----| -> Default-Arguments - -# 11| enter {...} -#-----| -> {...} - -# 11| exit {...} +# 11| {...} +#-----| -> exit {...} (normal) # 11| exit {...} (normal) #-----| -> exit {...} -# 11| {...} -#-----| -> param(...) - # 11| param(...) #-----| -> {...} -# 11| {...} +# 19| ...+... #-----| -> exit {...} (normal) -# 13| Default-Arguments -#-----| -> Add-Numbers-From-Array - -# 13| enter {...} -#-----| -> {...} - -# 13| exit {...} - # 13| exit {...} (normal) #-----| -> exit {...} -# 13| {...} -#-----| -> 0 +# 16| 0 +#-----| -> name1 # 14| param(...) #-----| -> {...} @@ -784,109 +949,97 @@ functions.ps1: # 14| {...} #-----| -> ...+... -# 16| 0 -#-----| -> name1 - # 17| name1 #-----| -> 1 -# 17| ...+... -#-----| -> param(...) - # 17| 1 #-----| -> ...+... -# 19| name -#-----| -> name2 - -# 19| ...+... -#-----| -> exit {...} (normal) +# 17| ...+... +#-----| -> param(...) # 19| ...+... #-----| -> name +# 19| name +#-----| -> name2 + # 19| name2 #-----| -> ...+... -# 22| Add-Numbers-From-Array -#-----| -> Add-Numbers-From-Pipeline +# 28| 0 +#-----| -> numbers -# 22| enter {...} -#-----| -> {...} +# 29| numbers +#-----| -> numbers -# 22| exit {...} +# 29| numbers +#-----| -> forach(... in ...) + +# 29| forach(... in ...) +#-----| -> number +#-----| -> sum + +# 31| number +#-----| -> forach(... in ...) + +# 33| sum +#-----| -> exit {...} (normal) # 22| exit {...} (normal) #-----| -> exit {...} -# 22| {...} -#-----| -> param(...) - # 24| param(...) #-----| -> {...} # 24| {...} #-----| -> ...=... -# 28| sum -#-----| -> 0 - # 28| ...=... #-----| -> sum -# 28| 0 -#-----| -> numbers +# 28| sum +#-----| -> 0 # 28| 0 #-----| -> 0 -# 29| forach(... in ...) -#-----| -> number -#-----| -> sum - # 29| number #-----| -> {...} -# 29| numbers -#-----| -> forach(... in ...) - -# 29| numbers -#-----| -> numbers - # 29| {...} #-----| -> ...=... -# 31| sum -#-----| -> number +# 33| sum +#-----| -> sum # 31| ...=... #-----| -> sum -# 31| number -#-----| -> forach(... in ...) +# 31| sum +#-----| -> number # 31| number #-----| -> number -# 33| sum -#-----| -> exit {...} (normal) - -# 33| sum -#-----| -> sum - -# 36| Add-Numbers-From-Pipeline -#-----| -> exit functions.ps1 (normal) - -# 36| enter {...} +# 42| 0 #-----| -> {...} -# 36| exit {...} +# 44| {...} +#-----| -> ...=... + +# 50| sum +#-----| -> exit {...} (normal) # 36| exit {...} (normal) #-----| -> exit {...} -# 36| {...} -#-----| -> param(...) +# 46| _ +#-----| -> {...} +#-----| -> {...} + +# 48| {...} +#-----| -> sum # 38| param(...) #-----| -> {...} @@ -894,66 +1047,54 @@ functions.ps1: # 41| {...} #-----| -> ...=... -# 42| sum -#-----| -> 0 - # 42| ...=... #-----| -> sum -# 42| 0 -#-----| -> {...} +# 42| sum +#-----| -> 0 # 42| 0 #-----| -> 0 -# 44| {...} -#-----| -> ...=... - -# 46| sum -#-----| -> _ +# 50| sum +#-----| -> sum # 46| ...=... #-----| -> sum -# 46| _ -#-----| -> {...} -#-----| -> {...} +# 46| sum +#-----| -> _ # 46| _ #-----| -> _ -# 48| {...} -#-----| -> sum +global.ps1: +# 2| 1 +#-----| -> ...=... -# 50| sum -#-----| -> exit {...} (normal) +# 3| ...=... +#-----| -> b -# 50| sum -#-----| -> sum +# 3| 2 +#-----| -> {...} -global.ps1: -# 1| {...} +# 5| {...} #-----| -> ...=... -# 1| enter global.ps1 -#-----| -> global.ps1 - -# 1| exit global.ps1 +# 6| ...+... +#-----| -> exit global.ps1 (normal) # 1| exit global.ps1 (normal) #-----| -> exit global.ps1 -# 1| global.ps1 -#-----| -> {...} - -# 2| a -#-----| -> 1 +# 1| {...} +#-----| -> ...=... # 2| ...=... #-----| -> a -# 2| 1 -#-----| -> ...=... +# 2| a +#-----| -> 1 # 2| 1 #-----| -> 1 @@ -961,391 +1102,364 @@ global.ps1: # 3| b #-----| -> 2 -# 3| ...=... -#-----| -> b - -# 3| 2 -#-----| -> {...} - # 3| 2 #-----| -> 2 -# 5| {...} -#-----| -> ...=... +# 6| ...=... +#-----| -> c # 6| c #-----| -> ...+... -# 6| ...=... -#-----| -> c +# 6| ...+... +#-----| -> a # 6| a #-----| -> b -# 6| ...+... -#-----| -> exit global.ps1 (normal) - -# 6| ...+... -#-----| -> a - # 6| b #-----| -> ...+... loops.ps1: -# 1| Test-While -#-----| -> Test-Break - # 1| {...} #-----| -> Test-While -# 1| enter loops.ps1 -#-----| -> loops.ps1 - -# 1| exit loops.ps1 - -# 1| exit loops.ps1 (normal) -#-----| -> exit loops.ps1 +# 1| Test-While +#-----| -> Test-Break -# 1| loops.ps1 -#-----| -> {...} +# 9| Test-Break +#-----| -> Test-Continue -# 1| enter {...} -#-----| -> {...} +# 17| Test-Continue +#-----| -> Test-DoWhile -# 1| exit {...} +# 25| Test-DoWhile +#-----| -> Test-DoUntil -# 1| exit {...} (normal) -#-----| -> exit {...} +# 33| Test-DoUntil +#-----| -> Test-For -# 1| {...} -#-----| -> {...} +# 41| Test-For +#-----| -> Test-ForEach -# 2| a -#-----| -> 0 +# 49| Test-ForEach +#-----| -> Test-For-Ever -# 2| ...=... -#-----| -> a +# 58| Test-For-Ever +#-----| -> exit loops.ps1 (normal) -# 2| {...} -#-----| -> ...=... +# 1| exit loops.ps1 (normal) +#-----| -> exit loops.ps1 # 2| 0 #-----| -> while(...) {...} -# 2| 0 -#-----| -> 0 - # 4| while(...) {...} -#-----| -> ... -le ... - -# 4| a -#-----| -> 10 +#-----| -> ... -le ... -# 4| ... -le ... -#-----| false -> exit {...} (normal) -#-----| true -> {...} +# 5| ...+... +#-----| -> ... -le ... # 4| ... -le ... #-----| -> a -# 4| 10 -#-----| -> ... -le ... +# 4| ... -le ... +#-----| -> {...} +#-----| -> exit {...} (normal) # 4| {...} #-----| -> ...=... -# 5| a -#-----| -> ...+... +# 1| exit {...} (normal) +#-----| -> exit {...} + +# 2| {...} +#-----| -> ...=... + +# 2| ...=... +#-----| -> a + +# 2| a +#-----| -> 0 + +# 2| 0 +#-----| -> 0 # 5| ...=... #-----| -> a # 5| a -#-----| -> 1 - -# 5| ...+... -#-----| -> ... -le ... +#-----| -> ...+... # 5| ...+... #-----| -> a +# 5| a +#-----| -> 1 + # 5| 1 #-----| -> ...+... -# 9| Test-Break -#-----| -> Test-Continue +# 4| a +#-----| -> 10 -# 9| enter {...} -#-----| -> {...} +# 4| 10 +#-----| -> ... -le ... -# 9| exit {...} +# 10| 0 +#-----| -> while(...) {...} -# 9| exit {...} (normal) -#-----| -> exit {...} +# 11| while(...) {...} +#-----| -> ... -le ... -# 9| {...} +# 11| ... -le ... #-----| -> {...} +#-----| -> exit {...} (normal) -# 10| a -#-----| -> 0 +# 11| {...} +#-----| -> break -# 10| ...=... -#-----| -> a +# 9| exit {...} (normal) +#-----| -> exit {...} # 10| {...} #-----| -> ...=... -# 10| 0 -#-----| -> while(...) {...} +# 10| ...=... +#-----| -> a -# 10| 0 +# 10| a #-----| -> 0 -# 11| while(...) {...} -#-----| -> ... -le ... - -# 11| a -#-----| -> 10 +# 10| 0 +#-----| -> 0 -# 11| ... -le ... -#-----| false -> exit {...} (normal) -#-----| true -> {...} +# 12| break +#-----| -> exit {...} (normal) # 11| ... -le ... #-----| -> a +# 11| a +#-----| -> 10 + # 11| 10 #-----| -> ... -le ... -# 11| {...} -#-----| -> break - -# 12| break -#-----| break -> exit {...} (normal) +# 18| 0 +#-----| -> while(...) {...} -# 17| Test-Continue -#-----| -> Test-DoWhile +# 19| while(...) {...} +#-----| -> ... -le ... -# 17| enter {...} +# 19| ... -le ... #-----| -> {...} +#-----| -> exit {...} (normal) -# 17| exit {...} +# 19| {...} +#-----| -> continue # 17| exit {...} (normal) #-----| -> exit {...} -# 17| {...} -#-----| -> {...} - -# 18| a -#-----| -> 0 +# 18| {...} +#-----| -> ...=... # 18| ...=... #-----| -> a -# 18| {...} -#-----| -> ...=... - -# 18| 0 -#-----| -> while(...) {...} +# 18| a +#-----| -> 0 # 18| 0 #-----| -> 0 -# 19| while(...) {...} +# 20| continue #-----| -> ... -le ... -# 19| a -#-----| -> 10 - -# 19| ... -le ... -#-----| false -> exit {...} (normal) -#-----| true -> {...} - # 19| ... -le ... #-----| -> a +# 19| a +#-----| -> 10 + # 19| 10 #-----| -> ... -le ... -# 19| {...} -#-----| -> continue +# 26| 0 +#-----| -> DoWhile -# 20| continue -#-----| continue -> ... -le ... +# 28| DoWhile +#-----| -> {...} -# 25| Test-DoWhile -#-----| -> Test-DoUntil +# 29| ...+... +#-----| -> ... -le ... -# 25| enter {...} +# 30| ... -le ... +#-----| -> a + +# 30| ... -le ... #-----| -> {...} +#-----| -> exit {...} (normal) -# 25| exit {...} +# 28| {...} +#-----| -> ...=... # 25| exit {...} (normal) #-----| -> exit {...} -# 25| {...} -#-----| -> {...} - -# 26| a -#-----| -> 0 +# 26| {...} +#-----| -> ...=... # 26| ...=... #-----| -> a -# 26| {...} -#-----| -> ...=... - -# 26| 0 -#-----| -> DoWhile +# 26| a +#-----| -> 0 # 26| 0 #-----| -> 0 -# 28| DoWhile -#-----| -> {...} - -# 28| {...} -#-----| -> ...=... +# 29| ...=... +#-----| -> a # 29| a #-----| -> ...+... -# 29| ...=... +# 29| ...+... #-----| -> a # 29| a #-----| -> 1 -# 29| ...+... -#-----| -> ... -le ... - -# 29| ...+... -#-----| -> a - # 29| 1 #-----| -> ...+... # 30| a #-----| -> 10 -# 30| ... -le ... -#-----| false -> exit {...} (normal) -#-----| true -> {...} - -# 30| ... -le ... -#-----| -> a - # 30| 10 #-----| -> ... -le ... -# 33| Test-DoUntil -#-----| -> Test-For +# 34| 0 +#-----| -> DoUntil -# 33| enter {...} +# 36| DoUntil #-----| -> {...} -# 33| exit {...} +# 37| ...+... +#-----| -> ... -ge ... -# 33| exit {...} (normal) -#-----| -> exit {...} +# 38| ... -ge ... +#-----| -> a -# 33| {...} +# 38| ... -ge ... #-----| -> {...} +#-----| -> exit {...} (normal) -# 34| a -#-----| -> 0 +# 36| {...} +#-----| -> ...=... -# 34| ...=... -#-----| -> a +# 33| exit {...} (normal) +#-----| -> exit {...} # 34| {...} #-----| -> ...=... -# 34| 0 -#-----| -> DoUntil +# 34| ...=... +#-----| -> a -# 34| 0 +# 34| a #-----| -> 0 -# 36| DoUntil -#-----| -> {...} +# 34| 0 +#-----| -> 0 -# 36| {...} -#-----| -> ...=... +# 37| ...=... +#-----| -> a # 37| a #-----| -> ...+... -# 37| ...=... +# 37| ...+... #-----| -> a # 37| a #-----| -> 1 -# 37| ...+... -#-----| -> ... -ge ... - -# 37| ...+... -#-----| -> a - # 37| 1 #-----| -> ...+... # 38| a #-----| -> 10 -# 38| ... -ge ... -#-----| true -> exit {...} (normal) -#-----| false -> {...} - -# 38| ... -ge ... -#-----| -> a - # 38| 10 #-----| -> ... -ge ... -# 41| Test-For -#-----| -> Test-ForEach +# 42| 0 +#-----| -> for(...;...;...) -# 41| enter {...} -#-----| -> {...} +# 44| for(...;...;...) +#-----| -> ...=... -# 41| exit {...} +# 45| ...+... +#-----| -> ... -le ... +#-----| -> ...=... -# 41| exit {...} (normal) -#-----| -> exit {...} +# 44| ... -le ... +#-----| -> i -# 41| {...} +# 44| ...=... +#-----| -> i + +# 44| 0 +#-----| -> ... -le ... + +# 44| ... -le ... #-----| -> {...} +#-----| -> exit {...} (normal) -# 42| a -#-----| -> 0 +# 44| {...} +#-----| -> ...=... -# 42| ...=... -#-----| -> a +# 41| exit {...} (normal) +#-----| -> exit {...} + +# 44| ...+... +#-----| -> ... -le ... # 42| {...} #-----| -> ...=... -# 42| 0 -#-----| -> for(...;...;...) +# 42| ...=... +#-----| -> a + +# 42| a +#-----| -> 0 # 42| 0 #-----| -> 0 -# 44| for(...;...;...) -#-----| -> ...=... +# 45| ...=... +#-----| -> a -# 44| i -#-----| -> 0 +# 45| a +#-----| -> ...+... + +# 45| ...+... +#-----| -> a + +# 45| a +#-----| -> 1 + +# 45| 1 +#-----| -> ...+... # 44| ...=... #-----| -> i -# 44| 0 -#-----| -> ... -le ... +# 44| i +#-----| -> 0 # 44| 0 #-----| -> 0 @@ -1353,88 +1467,58 @@ loops.ps1: # 44| i #-----| -> 10 -# 44| ... -le ... -#-----| false -> exit {...} (normal) -#-----| true -> {...} - -# 44| ... -le ... -#-----| -> i - # 44| 10 #-----| -> ... -le ... # 44| i #-----| -> ...+... -# 44| ...=... +# 44| ...+... #-----| -> i # 44| i #-----| -> 1 -# 44| ...+... -#-----| -> ... -le ... - -# 44| ...+... -#-----| -> i - # 44| 1 #-----| -> ...+... -# 44| {...} +# 50| ...,... #-----| -> ...=... -# 45| a -#-----| -> ...+... - -# 45| ...=... +# 51| ...=... #-----| -> a -# 45| a -#-----| -> 1 - -# 45| ...+... -#-----| -> ... -le ... -#-----| -> ...=... - -# 45| ...+... -#-----| -> a +# 51| 0 +#-----| -> letterArray -# 45| 1 -#-----| -> ...+... +# 52| letterArray +#-----| -> letterArray -# 49| Test-ForEach -#-----| -> Test-For-Ever +# 52| letterArray +#-----| -> forach(... in ...) -# 49| enter {...} -#-----| -> {...} +# 52| forach(... in ...) +#-----| -> letter +#-----| -> exit {...} (normal) -# 49| exit {...} +# 54| ...+... +#-----| -> forach(... in ...) -# 49| exit {...} (normal) -#-----| -> exit {...} +# 50| {...} +#-----| -> ...=... -# 49| {...} -#-----| -> {...} +# 50| ...=... +#-----| -> letterArray # 50| letterArray #-----| -> ...,... -# 50| ...=... -#-----| -> letterArray - -# 50| {...} -#-----| -> ...=... +# 50| ...,... +#-----| -> a # 50| a #-----| -> b -# 50| ...,... -#-----| -> ...=... - -# 50| ...,... -#-----| -> a - # 50| b #-----| -> c @@ -1447,110 +1531,120 @@ loops.ps1: # 51| a #-----| -> 0 -# 51| ...=... -#-----| -> a - -# 51| 0 -#-----| -> letterArray - # 51| 0 #-----| -> 0 -# 52| forach(... in ...) -#-----| -> exit {...} (normal) -#-----| -> letter - # 52| letter #-----| -> {...} -# 52| letterArray -#-----| -> forach(... in ...) - -# 52| letterArray -#-----| -> letterArray - # 53| {...} #-----| -> ...=... -# 54| a -#-----| -> ...+... +# 49| exit {...} (normal) +#-----| -> exit {...} # 54| ...=... #-----| -> a # 54| a -#-----| -> 1 - -# 54| ...+... -#-----| -> forach(... in ...) +#-----| -> ...+... # 54| ...+... #-----| -> a +# 54| a +#-----| -> 1 + # 54| 1 #-----| -> ...+... -# 58| Test-For-Ever -#-----| -> exit loops.ps1 (normal) - -# 58| enter {...} -#-----| -> {...} +# 59| 0 +#-----| -> for(...;...;...) -# 58| {...} -#-----| -> {...} +# 61| for(...;...;...) -# 59| a -#-----| -> 0 +# 59| {...} +#-----| -> ...=... # 59| ...=... #-----| -> a -# 59| {...} -#-----| -> ...=... - -# 59| 0 -#-----| -> for(...;...;...) +# 59| a +#-----| -> 0 # 59| 0 #-----| -> 0 -# 61| for(...;...;...) - try.ps1: +# 1| {...} +#-----| -> test-try-catch + # 1| test-try-catch #-----| -> test-try-with-throw-catch -# 1| enter try.ps1 -#-----| -> try.ps1 +# 10| test-try-with-throw-catch +#-----| -> test-try-with-throw-catch-with-throw -# 1| exit try.ps1 +# 21| test-try-with-throw-catch-with-throw +#-----| -> test-try-with-throw-catch-with-rethrow -# 1| exit try.ps1 (normal) -#-----| -> exit try.ps1 +# 32| test-try-with-throw-catch-with-rethrow +#-----| -> test-try-catch-specific-1 -# 1| try.ps1 -#-----| -> {...} +# 43| test-try-catch-specific-1 +#-----| -> test-try-catch-specific-1 -# 1| {...} -#-----| -> test-try-catch +# 52| test-try-catch-specific-1 +#-----| -> test-try-two-catch-specific-1 -# 1| enter {...} -#-----| -> {...} +# 61| test-try-two-catch-specific-1 +#-----| -> test-try-catch-specific-2 -# 1| exit {...} +# 72| test-try-catch-specific-2 +#-----| -> test-try-two-catch-specific-2 + +# 81| test-try-two-catch-specific-2 +#-----| -> test-try-three-catch-specific-2 + +# 92| test-try-three-catch-specific-2 +#-----| -> test-try-catch-finally + +# 105| test-try-catch-finally +#-----| -> test-try-finally + +# 116| test-try-finally +#-----| -> test-try-finally-catch-specific-1 + +# 125| test-try-finally-catch-specific-1 +#-----| -> test-nested-try-inner-finally + +# 136| test-nested-try-inner-finally +#-----| -> test-nested-try-inner-finally + +# 149| test-nested-try-inner-finally +#-----| -> test-nested-try-outer-finally + +# 164| test-nested-try-outer-finally +#-----| -> test-nested-try-inner-outer-finally + +# 179| test-nested-try-inner-outer-finally +#-----| -> exit try.ps1 (normal) + +# 1| exit try.ps1 (normal) +#-----| -> exit try.ps1 + +# 7| 1 +#-----| -> exit {...} (normal) # 1| exit {...} (normal) #-----| -> exit {...} -# 1| {...} -#-----| -> {...} +# 2| {...} +#-----| -> try {...} # 2| try {...} #-----| -> {...} -# 2| {...} -#-----| -> try {...} - # 2| {...} #-----| -> Write-Output @@ -1560,38 +1654,39 @@ try.ps1: # 3| Write-Output #-----| -> return ... -# 3| Hello! -#-----| -> Write-Output - # 7| return ... #-----| -> 1 -# 7| 1 -#-----| -> exit {...} (normal) +# 3| Hello! +#-----| -> Write-Output # 7| 1 #-----| -> 1 -# 10| test-try-with-throw-catch -#-----| -> test-try-with-throw-catch-with-throw - -# 10| enter {...} +# 12| b #-----| -> {...} -# 10| exit {...} +# 12| {...} +#-----| -> throw ... + +# 13| 42 +#-----| -> return ... + +# 18| return ... +#-----| -> 1 + +# 18| 1 +#-----| -> exit {...} (normal) # 10| exit {...} (normal) #-----| -> exit {...} -# 10| {...} -#-----| -> {...} +# 11| {...} +#-----| -> try {...} # 11| try {...} #-----| -> {...} -# 11| {...} -#-----| -> try {...} - # 11| {...} #-----| -> if (...) {...} @@ -1599,158 +1694,113 @@ try.ps1: #-----| -> b # 12| b -#-----| true -> {...} - -# 12| b -#-----| -> b - -# 12| {...} -#-----| -> throw ... +#-----| -> b # 13| throw ... #-----| -> 42 -# 13| 42 -#-----| -> return ... - # 13| 42 #-----| -> 42 -# 18| return ... +# 18| 1 #-----| -> 1 -# 18| 1 -#-----| -> exit {...} (normal) +# 23| b +#-----| -> {...} -# 18| 1 -#-----| -> 1 +# 23| {...} +#-----| -> throw ... -# 21| test-try-with-throw-catch-with-throw -#-----| -> test-try-with-throw-catch-with-rethrow +# 24| 42 +#-----| -> return ... -# 21| enter {...} -#-----| -> {...} +# 29| return ... +#-----| -> 1 -# 21| exit {...} +# 29| 1 +#-----| -> exit {...} (normal) # 21| exit {...} (normal) #-----| -> exit {...} -# 21| {...} -#-----| -> {...} +# 22| {...} +#-----| -> try {...} # 22| try {...} #-----| -> {...} -# 22| {...} -#-----| -> try {...} - # 22| {...} #-----| -> if (...) {...} # 23| if (...) {...} #-----| -> b -# 23| b -#-----| true -> {...} - # 23| b #-----| -> b -# 23| {...} -#-----| -> throw ... - # 24| throw ... #-----| -> 42 -# 24| 42 -#-----| -> return ... - # 24| 42 #-----| -> 42 -# 29| return ... +# 29| 1 #-----| -> 1 -# 29| 1 -#-----| -> exit {...} (normal) +# 34| b +#-----| -> {...} -# 29| 1 -#-----| -> 1 +# 34| {...} +#-----| -> throw ... -# 32| test-try-with-throw-catch-with-rethrow -#-----| -> test-try-catch-specific-1 +# 35| 42 +#-----| -> return ... -# 32| enter {...} -#-----| -> {...} +# 40| return ... +#-----| -> 1 -# 32| exit {...} +# 40| 1 +#-----| -> exit {...} (normal) # 32| exit {...} (normal) #-----| -> exit {...} -# 32| {...} -#-----| -> {...} +# 33| {...} +#-----| -> try {...} # 33| try {...} #-----| -> {...} -# 33| {...} -#-----| -> try {...} - # 33| {...} #-----| -> if (...) {...} # 34| if (...) {...} #-----| -> b -# 34| b -#-----| true -> {...} - # 34| b #-----| -> b -# 34| {...} -#-----| -> throw ... - # 35| throw ... #-----| -> 42 -# 35| 42 -#-----| -> return ... - # 35| 42 #-----| -> 42 -# 40| return ... -#-----| -> 1 - -# 40| 1 -#-----| -> exit {...} (normal) - # 40| 1 #-----| -> 1 -# 43| test-try-catch-specific-1 -#-----| -> test-try-catch-specific-1 - -# 43| enter {...} -#-----| -> {...} - -# 43| exit {...} +# 49| 1 +#-----| -> exit {...} (normal) # 43| exit {...} (normal) #-----| -> exit {...} -# 43| {...} -#-----| -> {...} +# 44| {...} +#-----| -> try {...} # 44| try {...} #-----| -> {...} -# 44| {...} -#-----| -> try {...} - # 44| {...} #-----| -> Write-Output @@ -1760,38 +1810,27 @@ try.ps1: # 45| Write-Output #-----| -> return ... -# 45| Hello! -#-----| -> Write-Output - # 49| return ... #-----| -> 1 -# 49| 1 -#-----| -> exit {...} (normal) +# 45| Hello! +#-----| -> Write-Output # 49| 1 #-----| -> 1 -# 52| test-try-catch-specific-1 -#-----| -> test-try-two-catch-specific-1 - -# 52| enter {...} -#-----| -> {...} - -# 52| exit {...} +# 58| 1 +#-----| -> exit {...} (normal) # 52| exit {...} (normal) #-----| -> exit {...} -# 52| {...} -#-----| -> {...} +# 53| {...} +#-----| -> try {...} # 53| try {...} #-----| -> {...} -# 53| {...} -#-----| -> try {...} - # 53| {...} #-----| -> Write-Output @@ -1801,38 +1840,27 @@ try.ps1: # 54| Write-Output #-----| -> return ... -# 54| Hello! -#-----| -> Write-Output - # 58| return ... #-----| -> 1 -# 58| 1 -#-----| -> exit {...} (normal) +# 54| Hello! +#-----| -> Write-Output # 58| 1 #-----| -> 1 -# 61| test-try-two-catch-specific-1 -#-----| -> test-try-catch-specific-2 - -# 61| enter {...} -#-----| -> {...} - -# 61| exit {...} +# 69| 2 +#-----| -> exit {...} (normal) # 61| exit {...} (normal) #-----| -> exit {...} -# 61| {...} -#-----| -> {...} +# 62| {...} +#-----| -> try {...} # 62| try {...} #-----| -> {...} -# 62| {...} -#-----| -> try {...} - # 62| {...} #-----| -> Write-Output @@ -1842,38 +1870,27 @@ try.ps1: # 63| Write-Output #-----| -> return ... -# 63| Hello! -#-----| -> Write-Output - # 69| return ... #-----| -> 2 -# 69| 2 -#-----| -> exit {...} (normal) +# 63| Hello! +#-----| -> Write-Output # 69| 2 #-----| -> 2 -# 72| test-try-catch-specific-2 -#-----| -> test-try-two-catch-specific-2 - -# 72| enter {...} -#-----| -> {...} - -# 72| exit {...} +# 78| 1 +#-----| -> exit {...} (normal) # 72| exit {...} (normal) #-----| -> exit {...} -# 72| {...} -#-----| -> {...} +# 73| {...} +#-----| -> try {...} # 73| try {...} #-----| -> {...} -# 73| {...} -#-----| -> try {...} - # 73| {...} #-----| -> Write-Output @@ -1883,38 +1900,27 @@ try.ps1: # 74| Write-Output #-----| -> return ... -# 74| Hello! -#-----| -> Write-Output - # 78| return ... #-----| -> 1 -# 78| 1 -#-----| -> exit {...} (normal) +# 74| Hello! +#-----| -> Write-Output # 78| 1 #-----| -> 1 -# 81| test-try-two-catch-specific-2 -#-----| -> test-try-three-catch-specific-2 - -# 81| enter {...} -#-----| -> {...} - -# 81| exit {...} +# 89| 2 +#-----| -> exit {...} (normal) # 81| exit {...} (normal) #-----| -> exit {...} -# 81| {...} -#-----| -> {...} +# 82| {...} +#-----| -> try {...} # 82| try {...} #-----| -> {...} -# 82| {...} -#-----| -> try {...} - # 82| {...} #-----| -> Write-Output @@ -1924,38 +1930,27 @@ try.ps1: # 83| Write-Output #-----| -> return ... -# 83| Hello! -#-----| -> Write-Output - # 89| return ... #-----| -> 2 -# 89| 2 -#-----| -> exit {...} (normal) +# 83| Hello! +#-----| -> Write-Output # 89| 2 #-----| -> 2 -# 92| test-try-three-catch-specific-2 -#-----| -> test-try-catch-finally - -# 92| enter {...} -#-----| -> {...} - -# 92| exit {...} +# 102| 3 +#-----| -> exit {...} (normal) # 92| exit {...} (normal) #-----| -> exit {...} -# 92| {...} -#-----| -> {...} +# 93| {...} +#-----| -> try {...} # 93| try {...} #-----| -> {...} -# 93| {...} -#-----| -> try {...} - # 93| {...} #-----| -> Write-Output @@ -1965,38 +1960,27 @@ try.ps1: # 94| Write-Output #-----| -> return ... -# 94| Hello! -#-----| -> Write-Output - # 102| return ... #-----| -> 3 -# 102| 3 -#-----| -> exit {...} (normal) +# 94| Hello! +#-----| -> Write-Output # 102| 3 #-----| -> 3 -# 105| test-try-catch-finally -#-----| -> test-try-finally - -# 105| enter {...} -#-----| -> {...} - -# 105| exit {...} +# 113| 1 +#-----| -> exit {...} (normal) # 105| exit {...} (normal) #-----| -> exit {...} -# 105| {...} -#-----| -> {...} +# 106| {...} +#-----| -> try {...} # 106| try {...} #-----| -> {...} -# 106| {...} -#-----| -> try {...} - # 106| {...} #-----| -> Write-Output @@ -2006,10 +1990,10 @@ try.ps1: # 107| Write-Output #-----| -> {...} -# 107| Hello! +# 110| {...} #-----| -> Write-Output -# 110| {...} +# 107| Hello! #-----| -> Write-Output # 111| Write-Output @@ -2018,38 +2002,27 @@ try.ps1: # 111| Write-Output #-----| -> return ... -# 111| Finally! -#-----| -> Write-Output - # 113| return ... #-----| -> 1 -# 113| 1 -#-----| -> exit {...} (normal) +# 111| Finally! +#-----| -> Write-Output # 113| 1 #-----| -> 1 -# 116| test-try-finally -#-----| -> test-try-finally-catch-specific-1 - -# 116| enter {...} -#-----| -> {...} - -# 116| exit {...} +# 122| 1 +#-----| -> exit {...} (normal) # 116| exit {...} (normal) #-----| -> exit {...} -# 116| {...} -#-----| -> {...} +# 117| {...} +#-----| -> try {...} # 117| try {...} #-----| -> {...} -# 117| {...} -#-----| -> try {...} - # 117| {...} #-----| -> Write-Output @@ -2059,10 +2032,10 @@ try.ps1: # 118| Write-Output #-----| -> {...} -# 118| Hello! +# 119| {...} #-----| -> Write-Output -# 119| {...} +# 118| Hello! #-----| -> Write-Output # 120| Write-Output @@ -2071,38 +2044,27 @@ try.ps1: # 120| Write-Output #-----| -> return ... -# 120| Finally! -#-----| -> Write-Output - # 122| return ... #-----| -> 1 -# 122| 1 -#-----| -> exit {...} (normal) +# 120| Finally! +#-----| -> Write-Output # 122| 1 #-----| -> 1 -# 125| test-try-finally-catch-specific-1 -#-----| -> test-nested-try-inner-finally - -# 125| enter {...} -#-----| -> {...} - -# 125| exit {...} +# 133| 1 +#-----| -> exit {...} (normal) # 125| exit {...} (normal) #-----| -> exit {...} -# 125| {...} -#-----| -> {...} +# 126| {...} +#-----| -> try {...} # 126| try {...} #-----| -> {...} -# 126| {...} -#-----| -> try {...} - # 126| {...} #-----| -> Write-Output @@ -2112,10 +2074,10 @@ try.ps1: # 127| Write-Output #-----| -> {...} -# 127| Hello! +# 130| {...} #-----| -> Write-Output -# 130| {...} +# 127| Hello! #-----| -> Write-Output # 131| Write-Output @@ -2124,31 +2086,23 @@ try.ps1: # 131| Write-Output #-----| -> return ... -# 131| Finally! -#-----| -> Write-Output - # 133| return ... #-----| -> 1 -# 133| 1 -#-----| -> exit {...} (normal) +# 131| Finally! +#-----| -> Write-Output # 133| 1 #-----| -> 1 -# 136| test-nested-try-inner-finally -#-----| -> test-nested-try-inner-finally - -# 136| enter {...} -#-----| -> {...} - -# 136| exit {...} +# 146| 1 +#-----| -> exit {...} (normal) # 136| exit {...} (normal) #-----| -> exit {...} -# 136| {...} -#-----| -> {...} +# 137| {...} +#-----| -> try {...} # 137| try {...} #-----| -> {...} @@ -2156,9 +2110,6 @@ try.ps1: # 137| {...} #-----| -> try {...} -# 137| {...} -#-----| -> try {...} - # 138| try {...} #-----| -> {...} @@ -2171,31 +2122,17 @@ try.ps1: # 139| Write-Output #-----| -> return ... -# 139| Hello! -#-----| -> Write-Output - # 146| return ... #-----| -> 1 -# 146| 1 -#-----| -> exit {...} (normal) +# 139| Hello! +#-----| -> Write-Output # 146| 1 #-----| -> 1 -# 149| test-nested-try-inner-finally -#-----| -> test-nested-try-outer-finally - -# 149| enter {...} -#-----| -> {...} - -# 149| exit {...} - -# 149| exit {...} (normal) -#-----| -> exit {...} - -# 149| {...} -#-----| -> {...} +# 150| {...} +#-----| -> try {...} # 150| try {...} #-----| -> {...} @@ -2203,9 +2140,6 @@ try.ps1: # 150| {...} #-----| -> try {...} -# 150| {...} -#-----| -> try {...} - # 151| try {...} #-----| -> {...} @@ -2218,43 +2152,41 @@ try.ps1: # 152| Write-Output #-----| -> {...} -# 152| Hello! +# 155| {...} #-----| -> Write-Output -# 155| {...} +# 152| Hello! #-----| -> Write-Output +# 161| 1 +#-----| -> exit {...} (normal) + +# 149| exit {...} (normal) +#-----| -> exit {...} + # 156| Write-Output #-----| -> Finally! # 156| Write-Output #-----| -> return ... -# 156| Finally! -#-----| -> Write-Output - # 161| return ... #-----| -> 1 -# 161| 1 -#-----| -> exit {...} (normal) +# 156| Finally! +#-----| -> Write-Output # 161| 1 #-----| -> 1 -# 164| test-nested-try-outer-finally -#-----| -> test-nested-try-inner-outer-finally - -# 164| enter {...} -#-----| -> {...} - -# 164| exit {...} +# 176| 1 +#-----| -> exit {...} (normal) # 164| exit {...} (normal) #-----| -> exit {...} -# 164| {...} -#-----| -> {...} +# 165| {...} +#-----| -> try {...} # 165| try {...} #-----| -> {...} @@ -2262,9 +2194,6 @@ try.ps1: # 165| {...} #-----| -> try {...} -# 165| {...} -#-----| -> try {...} - # 166| try {...} #-----| -> {...} @@ -2277,10 +2206,10 @@ try.ps1: # 167| Write-Output #-----| -> {...} -# 167| Hello! +# 173| {...} #-----| -> Write-Output -# 173| {...} +# 167| Hello! #-----| -> Write-Output # 174| Write-Output @@ -2289,31 +2218,23 @@ try.ps1: # 174| Write-Output #-----| -> return ... -# 174| Finally! -#-----| -> Write-Output - # 176| return ... #-----| -> 1 -# 176| 1 -#-----| -> exit {...} (normal) +# 174| Finally! +#-----| -> Write-Output # 176| 1 #-----| -> 1 -# 179| test-nested-try-inner-outer-finally -#-----| -> exit try.ps1 (normal) - -# 179| enter {...} -#-----| -> {...} - -# 179| exit {...} +# 193| 1 +#-----| -> exit {...} (normal) # 179| exit {...} (normal) #-----| -> exit {...} -# 179| {...} -#-----| -> {...} +# 180| {...} +#-----| -> try {...} # 180| try {...} #-----| -> {...} @@ -2321,9 +2242,6 @@ try.ps1: # 180| {...} #-----| -> try {...} -# 180| {...} -#-----| -> try {...} - # 181| try {...} #-----| -> {...} @@ -2336,10 +2254,10 @@ try.ps1: # 182| Write-Output #-----| -> {...} -# 182| Hello! +# 185| {...} #-----| -> Write-Output -# 185| {...} +# 182| Hello! #-----| -> Write-Output # 186| Write-Output @@ -2348,10 +2266,10 @@ try.ps1: # 186| Write-Output #-----| -> {...} -# 186| Finally! +# 190| {...} #-----| -> Write-Output -# 190| {...} +# 186| Finally! #-----| -> Write-Output # 191| Write-Output @@ -2360,14 +2278,106 @@ try.ps1: # 191| Write-Output #-----| -> return ... -# 191| Finally! -#-----| -> Write-Output - # 193| return ... #-----| -> 1 -# 193| 1 -#-----| -> exit {...} (normal) +# 191| Finally! +#-----| -> Write-Output # 193| 1 #-----| -> 1 + +conditionals.ps1: +# 1| exit conditionals.ps1 + +# 1| exit {...} + +# 11| exit {...} + +# 24| exit {...} + +# 34| exit {...} + +# 47| exit {...} + +# 57| exit {...} + +# 70| exit {...} + +# 84| exit {...} + +# 101| exit {...} + +# 110| exit {...} + +# 123| exit {...} + +functions.ps1: +# 1| exit functions.ps1 + +# 1| exit {...} + +# 11| exit {...} + +# 13| exit {...} + +# 22| exit {...} + +# 36| exit {...} + +global.ps1: +# 1| exit global.ps1 + +loops.ps1: +# 1| exit loops.ps1 + +# 1| exit {...} + +# 9| exit {...} + +# 17| exit {...} + +# 25| exit {...} + +# 33| exit {...} + +# 41| exit {...} + +# 49| exit {...} + +try.ps1: +# 1| exit try.ps1 + +# 1| exit {...} + +# 10| exit {...} + +# 21| exit {...} + +# 32| exit {...} + +# 43| exit {...} + +# 52| exit {...} + +# 61| exit {...} + +# 72| exit {...} + +# 81| exit {...} + +# 92| exit {...} + +# 105| exit {...} + +# 116| exit {...} + +# 125| exit {...} + +# 136| exit {...} + +# 149| exit {...} + +# 164| exit {...} + +# 179| exit {...} diff --git a/powershell/ql/test/library-tests/controlflow/graph/Cfg.ql b/powershell/ql/test/library-tests/controlflow/graph/Cfg.ql index 3449cc69e563..05f36b088a1b 100644 --- a/powershell/ql/test/library-tests/controlflow/graph/Cfg.ql +++ b/powershell/ql/test/library-tests/controlflow/graph/Cfg.ql @@ -4,8 +4,4 @@ import semmle.code.powershell.Cfg -class TestRelevantNode extends CfgNode { - string getOrderDisambiguation() { result = "" } -} - -import semmle.code.powershell.controlflow.internal.ControlFlowGraphImpl::TestOutput +import semmle.code.powershell.controlflow.internal.ControlFlowGraphImpl::TestOutput diff --git a/powershell/ql/test/library-tests/dataflow/fields/test.expected b/powershell/ql/test/library-tests/dataflow/fields/test.expected index 50635fd5358f..6106d937a704 100644 --- a/powershell/ql/test/library-tests/dataflow/fields/test.expected +++ b/powershell/ql/test/library-tests/dataflow/fields/test.expected @@ -163,6 +163,11 @@ edges | test.ps1:35:15:35:17 | x | test.ps1:35:9:35:17 | ...,... [element 2] | provenance | | | test.ps1:38:6:38:11 | arr8 [element 2] | test.ps1:38:6:38:14 | ...[...] | provenance | | | test.ps1:39:6:39:11 | arr8 [element 2] | test.ps1:39:6:39:21 | ...[...] | provenance | | +| test.ps1:52:22:54:6 | this [field] | test.ps1:53:14:53:19 | this [field] | provenance | | +| test.ps1:53:14:53:19 | this [field] | test.ps1:53:14:53:25 | field | provenance | | +| test.ps1:59:1:59:9 | [post] myClass [field] | test.ps1:61:1:61:9 | myClass [field] | provenance | | +| test.ps1:59:18:59:29 | Source | test.ps1:59:1:59:9 | [post] myClass [field] | provenance | | +| test.ps1:61:1:61:9 | myClass [field] | test.ps1:52:22:54:6 | this [field] | provenance | | nodes | test.ps1:1:1:1:3 | [post] a [f] | semmle.label | [post] a [f] | | test.ps1:1:8:1:18 | Source | semmle.label | Source | @@ -300,6 +305,12 @@ nodes | test.ps1:38:6:38:14 | ...[...] | semmle.label | ...[...] | | test.ps1:39:6:39:11 | arr8 [element 2] | semmle.label | arr8 [element 2] | | test.ps1:39:6:39:21 | ...[...] | semmle.label | ...[...] | +| test.ps1:52:22:54:6 | this [field] | semmle.label | this [field] | +| test.ps1:53:14:53:19 | this [field] | semmle.label | this [field] | +| test.ps1:53:14:53:25 | field | semmle.label | field | +| test.ps1:59:1:59:9 | [post] myClass [field] | semmle.label | [post] myClass [field] | +| test.ps1:59:18:59:29 | Source | semmle.label | Source | +| test.ps1:61:1:61:9 | myClass [field] | semmle.label | myClass [field] | subpaths testFailures #select @@ -314,3 +325,4 @@ testFailures | test.ps1:31:6:31:33 | ...[...] | test.ps1:29:31:29:41 | Source | test.ps1:31:6:31:33 | ...[...] | $@ | test.ps1:29:31:29:41 | Source | Source | | test.ps1:38:6:38:14 | ...[...] | test.ps1:33:6:33:17 | Source | test.ps1:38:6:38:14 | ...[...] | $@ | test.ps1:33:6:33:17 | Source | Source | | test.ps1:39:6:39:21 | ...[...] | test.ps1:33:6:33:17 | Source | test.ps1:39:6:39:21 | ...[...] | $@ | test.ps1:33:6:33:17 | Source | Source | +| test.ps1:53:14:53:25 | field | test.ps1:59:18:59:29 | Source | test.ps1:53:14:53:25 | field | $@ | test.ps1:59:18:59:29 | Source | Source | diff --git a/powershell/ql/test/library-tests/dataflow/fields/test.ps1 b/powershell/ql/test/library-tests/dataflow/fields/test.ps1 index f235c96e9483..c5c676670ba9 100644 --- a/powershell/ql/test/library-tests/dataflow/fields/test.ps1 +++ b/powershell/ql/test/library-tests/dataflow/fields/test.ps1 @@ -44,4 +44,18 @@ $arr9 = @(0, 1, $y) Sink $arr9[0] # clean Sink $arr9[1] # clean Sink $arr9[2] # $ MISSING: hasValueFlow=11 -Sink $arr9[$unknown] # MISSING: hasValueFlow=11 \ No newline at end of file +Sink $arr9[$unknown] # MISSING: hasValueFlow=11 + +class MyClass { + [string] $field + + [void]callSink() { + Sink $this.field # $ hasValueFlow=12 + } +} + +$myClass = [MyClass]::new() + +$myClass.field = Source "12" + +$myClass.callSink() \ No newline at end of file