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); }
public static IList<KeyValuePair<string, string>> GetArgumentValues(CodeActivityContext context, string argumentStartsWith) { PropertyDescriptorCollection properties = context.DataContext.GetProperties(); IList<KeyValuePair<string, string>> arguments = new ReadOnlyCollectionBuilder<KeyValuePair<string, string>>(); foreach (PropertyDescriptor property in properties) { // Get the name of the property/argument var name = property.DisplayName; // must be a string if ((property.PropertyType != typeof (string))) continue; // if an argumentStartsWith has a value and name starts with it if ((!string.IsNullOrWhiteSpace(argumentStartsWith)) && (!name.StartsWith(argumentStartsWith))) continue; var value = (string) property.GetValue(context.DataContext); // the property/argument must have a value if (string.IsNullOrWhiteSpace(value)) continue; arguments.Add(new KeyValuePair<string, string>(name, value)); } return arguments; }
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()); }
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 ); }
// Just splat the args and dispatch through a nested site public override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel) { Debug.Assert(args.Length == 2); int count = ((object[])args[1]).Length; ParameterExpression array = parameters[1]; var nestedArgs = new ReadOnlyCollectionBuilder<Expression>(count + 1); var delegateArgs = new Type[count + 3]; // args + target + returnType + CallSite nestedArgs.Add(parameters[0]); delegateArgs[0] = typeof(CallSite); delegateArgs[1] = typeof(object); for (int i = 0; i < count; i++) { nestedArgs.Add(Expression.ArrayAccess(array, Expression.Constant(i))); delegateArgs[i + 2] = typeof(object).MakeByRefType(); } delegateArgs[delegateArgs.Length - 1] = typeof(object); return Expression.IfThen( Expression.Equal(Expression.ArrayLength(array), Expression.Constant(count)), Expression.Return( returnLabel, Expression.MakeDynamic( Expression.GetDelegateType(delegateArgs), new ComInvokeAction(new CallInfo(count)), nestedArgs ) ) ); }
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); }
protected override Expression VisitLambda <T>(Expression <T> node) { _depth++; try { // Visit the lambda first, so we walk the tree and find any // constants we need to rewrite. node = (Expression <T>)base.VisitLambda(node); if (_depth != 1) { return(node); } var body = node.Body; if (_constants != null) { // Rewrite the constants, they can contain embedded // CodeContextExpressions for (int i = 0; i < _constants.Count; i++) { _constants[i] = Visit(_constants[i]); } // Add the consant pool variable to the top lambda // We first create the array and then assign into it so that we can refer to the // array and read values out that have already been created. ReadOnlyCollectionBuilder <Expression> assigns = new ReadOnlyCollectionBuilder <Expression>(_constants.Count + 2); assigns.Add(Expression.Assign( _constantPool, Expression.NewArrayBounds(typeof(object), Expression.Constant(_constants.Count)) )); // emit inner most constants first so they're available for outer most constants to consume for (int i = _constants.Count - 1; i >= 0; i--) { assigns.Add( Expression.Assign( Expression.ArrayAccess(_constantPool, Expression.Constant(i)), _constants[i] ) ); } assigns.Add(body); body = Expression.Block(new[] { _constantPool }, assigns); } // Rewrite the lambda return(Expression.Lambda <T>( body, node.Name + "$" + Interlocked.Increment(ref _uniqueNameId), node.TailCall, node.Parameters )); } finally { _depth--; } }
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); } }
private Expression MakeAssignBlock(ParameterExpression variable, Expression value) { var node = (BlockExpression)value; var newBlock = new ReadOnlyCollectionBuilder <Expression>(node.Expressions); newBlock[newBlock.Count - 1] = MakeAssign(variable, newBlock[newBlock.Count - 1]); return(Expression.Block(node.Variables, newBlock)); }
public void ReadOnlyCollectionBuilder_Reverse_Range() { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3, 4, 5 }); rocb.Reverse(1, 3); Assert.True(new[] { 1, 4, 3, 2, 5 }.SequenceEqual(rocb)); }
public void ReadOnlyCollectionBuilder_Reverse() { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); rocb.Reverse(); Assert.True(new[] { 3, 2, 1 }.SequenceEqual(rocb)); }
public void ReadOnlyCollectionBuilder_Clear2() { var rocb = new ReadOnlyCollectionBuilder <int>(); rocb.Clear(); Assert.Equal(0, rocb.Count); }
public void ReadOnlyCollectionBuilder_Ctor_Capacity(int capacity) { var rocb = new ReadOnlyCollectionBuilder <int>(capacity); Assert.Equal(capacity, rocb.Capacity); AssertEmpty(rocb); }
public void ReadOnlyCollectionBuilder_Ctor_Default() { var rocb = new ReadOnlyCollectionBuilder <int>(); Assert.Equal(0, rocb.Capacity); AssertEmpty(rocb); }
public void ReadOnlyCollectionBuilder_CopyTo_ArgumentChecking() { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); Assert.Throws <ArgumentNullException>(() => rocb.CopyTo(null, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => rocb.CopyTo(new int[3], -1)); Assert.Throws <ArgumentException>(() => rocb.CopyTo(new int[3], 3)); // NB: Consistent with List<T> behavior }
private ParameterExpression AddTemp(ParameterExpression variable) { if (this._temps == null) { this._temps = new ReadOnlyCollectionBuilder <ParameterExpression>(); } this._temps.Add(variable); return(variable); }
internal override MSAst.Expression Transform(AstGenerator ag) { // Transform to series of individual del statements. ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(_expressions.Length + 1); for (int i = 0; i < _expressions.Length; i++) { statements.Add(_expressions[i].TransformDelete(ag)); } statements.Add(AstUtils.Empty()); return ag.AddDebugInfo(MSAst.Expression.Block(statements), Span); }
public override MSAst.Expression Reduce() { // Transform to series of individual del statements. ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(_expressions.Length + 1); for (int i = 0; i < _expressions.Length; i++) { statements.Add(_expressions[i].TransformDelete()); } statements.Add(AstUtils.Empty()); return GlobalParent.AddDebugInfo(MSAst.Expression.Block(statements), Span); }
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()); }
public void ReadOnlyCollectionBuilder_ICollection_CopyTo1() { ICollection rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); var array = new int[3]; rocb.CopyTo(array, 0); Assert.True(new[] { 1, 2, 3 }.SequenceEqual(array)); }
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()); }
public void ReadOnlyCollectionBuilder_Contains1() { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 2, 3 }); Assert.True(rocb.Contains(1)); Assert.True(rocb.Contains(2)); Assert.True(rocb.Contains(3)); Assert.False(rocb.Contains(-1)); }
public void ReadOnlyCollectionBuilder_Contains3() { var rocb = new ReadOnlyCollectionBuilder <string>(new[] { "bar", "foo", "qux", null }); Assert.True(rocb.Contains("bar")); Assert.True(rocb.Contains("foo")); Assert.True(rocb.Contains("qux")); Assert.True(rocb.Contains(null)); Assert.False(rocb.Contains("baz")); }
public void ReadOnlyCollectionBuilder_Add() { var rocb = new ReadOnlyCollectionBuilder <int>(); for (int i = 1; i <= 10; i++) { rocb.Add(i); Assert.True(Enumerable.Range(1, i).SequenceEqual(rocb)); } }
void ChangeWhileEnumeratingRemove() { ReadOnlyCollectionBuilder <int> b = new ReadOnlyCollectionBuilder <int>(); b.Add(5); b.Add(6); foreach (int i in b) { b.Remove(5); } }
private readonly static Expression[] s_noArgs = new Expression[0]; // used in reference comparison, requires unique object identity private static Expression[] GetConvertedArgs(params Expression[] args) { ReadOnlyCollectionBuilder <Expression> paramArgs = new ReadOnlyCollectionBuilder <Expression>(args.Length); for (int i = 0; i < args.Length; i++) { paramArgs.Add(Expression.Convert(args[i], typeof(object))); } return(paramArgs.ToArray()); }
private static Expression CreateCloneExpression( ParameterExpression source, ParameterExpression destination, ParameterExpression cache) { var targets = CopyMemberExtractor.Extract <T>(); var expressions = new ReadOnlyCollectionBuilder <Expression>( CreateExpressions(targets, source, destination, cache)); //var expressions = CreateExpressions(targets, source, destination); return(Expression.Block(expressions)); }
public override MSAst.Expression Reduce() { // Transform to series of individual del statements. ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(_expressions.Length + 1); for (int i = 0; i < _expressions.Length; i++) { statements.Add(_expressions[i].TransformDelete()); } statements.Add(AstUtils.Empty()); return(GlobalParent.AddDebugInfo(MSAst.Expression.Block(statements), Span)); }
private static void AssertEmpty <T>(ReadOnlyCollectionBuilder <T> rocb) { Assert.Equal(0, rocb.Count); Assert.False(rocb.Contains(default(T))); Assert.False(rocb.Remove(default(T))); Assert.InRange(rocb.IndexOf(default(T)), int.MinValue, -1); IEnumerator <T> e = rocb.GetEnumerator(); Assert.False(e.MoveNext()); }
public void ReadOnlyCollectionBuilder_ICollection_SyncRoot() { ICollection rocb = new ReadOnlyCollectionBuilder <int>(); object root1 = rocb.SyncRoot; Assert.NotNull(root1); object root2 = rocb.SyncRoot; Assert.Same(root1, root2); }
public void ReadOnlyCollectionBuilder_IList_Contains2() { IList rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); Assert.True(rocb.Contains(1)); Assert.True(rocb.Contains(2)); Assert.True(rocb.Contains(3)); Assert.False(rocb.Contains("baz")); Assert.False(rocb.Contains(0)); Assert.False(rocb.Contains(null)); }
public void ReadOnlyCollectionBuilder_ICollection_CopyTo_ArgumentChecking() { ICollection rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); Assert.Throws <ArgumentNullException>(() => rocb.CopyTo(null, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => rocb.CopyTo(new int[3], -1)); Assert.Throws <ArgumentException>(() => rocb.CopyTo(new int[3], 3)); // NB: Consistent with List<T> behavior Assert.Throws <ArgumentException>(() => rocb.CopyTo(new int[3, 3], 0)); // CONSIDER: Throw ArgumentException instead to be consistent with List<T>, see https://github.com/dotnet/corefx/issues/14059 Assert.Throws <ArrayTypeMismatchException>(() => rocb.CopyTo(new string[3], 0)); }
public void ReadOnlyCollectionBuilder_CopyTo2() { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); var array = new int[5] { 1, 2, 3, 4, 5 }; rocb.CopyTo(array, 1); Assert.True(new[] { 1, 1, 2, 3, 5 }.SequenceEqual(array)); }
public void ReadOnlyCollectionBuilder_IEnumerator_Versioning_Reset(int index, Action <ReadOnlyCollectionBuilder <int> > edit) { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); IEnumerator enumerator = ((IEnumerable)rocb).GetEnumerator(); Assert.True(enumerator.MoveNext()); edit(rocb); Assert.Throws <InvalidOperationException>(() => enumerator.Reset()); }
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_IEnumeratorOfT_Versioning_Reset(int theoryIndex, Action <ReadOnlyCollectionBuilder <int> > edit) { _ = theoryIndex; var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); IEnumerator <int> enumerator = rocb.GetEnumerator(); Assert.True(enumerator.MoveNext()); edit(rocb); Assert.Throws <InvalidOperationException>(() => enumerator.Reset()); }
public void ReadOnlyCollectionBuilder_Indexer_IList_Get() { IList rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3, 4 }); // CONSIDER: Throw ArgumentOutOfRangeException instead, see https://github.com/dotnet/corefx/issues/14059 Assert.Throws <IndexOutOfRangeException>(() => rocb[-1]); AssertExtensions.Throws <ArgumentOutOfRangeException>("index", () => rocb[4]); Assert.Equal(1, rocb[0]); Assert.Equal(2, rocb[1]); Assert.Equal(3, rocb[2]); Assert.Equal(4, rocb[3]); }
public void ReadOnlyCollectionBuilder_Reverse_Range_ArgumentChecking() { var rocb = new ReadOnlyCollectionBuilder <int>(new[] { 1, 2, 3 }); AssertExtensions.Throws <ArgumentOutOfRangeException>("index", () => rocb.Reverse(-1, 1)); AssertExtensions.Throws <ArgumentOutOfRangeException>("count", () => rocb.Reverse(1, -1)); // CONSIDER: Throw ArgumentException just like List<T> does, see https://github.com/dotnet/corefx/issues/14059 // Assert.Throws<ArgumentException>(() => rocb.Reverse(3, 1)); // Assert.Throws<ArgumentException>(() => rocb.Reverse(1, 3)); // Assert.Throws<ArgumentException>(() => rocb.Reverse(2, 2)); // Assert.Throws<ArgumentException>(() => rocb.Reverse(3, 1)); }
public void ReadOnlyCollectionBuilder_ToArray(int length) { var rocb = new ReadOnlyCollectionBuilder <int>(); for (int i = 0; i < length; i++) { rocb.Add(i); } int[] array = rocb.ToArray(); Assert.True(Enumerable.Range(0, length).SequenceEqual(array)); }
public ScopeBuilder(MSA.ParameterExpression/*!*/[] parameters, int firstClosureParam, int localCount, ScopeBuilder parent, LexicalScope/*!*/ lexicalScope) { Debug.Assert(parent == null || parent.LexicalScope == lexicalScope.OuterScope); #if DEBUG _id = Interlocked.Increment(ref _Id); #endif _parent = parent; _parameters = parameters; _localCount = localCount; _firstClosureParam = firstClosureParam; _lexicalScope = lexicalScope; _hiddenVariables = new ReadOnlyCollectionBuilder<MSA.ParameterExpression>(); _localsTuple = DefineHiddenVariable("#locals", MakeLocalsTupleType()); _outermostClosureReferredTo = this; }
private AstGenerator(string name, bool generator, string profilerName, bool print) { _print = print; _isGenerator = generator; _name = name; _locals = new ReadOnlyCollectionBuilder<ParameterExpression>(); _params = new List<ParameterExpression>(); if (profilerName == null) { if (name.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0) { _profilerName = "module " + name; } else { _profilerName = "module " + System.IO.Path.GetFileNameWithoutExtension(name); } } else { _profilerName = profilerName; } }
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); } } }
public virtual void PrepareScope(PythonAst ast, ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals, List<MSAst.Expression> init) { }
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> /// Helper method for generating expressions that assign byRef call /// parameters back to their original variables /// </summary> private static Expression ReferenceArgAssign(Expression callArgs, Expression[] args) { ReadOnlyCollectionBuilder<Expression> block = null; for (int i = 0; i < args.Length; i++) { ContractUtils.Requires(args[i] is ParameterExpression); if (((ParameterExpression)args[i]).IsByRef) { if (block == null) block = new ReadOnlyCollectionBuilder<Expression>(); block.Add( Expression.Assign( args[i], Expression.Convert( Expression.ArrayIndex( callArgs, Expression.Constant(i) ), args[i].Type ) ) ); } } if (block != null) return Expression.Block(block); else return Expression.Empty(); }
private static Expression[] GetConvertedArgs(params Expression[] args) { ReadOnlyCollectionBuilder<Expression> paramArgs = new ReadOnlyCollectionBuilder<Expression>(args.Length); for (int i = 0; i < args.Length; i++) { paramArgs.Add(Expression.Convert(args[i], typeof(object))); } return paramArgs.ToArray(); }
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(); }
private MSAst.ParameterExpression[] CreateParameters(ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals) { MSAst.ParameterExpression[] parameters = new[] { _functionParam, _argumentsParam }; foreach (var param in _parameters) locals.Add(param.ParameterExpression); return parameters; }
/// <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 ); }
internal void CreateFunctionVariables(ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals, List<MSAst.Expression> init) { CreateVariables(locals, init); }
//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 Ast AddVariables(Ast expression) { ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>(); MSAst.ParameterExpression localContext = null; if (NeedsLocalContext) { localContext = _compContext; locals.Add(_compContext); } List<MSAst.Expression> body = new List<MSAst.Expression>(); CreateVariables(locals, body); if (localContext != null) { var createLocal = CreateLocalContext(_comprehension.Parent.LocalContext); body.Add(Ast.Assign(_compContext, createLocal)); body.Add(expression); } else { body.Add(expression); } return Expression.Block( locals, body ); }
internal void CreateVariables(ReadOnlyCollectionBuilder<ParameterExpression> locals, List<Expression> init) { if (_scopeVars != null) foreach (var local in _scopeVars) { Debug.Assert(local.Kind == VariableKind.Local || local.Kind == VariableKind.Parameter); ClosureExpression closure = GetVariableExpression(local) as ClosureExpression; if (closure != null) { init.Add(closure.Create()); locals.Add((ParameterExpression)closure.ClosureCell); } else if (local.Kind == VariableKind.Local) { locals.Add((ParameterExpression)GetVariableExpression(local)); if (local.ReadBeforeInitialized) { init.Add( AssignValue( GetVariableExpression(local), Expression.Field(null, typeof(Uninitialized).GetField("Value")) ) ); } } } }
private MSAst.ParameterExpression[] CreateParameters(bool needsWrapperMethod, ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals) { MSAst.ParameterExpression[] parameters; if (needsWrapperMethod) { parameters = new[] { _functionParam, Ast.Parameter(typeof(object[]), "allArgs") }; foreach (var param in _parameters) { locals.Add(param.ParameterExpression); } } else { parameters = new MSAst.ParameterExpression[_parameters.Length + 1]; for (int i = 1; i < parameters.Length; i++) { parameters[i] = _parameters[i - 1].ParameterExpression; } parameters[0] = _functionParam; } return parameters; }
public void ReplaceAssemblyInfoPropertiesTests_WhenChangingAllPropertiesInWorkflowShouldUpdateAssemblyInfoWithSameValues() { const string searchPatternShell = @"[\[<]+.*{0}.*\(\x22{1}\x22\)[\]>]+"; string[] filePaths = new[] { "ReplaceTestAssemblyInfo.cs", "ReplaceTestAssemblyInfo.vb", "ReplaceTestAssemblyInfo.cpp", "ReplaceTestAssemblyInfo.fs" }; const bool forceCreate = true; IList<Tuple<string, string>> assemblyProperties = new ReadOnlyCollectionBuilder<Tuple<string, string>> { new Tuple<string, string>("AssemblyTitle", "Assembly Title"), new Tuple<string, string>("AssemblyDescription", "Assembly Description"), new Tuple<string, string>("AssemblyConfiguration", "Assembly Configuration"), new Tuple<string, string>("AssemblyCompany", "Assembly Company"), new Tuple<string, string>("AssemblyProduct", "Assembly Product"), new Tuple<string, string>("AssemblyCopyright", "Assembly Copyright"), new Tuple<string, string>("AssemblyTrademark", "Assembly Trademark"), new Tuple<string, string>("AssemblyCulture", "Assembly Culture"), new Tuple<string, string>("AssemblyInformationalVersion", "Assembly Informational Version"), }; foreach (var file in filePaths) { // Create an instance of our test workflow var workflow = new Tests.TestReplaceAssemblyInfoPropertiesWorkflow(); // Create the workflow run-time environment var workflowInvoker = new WorkflowInvoker(workflow); var testFilename = string.Format("AllPropertiesTestAssemblyInfo{0}", Path.GetExtension(file)); File.Copy(file, testFilename); var extension = " " + Path.GetExtension(testFilename).Remove(0, 1); // Set the workflow arguments workflow.FilePath = testFilename; workflow.ForceCreate = forceCreate; workflow.BuildDate = DateTime.Now; workflow.AssemblyTitleReplacementPattern = assemblyProperties[0].Item2 + extension; workflow.AssemblyDescriptionReplacementPattern = assemblyProperties[1].Item2 + extension; workflow.AssemblyConfigurationReplacementPattern = assemblyProperties[2].Item2 + extension; workflow.AssemblyCompanyReplacementPattern = assemblyProperties[3].Item2 + extension; workflow.AssemblyProductReplacementPattern = assemblyProperties[4].Item2 + extension; workflow.AssemblyCopyrightReplacementPattern = assemblyProperties[5].Item2 + extension; workflow.AssemblyTrademarkReplacementPattern = assemblyProperties[6].Item2 + extension; workflow.AssemblyCultureReplacementPattern = assemblyProperties[7].Item2 + extension; workflow.AssemblyInformationalVersionReplacementPattern = assemblyProperties[8].Item2 + extension; workflow.BuildDetail = new InArgument<IBuildDetail>(env => new BuildDetailStub(99)); // Invoke the workflow and capture the outputs workflowInvoker.Invoke(); // Verify using RegEx var fileData = File.ReadAllText(testFilename); foreach (var propertyTuple in assemblyProperties) { var regexPattern = string.Format(searchPatternShell, propertyTuple.Item1, propertyTuple.Item2 + extension); var regex = new Regex(regexPattern); Assert.IsTrue(regex.IsMatch(fileData), string.Format("Test Failed: File: {0} - Property: {1} - Value: {2}", testFilename, propertyTuple.Item1, propertyTuple.Item2 + extension)); } } }
public virtual void PrepareScope(TotemAst ast, ReadOnlyCollectionBuilder<ParameterExpression> locals, List<Expression> init) { }
private Microsoft.Scripting.Ast.LightExpression<Func<CodeContext, CodeContext>> MakeClassBody() { // we always need to create a nested context for class defs var init = new List<MSAst.Expression>(); var locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>(); locals.Add(LocalCodeContextVariable); locals.Add(PythonAst._globalContext); init.Add(Ast.Assign(PythonAst._globalContext, new GetGlobalContextExpression(_parentContextParam))); GlobalParent.PrepareScope(locals, init); CreateVariables(locals, init); var createLocal = CreateLocalContext(_parentContextParam); init.Add(Ast.Assign(LocalCodeContextVariable, createLocal)); List<MSAst.Expression> statements = new List<MSAst.Expression>(); // Create the body MSAst.Expression bodyStmt = _body; // __module__ = __name__ MSAst.Expression modStmt = AssignValue(GetVariableExpression(_modVariable), GetVariableExpression(_modNameVariable)); string doc = GetDocumentation(_body); if (doc != null) { statements.Add( AssignValue( GetVariableExpression(_docVariable), AstUtils.Constant(doc) ) ); } if (_body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames) { bodyStmt = AddFrame(LocalContext, FuncCodeExpr, bodyStmt); locals.Add(FunctionStackVariable); } bodyStmt = WrapScopeStatements( Ast.Block( Ast.Block(init), statements.Count == 0 ? EmptyBlock : Ast.Block(new ReadOnlyCollection<MSAst.Expression>(statements)), modStmt, bodyStmt, LocalContext ), _body.CanThrow ); var lambda = AstUtils.LightLambda<Func<CodeContext, CodeContext>>( typeof(CodeContext), Ast.Block( locals, bodyStmt ), Name + "$" + Interlocked.Increment(ref _classId), new[] { _parentContextParam } ); return lambda; }
/// <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()); }