public override MSAst.Expression Reduce() { ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(); for (int i = 0; i < _names.Length; i++) { statements.Add( // _references[i] = PythonOps.Import(<code context>, _names[i]) GlobalParent.AddDebugInfoAndVoid( AssignValue( Parent.GetVariableExpression(_variables[i]), LightExceptions.CheckAndThrow( Expression.Call( _asNames[i] == null ? AstMethods.ImportTop : AstMethods.ImportBottom, Parent.LocalContext, // 1st arg - code context AstUtils.Constant(_names[i].MakeString()), // 2nd arg - module name AstUtils.Constant(_forceAbsolute ? 0 : -1) // 3rd arg - absolute or relative imports ) ) ), _names[i].Span ) ); } statements.Add(AstUtils.Empty()); return GlobalParent.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span); }
public ICollection <CuratorTransactionResult> commit() { CheckAlreadyCommited(); isCommitted = true; AtomicBoolean firstTime = new AtomicBoolean(true); List <OpResult> resultList = RetryLoop.callWithRetry ( client.getZookeeperClient(), CallableUtils.FromFunc(() => doOperation(firstTime))); if (resultList.Count != transaction.metadataSize()) { throw new InvalidOperationException(String.Format("Result size ({0}) doesn't match input size ({1})", resultList.Count, transaction.metadataSize())); } var builder = new ReadOnlyCollectionBuilder <CuratorTransactionResult>(); for (int i = 0; i < resultList.Count; ++i) { OpResult opResult = resultList[i]; CuratorMultiTransactionRecord.TypeAndPath metadata = transaction.getMetadata(i); CuratorTransactionResult curatorResult = makeCuratorResult(opResult, metadata); builder.Add(curatorResult); } return(builder.ToReadOnlyCollection()); }
public TotemArgs(TotemContext context, string[] names, IList<object> args, Dictionary<string, object> kwargs) : base(context.GetType<Types.Arguments>()) { _names = new ReadOnlyCollectionBuilder<string>(names).ToReadOnlyCollection(); var vb = new ReadOnlyCollectionBuilder<object>(); var nvb = new Dictionary<string, object>(); var snb = new ReadOnlyCollectionBuilder<string>(); for (var i = 0; i < args.Count; i++) { vb.Add(args[i]); if (i < names.Length) nvb.Add(names[i], args[i]); } foreach (var arg in kwargs) { nvb.Add(arg.Key, arg.Value); snb.Add(arg.Key); } _values = vb.ToReadOnlyCollection(); _namedValues = new ReadOnlyDictionary<string, object>(nvb); _named = snb.ToReadOnlyCollection(); }
public override System.Linq.Expressions.Expression Reduce() { if (_statements.Length == 0) return GlobalParent.AddDebugInfoAndVoid(Utils.Empty(), Span); ReadOnlyCollectionBuilder<ParameterExpression> locals = new ReadOnlyCollectionBuilder<ParameterExpression>(); List<Expression> init = new List<Expression>(); init.Add(Expression.ClearDebugInfo(GlobalParent.Document)); CreateVariables(locals, init); foreach (var statement in _statements) { int newline = GlobalParent.IndexToLocation(statement.StartIndex).Line; if (statement.CanThrow && newline != -1) init.Add(UpdateLineNumber(newline)); init.Add(statement); } return GlobalParent.AddDebugInfoAndVoid( Expression.Block( locals.ToReadOnlyCollection(), init ), Span ); }
public override MSAst.Expression Reduce() { ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); for (int i = 0; i < _names.Length; i++) { statements.Add( // _references[i] = PythonOps.Import(<code context>, _names[i]) GlobalParent.AddDebugInfoAndVoid( AssignValue( Parent.GetVariableExpression(_variables[i]), LightExceptions.CheckAndThrow( Expression.Call( _asNames[i] == null ? AstMethods.ImportTop : AstMethods.ImportBottom, Parent.LocalContext, // 1st arg - code context AstUtils.Constant(_names[i].MakeString()), // 2nd arg - module name AstUtils.Constant(_forceAbsolute ? 0 : -1) // 3rd arg - absolute or relative imports ) ) ), _names[i].Span ) ); } statements.Add(AstUtils.Empty()); return(GlobalParent.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span)); }
internal override MSAst.Expression Transform(AstGenerator ag) { ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(); for (int i = 0; i < _names.Length; i++) { statements.Add( // _references[i] = PythonOps.Import(<code context>, _names[i]) ag.AddDebugInfoAndVoid( GlobalAllocator.Assign( ag.Globals.GetVariable(ag, _variables[i]), Ast.Call( AstGenerator.GetHelperMethod( // helper _asNames[i] == null ? "ImportTop" : "ImportBottom" ), ag.LocalContext, // 1st arg - code context AstUtils.Constant(_names[i].MakeString()), // 2nd arg - module name AstUtils.Constant(_forceAbsolute ? 0 : -1) // 3rd arg - absolute or relative imports ) ), _names[i].Span ) ); } statements.Add(AstUtils.Empty()); return ag.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span); }
private LambdaSignature() { Type target = typeof(T); if (!typeof(Delegate).IsAssignableFrom(target)) { throw new InvalidOperationException(); } MethodInfo invoke = target.GetMethod("Invoke"); ParameterInfo[] pis = invoke.GetParameters(); if (pis[0].ParameterType != typeof(CallSite)) { throw new InvalidOperationException(); } var @params = new ReadOnlyCollectionBuilder <ParameterExpression>(pis.Length - 1); for (int i = 0; i < pis.Length - 1; i++) { @params.Add(Expression.Parameter(pis[i + 1].ParameterType, "$arg" + i)); } Parameters = @params.ToReadOnlyCollection(); ReturnLabel = Expression.Label(invoke.GetReturnType()); }
public override MSAst.Expression Reduce() { if (_statements.Length == 0) { return GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span); } ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(); int curStart = -1; foreach (var statement in _statements) { // CPython debugging treats multiple statements on the same line as a single step, we // match that behavior here. if (statement.Start.Line == curStart) { statements.Add(new DebugInfoRemovalExpression(statement, curStart)); } else { if (statement.CanThrow && statement.Start.IsValid) { statements.Add(UpdateLineNumber(statement.Start.Line)); } statements.Add(statement); } curStart = statement.Start.Line; } return Ast.Block(statements.ToReadOnlyCollection()); }
private GenericInterpretedBinder() { var invokeMethod = typeof(T).GetMethod("Invoke"); var methodParams = invokeMethod.GetParameters(); ReadOnlyCollectionBuilder <ParameterExpression> prms = new ReadOnlyCollectionBuilder <ParameterExpression>(methodParams.Length); ReadOnlyCollectionBuilder <Expression> invokePrms = new ReadOnlyCollectionBuilder <Expression>(methodParams.Length); for (int i = 0; i < methodParams.Length; i++) { var param = Expression.Parameter(methodParams[i].ParameterType); if (i == 0) { invokePrms.Add(Expression.Convert(param, typeof(CallSite <T>))); } else { invokePrms.Add(param); } prms.Add(param); } _parameters = prms.ToReadOnlyCollection(); _updateExpression = Expression.Block( Expression.Label(CallSiteBinder.UpdateLabel), Expression.Invoke( Expression.Property( invokePrms[0], typeof(CallSite <T>).GetDeclaredProperty("Update") ), invokePrms.ToReadOnlyCollection() ) ); }
internal static ReadOnlyCollection <T> ToReadOnly <T>(this IEnumerable <T> enumerable) { if (enumerable == null) { return(EmptyReadOnlyCollection <T> .Instance); } TrueReadOnlyCollection <T> onlys = enumerable as TrueReadOnlyCollection <T>; if (onlys != null) { return(onlys); } ReadOnlyCollectionBuilder <T> builder = enumerable as ReadOnlyCollectionBuilder <T>; if (builder != null) { return(builder.ToReadOnlyCollection()); } ICollection <T> is2 = enumerable as ICollection <T>; if (is2 == null) { return(new TrueReadOnlyCollection <T>(new List <T>(enumerable).ToArray())); } int count = is2.Count; if (count == 0) { return(EmptyReadOnlyCollection <T> .Instance); } T[] array = new T[count]; is2.CopyTo(array, 0); return(new TrueReadOnlyCollection <T>(array)); }
public override MSAst.Expression Reduce() { if (_statements.Length == 0) { return(GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span)); } ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); int curStart = -1; foreach (var statement in _statements) { // CPython debugging treats multiple statements on the same line as a single step, we // match that behavior here. int newline = GlobalParent.IndexToLocation(statement.StartIndex).Line; if (newline == curStart) { statements.Add(new DebugInfoRemovalExpression(statement, curStart)); } else { if (statement.CanThrow && newline != -1) { statements.Add(UpdateLineNumber(newline)); } statements.Add(statement); } curStart = newline; } return(Ast.Block(statements.ToReadOnlyCollection())); }
internal LoopFunc CreateDelegate() { var loop = (LoopExpression)Visit(_loop); var body = new ReadOnlyCollectionBuilder <Expression>(); var finallyClause = new ReadOnlyCollectionBuilder <Expression>(); foreach (var variable in _loopVariables) { LocalVariable local; if (!_outerVariables.TryGetValue(variable.Key, out local)) { local = _closureVariables[variable.Key]; } Expression elemRef = local.LoadFromArray(_frameDataVar, _frameClosureVar); if (local.InClosureOrBoxed) { var box = variable.Value.BoxStorage; Debug.Assert(box != null); body.Add(Expression.Assign(box, elemRef)); AddTemp(box); } else { // Always initialize the variable even if it is only written to. // If a write-only variable is actually not assigned during execution of the loop we will still write some value back. // This value must be the original value, which we assign at entry. body.Add(Expression.Assign(variable.Key, AstUtils.Convert(elemRef, variable.Key.Type))); if ((variable.Value.Access & ExpressionAccess.Write) != 0) { finallyClause.Add(Expression.Assign(elemRef, AstUtils.Box(variable.Key))); } AddTemp(variable.Key); } } if (finallyClause.Count > 0) { body.Add(Expression.TryFinally(loop, Expression.Block(finallyClause))); } else { body.Add(loop); } body.Add(Expression.Label(_returnLabel, Expression.Constant(_loopEndInstructionIndex - _loopStartInstructionIndex))); var lambda = Expression.Lambda <LoopFunc>( _temps != null ? Expression.Block(_temps.ToReadOnlyCollection(), body) : Expression.Block(body), new[] { _frameDataVar, _frameClosureVar, _frameVar } ); return(lambda.Compile()); }
private ReadOnlyCollection <Expression> ToTemp(ReadOnlyCollectionBuilder <Expression> block, ICollection <Expression> args) { var spilledArgs = new ReadOnlyCollectionBuilder <Expression>(args.Count); foreach (var arg in args) { spilledArgs.Add(ToTemp(block, arg)); } return(spilledArgs.ToReadOnlyCollection()); }
internal MSAst.Expression ReduceWorker() { ReadOnlyCollectionBuilder <MSAst.Expression> block = new ReadOnlyCollectionBuilder <MSAst.Expression>(); if (_body is ReturnStatement && (_languageFeatures == ModuleOptions.None || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret))) { // for simple eval's we can construct a simple tree which just // leaves the value on the stack. Return's can't exist in modules // so this is always safe. Debug.Assert(!_isModule); var ret = (ReturnStatement)_body; return(Ast.Block( Ast.DebugInfo( _document, ret.Expression.Start.Line, ret.Expression.Start.Column, ret.Expression.End.Line, ret.Expression.End.Column ), AstUtils.Convert( ret.Expression.Reduce(), typeof(object) ) )); } AddInitialiation(block); if (_isModule) { block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body)))); } block.Add(_body); MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, Body.CanThrow); // new ComboActionRewriter().VisitNode(Transform(ag)) body = AddModulePublishing(body); body = AddProfiling(body); body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object))); if (body.Type == typeof(void)) { body = Ast.Block(body, Ast.Constant(null)); } return(body); }
public void ReadOnlyCollectionBuilder_ToReadOnlyCollection(int length) { var rocb = new ReadOnlyCollectionBuilder <int>(); for (int i = 0; i < length; i++) { rocb.Add(i); } ReadOnlyCollection <int> collection = rocb.ToReadOnlyCollection(); Assert.Equal(length, collection.Count); Assert.True(Enumerable.Range(0, length).SequenceEqual(collection)); AssertEmpty(rocb); }
public void ReadOnlyCollectionBuilder_Ctor_Collection(IEnumerable <int> collection) { var rocb = new ReadOnlyCollectionBuilder <int>(collection); Assert.Equal(collection.Count(), rocb.Count); Assert.True(collection.SequenceEqual(rocb)); int[] array = rocb.ToArray(); Assert.Equal(collection.Count(), array.Length); Assert.True(collection.SequenceEqual(array)); ReadOnlyCollection <int> roc = rocb.ToReadOnlyCollection(); Assert.Equal(collection.Count(), roc.Count); Assert.True(collection.SequenceEqual(roc)); AssertEmpty(rocb); // ToReadOnlyCollection behavior is to empty the builder }
public override System.Linq.Expressions.Expression Reduce() { if (_statements.Length == 0) return GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span); ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(); foreach (var stmt in _statements) { var line = GlobalParent.IndexToLocation(stmt.StartIndex).Line; if (stmt.CanThrow && line != -1) { statements.Add(UpdateLineNumber(line)); } statements.Add(stmt); } return Ast.Block(statements.ToReadOnlyCollection()); }
internal override void FinishBind(TotemNameBinder binder) { if (_freeVars != null && _freeVars.Count > 0) { ReadOnlyCollectionBuilder<TotemVariable> closureVariables = new ReadOnlyCollectionBuilder<TotemVariable>(); _closureType = MutableTuple.MakeTupleType(_freeVars.Select(v => typeof(ClosureCell)).ToArray()); _localClosureTuple = Expression.Parameter(_closureType, "$closure"); for (var i = 0; i < _freeVars.Count; i++) { var variable = _freeVars[i]; _variableMapping[variable] = new ClosureExpression(variable, Expression.Property(_localClosureTuple, String.Format("Item{0:D3}", i)), null); closureVariables.Add(variable); } _closureVariables = closureVariables.ToReadOnlyCollection(); } if (_scopeVars != null) foreach (var local in _scopeVars) { if (local.Kind == VariableKind.Parameter) // handled in subclass continue; // scope variables, defined in this scope Debug.Assert(local.Kind == VariableKind.Local); Debug.Assert(local.Scope == this); if (local.AccessedInNestedScope) { // Closure variable _variableMapping[local] = new ClosureExpression(local, Expression.Parameter(typeof(ClosureCell), local.Name), null); } else { // Not used in nested function-scopes _variableMapping[local] = Expression.Parameter(typeof(object), local.Name); } } }
/// <summary> /// Creates the LambdaExpression which implements the body of the function. /// /// The functions signature is either "object Function(PythonFunction, ...)" /// where there is one object parameter for each user defined parameter or /// object Function(PythonFunction, object[]) for functions which take more /// than PythonCallTargets.MaxArgs arguments. /// </summary> private MSAst.LambdaExpression CreateFunctionLambda() { bool needsWrapperMethod = _parameters.Length > PythonCallTargets.MaxArgs; Delegate originalDelegate; Type delegateType = GetDelegateType(_parameters, needsWrapperMethod, out originalDelegate); MSAst.ParameterExpression localContext = null; ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>(); if (NeedsLocalsDictionary || ContainsNestedFreeVariables) { localContext = LocalCodeContextVariable; locals.Add(localContext); } MSAst.ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals); List<MSAst.Expression> init = new List<MSAst.Expression>(); foreach (var param in _parameters) { IPythonVariableExpression pyVar = GetVariableExpression(param.PythonVariable) as IPythonVariableExpression; if (pyVar != null) { var varInit = pyVar.Create(); if (varInit != null) { init.Add(varInit); } } } // Transform the parameters. init.Add(Ast.ClearDebugInfo(GlobalParent.Document)); locals.Add(PythonAst._globalContext); init.Add(Ast.Assign(PythonAst._globalContext, Ast.Call(_GetGlobalContext, _parentContext))); GlobalParent.PrepareScope(locals, init); // Create variables and references. Since references refer to // parameters, do this after parameters have been created. CreateFunctionVariables(locals, init); // Initialize parameters - unpack tuples. // Since tuples unpack into locals, this must be done after locals have been created. InitializeParameters(init, needsWrapperMethod, parameters); List<MSAst.Expression> statements = new List<MSAst.Expression>(); // add beginning sequence point statements.Add(GlobalParent.AddDebugInfo( AstUtils.Empty(), new SourceSpan(new SourceLocation(0, Start.Line, Start.Column), new SourceLocation(0, Start.Line, Int32.MaxValue)))); // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close(). // The exception traceback needs to come from the generator's method body, and so we must do the check and throw // from inside the generator. if (IsGenerator) { MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None); statements.Add(s1); } MSAst.ParameterExpression extracted = null; if (!IsGenerator && _canSetSysExcInfo) { // need to allocate the exception here so we don't share w/ exceptions made & freed // during the body. extracted = Ast.Parameter(typeof(Exception), "$ex"); locals.Add(extracted); } if (_body.CanThrow && !(_body is SuiteStatement) && _body.Start.IsValid) { statements.Add(UpdateLineNumber(_body.Start.Line)); } statements.Add(Body); MSAst.Expression body = Ast.Block(statements); // If this function can modify sys.exc_info() (_canSetSysExcInfo), then it must restore the result on finish. // // Wrap in // $temp = PythonOps.SaveCurrentException() // <body> // PythonOps.RestoreCurrentException($temp) // Skip this if we're a generator. For generators, the try finally is handled by the PythonGenerator class // before it's invoked. This is because the restoration must occur at every place the function returns from // a yield point. That's different than the finally semantics in a generator. if (extracted != null) { MSAst.Expression s = AstUtils.Try( Ast.Assign( extracted, Ast.Call(AstMethods.SaveCurrentException) ), body ).Finally( Ast.Call( AstMethods.RestoreCurrentException, extracted ) ); body = s; } if (_body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames) { body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(PythonFunction).GetProperty("__code__")), body); locals.Add(FunctionStackVariable); } body = AddProfiling(body); body = WrapScopeStatements(body, _body.CanThrow); body = Ast.Block(body, AstUtils.Empty()); body = AddReturnTarget(body); MSAst.Expression bodyStmt = body; if (localContext != null) { var createLocal = CreateLocalContext(_parentContext); init.Add( Ast.Assign( localContext, createLocal ) ); } init.Add(bodyStmt); bodyStmt = Ast.Block(init); // wrap a scope if needed bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt); return Ast.Lambda( delegateType, AddDefaultReturn(bodyStmt, typeof(object)), Name + "$" + Interlocked.Increment(ref _lambdaId), parameters ); }
public override MSAst.Expression Reduce() { MSAst.Expression destination = _dest; if (_expressions.Length == 0) { MSAst.Expression result; if (destination != null) { result = Ast.Call( AstMethods.PrintNewlineWithDest, Parent.LocalContext, destination ); } else { result = Ast.Call( AstMethods.PrintNewline, Parent.LocalContext ); } return GlobalParent.AddDebugInfo(result, Span); } else { // Create list for the individual statements ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(); // Store destination in a temp, if we have one MSAst.ParameterExpression temp = null; if (destination != null) { temp = Ast.Variable(typeof(object), "destination"); statements.Add(MakeAssignment(temp, destination)); destination = temp; } for (int i = 0; i < _expressions.Length; i++) { bool withComma = (i < _expressions.Length - 1 || _trailingComma);// ? "PrintComma" : "Print"; Expression current = _expressions[i]; MSAst.MethodCallExpression mce; if (destination != null) { mce = Ast.Call( withComma ? AstMethods.PrintCommaWithDest : AstMethods.PrintWithDest, Parent.LocalContext, destination, AstUtils.Convert(current, typeof(object)) ); } else { mce = Ast.Call( withComma ? AstMethods.PrintComma : AstMethods.Print, Parent.LocalContext, AstUtils.Convert(current, typeof(object)) ); } statements.Add(mce); } statements.Add(AstUtils.Empty()); MSAst.Expression res; if (temp != null) { res = Ast.Block(new[] { temp }, statements.ToReadOnlyCollection()); } else { res = Ast.Block(statements.ToReadOnlyCollection()); } return GlobalParent.AddDebugInfo(res, Span); } }
/// <summary> /// Creates the LambdaExpression which implements the body of the function. /// /// The functions signature is either "object Function(PythonFunction, ...)" /// where there is one object parameter for each user defined parameter or /// object Function(PythonFunction, object[]) for functions which take more /// than PythonCallTargets.MaxArgs arguments. /// </summary> private LightLambdaExpression CreateFunctionLambda() { bool needsWrapperMethod = _parameters.Length > PythonCallTargets.MaxArgs; Type delegateType = GetDelegateType(_parameters, needsWrapperMethod, out _); MSAst.ParameterExpression localContext = null; ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(); if (NeedsLocalContext) { localContext = LocalCodeContextVariable; locals.Add(localContext); } MSAst.ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals); List <MSAst.Expression> init = new List <MSAst.Expression>(); foreach (var param in _parameters) { if (GetVariableExpression(param.PythonVariable) is IPythonVariableExpression pyVar) { var varInit = pyVar.Create(); if (varInit != null) { init.Add(varInit); } } } // Transform the parameters. init.Add(Ast.ClearDebugInfo(GlobalParent.Document)); locals.Add(PythonAst._globalContext); init.Add(Ast.Assign(PythonAst._globalContext, new GetGlobalContextExpression(_parentContext))); GlobalParent.PrepareScope(locals, init); // Create variables and references. Since references refer to // parameters, do this after parameters have been created. CreateFunctionVariables(locals, init); // Initialize parameters - unpack tuples. // Since tuples unpack into locals, this must be done after locals have been created. InitializeParameters(init, needsWrapperMethod, parameters); List <MSAst.Expression> statements = new List <MSAst.Expression>(); // add beginning sequence point var start = GlobalParent.IndexToLocation(StartIndex); statements.Add(GlobalParent.AddDebugInfo( AstUtils.Empty(), new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, int.MaxValue)))); // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close(). // The exception traceback needs to come from the generator's method body, and so we must do the check and throw // from inside the generator. if (IsGenerator) { MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None); statements.Add(s1); } if (Body.CanThrow && !(Body is SuiteStatement) && Body.StartIndex != -1) { statements.Add(UpdateLineNumber(GlobalParent.IndexToLocation(Body.StartIndex).Line)); } statements.Add(Body); MSAst.Expression body = Ast.Block(statements); if (Body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames) { body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(PythonFunction).GetProperty(nameof(PythonFunction.__code__))), body); locals.Add(FunctionStackVariable); } body = AddProfiling(body); body = WrapScopeStatements(body, Body.CanThrow); body = Ast.Block(body, AstUtils.Empty()); body = AddReturnTarget(body); MSAst.Expression bodyStmt = body; if (localContext != null) { var createLocal = CreateLocalContext(_parentContext); init.Add( Ast.Assign( localContext, createLocal ) ); } init.Add(bodyStmt); bodyStmt = Ast.Block(init); // wrap a scope if needed bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt); return(AstUtils.LightLambda( typeof(object), delegateType, AddDefaultReturn(bodyStmt, typeof(object)), Name + "$" + Interlocked.Increment(ref _lambdaId), parameters )); }
public override MSAst.Expression Reduce() { MSAst.Expression destination = _dest; if (_expressions.Length == 0) { MSAst.Expression result; if (destination != null) { result = Ast.Call( AstMethods.PrintNewlineWithDest, Parent.LocalContext, destination ); } else { result = Ast.Call( AstMethods.PrintNewline, Parent.LocalContext ); } return(GlobalParent.AddDebugInfo(result, Span)); } else { // Create list for the individual statements ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); // Store destination in a temp, if we have one MSAst.ParameterExpression temp = null; if (destination != null) { temp = Ast.Variable(typeof(object), "destination"); statements.Add(MakeAssignment(temp, destination)); destination = temp; } for (int i = 0; i < _expressions.Length; i++) { bool withComma = (i < _expressions.Length - 1 || _trailingComma);// ? "PrintComma" : "Print"; Expression current = _expressions[i]; MSAst.MethodCallExpression mce; if (destination != null) { mce = Ast.Call( withComma ? AstMethods.PrintCommaWithDest : AstMethods.PrintWithDest, Parent.LocalContext, destination, AstUtils.Convert(current, typeof(object)) ); } else { mce = Ast.Call( withComma ? AstMethods.PrintComma : AstMethods.Print, Parent.LocalContext, AstUtils.Convert(current, typeof(object)) ); } statements.Add(mce); } statements.Add(AstUtils.Empty()); MSAst.Expression res; if (temp != null) { res = Ast.Block(new[] { temp }, statements.ToReadOnlyCollection()); } else { res = Ast.Block(statements.ToReadOnlyCollection()); } return(GlobalParent.AddDebugInfo(res, Span)); } }
/// <summary> /// WithStatement is translated to the DLR AST equivalent to /// the following Python code snippet (from with statement spec): /// /// mgr = (EXPR) /// exit = mgr.__exit__ # Not calling it yet /// value = mgr.__enter__() /// exc = True /// try: /// VAR = value # Only if "as VAR" is present /// BLOCK /// except: /// # The exceptional case is handled here /// exc = False /// if not exit(*sys.exc_info()): /// raise /// # The exception is swallowed if exit() returns true /// finally: /// # The normal and non-local-goto cases are handled here /// if exc: /// exit(None, None, None) /// /// </summary> public override MSAst.Expression Reduce() { // Five statements in the result... ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(6); ReadOnlyCollectionBuilder<MSAst.ParameterExpression> variables = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>(6); MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with"); variables.Add(lineUpdated); //****************************************************************** // 1. mgr = (EXPR) //****************************************************************** MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager"); variables.Add(manager); statements.Add( GlobalParent.AddDebugInfo( Ast.Assign( manager, _contextManager ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 2. exit = mgr.__exit__ # Not calling it yet //****************************************************************** MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit"); variables.Add(exit); statements.Add( MakeAssignment( exit, GlobalParent.Get( "__exit__", manager ) ) ); //****************************************************************** // 3. value = mgr.__enter__() //****************************************************************** MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value"); variables.Add(value); statements.Add( GlobalParent.AddDebugInfoAndVoid( MakeAssignment( value, Parent.Invoke( new CallSignature(0), Parent.LocalContext, GlobalParent.Get( "__enter__", manager ) ) ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 4. exc = True //****************************************************************** MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc"); variables.Add(exc); statements.Add( MakeAssignment( exc, AstUtils.Constant(true) ) ); //****************************************************************** // 5. The final try statement: // // try: // VAR = value # Only if "as VAR" is present // BLOCK // except: // # The exceptional case is handled here // exc = False // if not exit(*sys.exc_info()): // raise // # The exception is swallowed if exit() returns true // finally: // # The normal and non-local-goto cases are handled here // if exc: // exit(None, None, None) //****************************************************************** MSAst.ParameterExpression exception; MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List<DynamicStackFrame>), "$nestedFrames"); variables.Add(nestedFrames); statements.Add( // try: AstUtils.Try( AstUtils.Try(// try statement body PushLineUpdated(false, lineUpdated), _var != null ? (MSAst.Expression)Ast.Block( // VAR = value _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None), // BLOCK _body, AstUtils.Empty() ) : // BLOCK (MSAst.Expression)_body // except:, // try statement location ).Catch(exception = Ast.Variable(typeof(Exception), "exception"), // Python specific exception handling code TryStatement.GetTracebackHeader( this, exception, GlobalParent.AddDebugInfoAndVoid( Ast.Block( // exc = False MakeAssignment( exc, AstUtils.Constant(false) ), Ast.Assign( nestedFrames, Ast.Call(AstMethods.GetAndClearDynamicStackFrames) ), // if not exit(*sys.exc_info()): // raise AstUtils.IfThen( GlobalParent.Convert( typeof(bool), ConversionResultKind.ExplicitCast, GlobalParent.Operation( typeof(bool), PythonOperationKind.IsFalse, MakeExitCall(exit, exception) ) ), UpdateLineUpdated(true), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), Ast.Throw( Ast.Call( AstMethods.MakeRethrowExceptionWorker, exception ) ) ) ), _body.Span ) ), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), PopLineUpdated(lineUpdated), Ast.Empty() ) // finally: ).Finally( // if exc: // exit(None, None, None) AstUtils.IfThen( exc, GlobalParent.AddDebugInfoAndVoid( Ast.Block( Ast.Dynamic( GlobalParent.PyContext.Invoke( new CallSignature(3) // signature doesn't include function ), typeof(object), new MSAst.Expression[] { Parent.LocalContext, exit, AstUtils.Constant(null), AstUtils.Constant(null), AstUtils.Constant(null) } ), Ast.Empty() ), _contextManager.Span ) ) ) ); statements.Add(AstUtils.Empty()); return Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection()); }
internal MSAst.Expression ReduceWorker() { var retStmt = _body as ReturnStatement; if (retStmt != null) { var ret = (ReturnStatement)_body; Ast simpleBody; simpleBody = retStmt.Expression.Reduce(); var start = IndexToLocation(ret.Expression.StartIndex); var end = IndexToLocation(ret.Expression.EndIndex); return Ast.Block( Ast.DebugInfo( _document, start.Line, start.Column, end.Line, end.Column ), AstUtils.Convert(simpleBody, typeof(object)) ); } ReadOnlyCollectionBuilder<MSAst.Expression> block = new ReadOnlyCollectionBuilder<MSAst.Expression>(); if (!(_body is SuiteStatement) && _body.CanThrow) { // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement // at the top level we can miss some line number updates. block.Add(UpdateLineNumber(_body.Start.Line)); } block.Add(_body); MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, Body.CanThrow); // new ComboActionRewriter().VisitNode(Transform(ag)) body = AddProfiling(body); body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object))); if (body.Type == typeof(void)) { body = Ast.Block(body, Ast.Constant(null)); } return body; }
public void TestReadOnlyCollectionBuilder() { int cnt = 0; // Empty ReadOnlyCollectionBuilder <int> a = new ReadOnlyCollectionBuilder <int>(); AreEqual(0, a.Count); AreEqual(0, a.Capacity); AreEqual(a.ToReadOnlyCollection().Count, 0); AreEqual(a.ToReadOnlyCollection().Count, 0); // Simple case a.Add(5); AreEqual(1, a.Count); AreEqual(4, a.Capacity); AreEqual(a.ToReadOnlyCollection()[0], 5); AreEqual(a.ToReadOnlyCollection().Count, 0); // Will reset a = new ReadOnlyCollectionBuilder <int>(0); AreEqual(0, a.Count); AssertError <ArgumentException>(() => a = new ReadOnlyCollectionBuilder <int>(-1)); a = new ReadOnlyCollectionBuilder <int>(5); for (int i = 1; i <= 10; i++) { a.Add(i); } AreEqual(10, a.Capacity); System.Collections.ObjectModel.ReadOnlyCollection <int> readonlyCollection = a.ToReadOnlyCollection(); AreEqual(0, a.Capacity); AreEqual(readonlyCollection.Count, 10); ReadOnlyCollectionBuilder <int> b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); b.Add(11); AreEqual(b.Count, 11); AssertError <ArgumentException>(() => a = new ReadOnlyCollectionBuilder <int>(null)); // Capacity tests b.Capacity = 11; AssertError <ArgumentException>(() => b.Capacity = 10); b.Capacity = 50; AreEqual(b.Count, 11); AreEqual(b.Capacity, 50); // IndexOf cases AreEqual(b.IndexOf(5), 4); AreEqual(b[4], 5); a = new ReadOnlyCollectionBuilder <int>(); AreEqual(a.IndexOf(5), -1); // Insert cases b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); AssertError <ArgumentException>(() => b.Insert(11, 11)); b.Insert(2, 24); AreEqual(b.Count, 11); AreEqual(b[1], 2); AreEqual(b[2], 24); AreEqual(b[3], 3); b.Insert(11, 1234); AssertError <ArgumentException>(() => b.Insert(-1, 55)); AreEqual(b[11], 1234); AreEqual(b.ToReadOnlyCollection().Count, 12); // Remove b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); AreEqual(b.Remove(2), true); AreEqual(b[0], 1); AreEqual(b[1], 3); AreEqual(b[2], 4); AreEqual(b.Remove(2), false); // RemoveAt b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); b.RemoveAt(2); AreEqual(b[1], 2); AreEqual(b[2], 4); AreEqual(b[3], 5); AssertError <ArgumentException>(() => b.RemoveAt(-5)); AssertError <ArgumentException>(() => b.RemoveAt(9)); // Clear b.Clear(); AreEqual(b.Count, 0); AreEqual(b.ToReadOnlyCollection().Count, 0); b = new ReadOnlyCollectionBuilder <int>(); b.Clear(); AreEqual(b.Count, 0); // Contains b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); AreEqual(b.Contains(5), true); AreEqual(b.Contains(-3), false); ReadOnlyCollectionBuilder <object> c = new ReadOnlyCollectionBuilder <object>(); c.Add("HI"); AreEqual(c.Contains("HI"), true); AreEqual(c.Contains(null), false); c.Add(null); AreEqual(c.Contains(null), true); // CopyTo b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); int[] ary = new int[10]; b.CopyTo(ary, 0); AreEqual(ary[0], 1); AreEqual(ary[9], 10); // Reverse b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); b.Reverse(); // 1..10 cnt = 10; for (int i = 0; i < 10; i++) { AreEqual(b[i], cnt--); } b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); AssertError <ArgumentException>(() => b.Reverse(-1, 5)); AssertError <ArgumentException>(() => b.Reverse(5, -1)); b.Reverse(3, 3); // 1,2,3,4,5,6,7,8,9.10 // 1,2,3,6,5,4,7,8,9,10 AreEqual(b[1], 2); AreEqual(b[2], 3); AreEqual(b[3], 6); AreEqual(b[4], 5); AreEqual(b[5], 4); AreEqual(b[6], 7); // ToArray b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); int[] intAry = b.ToArray(); AreEqual(intAry[0], 1); AreEqual(intAry[9], 10); b = new ReadOnlyCollectionBuilder <int>(); intAry = b.ToArray(); AreEqual(intAry.Length, 0); // IEnumerable cases b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); cnt = 0; foreach (int i in b) { cnt++; } AreEqual(cnt, 10); b = new ReadOnlyCollectionBuilder <int>(); cnt = 0; foreach (int i in b) { cnt++; } AreEqual(cnt, 0); // Error case AssertError <InvalidOperationException>(() => ChangeWhileEnumeratingAdd()); AssertError <InvalidOperationException>(() => ChangeWhileEnumeratingRemove()); // IList members b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); System.Collections.IList lst = b; // IsReadOnly AreEqual(lst.IsReadOnly, false); // Add AreEqual(lst.Add(11), 10); AreEqual(lst.Count, 11); AssertError <ArgumentException>(() => lst.Add("MOM")); AssertError <ArgumentException>(() => lst.Add(null)); c = new ReadOnlyCollectionBuilder <object>(); c.Add("HI"); c.Add(null); lst = c; lst.Add(null); AreEqual(lst.Count, 3); // Contains lst = b; AreEqual(lst.Contains(5), true); AreEqual(lst.Contains(null), false); lst = c; AreEqual(lst.Contains("HI"), true); AreEqual(lst.Contains("hi"), false); AreEqual(lst.Contains(null), true); // IndexOf lst = b; AreEqual(lst.IndexOf(null), -1); AreEqual(lst.IndexOf(1234), -1); AreEqual(lst.IndexOf(5), 4); // Insert b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); lst = b; AssertError <ArgumentException>(() => lst.Insert(11, 11)); lst.Insert(2, 24); AreEqual(lst.Count, 11); AreEqual(lst[1], 2); AreEqual(lst[2], 24); AreEqual(lst[3], 3); lst.Insert(11, 1234); AssertError <ArgumentException>(() => lst.Insert(-1, 55)); AreEqual(lst[11], 1234); AssertError <ArgumentException>(() => lst.Insert(3, "MOM")); // IsFixedSize AreEqual(lst.IsFixedSize, false); // Remove b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); lst = b; lst.Remove(2); AreEqual(lst[0], 1); AreEqual(lst[1], 3); AreEqual(lst[2], 4); lst.Remove(2); // Indexing lst[3] = 234; AreEqual(lst[3], 234); AssertError <ArgumentException>(() => lst[3] = null); AssertError <ArgumentException>(() => lst[3] = "HI"); // ICollection<T> // IsReadOnly System.Collections.Generic.ICollection <int> col = b; AreEqual(col.IsReadOnly, false); // ICollection b = new ReadOnlyCollectionBuilder <int>(readonlyCollection); System.Collections.ICollection col2 = b; AreEqual(col2.IsSynchronized, false); Assert(col2.SyncRoot != null); intAry = new int[10]; col2.CopyTo(intAry, 0); AreEqual(intAry[0], 1); AreEqual(intAry[9], 10); string[] str = new string[50]; AssertError <ArrayTypeMismatchException>(() => col2.CopyTo(str, 0)); }
internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op) { // if we just have a simple named multi-assignment (e.g. a, b = 1,2) // then go ahead and step over the entire statement at once. If we have a // more complex statement (e.g. a.b, c.d = 1, 2) then we'll step over the // sets individually as they could be property sets the user wants to step // into. TODO: Enable stepping of the right hand side? bool emitIndividualSets = false; foreach (Expression e in _items) { if (IsComplexAssignment(e)) { emitIndividualSets = true; break; } } SourceSpan rightSpan = SourceSpan.None; SourceSpan leftSpan = (Span.Start.IsValid && span.IsValid) ? new SourceSpan(Span.Start, span.End) : SourceSpan.None; SourceSpan totalSpan = SourceSpan.None; if (emitIndividualSets) { rightSpan = span; leftSpan = SourceSpan.None; totalSpan = (Span.Start.IsValid && span.IsValid) ? new SourceSpan(Span.Start, span.End) : SourceSpan.None; } // 1. Evaluate the expression and assign the value to the temp. MSAst.ParameterExpression right_temp = Ast.Variable(typeof(object), "unpacking"); // 2. Add the assignment "right_temp = right" into the suite/block MSAst.Expression assignStmt1 = MakeAssignment(right_temp, right); // 3. Call GetEnumeratorValues on the right side (stored in temp) MSAst.Expression enumeratorValues = Expression.Convert(LightExceptions.CheckAndThrow( Expression.Call( emitIndividualSets ? AstMethods.GetEnumeratorValues : AstMethods.GetEnumeratorValuesNoComplexSets, // method // arguments Parent.LocalContext, right_temp, AstUtils.Constant(_items.Length) ) ), typeof(object[])); // 4. Create temporary variable for the array MSAst.ParameterExpression array_temp = Ast.Variable(typeof(object[]), "array"); // 5. Assign the value of the method call (mce) into the array temp // And add the assignment "array_temp = Ops.GetEnumeratorValues(...)" into the block MSAst.Expression assignStmt2 = MakeAssignment( array_temp, enumeratorValues, rightSpan ); ReadOnlyCollectionBuilder<MSAst.Expression> sets = new ReadOnlyCollectionBuilder<MSAst.Expression>(_items.Length + 1); for (int i = 0; i < _items.Length; i++) { // target = array_temp[i] Expression target = _items[i]; if (target == null) { continue; } // 6. array_temp[i] MSAst.Expression element = Ast.ArrayAccess( array_temp, // array expression AstUtils.Constant(i) // index ); // 7. target = array_temp[i], and add the transformed assignment into the list of sets MSAst.Expression set = target.TransformSet( emitIndividualSets ? // span target.Span : SourceSpan.None, element, PythonOperationKind.None ); sets.Add(set); } // 9. add the sets as their own block so they can be marked as a single span, if necessary. sets.Add(AstUtils.Empty()); MSAst.Expression itemSet = GlobalParent.AddDebugInfo(Ast.Block(sets.ToReadOnlyCollection()), leftSpan); // 10. Return the suite statement (block) return GlobalParent.AddDebugInfo(Ast.Block(new[] { array_temp, right_temp }, assignStmt1, assignStmt2, itemSet, AstUtils.Empty()), totalSpan); }
/// <summary> /// WithStatement is translated to the DLR AST equivalent to /// the following Python code snippet (from with statement spec): /// /// mgr = (EXPR) /// exit = mgr.__exit__ # Not calling it yet /// value = mgr.__enter__() /// exc = True /// try: /// VAR = value # Only if "as VAR" is present /// BLOCK /// except: /// # The exceptional case is handled here /// exc = False /// if not exit(*sys.exc_info()): /// raise /// # The exception is swallowed if exit() returns true /// finally: /// # The normal and non-local-goto cases are handled here /// if exc: /// exit(None, None, None) /// /// </summary> public override MSAst.Expression Reduce() { // Five statements in the result... ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(6); ReadOnlyCollectionBuilder <MSAst.ParameterExpression> variables = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(6); MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with"); variables.Add(lineUpdated); //****************************************************************** // 1. mgr = (EXPR) //****************************************************************** MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager"); variables.Add(manager); statements.Add( GlobalParent.AddDebugInfo( Ast.Assign( manager, _contextManager ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 2. exit = mgr.__exit__ # Not calling it yet //****************************************************************** MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit"); variables.Add(exit); statements.Add( MakeAssignment( exit, GlobalParent.Get( "__exit__", manager ) ) ); //****************************************************************** // 3. value = mgr.__enter__() //****************************************************************** MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value"); variables.Add(value); statements.Add( GlobalParent.AddDebugInfoAndVoid( MakeAssignment( value, Parent.Invoke( new CallSignature(0), Parent.LocalContext, GlobalParent.Get( "__enter__", manager ) ) ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 4. exc = True //****************************************************************** MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc"); variables.Add(exc); statements.Add( MakeAssignment( exc, AstUtils.Constant(true) ) ); //****************************************************************** // 5. The final try statement: // // try: // VAR = value # Only if "as VAR" is present // BLOCK // except: // # The exceptional case is handled here // exc = False // if not exit(*sys.exc_info()): // raise // # The exception is swallowed if exit() returns true // finally: // # The normal and non-local-goto cases are handled here // if exc: // exit(None, None, None) //****************************************************************** MSAst.ParameterExpression exception; MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List <DynamicStackFrame>), "$nestedFrames"); variables.Add(nestedFrames); statements.Add( // try: AstUtils.Try( AstUtils.Try(// try statement body PushLineUpdated(false, lineUpdated), _var != null ? (MSAst.Expression)Ast.Block( // VAR = value _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None), // BLOCK _body, AstUtils.Empty() ) : // BLOCK (MSAst.Expression)_body // except:, // try statement location ).Catch(exception = Ast.Variable(typeof(Exception), "exception"), // Python specific exception handling code TryStatement.GetTracebackHeader( this, exception, GlobalParent.AddDebugInfoAndVoid( Ast.Block( // exc = False MakeAssignment( exc, AstUtils.Constant(false) ), Ast.Assign( nestedFrames, Ast.Call(AstMethods.GetAndClearDynamicStackFrames) ), // if not exit(*sys.exc_info()): // raise AstUtils.IfThen( GlobalParent.Convert( typeof(bool), ConversionResultKind.ExplicitCast, GlobalParent.Operation( typeof(bool), PythonOperationKind.IsFalse, MakeExitCall(exit, exception) ) ), UpdateLineUpdated(true), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), Ast.Throw( Ast.Call( AstMethods.MakeRethrowExceptionWorker, exception ) ) ) ), _body.Span ) ), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), PopLineUpdated(lineUpdated), Ast.Empty() ) // finally: ).Finally( // if exc: // exit(None, None, None) AstUtils.IfThen( exc, GlobalParent.AddDebugInfoAndVoid( Ast.Block( Ast.Dynamic( GlobalParent.PyContext.Invoke( new CallSignature(3) // signature doesn't include function ), typeof(object), new MSAst.Expression[] { Parent.LocalContext, exit, AstUtils.Constant(null), AstUtils.Constant(null), AstUtils.Constant(null) } ), Ast.Empty() ), _contextManager.Span ) ) ) ); statements.Add(AstUtils.Empty()); return(Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection())); }
public void CompleteLoading() { _tcs.TrySetResult(_bufferBuilder.ToReadOnlyCollection()); _navigationManager.LocationChanged += OnLocationChanged; }
internal Expression ReduceWorker() { var retStmt = _body as ReturnStmt; ReadOnlyCollectionBuilder<Expression> block = new ReadOnlyCollectionBuilder<Expression>(); AddInitialization(block); if (!(_body is BlockStmt) && _body.CanThrow) { // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement // at the top level we can miss some line number updates. block.Add(UpdateLineNumber(_body.Start.Line)); } block.Add(_body); Expression body = Expression.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, _body.CanThrow); body = AddModulePublishing(body); body = AddProfiling(body); if ((((TotemCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0) { body = LightExceptions.Rewrite(body); } body = Expression.Label(FunctionDefinition._returnLabel, Utils.Convert(body, typeof(object))); if (body.Type == typeof(void)) body = Expression.Block(body, Expression.Constant(null)); return body; }
private static ReadOnlyDictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>> GetOperators(TotemType type) { Debug.Assert(type.IsSystemType, "Should only be called for system types as totem types should populate operators by themselves"); if(!type.IsTotemType) return new ReadOnlyDictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>( new Dictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>()); Dictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>> ops = new Dictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>(); var t = TotemBinder.GetProxyType(type.UnderlyingSystemType) ?? type.UnderlyingSystemType; var methods = t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly) .GroupBy(m => m.Name); var names = Enum.GetNames(typeof(TotemOperationKind)); foreach (var methodGroup in methods) { var builder = new ReadOnlyCollectionBuilder<MethodOrFunction>(); foreach (var method in methodGroup) { if(method.IsSpecialName) builder.Add(new MethodOrFunction(method)); } if (builder.Count > 0) { TotemOperationKind kind; if (Enum.TryParse<TotemOperationKind>(methodGroup.Key, out kind)) ops.Add(kind, builder.ToReadOnlyCollection()); } } return new ReadOnlyDictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>(ops); }
private LightLambdaExpression CreateFunctionLambda() { bool needsWrapperMethod = _parameters.Length > TotemCallTargets.MAX_ARGS; Delegate originalDelegate; Type delegateType = GetDelegateType(_parameters, needsWrapperMethod, out originalDelegate); ReadOnlyCollectionBuilder<ParameterExpression> locals = new ReadOnlyCollectionBuilder<ParameterExpression>(); ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals); List<Expression> init = new List<Expression>(); foreach (var param in _parameters) { ITotemVariableExpression toVar = GetVariableExpression(param.TotemVariable) as ITotemVariableExpression; if (toVar != null) { var varInit = toVar.Create(); if (varInit != null) init.Add(varInit); } } // Transform the parameters. init.Add(Expression.ClearDebugInfo(GlobalParent.Document)); locals.Add(TotemAst._globalContext); init.Add(Expression.Assign(TotemAst._globalContext, new GetGlobalContextExpression(_parentContext))); if (IsClosure) { locals.Add(LocalClosureTuple); init.Add( Expression.Assign( LocalClosureTuple, Utils.Convert( _localClosure, LocalClosureTupleType ) ) ); } GlobalParent.PrepareScope(locals, init); // Create variables and references. Since references refer to // parameters, do this after parameters have been created. CreateFunctionVariables(locals, init); // Initialize parameters - unpack tuples. // Since tuples unpack into locals, this must be done after locals have been created. InitializeParameters(init, needsWrapperMethod, parameters); List<Expression> statements = new List<Expression>(); // Add beginning sequence point var start = GlobalParent.IndexToLocation(StartIndex); statements.Add( GlobalParent.AddDebugInfo( Utils.Empty(), new SourceSpan( new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, Int32.MaxValue) ) ) ); // For generators, we need to do a check before the first statement for Generator.Throw / Generator.Close. // The exception traceback needs to come from the generator's method body, and so we must do the check and throw // from inside the generator. if (IsGenerator) { //Expression s1 = YieldExpr.CreateCheckThrowExpression(SourceSpan.None); //statements.Add(s1); throw new NotImplementedException("Generators"); } if (_body.CanThrow && !(_body is BlockStmt) && _body.StartIndex != -1) { statements.Add( UpdateLineNumber( GlobalParent.IndexToLocation(_body.StartIndex).Line ) ); } statements.Add(Body); Expression body = Expression.Block(statements); body = AddProfiling(body); body = WrapScopeStatements(body, _body.CanThrow); body = Expression.Block(body, Utils.Empty()); body = AddReturnTarget(body); Expression bodyStmt = body; init.Add(bodyStmt); bodyStmt = Expression.Block(init); // wrap a scope if needed bodyStmt = Expression.Block(locals.ToReadOnlyCollection(), bodyStmt); return Utils.LightLambda( typeof(object), delegateType, AddDefaultReturn(bodyStmt, typeof(object)), Name + "$" + Interlocked.Increment(ref _lambdaId), parameters ); }
internal ReadOnlyCollection<MSAst.Expression> Transform(Statement/*!*/[]/*!*/ from) { Debug.Assert(from != null); var to = new ReadOnlyCollectionBuilder<MSAst.Expression>(from.Length + 1); SourceLocation start = SourceLocation.Invalid; for (int i = 0; i < from.Length; i++) { Debug.Assert(from[i] != null); to.Add(TransformMaybeSingleLineSuite(from[i], start)); start = from[i].Start; } to.Add(AstUtils.Empty()); return to.ToReadOnlyCollection(); }
public static LightDynamicExpression LightDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollectionBuilder<Expression> arguments) { ContractUtils.RequiresNotNull(arguments, "arguments"); return new LightTypedDynamicExpressionN(binder, returnType, arguments.ToReadOnlyCollection()); }
/// <summary> /// Creates the LambdaExpression which implements the body of the function. /// /// The functions signature is either "object Function(PythonFunction, ...)" /// where there is one object parameter for each user defined parameter or /// object Function(PythonFunction, object[]) for functions which take more /// than PythonCallTargets.MaxArgs arguments. /// </summary> private LightLambdaExpression CreateFunctionLambda() { bool needsWrapperMethod = _parameters.Length > PythonCallTargets.MaxArgs; Delegate originalDelegate; Type delegateType = GetDelegateType(_parameters, needsWrapperMethod, out originalDelegate); MSAst.ParameterExpression localContext = null; ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(); if (NeedsLocalContext) { localContext = LocalCodeContextVariable; locals.Add(localContext); } MSAst.ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals); List <MSAst.Expression> init = new List <MSAst.Expression>(); foreach (var param in _parameters) { IPythonVariableExpression pyVar = GetVariableExpression(param.PythonVariable) as IPythonVariableExpression; if (pyVar != null) { var varInit = pyVar.Create(); if (varInit != null) { init.Add(varInit); } } } // Transform the parameters. init.Add(Ast.ClearDebugInfo(GlobalParent.Document)); locals.Add(PythonAst._globalContext); init.Add(Ast.Assign(PythonAst._globalContext, new GetGlobalContextExpression(_parentContext))); GlobalParent.PrepareScope(locals, init); // Create variables and references. Since references refer to // parameters, do this after parameters have been created. CreateFunctionVariables(locals, init); // If the __class__ variable is used the a class method then we need to initialize it. // This must be done before parameter initialization (in case one of the parameters is called __class__). ClassDefinition parent = FindParentOfType <ClassDefinition>(); PythonVariable pVar; if (parent != null && TryGetVariable("__class__", out pVar)) { init.Add( AssignValue( GetVariableExpression(pVar), Ast.Call(AstMethods.LookupName, parent.Parent.LocalContext, Ast.Constant(parent.Name)) ) ); } // Initialize parameters - unpack tuples. // Since tuples unpack into locals, this must be done after locals have been created. InitializeParameters(init, needsWrapperMethod, parameters); List <MSAst.Expression> statements = new List <MSAst.Expression>(); // add beginning sequence point var start = GlobalParent.IndexToLocation(StartIndex); statements.Add(GlobalParent.AddDebugInfo( AstUtils.Empty(), new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, Int32.MaxValue)))); // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close(). // The exception traceback needs to come from the generator's method body, and so we must do the check and throw // from inside the generator. if (IsGenerator) { MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None); statements.Add(s1); } MSAst.ParameterExpression extracted = null; if (!IsGenerator && _canSetSysExcInfo) { // need to allocate the exception here so we don't share w/ exceptions made & freed // during the body. extracted = Ast.Parameter(typeof(Exception), "$ex"); locals.Add(extracted); } if (_body.CanThrow && !(_body is SuiteStatement) && _body.StartIndex != -1) { statements.Add(UpdateLineNumber(GlobalParent.IndexToLocation(_body.StartIndex).Line)); } statements.Add(Body); MSAst.Expression body = Ast.Block(statements); // If this function can modify sys.exc_info() (_canSetSysExcInfo), then it must restore the result on finish. // // Wrap in // $temp = PythonOps.SaveCurrentException() // <body> // PythonOps.RestoreCurrentException($temp) // Skip this if we're a generator. For generators, the try finally is handled by the PythonGenerator class // before it's invoked. This is because the restoration must occur at every place the function returns from // a yield point. That's different than the finally semantics in a generator. if (extracted != null) { MSAst.Expression s = AstUtils.Try( Ast.Assign( extracted, Ast.Call(AstMethods.SaveCurrentException) ), body ).Finally( Ast.Call( AstMethods.RestoreCurrentException, extracted ) ); body = s; } if (_body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames) { body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(PythonFunction).GetProperty("__code__")), body); locals.Add(FunctionStackVariable); } body = AddProfiling(body); body = WrapScopeStatements(body, _body.CanThrow); body = Ast.Block(body, AstUtils.Empty()); body = AddReturnTarget(body); MSAst.Expression bodyStmt = body; if (localContext != null) { var createLocal = CreateLocalContext(_parentContext); init.Add( Ast.Assign( localContext, createLocal ) ); } init.Add(bodyStmt); bodyStmt = Ast.Block(init); // wrap a scope if needed bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt); return(AstUtils.LightLambda( typeof(object), delegateType, AddDefaultReturn(bodyStmt, typeof(object)), Name + "$" + Interlocked.Increment(ref _lambdaId), parameters )); }
internal override MSAst.Expression Transform(AstGenerator ag) { MSAst.Expression destination = ag.TransformAsObject(_dest); if (_expressions.Length == 0) { MSAst.Expression result; if (destination != null) { result = Ast.Call( AstGenerator.GetHelperMethod("PrintNewlineWithDest"), ag.LocalContext, destination ); } else { result = Ast.Call( AstGenerator.GetHelperMethod("PrintNewline"), ag.LocalContext ); } return ag.AddDebugInfo(result, Span); } else { // Create list for the individual statements ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(); // Store destination in a temp, if we have one if (destination != null) { MSAst.ParameterExpression temp = ag.GetTemporary("destination"); statements.Add( AstGenerator.MakeAssignment(temp, destination) ); destination = temp; } for (int i = 0; i < _expressions.Length; i++) { string method = (i < _expressions.Length - 1 || _trailingComma) ? "PrintComma" : "Print"; Expression current = _expressions[i]; MSAst.MethodCallExpression mce; if (destination != null) { mce = Ast.Call( AstGenerator.GetHelperMethod(method + "WithDest"), ag.LocalContext, destination, ag.TransformAsObject(current) ); } else { mce = Ast.Call( AstGenerator.GetHelperMethod(method), ag.LocalContext, ag.TransformAsObject(current) ); } statements.Add(mce); } statements.Add(AstUtils.Empty()); return ag.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span); } }
//internal static Func<TotemFunction, TotemArgs, object> FunctionDelegate = new Func<TotemFunction, TotemArgs, object>((fn, args) => //{ // fn.Code.LazyCompileFirstTarget(fn); // return ((Func<TotemFunction, TotemArgs, object>)fn.Code.Target)(fn, args); //}); /// <summary> /// Creates the LambdaExpression which implements the body of the function. /// /// The functions signature is either "object Function(PythonFunction, ...)" /// where there is one object parameter for each user defined parameter or /// object Function(PythonFunction, object[]) for functions which take more /// than PythonCallTargets.MaxArgs arguments. /// </summary> private LightLambdaExpression CreateFunctionLambda() { Type delegateType = typeof(Func<TotemFunction, TotemArgs, object>); MSAst.ParameterExpression localContext = null; ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>(); if (NeedsLocalContext || CanThrow) { localContext = LocalCodeContextVariable; locals.Add(localContext); } MSAst.ParameterExpression[] parameters = CreateParameters(locals); List<MSAst.Expression> init = new List<Ast>(); foreach (var param in _parameters) { ITotemVariableExpression toVar = GetVariableExpression(param.TotemVariable) as ITotemVariableExpression; if (toVar != null) { var varInit = toVar.Create(); if (varInit != null) init.Add(varInit); } } // Transform the parameters. init.Add(Ast.ClearDebugInfo(GlobalParent.Document)); locals.Add(TotemAst._globalContext); init.Add(Ast.Assign(TotemAst._globalContext, new GetGlobalContextExpression(_parentContext))); GlobalParent.PrepareScope(locals, init); // Create variables and references. Since references refer to // parameters, do this after parameters have been created. CreateFunctionVariables(locals, init); // Initialize parameters - unpack tuples. // Since tuples unpack into locals, this must be done after locals have been created. InitializeParameters(init, parameters); List<MSAst.Expression> statements = new List<MSAst.Expression>(); // add beginning sequence point var start = GlobalParent.IndexToLocation(StartIndex); statements.Add( GlobalParent.AddDebugInfo( AstUtils.Empty(), new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, Int32.MaxValue)) // TODO: augment, not correct for totem ) ); // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close(). // The exception traceback needs to come from the generator's method body, and so we must do the check and throw // from inside the generator. if (IsGenerator) { //throw new NotImplementedException(); //MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None); //statements.Add(s1); } if (_body.CanThrow && !(_body is SuiteStatement) && _body.StartIndex != -1) { statements.Add(UpdateLineNumber(GlobalParent.IndexToLocation(_body.StartIndex).Line)); } statements.Add(Body); MSAst.Expression body = Ast.Block(statements); if (_body.CanThrow && GlobalParent.TotemContext.TotemOptions.Frames) { //body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(TotemFunction).GetProperty("Code")), body); locals.Add(FunctionStackVariable); } body = AddProfiling(body); body = WrapScopeStatements(body, _body.CanThrow); body = Ast.Block(body, Ast.Empty()); body = AddReturnTarget(body); MSAst.Expression bodyStmt = body; if (localContext != null) { var createLocal = CreateLocalContext(_parentContext); init.Add( Ast.Assign( localContext, createLocal ) ); } init.Add(bodyStmt); bodyStmt = Ast.Block(init); // wrap a scope if needed bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt); return AstUtils.LightLambda( typeof(object), delegateType, AddDefaultReturn(bodyStmt, typeof(object)), Name + "$" + Interlocked.Increment(ref _lambdaId), parameters ); }
internal MSAst.Expression ReduceWorker() { var retStmt = _body as ReturnStatement; if (retStmt != null && (_languageFeatures == ModuleOptions.None || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret) || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret | ModuleOptions.LightThrow))) { // for simple eval's we can construct a simple tree which just // leaves the value on the stack. Return's can't exist in modules // so this is always safe. Debug.Assert(!_isModule); var ret = (ReturnStatement)_body; Ast simpleBody; if ((_languageFeatures & ModuleOptions.LightThrow) != 0) { simpleBody = LightExceptions.Rewrite(retStmt.Expression.Reduce()); } else { simpleBody = retStmt.Expression.Reduce(); } var start = IndexToLocation(ret.Expression.StartIndex); var end = IndexToLocation(ret.Expression.EndIndex); return Ast.Block( Ast.DebugInfo( _document, start.Line, start.Column, end.Line, end.Column ), AstUtils.Convert(simpleBody, typeof(object)) ); } ReadOnlyCollectionBuilder<MSAst.Expression> block = new ReadOnlyCollectionBuilder<MSAst.Expression>(); AddInitialiation(block); if (_isModule) { block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body)))); } if (!(_body is SuiteStatement) && _body.CanThrow) { // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement // at the top level we can miss some line number updates. block.Add(UpdateLineNumber(_body.Start.Line)); } block.Add(_body); MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, Body.CanThrow); // new ComboActionRewriter().VisitNode(Transform(ag)) body = AddModulePublishing(body); body = AddProfiling(body); if ((((PythonCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0) { body = LightExceptions.Rewrite(body); } body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object))); if (body.Type == typeof(void)) { body = Ast.Block(body, Ast.Constant(null)); } return body; }
public ReadOnlyCollection <IWebElement> DownloadTimbratureCurrentMonth(string user, string pwd, DateTime targetDate, TimbratureBuilder builder, System.ComponentModel.BackgroundWorker worker) { #pragma warning disable CS0618 // Type or member is obsolete wait.Until(ExpectedConditions.ElementExists(By.Name("m_cUserName"))); wait.Until(ExpectedConditions.ElementExists(By.Name("m_cPassword"))); wait.Until(ExpectedConditions.ElementExists(By.CssSelector("input[class='buttonlogin Accedi_ctrl']"))); try { worker.ReportProgress(5); // LOGIN driver.FindElement(By.Name("m_cUserName")).SendKeys(user); driver.FindElement(By.Name("m_cPassword")).SendKeys(pwd); driver.FindElement(By.CssSelector("input[class='buttonlogin Accedi_ctrl']")).Click(); // TIMBRATURE wait.Until(ExpectedConditions.ElementExists(By.CssSelector("td[class='grid_title grid_cell_title']"))); worker.ReportProgress(40); String tableId = driver.FindElement(By.ClassName("hfpr_wcartellino2c_container")).GetAttribute("id"); Regex rx = new Regex(@"^(.*?)_container", RegexOptions.Compiled | RegexOptions.IgnoreCase); MatchCollection matches = rx.Matches(tableId); if (matches.Count > 0) { ReadOnlyCollectionBuilder <IWebElement> collection = new ReadOnlyCollectionBuilder <IWebElement>(5); String randomId = matches[0].Groups[1].Value; DateTime currentPageMonth = DateTime.Now; DateTime firstDayNumber = Utils.getFirstWorkingDayOfWeekAsDate(targetDate);//todo check if first day is previous month DateTime currDay = firstDayNumber; bool bNewMonth = false; for (int i = 0; i < 5; ++i) { currDay = firstDayNumber.AddDays(i); bNewMonth = currDay.Month != currentPageMonth.Month; if (!bNewMonth) { IWebElement elem = driver.FindElement(By.Id(randomId + "_Grid1_row" + (currDay.Day - 1))); builder.addDate(elem, currDay.DayOfWeek); collection.Add(elem); worker.ReportProgress(52 + i * 12); } else { IWebElement currMonth = new SelectElement(driver.FindElement(By.ClassName("TxtMese_ctrl"))).SelectedOption; if ((currDay.Month < currentPageMonth.Month && currDay.Year == currentPageMonth.Year) || currDay.Year < currentPageMonth.Year) { driver.FindElement(By.ClassName("BtnMesePrev_ctrl")).Click(); currentPageMonth = currentPageMonth.AddMonths(-1); } else { driver.FindElement(By.ClassName("BtnMeseNext_ctrl")).Click(); currentPageMonth = currentPageMonth.AddMonths(1); } wait.Until(ExpectedConditions.ElementSelectionStateToBe(currMonth, false)); wait.Until(ExpectedConditions.ElementExists(By.CssSelector("td[class='grid_title grid_cell_title']"))); i--;//redo current loop, we changed month } } return(collection.ToReadOnlyCollection()); } else { //ReadOnlyCollection<IWebElement> selected = driver.FindElements(By.CssSelector("tr[class='grid_row grid_rowselected']")); // WTF ZUCCHETTI ReadOnlyCollection <IWebElement> selected = driver.FindElements(By.XPath("//*[@class='grid_row grid_rowselected']")); // WTF ZUCCHETTI ReadOnlyCollection <IWebElement> selectedOdd = driver.FindElements(By.CssSelector("tr[class='grid_rowodd grid_rowselected']")); // WTF ZUCCHETTI ReadOnlyCollection <IWebElement> pairRowsRO = driver.FindElements(By.XPath("//*[@class='grid_row']")); // REALLYYY. ZUCCHETTI PLZ ReadOnlyCollection <IWebElement> oddRowsRO = driver.FindElements(By.XPath("//*[@class='grid_rowodd']")); // REALLYYY. ZUCCHETTI PLZ return(new ReadOnlyCollectionBuilder <IWebElement>(pairRowsRO.Concat(oddRowsRO) .Concat(selectedOdd) .Concat(selected)) .ToReadOnlyCollection()); } } catch { } return(new ReadOnlyCollectionBuilder <IWebElement>().ToReadOnlyCollection()); #pragma warning restore CS0618 // Type or member is obsolete }
internal MSAst.Expression ReduceWorker() { ReadOnlyCollectionBuilder<MSAst.Expression> block = new ReadOnlyCollectionBuilder<MSAst.Expression>(); if (_body is ReturnStatement && (_languageFeatures == ModuleOptions.None || _languageFeatures == ModuleOptions.Interpret)) { // for simple eval's we can construct a simple tree which just // leaves the value on the stack. Return's can't exist in modules // so this is always safe. Debug.Assert(!_isModule); return AstUtils.Convert(((ReturnStatement)_body).Expression.Reduce(), typeof(object)); } AddInitialiation(block); if (_isModule) { block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body)))); } block.Add(_body); MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, Body.CanThrow); // new ComboActionRewriter().VisitNode(Transform(ag)) body = AddModulePublishing(body); body = AddProfiling(body); body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object))); if (body.Type == typeof(void)) { body = Ast.Block(body, Ast.Constant(null)); } return body; }
internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op) { // if we just have a simple named multi-assignment (e.g. a, b = 1,2) // then go ahead and step over the entire statement at once. If we have a // more complex statement (e.g. a.b, c.d = 1, 2) then we'll step over the // sets individually as they could be property sets the user wants to step // into. TODO: Enable stepping of the right hand side? bool emitIndividualSets = false; foreach (Expression e in _items) { if (IsComplexAssignment(e)) { emitIndividualSets = true; break; } } SourceSpan rightSpan = SourceSpan.None; SourceSpan leftSpan = (Span.Start.IsValid && span.IsValid) ? new SourceSpan(Span.Start, span.End) : SourceSpan.None; SourceSpan totalSpan = SourceSpan.None; if (emitIndividualSets) { rightSpan = span; leftSpan = SourceSpan.None; totalSpan = (Span.Start.IsValid && span.IsValid) ? new SourceSpan(Span.Start, span.End) : SourceSpan.None; } // 1. Evaluate the expression and assign the value to the temp. MSAst.ParameterExpression right_temp = Ast.Variable(typeof(object), "unpacking"); // 2. Add the assignment "right_temp = right" into the suite/block MSAst.Expression assignStmt1 = MakeAssignment(right_temp, right); // 3. Call GetEnumeratorValues on the right side (stored in temp) MSAst.Expression enumeratorValues = Expression.Convert(LightExceptions.CheckAndThrow( Expression.Call( emitIndividualSets ? AstMethods.GetEnumeratorValues : AstMethods.GetEnumeratorValuesNoComplexSets, // method // arguments Parent.LocalContext, right_temp, AstUtils.Constant(_items.Length) ) ), typeof(object[])); // 4. Create temporary variable for the array MSAst.ParameterExpression array_temp = Ast.Variable(typeof(object[]), "array"); // 5. Assign the value of the method call (mce) into the array temp // And add the assignment "array_temp = Ops.GetEnumeratorValues(...)" into the block MSAst.Expression assignStmt2 = MakeAssignment( array_temp, enumeratorValues, rightSpan ); ReadOnlyCollectionBuilder <MSAst.Expression> sets = new ReadOnlyCollectionBuilder <MSAst.Expression>(_items.Length + 1); for (int i = 0; i < _items.Length; i++) { // target = array_temp[i] Expression target = _items[i]; if (target == null) { continue; } // 6. array_temp[i] MSAst.Expression element = Ast.ArrayAccess( array_temp, // array expression AstUtils.Constant(i) // index ); // 7. target = array_temp[i], and add the transformed assignment into the list of sets MSAst.Expression set = target.TransformSet( emitIndividualSets ? // span target.Span : SourceSpan.None, element, PythonOperationKind.None ); sets.Add(set); } // 9. add the sets as their own block so they can be marked as a single span, if necessary. sets.Add(AstUtils.Empty()); MSAst.Expression itemSet = GlobalParent.AddDebugInfo(Ast.Block(sets.ToReadOnlyCollection()), leftSpan); // 10. Return the suite statement (block) return(GlobalParent.AddDebugInfo(Ast.Block(new[] { array_temp, right_temp }, assignStmt1, assignStmt2, itemSet, AstUtils.Empty()), totalSpan)); }
public static LightDynamicExpression LightDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollectionBuilder <Expression> arguments) { ContractUtils.RequiresNotNull(arguments, "arguments"); return(new LightTypedDynamicExpressionN(binder, returnType, arguments.ToReadOnlyCollection())); }
internal MSAst.Expression ReduceWorker() { var retStmt = _body as ReturnStatement; if (retStmt != null && (_languageFeatures == ModuleOptions.None || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret) || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret | ModuleOptions.LightThrow))) { // for simple eval's we can construct a simple tree which just // leaves the value on the stack. Return's can't exist in modules // so this is always safe. Debug.Assert(!IsModule); var ret = (ReturnStatement)_body; Ast simpleBody; if ((_languageFeatures & ModuleOptions.LightThrow) != 0) { simpleBody = LightExceptions.Rewrite(retStmt.Expression.Reduce()); } else { simpleBody = retStmt.Expression.Reduce(); } var start = IndexToLocation(ret.Expression.StartIndex); var end = IndexToLocation(ret.Expression.EndIndex); return(Ast.Block( Ast.DebugInfo( _document, start.Line, start.Column, end.Line, end.Column ), AstUtils.Convert(simpleBody, typeof(object)) )); } ReadOnlyCollectionBuilder <MSAst.Expression> block = new ReadOnlyCollectionBuilder <MSAst.Expression>(); AddInitialiation(block); if (IsModule) { block.Add(AssignValue(GetVariableExpression(DocVariable), Ast.Constant(GetDocumentation(_body)))); } if (!(_body is SuiteStatement) && _body.CanThrow) { // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement // at the top level we can miss some line number updates. block.Add(UpdateLineNumber(_body.Start.Line)); } block.Add(_body); MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection()); body = WrapScopeStatements(body, Body.CanThrow); // new ComboActionRewriter().VisitNode(Transform(ag)) body = AddModulePublishing(body); body = AddProfiling(body); if ((((PythonCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0) { body = LightExceptions.Rewrite(body); } body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object))); if (body.Type == typeof(void)) { body = Ast.Block(body, Ast.Constant(null)); } return(body); }
/// <summary> /// WithStatement is translated to the DLR AST equivalent to /// the following Python code snippet (from with statement spec): /// /// mgr = (EXPR) /// exit = mgr.__exit__ # Not calling it yet /// value = mgr.__enter__() /// exc = True /// try: /// VAR = value # Only if "as VAR" is present /// BLOCK /// except: /// # The exceptional case is handled here /// exc = False /// if not exit(*sys.exc_info()): /// raise /// # The exception is swallowed if exit() returns true /// finally: /// # The normal and non-local-goto cases are handled here /// if exc: /// exit(None, None, None) /// /// </summary> internal override MSAst.Expression Transform(AstGenerator ag) { MSAst.ParameterExpression lineUpdated = ag.GetTemporary("$lineUpdated_with", typeof(bool)); // Five statements in the result... ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(6); //****************************************************************** // 1. mgr = (EXPR) //****************************************************************** MSAst.ParameterExpression manager = ag.GetTemporary("with_manager"); statements.Add( ag.MakeAssignment( manager, ag.Transform(_contextManager), new SourceSpan(Start, _header) ) ); //****************************************************************** // 2. exit = mgr.__exit__ # Not calling it yet //****************************************************************** MSAst.ParameterExpression exit = ag.GetTemporary("with_exit"); statements.Add( AstGenerator.MakeAssignment( exit, ag.Get( typeof(object), "__exit__", manager ) ) ); //****************************************************************** // 3. value = mgr.__enter__() //****************************************************************** MSAst.ParameterExpression value = ag.GetTemporary("with_value"); statements.Add( ag.AddDebugInfoAndVoid( AstGenerator.MakeAssignment( value, ag.Invoke( typeof(object), new CallSignature(0), ag.Get( typeof(object), "__enter__", manager ) ) ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 4. exc = True //****************************************************************** MSAst.ParameterExpression exc = ag.GetTemporary("with_exc", typeof(bool)); statements.Add( AstGenerator.MakeAssignment( exc, AstUtils.Constant(true) ) ); //****************************************************************** // 5. The final try statement: // // try: // VAR = value # Only if "as VAR" is present // BLOCK // except: // # The exceptional case is handled here // exc = False // if not exit(*sys.exc_info()): // raise // # The exception is swallowed if exit() returns true // finally: // # The normal and non-local-goto cases are handled here // if exc: // exit(None, None, None) //****************************************************************** MSAst.ParameterExpression exception = ag.GetTemporary("exception", typeof(Exception)); MSAst.ParameterExpression nestedFrames = ag.GetTemporary("$nestedFrames", typeof(List<DynamicStackFrame>)); statements.Add( // try: AstUtils.Try( AstUtils.Try(// try statement body ag.PushLineUpdated(false, lineUpdated), _var != null ? Ast.Block( // VAR = value _var.TransformSet(ag, SourceSpan.None, value, PythonOperationKind.None), // BLOCK ag.Transform(_body), AstUtils.Empty() ) : // BLOCK ag.Transform(_body) // except:, // try statement location ).Catch(exception, // Python specific exception handling code TryStatement.GetTracebackHeader( ag, exception, ag.AddDebugInfoAndVoid( Ast.Block( // exc = False AstGenerator.MakeAssignment( exc, AstUtils.Constant(false) ), Ast.Assign( nestedFrames, Ast.Call(AstGenerator.GetHelperMethod("GetAndClearDynamicStackFrames")) ), // if not exit(*sys.exc_info()): // raise AstUtils.IfThen( ag.Convert( typeof(bool), ConversionResultKind.ExplicitCast, ag.Operation( typeof(bool), PythonOperationKind.Not, MakeExitCall(ag, exit, exception) ) ), ag.UpdateLineUpdated(true), Ast.Call( AstGenerator.GetHelperMethod("SetDynamicStackFrames"), nestedFrames ), Ast.Throw( Ast.Call( AstGenerator.GetHelperMethod("MakeRethrowExceptionWorker"), exception ) ) ) ), _body.Span ) ), Ast.Call( AstGenerator.GetHelperMethod("SetDynamicStackFrames"), nestedFrames ), ag.PopLineUpdated(lineUpdated), Ast.Empty() ) // finally: ).Finally( // if exc: // exit(None, None, None) AstUtils.IfThen( exc, ag.AddDebugInfoAndVoid( Ast.Block( Ast.Dynamic( ag.PyContext.Invoke( new CallSignature(3) // signature doesn't include function ), typeof(object), new MSAst.Expression[] { ag.LocalContext, exit, AstUtils.Constant(null), AstUtils.Constant(null), AstUtils.Constant(null) } ), Ast.Empty() ), _contextManager.Span ) ) ) ); statements.Add(AstUtils.Empty()); return Ast.Block(statements.ToReadOnlyCollection()); }