Exemple #1
0
        private ComprehensionScope MakeGeneratorComprehensionScope(Comprehension node)
        {
            var unit = new GeneratorComprehensionAnalysisUnit(node, _tree, _curUnit, _scope);

            unit.Enqueue();
            return((ComprehensionScope)unit.Scope);
        }
Exemple #2
0
        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);
        }
Exemple #5
0
        private void CollectNames(Comprehension c)
        {
            var nc = new NameCollectorWalker(_localNames, _localNameNodes);

            foreach (var cfor in c.Iterators.OfType <ComprehensionFor>())
            {
                cfor.Left?.Walk(nc);
            }
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
            }
        }
Exemple #8
0
        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;
            }
        }
Exemple #9
0
        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)
 {
 }
Exemple #11
0
        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);
            }
        }
Exemple #13
0
        /// <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);
        }
Exemple #16
0
        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);
                    }
                }
            }
        }
Exemple #17
0
        // 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);
        }
Exemple #18
0
  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;
 }
Exemple #19
0
 public SetComprehensionAnalysisUnit(Comprehension node, PythonAst parent, AnalysisUnit outerUnit, InterpreterScope outerScope)
     : base(node, parent,
            new ComprehensionScope(new SetInfo(outerUnit.ProjectState, node), node, outerScope),
            outerUnit)
 {
 }
Exemple #20
0
    // {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;
 }
Exemple #22
0
    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;
    }
Exemple #23
0
 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;
    }
Exemple #25
0
 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)
 {
 }
Exemple #27
0
        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;
		
	}
Exemple #30
0
 public ComprehensionScope(AnalysisValue comprehensionResult, Comprehension comprehension, InterpreterScope outerScope)
     : base(comprehensionResult, comprehension, outerScope)
 {
 }
Exemple #31
0
    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;
    }
Exemple #32
0
 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;
 }