private ComprehensionScope MakeGeneratorComprehensionScope(Comprehension node) { var unit = new GeneratorComprehensionAnalysisUnit(node, _tree, _curUnit, _scope); unit.Enqueue(); return((ComprehensionScope)unit.Scope); }
private ComprehensionScope MakeDictComprehensionScope(Comprehension node) { var unit = new DictionaryComprehensionAnalysisUnit(node, _tree, _curUnit, _scope); unit.Enqueue(); return((ComprehensionScope)unit.Scope); }
internal void ProcessComprehension(Comprehension node) { foreach (var cfor in node.Iterators.OfType <ComprehensionFor>().Where(c => c.Left != null)) { var value = GetValueFromExpression(cfor.List); if (value != null) { switch (cfor.Left) { case NameExpression nex when value is IPythonCollection coll: DeclareVariable(nex.Name, coll.GetIterator().Next, VariableSource.Declaration, GetLoc(nex)); break; case NameExpression nex: DeclareVariable(nex.Name, UnknownType, VariableSource.Declaration, GetLoc(nex)); break; case TupleExpression tex when value is IPythonDictionary dict && tex.Items.Count > 0: if (tex.Items[0] is NameExpression nx0 && !string.IsNullOrEmpty(nx0.Name)) { DeclareVariable(nx0.Name, dict.Keys.FirstOrDefault() ?? UnknownType, VariableSource.Declaration, GetLoc(nx0)); } if (tex.Items.Count > 1 && tex.Items[1] is NameExpression nx1 && !string.IsNullOrEmpty(nx1.Name)) { DeclareVariable(nx1.Name, dict.Values.FirstOrDefault() ?? UnknownType, VariableSource.Declaration, GetLoc(nx1)); } foreach (var item in tex.Items.Skip(2).OfType <NameExpression>().Where(x => !string.IsNullOrEmpty(x.Name))) { DeclareVariable(item.Name, UnknownType, VariableSource.Declaration, GetLoc(item)); } break; } } } }
public ComprehensionAnalysisUnit(Comprehension node, PythonAst parent, InterpreterScope scope, AnalysisUnit outerUnit) : base(node, parent, scope, false) { _outerUnit = outerUnit; _parent = parent; AnalysisLog.NewUnit(this); }
private void CollectNames(Comprehension c) { var nc = new NameCollectorWalker(_localNames, _localNameNodes); foreach (var cfor in c.Iterators.OfType <ComprehensionFor>()) { cfor.Left?.Walk(nc); } }
public override Verb CreateVerb(string[] tokens) { if (fieldListParser.Parse(source, position).If(out var fields, out var i)) { var index = i; var parameters = new Parameters(fields); if (freeParser.Scan(source, index, "^ ' '* 'in' /b")) { index = freeParser.Position; freeParser.ColorAll(KeyWords); if (GetExpression(source, index, PassAlong("^ ' '* 'do' /b", true, KeyWords)).If(out var arrayExp, out var j)) { index = j; var newSource = new Block(); var ifExpression = new Block(); var addingToIf = false; foreach (var verb in arrayExp.AsAdded) { if (verb is If) { addingToIf = true; continue; } if (addingToIf) { ifExpression.Add(verb); } else { newSource.Add(verb); } } if (GetExpression(source, index, PassAlong("^ ' '* [',)']", false)).If(out var yieldExp, out var k)) { overridePosition = k; var comprehension = new Comprehension(yieldExp, parameters, new Region()) { ArrayBlock = newSource }; if (ifExpression.Count > 0) { comprehension.SetIf(ifExpression); } result.Value = comprehension; return(new NullOp()); } } } } return(null); }
private void ProcessComprehension(Comprehension c, Node item, IEnumerable <ComprehensionIterator> iterators) { CollectNames(c); var ew = new ExpressionWalker(_walker, _localNames, _localNameNodes); item?.Walk(ew); foreach (var iter in iterators) { iter.Walk(ew); } }
public override void InferReturnTypeForExpressionFunction(Method meth) { meth.ReturnType = SystemTypes.Void; StatementList statements = meth.Body == null ? null : meth.Body.Statements; ExpressionStatement es = statements == null || statements.Count != 1 ? null : statements[0] as ExpressionStatement; Comprehension q = es == null ? null : es.Expression as Comprehension; if (q != null && q.Type != null && TypeNode.StripModifiers(q.Type).Template == SystemTypes.GenericIEnumerable) { meth.ReturnType = q.Type; } }
private void ExitComprehension(Comprehension node) { var children = _stack.Exit(); var span = node.GetSpan(_ast); _stack.AddSymbol(new HierarchicalSymbol( $"<{node.NodeName}>", SymbolKind.None, span, children: children )); }
public ListComprehensionAnalysisUnit(Comprehension node, PythonAst parent, AnalysisUnit outerUnit, InterpreterScope outerScope) : base(node, parent, new ComprehensionScope( new ListInfo( VariableDef.EmptyArray, outerUnit.State.ClassInfos[BuiltinTypeId.List], node, outerUnit.ProjectEntry ), node, outerScope), outerUnit) { }
private bool WalkIterators(Comprehension node) { if (node.Iterators != null) { foreach (ComprehensionIterator ci in node.Iterators) { ci.Walk(this); } } return(false); }
internal static void WalkComprehension(ExpressionEvaluator ee, Comprehension comp, int start = 1) { foreach (var compFor in comp.Iterators.Skip(start).OfType <ComprehensionFor>()) { var listTypes = ee.Evaluate(compFor.List); ee.AssignTo(comp, compFor.Left, listTypes.GetEnumeratorTypes(comp, ee._unit)); } foreach (var compIf in comp.Iterators.OfType <ComprehensionIf>()) { ee.EvaluateMaybeNull(compIf.Test); } }
/// <summary> /// Makes sure we create a scope for a comprehension (generator, set, dict, or list comprehension in 3.x) where /// the variables which are assigned will be stored. /// </summary> private void EnsureComprehensionScope(Comprehension node, Func <Comprehension, ComprehensionScope> makeScope) { InterpreterScope scope, declScope = _scope; if (!declScope.TryGetNodeScope(node, out scope)) { scope = makeScope(node); declScope.AddNodeScope(node, scope); declScope.Children.Add(scope); } _scope = scope; }
public GeneratorComprehensionAnalysisUnit(Comprehension node, PythonAst parent, AnalysisUnit outerUnit, InterpreterScope outerScope) : base(node, parent, new ComprehensionScope( new GeneratorInfo( outerUnit.State, outerUnit.ProjectEntry ), node, outerScope ), outerUnit ) { }
public override Verb CreateVerb(string[] tokens) { Color(position, tokens[1].Length, Structures); Color(tokens[2].Length, KeyWords); var index = NextPosition; Comprehension current = null; while (index < source.Length) { if (arraySubComprehensionParser.Scan(source, index)) { index = arraySubComprehensionParser.Position; var comprehension = (Comprehension)arraySubComprehensionParser.Value; if (current == null) { current = comprehension; } else { current.PushDownInnerComprehension(comprehension); } } else { return(null); } if (freeParser.Scan(source, index, "^ ' '* ','")) { index = freeParser.Position; freeParser.ColorAll(Structures); continue; } if (freeParser.Scan(source, index, "^ ' '* ')'") && current != null) { overridePosition = freeParser.Position; freeParser.ColorAll(Structures); result.Value = current; return(new Push(current)); } return(null); } return(null); }
public IMember GetValueFromComprehension(Comprehension node) { var oldVariables = CurrentScope.Variables.OfType <Variable>().ToDictionary(k => k.Name, v => v); try { ProcessComprehension(node); // TODO: Evaluate comprehensions to produce exact contents, if possible. switch (node) { case ListComprehension lc: var v1 = GetValueFromExpression(lc.Item) ?? UnknownType; return(PythonCollectionType.CreateList(Module, new[] { v1 })); case SetComprehension sc: var v2 = GetValueFromExpression(sc.Item) ?? UnknownType; return(PythonCollectionType.CreateSet(Module, new[] { v2 })); case DictionaryComprehension dc: var k = GetValueFromExpression(dc.Key) ?? UnknownType; var v = GetValueFromExpression(dc.Value) ?? UnknownType; return(new PythonDictionary(new PythonDictionaryType(Interpreter.ModuleResolution.BuiltinsModule), new Dictionary <IMember, IMember> { { k, v } })); } return(UnknownType); } finally { // Remove temporary variables since this is assignment and the right hand // side comprehension does not leak internal variables into the scope. var newVariables = CurrentScope.Variables.ToDictionary(k => k.Name, v => v); var variables = (VariableCollection)CurrentScope.Variables; foreach (var kvp in newVariables) { if (!oldVariables.ContainsKey(kvp.Key)) { variables.RemoveVariable(kvp.Key); } } } }
// TODO: Remove this? There shouldn't be any ANFs that need to be serialized in a contract public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction anf) { // we can serialize an ANF only if it is really just a wrapper around a comprehension // in that case, just serialize the comprehension and let the deserializer // reconstruct the ANF. if (anf == null) { return(null); } if (anf.Body == null) { return(anf); } if (anf.Body.Statements == null) { return(anf); } if (anf.Body.Statements.Count != 1) { return(anf); } ExpressionStatement es = anf.Body.Statements[0] as ExpressionStatement; if (es == null) { return(anf); } Comprehension q = es.Expression as Comprehension; if (q == null) { return(anf); } this.VisitComprehension(q); return(anf); }
public override Expression VisitComprehension(Comprehension comprehension){ if (comprehension == null) return null; if (comprehension.Elements == null) return null; if (comprehension.IsDisplay){ if (comprehension.Elements.Count == 0) { comprehension.Type = SystemTypes.GenericIEnumerable.GetTemplateInstance(this.currentType,SystemTypes.Object); return comprehension; } }else{ if (comprehension.Elements.Count != 1 && comprehension.Elements.Count != 2) return null; } comprehension.BindingsAndFilters = this.VisitExpressionList(comprehension.BindingsAndFilters); comprehension.Elements = this.VisitExpressionList(comprehension.Elements); TypeNode unifiedType = null; TypeNodeList tl = new TypeNodeList(); for (int i = 0, n = comprehension.Elements == null ? 0 : comprehension.Elements.Count; i < n; i++){ Expression e = comprehension.Elements[i]; if (e == null || e.Type == null) continue; Literal lit = e as Literal; if (lit != null && lit.Value == null) continue; //This prevents null from participating in the type unification, which is by design. if (e.Type == null) continue; //e is a bad expression tl.Add(e.Type); } unifiedType = this.typeSystem.UnifiedType(tl, this.TypeViewer); if (unifiedType == null) unifiedType = SystemTypes.Object; comprehension.Type = OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.GenericIEnumerable.GetTemplateInstance(this.currentType, unifiedType)); return comprehension; }
public SetComprehensionAnalysisUnit(Comprehension node, PythonAst parent, AnalysisUnit outerUnit, InterpreterScope outerScope) : base(node, parent, new ComprehensionScope(new SetInfo(outerUnit.ProjectState, node), node, outerScope), outerUnit) { }
// {1,2,3} ==> // { [ / (IList/IDictionary) t = new T(); ] // [ yield return 1 / t.Add(1) ]; // ... // [ / return (T) t ]; // } // { T1 x in A, P(x); B(x) ; default } ==> // { [ /(IList/IDictionary) t = new T(); ] // bool empty = true; // only for compr. with default // foreach(T1 x in A) { if P(x){ empty = false; [ yield return B(x) / t.Add(B(x)) ];} } // if (empty) [ yield return default / t.Add(default) ]; // only for compr. with default // [ / return (T)t]; // } public override Expression VisitComprehension(Comprehension comprehension){ if (comprehension == null) return null; Block b = new Block(new StatementList()); // return value from this visitor Expression empty = null; // will be either a local or a field #region Local variables used when in a non-Enumerable context. // TODO: could be a structure, not a class!! (at least write some test cases) TypeNode nonEnumClass = null; Local retVal = null; Method addMethod = null; NodeType addMethodCallType = NodeType.Callvirt; // assume virtual calls bool useIListMethods = false; // use a local so it is evaluated only once in case of side-effects for get_Key and get_Value Local de = null; Method keyMethod = null; Method valueMethod = null; #endregion bool defaultIsPresent = !comprehension.IsDisplay && comprehension.Elements.Count > 1; bool notEnumContext = comprehension.nonEnumerableTypeCtor != null; #region Set non-Enumerable locals to the appropriate values. // TODO: Look for these things in Checker and if it can't find them, issue diagnostics if (notEnumContext){ Method tempM = comprehension.nonEnumerableTypeCtor as Method; addMethod = comprehension.AddMethod; if (!addMethod.IsVirtual) addMethodCallType = NodeType.Call; keyMethod = SystemTypes.DictionaryEntry.GetMethod(Identifier.For("get_Key")); valueMethod = SystemTypes.DictionaryEntry.GetMethod(Identifier.For("get_Value")); if (tempM != null) nonEnumClass = (Class) tempM.DeclaringType; else nonEnumClass = (TypeNode) comprehension.nonEnumerableTypeCtor; TypeNode elementType = TypeNode.StripModifiers(comprehension.TemporaryHackToHoldType).TemplateArguments[0]; if (this.GetTypeView(nonEnumClass).IsAssignableTo(SystemTypes.IList)){ retVal = new Local(Identifier.For("SS$retVal"),SystemTypes.IList,b); useIListMethods = true; } else if ((comprehension.Elements.Count == 0 || this.GetTypeView(elementType).IsAssignableTo(SystemTypes.DictionaryEntry)) && this.GetTypeView(nonEnumClass).IsAssignableTo(SystemTypes.IDictionary)){ retVal = new Local(Identifier.For("SS$retVal"),SystemTypes.IDictionary,b); useIListMethods = false; // means "use IDictionary methods" de = new Local(Identifier.For("SS$dictionaryEntry"),SystemTypes.DictionaryEntry,b); Debug.Assert(de != null && keyMethod != null && valueMethod != null); } else if ((comprehension.Elements.Count == 0 || this.GetTypeView(elementType).IsAssignableTo(SystemTypes.DictionaryEntry)) && addMethod != null && addMethod.GetParameterTypes().Length == 2){ retVal = new Local(Identifier.For("SS$retVal"),nonEnumClass,b); useIListMethods = false; // means "use IDictionary methods" de = new Local(Identifier.For("SS$dictionaryEntry"),SystemTypes.DictionaryEntry,b); Debug.Assert(de != null && keyMethod != null && valueMethod != null); } else if (addMethod != null){ retVal = new Local(Identifier.For("SS$retVal"),nonEnumClass,b); useIListMethods = true; } Debug.Assert(retVal != null && addMethod != null); } if (defaultIsPresent){ if (notEnumContext){ empty = new Local(Identifier.For("SS$empty"),SystemTypes.Boolean,b); }else{ Field emptyField = new Field(Identifier.Empty); Class scope = null; // defaultIsPresent ==> comprehension.Elements != null for (int i = 0, n = comprehension.Elements.Count; i < n; i++){ // really it should always be the first one, but better be careful ComprehensionBinding cb = comprehension.BindingsAndFilters[i] as ComprehensionBinding; if (cb != null){ scope = cb.ScopeForTemporaryVariables.ClosureClass; break; } } Debug.Assert(scope != null); //TODO: this assert actually fires emptyField.DeclaringType = scope; emptyField.Flags = FieldFlags.CompilerControlled; emptyField.Name = Identifier.For("SS$empty: "+comprehension.GetHashCode()); emptyField.Type = SystemTypes.Boolean; scope.Members.Add(emptyField); empty = new MemberBinding(new ImplicitThis(scope, 0), emptyField); } } #endregion #region retVal := new T(); if (notEnumContext){ Method m = comprehension.nonEnumerableTypeCtor as Method; if (m != null) b.Statements.Add(new AssignmentStatement(retVal, new Construct(new MemberBinding(null,m),new ExpressionList(),nonEnumClass))); else{ TypeNode structure = comprehension.nonEnumerableTypeCtor as TypeNode; b.Statements.Add(new AssignmentStatement(retVal, new Local(StandardIds.NewObj,nonEnumClass))); // !!!! Local normalizes to a pseudo-ctor call for a structure! } } #endregion #region bool empty := true; if (defaultIsPresent){ b.Statements.Add(new AssignmentStatement(empty,new Literal(true,SystemTypes.Boolean))); } #endregion #region Generate code for Displays if (comprehension.IsDisplay){ for (int i = 0, n = comprehension.Elements.Count; i < n; i++){ // Statement s = // notEnumContext ? // new ExpressionStatement(new MethodCall(new MemberBinding(retVal,addMethod),new ExpressionList(Box(comprehension.Elements[i])), // (retVal.Type.IsValueType ? NodeType.Call : NodeType.Callvirt), // SystemTypes.Int32,comprehension.SourceContext)) // : // new Yield(comprehension.Elements[i]) // ; if (useIListMethods){ if (notEnumContext) b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(retVal,addMethod),new ExpressionList(Box(comprehension.Elements[i])), addMethodCallType, SystemTypes.Int32,comprehension.SourceContext))); else b.Statements.Add(new Yield(comprehension.Elements[i])); }else{ // assume IDictionary! if (notEnumContext) { b.Statements.Add(new AssignmentStatement(de,comprehension.Elements[i])); //retval.Add(de.Key,de.Value) (actually, it is "reval.Add(de.get_Key(),de.get_Value())") b.Statements.Add( new ExpressionStatement( new MethodCall(new MemberBinding(retVal,addMethod), new ExpressionList( new MethodCall(new MemberBinding(de,keyMethod),new ExpressionList(),NodeType.Call,SystemTypes.Object), new MethodCall(new MemberBinding(de,valueMethod),new ExpressionList(),NodeType.Call,SystemTypes.Object)), addMethodCallType,SystemTypes.Void))); } else b.Statements.Add(new Yield(comprehension.Elements[i])); } } if (notEnumContext){ if (retVal.Type.IsValueType){ b.Statements.Add(new ExpressionStatement(retVal)); }else{ b.Statements.Add(new ExpressionStatement(new BinaryExpression(retVal,new Literal(nonEnumClass, SystemTypes.Type), NodeType.Castclass,nonEnumClass))); } } if (notEnumContext) return this.VisitExpression(new BlockExpression(b,retVal.Type)); else return new BlockExpression(this.VisitBlock(b),SystemTypes.Void); } #endregion #region Generate code for "true" Comprehensions Block newBlock = new Block(new StatementList(4)); newBlock.HasLocals = true; TypeNode t = null; #region empty := false if (defaultIsPresent){ newBlock.Statements.Add(new AssignmentStatement(empty,new Literal(false,SystemTypes.Boolean))); } #endregion #region either "yield return T(x)" or "t.Add(T(x))" if (notEnumContext){ if (useIListMethods){ if (comprehension.Elements[0]== null) return null; newBlock.Statements.Add( new ExpressionStatement( new MethodCall(new MemberBinding(retVal,addMethod),new ExpressionList(Box(comprehension.Elements[0])),addMethodCallType,SystemTypes.Int32,comprehension.Elements[0].SourceContext))); }else{ // assume IDictionary! newBlock.Statements.Add(new AssignmentStatement(de,comprehension.Elements[0])); //retval.Add(de.Key,de.Value) (actually, it is "reval.Add(de.get_Key(),de.get_Value())") newBlock.Statements.Add( new ExpressionStatement( new MethodCall(new MemberBinding(retVal,addMethod), new ExpressionList( new MethodCall(new MemberBinding(de,keyMethod),new ExpressionList(),NodeType.Call,SystemTypes.Object), new MethodCall(new MemberBinding(de,valueMethod),new ExpressionList(),NodeType.Call,SystemTypes.Object)), addMethodCallType,SystemTypes.Void))); } }else{ newBlock.Statements.Add(new Yield(comprehension.Elements[0])); } #endregion #region Generate the "foreach" and "if P(x)" parts for (int i = comprehension.BindingsAndFilters.Count - 1; i >= 0; i--) { ComprehensionBinding qb = comprehension.BindingsAndFilters[i] as ComprehensionBinding ; if (qb != null){ Expression forEachTargetVariable = qb.TargetVariable; if (qb.SourceEnumerable== null) return null; if (qb.AsTargetVariableType != null){ Local l = new Local(Identifier.For("SS$dummyForEachVar"),qb.SourceEnumerable.Type,newBlock); forEachTargetVariable = l; Block b2 = new Block(new StatementList(2)); b2.Statements.Add(new AssignmentStatement(qb.TargetVariable, new BinaryExpression(l,new MemberBinding(null,qb.AsTargetVariableType),NodeType.Isinst,qb.AsTargetVariableType))); b2.Statements.Add(new If(new BinaryExpression(qb.TargetVariable,new Literal(null,SystemTypes.Type),NodeType.Ne), newBlock,null)); newBlock = b2; } CollectionEnumerator ce = qb.SourceEnumerable as CollectionEnumerator; UnaryExpression u = ce == null ? null : ce.Collection as UnaryExpression; BinaryExpression be = u == null ? null : u.Operand as BinaryExpression; if (be != null && be.NodeType == NodeType.Range){ // implement Range with a for-loop AssignmentStatement init = new AssignmentStatement(forEachTargetVariable,be.Operand1); AssignmentStatement incr = new AssignmentStatement(forEachTargetVariable, new BinaryExpression(forEachTargetVariable,new Literal(1,SystemTypes.Int32),NodeType.Add,SystemTypes.Int32)); Expression cond = new BinaryExpression(forEachTargetVariable,be.Operand2,NodeType.Le,SystemTypes.Boolean); For forloop = new For(new StatementList(init),cond,new StatementList(incr),newBlock); newBlock = new Block(new StatementList(forloop)); }else{ // Just use the source enumerable as an IEnumerable in a foreach loop ForEach fe = new ForEach(qb.SourceEnumerable.Type,forEachTargetVariable,qb.SourceEnumerable,newBlock); fe.ScopeForTemporaryVariables = qb.ScopeForTemporaryVariables; newBlock = new Block(new StatementList(fe)); } }else{ // it's a filter newBlock = new Block(new StatementList(new If(comprehension.BindingsAndFilters[i],newBlock,null))); } } // Need to normalize any foreach loop and if-stmt we just generated newBlock = this.VisitBlock(newBlock); b.Statements.Add(newBlock); #endregion if ( comprehension.Mode == ComprehensionMode.Comprehension ) { #region if (empty) [ yield return default / t.Add(default) ]; if (defaultIsPresent){ Expression addArg = comprehension.Elements[1]; if (useIListMethods){ if (notEnumContext){ newBlock.Statements.Add( this.VisitIf( // need to normalize it new If(new BinaryExpression(empty,new Literal(true,SystemTypes.Boolean),NodeType.Eq), new Block(new StatementList(new ExpressionStatement( new MethodCall(new MemberBinding(retVal,addMethod),new ExpressionList(Box(addArg)),addMethodCallType,SystemTypes.Int32,comprehension.Elements[0].SourceContext)))) ,null))); }else{ newBlock.Statements.Add( this.VisitIf( // need to normalize it new If(new BinaryExpression(empty,new Literal(true,SystemTypes.Boolean),NodeType.Eq), new Block(new StatementList(new Yield(addArg))), null))); } } else { //assume IDictionary! if (notEnumContext){ newBlock.Statements.Add( this.VisitIf( // need to normalize it new If(new BinaryExpression(empty,new Literal(true,SystemTypes.Boolean),NodeType.Eq), new Block(new StatementList(new ExpressionStatement( new MethodCall(new MemberBinding(retVal,addMethod), new ExpressionList( new MethodCall(new MemberBinding(addArg,keyMethod),new ExpressionList(),NodeType.Call,SystemTypes.Object), new MethodCall(new MemberBinding(addArg,valueMethod),new ExpressionList(),NodeType.Call,SystemTypes.Object)), addMethodCallType,SystemTypes.Void)))), null))); } else { newBlock.Statements.Add( this.VisitIf( // need to normalize it new If(new BinaryExpression(empty,new Literal(true,SystemTypes.Boolean),NodeType.Eq), new Block(new StatementList(new Yield(addArg))), null))); } } } #endregion #region [ / return t]; if (notEnumContext){ if (retVal.Type.IsValueType) b.Statements.Add(new ExpressionStatement(retVal)); else b.Statements.Add(new ExpressionStatement(new BinaryExpression(retVal,new Literal(nonEnumClass, SystemTypes.Type), NodeType.Castclass,nonEnumClass))); } #endregion }else{ #region Reduction Method getValMethod = this.GetTypeView(t).GetMethod(Identifier.For("get_Value"),null); MethodCall getValCall = new MethodCall(new MemberBinding(new UnaryExpression(retVal, NodeType.AddressOf, retVal.Type.GetReferenceType()),getValMethod),new ExpressionList(),NodeType.Callvirt,SystemTypes.Object,comprehension.Elements[0].SourceContext); Expression e = null; if (comprehension.Elements[0].Type.IsValueType) { e = Unbox(getValCall,comprehension.Elements[0].Type); }else{ e = new BinaryExpression(getValCall,new Literal(comprehension.Elements[0].Type, SystemTypes.Type), NodeType.Castclass); } newBlock.Statements.Add(new ExpressionStatement(e)); #endregion } if (notEnumContext) return this.VisitExpression(new BlockExpression(b,retVal.Type,comprehension.SourceContext)); else return new BlockExpression(b,SystemTypes.Void,comprehension.SourceContext); #endregion }
public override Expression VisitComprehension(Comprehension comprehension){ if (comprehension == null) return null; if (comprehension.IsDisplay){ comprehension.Elements = this.VisitExpressionList(comprehension.Elements); return comprehension; } Scope savedScope = this.scope; Scope scope = savedScope; Block filter = new Block(new StatementList()); for (int i = 0, n = comprehension.BindingsAndFilters == null ? 0 : comprehension.BindingsAndFilters.Count; i < n; i++){ ComprehensionBinding comprehensionBinding = comprehension.BindingsAndFilters[i] as ComprehensionBinding; if (comprehensionBinding != null){ filter = new Block(new StatementList()); scope = this.scope = comprehensionBinding.ScopeForTemporaryVariables = new BlockScope(scope, filter); this.AddToAllScopes(this.scope); comprehensionBinding.TargetVariableType = this.VisitTypeReference(comprehensionBinding.TargetVariableType, true); comprehensionBinding.AsTargetVariableType = this.VisitTypeReference(comprehensionBinding.AsTargetVariableType); comprehensionBinding.SourceEnumerable = this.VisitExpression(comprehensionBinding.SourceEnumerable); Identifier targetId = comprehensionBinding.TargetVariable as Identifier; if (targetId != null){ Field f = new Field(); f.DeclaringType = scope; f.Flags = FieldFlags.CompilerControlled|FieldFlags.InitOnly; f.Name = targetId; f.Type = comprehensionBinding.TargetVariableType; scope.Members.Add(f); comprehensionBinding.TargetVariable = new MemberBinding(new ImplicitThis(scope, 0), f); comprehensionBinding.TargetVariable.SourceContext = targetId.SourceContext; this.AddNodePositionAndInfo(targetId, comprehensionBinding.TargetVariable, IdentifierContexts.AllContext); } }else{ // it's a filter Expression qf = comprehension.BindingsAndFilters[i] = this.VisitExpression(comprehension.BindingsAndFilters[i]); if (qf != null) filter.Statements.Add(new ExpressionStatement(qf)); //REVIEW: why do this here? //Also, does this assumes that qf will not be changed by a later visitor? } } if (comprehension.Elements != null && comprehension.Elements.Count > 0) comprehension.Elements[0] = this.VisitExpression(comprehension.Elements[0]); this.scope = savedScope; if (comprehension.Elements != null && comprehension.Elements.Count > 1) comprehension.Elements[1] = this.VisitExpression(comprehension.Elements[1]); return comprehension; }
public override Expression VisitComprehension(Comprehension comprehension) { if (comprehension == null) return null; if (this._string == null){ this._string = new StringBuilder(); } if (comprehension.nonEnumerableTypeCtor != null){ // then this comprehension represents an expression of the form "new T{...}" this._string.Append("new"); this.AddType(comprehension.Type); this._string.Append(","); this.Visit(comprehension.AddMethod); this._string.Append(","); this.Visit(comprehension.nonEnumerableTypeCtor); this._string.Append(","); } if (comprehension.IsDisplay){ this._string.Append("(|"); TypeNode t = comprehension.nonEnumerableTypeCtor == null ? comprehension.Type : comprehension.TemporaryHackToHoldType; t = TypeNode.StripModifiers(t); Debug.Assert(t != null && t.TemplateArguments != null && t.TemplateArguments.Count == 1, "ContractSerializer: bad display"); this.AddType(t.TemplateArguments[0]); this._string.Append(","); this.VisitExpressionList(comprehension.Elements); this._string.Append("|)"); }else{ if (comprehension.BindingsAndFilters == null) return null; this._string.Append("{|"); for (int i = 0, n = comprehension.BindingsAndFilters.Count; i < n; i++){ ComprehensionBinding b = comprehension.BindingsAndFilters[i] as ComprehensionBinding; if (b != null){ this._string.Append("{"); this.AddType(b.TargetVariableType); this._string.Append(","); this.VisitExpression(b.TargetVariable); this._string.Append(","); this.VisitExpression(b.SourceEnumerable); this._string.Append("}"); } else { // filter this._string.Append("("); this.VisitExpression(comprehension.BindingsAndFilters[i]); this._string.Append(")"); } } this._string.Append(";"); this.VisitExpression(comprehension.Elements[0]); if (comprehension.Elements.Count > 1){ this._string.Append(";"); this.VisitExpression(comprehension.Elements[1]); } this._string.Append("|}"); } return comprehension; }
public virtual void VisitComprehension(Comprehension comprehension) { if (comprehension == null) return; this.VisitExpressionList(comprehension.BindingsAndFilters); this.VisitExpressionList(comprehension.Elements); }
public virtual Differences VisitComprehension(Comprehension comprehension1, Comprehension comprehension2){ Differences differences = new Differences(comprehension1, comprehension2); if (comprehension1 == null || comprehension2 == null){ if (comprehension1 != comprehension2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } Comprehension changes = (Comprehension)comprehension2.Clone(); Comprehension deletions = (Comprehension)comprehension2.Clone(); Comprehension insertions = (Comprehension)comprehension2.Clone(); ExpressionList exprChanges, exprDeletions, exprInsertions; Differences diff = this.VisitExpressionList(comprehension1.BindingsAndFilters, comprehension2.BindingsAndFilters, out exprChanges, out exprDeletions, out exprInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.BindingsAndFilters = exprChanges; deletions.BindingsAndFilters = exprDeletions; insertions.BindingsAndFilters = exprInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; diff = this.VisitExpressionList(comprehension1.Elements, comprehension2.Elements, out exprChanges, out exprDeletions, out exprInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.Elements = exprChanges; deletions.Elements = exprDeletions; insertions.Elements = exprInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (comprehension1.Mode == comprehension2.Mode) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++; if (differences.NumberOfDifferences == 0){ differences.Changes = null; differences.Deletions = null; differences.Insertions = null; }else{ differences.Changes = changes; differences.Deletions = deletions; differences.Insertions = insertions; } return differences; }
public override Expression VisitComprehension(Comprehension Comprehension) { if (Comprehension == null) return null; return base.VisitComprehension((Comprehension)Comprehension.Clone()); }
public DictionaryComprehensionAnalysisUnit(Comprehension node, PythonAst parent, AnalysisUnit outerUnit, InterpreterScope outerScope) : base(node, parent, new ComprehensionScope(new DictionaryInfo(outerUnit.ProjectEntry, node), node, outerScope), outerUnit) { }
public override Expression VisitComprehension(Comprehension comprehension) { if (comprehension == null) { return(null); } if (this._string == null) { this._string = new StringBuilder(); } if (comprehension.nonEnumerableTypeCtor != null) { // then this comprehension represents an expression of the form "new T{...}" this._string.Append("new"); this.AddType(comprehension.Type); this._string.Append(","); this.Visit(comprehension.AddMethod); this._string.Append(","); this.Visit(comprehension.nonEnumerableTypeCtor); this._string.Append(","); } if (comprehension.IsDisplay) { this._string.Append("(|"); TypeNode t = comprehension.nonEnumerableTypeCtor == null ? comprehension.Type : comprehension.TemporaryHackToHoldType; t = TypeNode.StripModifiers(t); Debug.Assert(t != null && t.TemplateArguments != null && t.TemplateArguments.Count == 1, "ContractSerializer: bad display"); this.AddType(t.TemplateArguments[0]); this._string.Append(","); this.VisitExpressionList(comprehension.Elements); this._string.Append("|)"); } else { if (comprehension.BindingsAndFilters == null) { return(null); } this._string.Append("{|"); for (int i = 0, n = comprehension.BindingsAndFilters.Count; i < n; i++) { ComprehensionBinding b = comprehension.BindingsAndFilters[i] as ComprehensionBinding; if (b != null) { this._string.Append("{"); this.AddType(b.TargetVariableType); this._string.Append(","); this.VisitExpression(b.TargetVariable); this._string.Append(","); this.VisitExpression(b.SourceEnumerable); this._string.Append("}"); } else { // filter this._string.Append("("); this.VisitExpression(comprehension.BindingsAndFilters[i]); this._string.Append(")"); } } this._string.Append(";"); this.VisitExpression(comprehension.Elements[0]); if (comprehension.Elements.Count > 1) { this._string.Append(";"); this.VisitExpression(comprehension.Elements[1]); } this._string.Append("|}"); } return(comprehension); }
void Display(out Expression e) { Comprehension ch = new Comprehension(); ExpressionList es = new ExpressionList(); TypeNode tn = null; Expect(68); PType(out tn); ch.Type = SystemTypes.GenericIEnumerable.GetTemplateInstance(currentAssembly,tn); Expect(23); if (StartOf(3)) { Expr(out e); es.Add(e); while (la.kind == 23) { Get(); Expr(out e); es.Add(e); } } Expect(69); ch.Elements = es; e = ch; }
void TrueComprehension(out Expression e) { Expression body; ExpressionList elist; BlockScope oldBlock = currentBlock; Comprehension compr = new Comprehension(); Expect(65); FiltersAndBindings(out elist); Expect(66); Expr(out body); Expect(67); compr.BindingsAndFilters = elist; compr.Elements = new ExpressionList(body); compr.Type = SystemTypes.GenericIEnumerable.GetTemplateInstance(currentAssembly,body.Type); e = compr; currentBlock = oldBlock; }
public ComprehensionScope(AnalysisValue comprehensionResult, Comprehension comprehension, InterpreterScope outerScope) : base(comprehensionResult, comprehension, outerScope) { }
public override Expression VisitComprehension(Comprehension comprehension) { if (comprehension == null) return null; if ((this.insideMethodContract || this.insideInvariant) && this.currentMethod != null && this.currentMethod.DeclaringType != null && this.currentMethod.DeclaringType is ClosureClass) { // for now we don't allow comprehensions that end up creating closures in contracts because we aren't // able to deserialize them for cross-assembly inheritance and for static verification this.HandleError(comprehension, Error.GeneralComprehensionsNotAllowedInMethodContracts); return null; } if (comprehension.BindingsAndFilters != null) { for (int i = 0; i < comprehension.BindingsAndFilters.Count; i++) { Expression bindingOrFilter = comprehension.BindingsAndFilters[i]; ComprehensionBinding comprehensionBinding = bindingOrFilter as ComprehensionBinding; if (comprehensionBinding != null) { comprehensionBinding.TargetVariableType = this.VisitTypeReference(comprehensionBinding.TargetVariableType); comprehensionBinding.TargetVariable = this.VisitTargetExpression(comprehensionBinding.TargetVariable); comprehensionBinding.AsTargetVariableType = this.VisitTypeReference(comprehensionBinding.AsTargetVariableType); comprehensionBinding.SourceEnumerable = this.VisitEnumerableCollection(comprehensionBinding.SourceEnumerable, comprehensionBinding.TargetVariableType); if (comprehensionBinding.AsTargetVariableType != null) { if (comprehensionBinding.AsTargetVariableType.IsValueType) { this.HandleError(comprehensionBinding, Error.AsMustHaveReferenceType, this.GetTypeName(comprehensionBinding.AsTargetVariableType)); return null; } else if (!this.GetTypeView(comprehensionBinding.AsTargetVariableType).IsAssignableTo(comprehensionBinding.TargetVariableType)) { this.HandleError(comprehensionBinding, Error.ImpossibleCast, this.GetTypeName(comprehensionBinding.TargetVariableType), this.GetTypeName(comprehensionBinding.AsTargetVariableType)); return null; } } if (comprehensionBinding.TargetVariableType == null) { return null; //REVIEW: does Normalizer care about this being non null. Perhaps it should check for it and fail gracefully. //If so, there is no neeed to stop the error checking this abruptly } } else { // it should be a filter comprehension.BindingsAndFilters[i] = this.VisitBooleanExpression(bindingOrFilter); if (comprehension.BindingsAndFilters[i] == null) { // then something went wrong, bail out and null out this entire comprehension return null; } } } } comprehension.Elements = this.VisitExpressionList(comprehension.Elements); if (comprehension.Elements == null) return null; TypeNode comprehensionType = TypeNode.StripModifiers(comprehension.Type); if (comprehensionType == null) return null; TypeNode eltType = null; if (comprehension.nonEnumerableTypeCtor == null) { // then this comprehension is within a quantifier // the elements need to be of the type the quantifier consumes if (comprehensionType.TemplateArguments ==null || comprehensionType.TemplateArguments.Count ==0) { this.HandleError(comprehension, Error.NoSuchType, this.GetTypeName(comprehensionType)); return null; } if (comprehensionType.Template != SystemTypes.GenericIEnumerable || comprehensionType.TemplateArguments == null || comprehensionType.TemplateArguments.Count != 1) { return null; //Resolver failed, bail out } eltType = comprehensionType.TemplateArguments[0]; } else { // this comprehension is within a "new T{...}" expression. // the resolver put the unified type that was computed for the elements into a temporary place // so that the type of the comprehension could be modified to be T since it took the place of // the construct node that had been representing the "new T{...}" expression. // if (comprehension.Type.Template != SystemTypes.GenericIEnumerable || // comprehension.Type.TemplateArguments == null || comprehension.Type.TemplateArguments.Length != 1){ // return null; //Resolver failed, bail out // } if (comprehension.TemporaryHackToHoldType == null) { return null; } TypeNode temp = TypeNode.StripModifiers(comprehension.TemporaryHackToHoldType); if (temp.Template != SystemTypes.GenericIEnumerable || temp.TemplateArguments == null || temp.TemplateArguments.Count != 1) { return null; //Resolver failed, bail out } eltType = temp.TemplateArguments[0]; } if (eltType == null) { Debug.Assert(false); return null; } for (int i = 0, n = comprehension.Elements.Count; i < n; i++) { Expression e = comprehension.Elements[i]; if (e == null) continue; comprehension.Elements[i] = e = this.typeSystem.ImplicitCoercion(e, eltType, this.TypeViewer); if (e == null) return null; //REVIEW: Normalizer should not rely on these elements not being null, so why not just continue? } if (comprehension.nonEnumerableTypeCtor == null) { if (!this.insideMethodContract && !this.insideAssertOrAssume && !this.insideQuantifier) { this.yieldNode = new Yield(); // } } else { InstanceInitializer c = comprehension.nonEnumerableTypeCtor as InstanceInitializer; if (c != null) { if (c.DeclaringType != null && c.DeclaringType.IsAbstract) { if (c.DeclaringType.IsSealed) this.HandleError(comprehension, Error.ConstructsAbstractSealedClass, this.GetTypeName(c.DeclaringType)); else this.HandleError(comprehension, Error.ConstructsAbstractClass, this.GetTypeName(c.DeclaringType)); } else if (this.NotAccessible(c)) { this.HandleError(comprehension, Error.MemberNotVisible, this.GetMemberSignature(c)); return null; } this.CheckForObsolesence(comprehension, c); if (this.NotAccessible(comprehension.AddMethod)) { this.HandleError(comprehension, Error.MemberNotVisible, this.GetMethodSignature(comprehension.AddMethod)); return null; } this.CheckForObsolesence(comprehension, comprehension.AddMethod); } } return comprehension; }
public virtual Expression VisitComprehension(Comprehension comprehension){ if (comprehension == null) return null; comprehension.BindingsAndFilters = this.VisitExpressionList(comprehension.BindingsAndFilters); comprehension.Elements = this.VisitExpressionList(comprehension.Elements); return comprehension; }
private static string comprehension2str(Comprehension comp) {//int i in(0:10),int j in (0:5);a[i]==a[j];a[j]=b[i] StringBuilder sb = new StringBuilder(); //filters for (int i = 0; i < comp.BindingsAndFilters.Count; i++) { if (i > 0) sb.Append(", "); ComprehensionBinding cb = (ComprehensionBinding)comp.BindingsAndFilters[i]; sb.Append(comprehensionbinding2str(cb)); } sb.Append("; "); //elements for (int i = 0; i < comp.Elements.Count; i++) { if (i > 0) sb.Append("; "); Expression exp = comp.Elements[i]; sb.Append(expression2str(exp)); } return sb.ToString(); }
public virtual Expression VisitComprehension(Comprehension comprehension1, Comprehension comprehension2) { if (comprehension1 == null) return null; if (comprehension2 == null) { comprehension1.BindingsAndFilters = this.VisitExpressionList(comprehension1.BindingsAndFilters, null); comprehension1.Elements = this.VisitExpressionList(comprehension1.Elements, null); } else { comprehension1.BindingsAndFilters = this.VisitExpressionList(comprehension1.BindingsAndFilters, comprehension2.BindingsAndFilters); comprehension1.Elements = this.VisitExpressionList(comprehension1.Elements, comprehension2.Elements); } return comprehension1; }