private SemanticChecks(Parser parser) { IsConstantValueVisitor visitor = new IsConstantValueVisitor { CheckingAttributeArgument = true }; this._isConstantValueVisitor = visitor; this._parser = parser; }
public static bool IsConstant(Ast ast, out object constantValue, bool forAttribute = false, bool forRequires = false) { try { IsConstantValueVisitor visitor2 = new IsConstantValueVisitor { CheckingAttributeArgument = forAttribute, CheckingRequiresArgument = forRequires }; if ((bool) ast.Accept(visitor2)) { Ast parent = ast.Parent; while (parent != null) { if (parent is DataStatementAst) { break; } parent = parent.Parent; } if (parent == null) { ConstantValueVisitor visitor = new ConstantValueVisitor { AttributeArgument = forAttribute, RequiresArgument = forRequires }; constantValue = ast.Accept(visitor); return true; } } } catch (Exception exception) { CommandProcessorBase.CheckForSevereException(exception); } constantValue = null; return false; }
public static bool IsConstant(Ast ast, out object constantValue, bool forAttribute = false, bool forRequires = false) { try { IsConstantValueVisitor visitor2 = new IsConstantValueVisitor { CheckingAttributeArgument = forAttribute, CheckingRequiresArgument = forRequires }; if ((bool)ast.Accept(visitor2)) { Ast parent = ast.Parent; while (parent != null) { if (parent is DataStatementAst) { break; } parent = parent.Parent; } if (parent == null) { ConstantValueVisitor visitor = new ConstantValueVisitor { AttributeArgument = forAttribute, RequiresArgument = forRequires }; constantValue = ast.Accept(visitor); return(true); } } } catch (Exception exception) { CommandProcessorBase.CheckForSevereException(exception); } constantValue = null; return(false); }
/// <summary> /// Resolves using module to a collection of PSModuleInfos. Doesn't throw. /// PSModuleInfo objects are returned in the right order: i.e. if multiply versions of the module /// is presented on the system and user didn't specify version, we will return all of them, but newer one would go first. /// </summary> /// <param name="usingStatementAst">Using statement.</param> /// <param name="exception">If exception happens, return exception object.</param> /// <param name="wildcardCharactersUsed"> /// True if in the module name uses wildcardCharacter. /// We don't want to resolve any wild-cards in using module. /// </param> /// <param name="isConstant">True if module hashtable contains constant value (it's our requirement).</param> /// <returns>Modules, if can resolve it. null if any problems happens.</returns> private Collection <PSModuleInfo> GetModulesFromUsingModule(UsingStatementAst usingStatementAst, out Exception exception, out bool wildcardCharactersUsed, out bool isConstant) { exception = null; wildcardCharactersUsed = false; isConstant = true; // fullyQualifiedName can be string or hashtable object fullyQualifiedName; if (usingStatementAst.ModuleSpecification != null) { object resultObject; if (!IsConstantValueVisitor.IsConstant(usingStatementAst.ModuleSpecification, out resultObject, forAttribute: false, forRequires: true)) { isConstant = false; return(null); } var hashtable = resultObject as System.Collections.Hashtable; var ms = new ModuleSpecification(); exception = ModuleSpecification.ModuleSpecificationInitHelper(ms, hashtable); if (exception != null) { return(null); } if (WildcardPattern.ContainsWildcardCharacters(ms.Name)) { wildcardCharactersUsed = true; return(null); } fullyQualifiedName = ms; } else { string fullyQualifiedNameStr = usingStatementAst.Name.Value; if (WildcardPattern.ContainsWildcardCharacters(fullyQualifiedNameStr)) { wildcardCharactersUsed = true; return(null); } // case 1: relative path. Relative for file in the same folder should include .\ bool isPath = fullyQualifiedNameStr.Contains(@"\"); if (isPath && !LocationGlobber.IsAbsolutePath(fullyQualifiedNameStr)) { string rootPath = Path.GetDirectoryName(_parser._fileName); if (rootPath != null) { fullyQualifiedNameStr = Path.Combine(rootPath, fullyQualifiedNameStr); } } // case 2: Module by name // case 3: Absolute Path // We don't need to do anything for these cases, FullyQualifiedName already handle it. fullyQualifiedName = fullyQualifiedNameStr; } var commandInfo = new CmdletInfo("Get-Module", typeof(GetModuleCommand)); // TODO(sevoroby): we should consider an async call with cancellation here. UsingStatementResolvePowerShell.Commands.Clear(); try { return(UsingStatementResolvePowerShell.AddCommand(commandInfo) .AddParameter("FullyQualifiedName", fullyQualifiedName) .AddParameter("ListAvailable", true) .Invoke <PSModuleInfo>()); } catch (Exception e) { exception = e; return(null); } }
private Action<List<Expression>, Expression> GetSwitchBodyGenerator(SwitchStatementAst switchStatementAst, AutomaticVarSaver avs, ParameterExpression skipDefault) { return (exprs, newValue) => { var clauseEvalBinder = PSSwitchClauseEvalBinder.Get(switchStatementAst.Flags); exprs.Add(avs.SetNewValue(newValue)); if (skipDefault != null) { exprs.Add(Expression.Assign(skipDefault, ExpressionCache.Constant(false))); } IsConstantValueVisitor iscvv = new IsConstantValueVisitor(); ConstantValueVisitor cvv = new ConstantValueVisitor(); int clauseCount = switchStatementAst.Clauses.Count; for (int i = 0; i < clauseCount; i++) { var clause = switchStatementAst.Clauses[i]; Expression test; object constValue = ((bool)clause.Item1.Accept(iscvv)) ? clause.Item1.Accept(cvv) : null; if (constValue is ScriptBlock) { var call = Expression.Call(Expression.Constant(constValue), CachedReflectionInfo.ScriptBlock_DoInvokeReturnAsIs, /*useLocalScope=*/ ExpressionCache.Constant(true), /*errorHandlingBehavior=*/ Expression.Constant(ScriptBlock.ErrorHandlingBehavior.WriteToExternalErrorPipe), /*dollarUnder=*/ GetLocal((int)AutomaticVariable.Underbar).Convert(typeof(object)), /*input=*/ ExpressionCache.AutomationNullConstant, /*scriptThis=*/ ExpressionCache.AutomationNullConstant, /*args=*/ ExpressionCache.NullObjectArray); test = DynamicExpression.Dynamic(PSConvertBinder.Get(typeof(bool)), typeof(bool), call); } else if (constValue != null) { SwitchFlags flags = switchStatementAst.Flags; Expression conditionExpr = constValue is Regex || constValue is WildcardPattern ? (Expression)Expression.Constant(constValue) : DynamicExpression.Dynamic(PSToStringBinder.Get(), typeof(string), (constValue is Type) ? Expression.Constant(constValue, typeof(Type)) : Expression.Constant(constValue), _executionContextParameter); Expression currentAsString = DynamicExpression.Dynamic(PSToStringBinder.Get(), typeof(string), GetLocal((int)AutomaticVariable.Underbar), _executionContextParameter); if ((flags & SwitchFlags.Regex) != 0 || constValue is Regex) { test = Expression.Call(CachedReflectionInfo.SwitchOps_ConditionSatisfiedRegex, /*caseSensitive=*/ ExpressionCache.Constant((flags & SwitchFlags.CaseSensitive) != 0), /*condition=*/ conditionExpr, /*errorPosition=*/ Expression.Constant(clause.Item1.Extent), /*str=*/ currentAsString, /*context=*/ _executionContextParameter); } else if ((flags & SwitchFlags.Wildcard) != 0 || constValue is WildcardPattern) { // It would be a little better to just build the wildcard at compile time, but // the runtime method must exist when variable cases are involved. test = Expression.Call(CachedReflectionInfo.SwitchOps_ConditionSatisfiedWildcard, /*caseSensitive=*/ ExpressionCache.Constant((flags & SwitchFlags.CaseSensitive) != 0), /*condition=*/ conditionExpr, /*str=*/ currentAsString, /*context=*/ _executionContextParameter); } else { test = CallStringEquals(conditionExpr, currentAsString, ((flags & SwitchFlags.CaseSensitive) == 0)); } } else { var cond = Compile(clause.Item1); test = DynamicExpression.Dynamic(clauseEvalBinder, typeof(bool), cond, GetLocal((int)AutomaticVariable.Underbar), _executionContextParameter); } exprs.Add(UpdatePosition(clause.Item1)); if (skipDefault != null) { exprs.Add(Expression.IfThen( test, Expression.Block(Compile(clause.Item2), Expression.Assign(skipDefault, ExpressionCache.Constant(true))))); } else { exprs.Add(Expression.IfThen(test, Compile(clause.Item2))); } } if (skipDefault != null) { exprs.Add(Expression.IfThen(Expression.Not(skipDefault), Compile(switchStatementAst.Default))); } }; }
private Expression<Func<string>> GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) { return visitor.CheckingClassAttributeArguments ? (Expression<Func<string>>)(() => ParserStrings.ParameterAttributeArgumentNeedsToBeConstant) : () => ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock; }
private bool IsValidAttributeArgument(Ast ast, IsConstantValueVisitor visitor) { return (bool)ast.Accept(visitor); }
private Action<List<Expression>, Expression> GetSwitchBodyGenerator(SwitchStatementAst switchStatementAst, AutomaticVarSaver avs, ParameterExpression skipDefault) { return delegate (List<Expression> exprs, Expression newValue) { PSSwitchClauseEvalBinder binder = PSSwitchClauseEvalBinder.Get(switchStatementAst.Flags); exprs.Add(avs.SetNewValue(newValue)); if (skipDefault != null) { exprs.Add(Expression.Assign(skipDefault, ExpressionCache.Constant(false))); } IsConstantValueVisitor visitor = new IsConstantValueVisitor(); ConstantValueVisitor visitor2 = new ConstantValueVisitor(); int count = switchStatementAst.Clauses.Count; for (int j = 0; j < count; j++) { Expression expression; Tuple<ExpressionAst, StatementBlockAst> tuple = switchStatementAst.Clauses[j]; object obj2 = ((bool) tuple.Item1.Accept(visitor)) ? tuple.Item1.Accept(visitor2) : null; if (obj2 is ScriptBlock) { MethodCallExpression expression2 = Expression.Call(Expression.Constant(obj2), CachedReflectionInfo.ScriptBlock_DoInvokeReturnAsIs, new Expression[] { ExpressionCache.Constant(true), Expression.Constant(ScriptBlock.ErrorHandlingBehavior.WriteToExternalErrorPipe), this.GetLocal(0).Convert(typeof(object)), ExpressionCache.AutomationNullConstant, ExpressionCache.AutomationNullConstant, ExpressionCache.NullObjectArray }); expression = Expression.Dynamic(PSConvertBinder.Get(typeof(bool)), typeof(bool), expression2); } else if (obj2 != null) { SwitchFlags flags = switchStatementAst.Flags; Expression expression3 = Expression.Constant(((obj2 is Regex) || (obj2 is WildcardPattern)) ? obj2 : obj2.ToString()); Expression expression4 = Expression.Dynamic(PSToStringBinder.Get(), typeof(string), this.GetLocal(0), _executionContextParameter); if (((flags & SwitchFlags.Regex) != SwitchFlags.None) || (obj2 is Regex)) { expression = Expression.Call(CachedReflectionInfo.SwitchOps_ConditionSatisfiedRegex, ExpressionCache.Constant((flags & SwitchFlags.CaseSensitive) != SwitchFlags.None), expression3, Expression.Constant(tuple.Item1.Extent), expression4, _executionContextParameter); } else if (((flags & SwitchFlags.Wildcard) != SwitchFlags.None) || (obj2 is WildcardPattern)) { expression = Expression.Call(CachedReflectionInfo.SwitchOps_ConditionSatisfiedWildcard, ExpressionCache.Constant((flags & SwitchFlags.CaseSensitive) != SwitchFlags.None), expression3, expression4, _executionContextParameter); } else { expression = CallStringEquals(expression3, expression4, (flags & SwitchFlags.CaseSensitive) == SwitchFlags.None); } } else { Expression expression5 = this.Compile(tuple.Item1); expression = Expression.Dynamic(binder, typeof(bool), expression5, this.GetLocal(0), _executionContextParameter); } exprs.Add(this.UpdatePosition(tuple.Item1)); if (skipDefault != null) { exprs.Add(Expression.IfThen(expression, Expression.Block(this.Compile(tuple.Item2), Expression.Assign(skipDefault, ExpressionCache.Constant(true))))); } else { exprs.Add(Expression.IfThen(expression, this.Compile(tuple.Item2))); } } if (skipDefault != null) { exprs.Add(Expression.IfThen(Expression.Not(skipDefault), this.Compile(switchStatementAst.Default))); } }; }