Example #1
0
        public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name)
        {
            // Must unconditionally call the base implementation of GetMember
            var ignored = base.GetMember(node, unit, name);

            var mro = ClassInfo._mro;

            if (!mro.IsValid)
            {
                return(AnalysisSet.Empty);
            }

            // First item in MRO list is always the class itself.
            var member = Values.Mro.GetMemberFromMroNoReferences(mro.Skip(1), node, unit, name, addRef: true);

            if (member == null)
            {
                return(AnalysisSet.Empty);
            }

            var          instances = _instances.Any() ? _instances : unit.ProjectState._noneInst.SelfSet;
            IAnalysisSet result    = AnalysisSet.Empty;

            foreach (var instance in instances)
            {
                var desc = member.GetDescriptor(node, instance, this, unit);
                result = result.Union(desc);
            }

            return(result);
        }
        internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength)
        {
            if (strength > 0 && av is ProtocolInfo pi && pi.Push())
            {
                try {
                    var name = _protocols.OfType <NameProtocol>().FirstOrDefault();
                    if (_protocols.Count == 1 && name != null)
                    {
                        return(this);
                    }

                    var protocols = _protocols.Union(pi._protocols, out bool changed);
                    if (!changed)
                    {
                        return(this);
                    }

                    if (name != null)
                    {
                        protocols.Split <NameProtocol>(out _, out protocols);
                        protocols = protocols.Add(name);
                    }

                    return(new ProtocolInfo(DeclaringModule, State)
                    {
                        _protocols = protocols
                    });
                } finally {
                    pi.Pop();
                }
            }

            return(this);
        }
        private static IAnalysisSet QuickOp(IAnalysisSet lhs, PythonOperator op, IAnalysisSet rhs, PythonAnalyzer state)
        {
            // Concrete return for known (or conventional) operations
            switch (op)
            {
            case PythonOperator.Equal:
            case PythonOperator.In:
            case PythonOperator.Is:
            case PythonOperator.IsNot:
            case PythonOperator.Not:
            case PythonOperator.NotEqual:
            case PythonOperator.NotIn:
                return(state.ClassInfos[BuiltinTypeId.Bool].Instance);

            case PythonOperator.GreaterThan:
            case PythonOperator.GreaterThanOrEqual:
            case PythonOperator.LessThan:
            case PythonOperator.LessThanOrEqual:
                return(lhs.Union(rhs));

            case PythonOperator.Negate:
            case PythonOperator.Pos:
                return(rhs);
            }
            return(null);
        }
Example #4
0
        private static IAnalysisSet FsBasename(FunctionValue func, Node node, AnalysisUnit unit, IAnalysisSet @this, IAnalysisSet[] args)
        {
            CallNode     call = (CallNode)node;
            IAnalysisSet res  = AnalysisSet.Empty;

            if (args.Length == 2)
            {
                foreach (var extArg in args[1])
                {
                    var strExt = extArg.Value.GetStringValue();
                    if (strExt != null)
                    {
                        foreach (var nameArg in args[0])
                        {
                            string name = nameArg.Value.GetStringValue();
                            if (name != null)
                            {
                                string oldName = name;
                                if (name.EndsWith(strExt, StringComparison.OrdinalIgnoreCase))
                                {
                                    name = name.Substring(0, name.Length - strExt.Length);
                                }
                                res = res.Union(unit.Analyzer.GetConstant(name).Proxy);
                            }
                        }
                    }
                }
            }
            if (res.Count == 0)
            {
                return(unit.Analyzer._emptyStringValue.SelfSet);
            }
            return(res);
        }
Example #5
0
            public IAnalysisSet GetValue(Node node, AnalysisUnit unit, ProjectEntry declaringScope, IAnalysisSet @this, bool addRef)
            {
                IAnalysisSet res   = _propDesc.GetValue(node, unit, declaringScope, @this, addRef);
                var          types = _instance._linkedValues.GetTypes(unit, declaringScope);

                try {
                    foreach (var prototype in types)
                    {
                        if (ObjectValue.PushProtoLookup(prototype.Value))
                        {
                            var value = prototype.Value.GetProperty(node, unit, _name);
                            if (value != null)
                            {
                                res = res.Union(value.GetValue(node, unit, declaringScope, @this, addRef));
                            }
                        }
                    }
                } finally {
                    foreach (var prototype in types)
                    {
                        ObjectValue.PopProtoLookup(prototype.Value);
                    }
                }

                return(res);
            }
Example #6
0
        public IAnalysisSet ResolveParameter(AnalysisUnit unit, string name, ArgumentSet arguments)
        {
            var parameters = FunctionDefinition.Parameters;

            if (parameters == null || parameters.Count == 0)
            {
                return(ResolveParameter(unit, name));
            }

            for (int i = 0; i < parameters.Count; ++i)
            {
                if (parameters[i].Name == name)
                {
                    IAnalysisSet res = AnalysisSet.Empty;
                    if (i < arguments.Count)
                    {
                        arguments.Args[i].Split(v => (v as ParameterInfo)?.Function != this, out var args, out _);
                        res = res.Union(args);
                    }
                    if (parameters[i].IsList)
                    {
                        arguments.SequenceArgs.Split(v => (v as ParameterInfo)?.Function != this, out var args, out _);
                        res = res.Add(new LazyIndexableInfo(parameters[i], args, () => ResolveParameter(_analysisUnit, parameters[i].Name)));
                    }
                    if (parameters[i].IsDictionary)
                    {
                        arguments.DictArgs.Split(v => (v as ParameterInfo)?.Function != this, out var args, out _);
                        res = res.Add(new LazyIndexableInfo(parameters[i], args, () => ResolveParameter(_analysisUnit, parameters[i].Name)));
                    }
                    return(res);
                }
            }

            return(ResolveParameter(unit, name));
        }
Example #7
0
        private IAnalysisSet GetRecurse(AnalysisValue protoStart, Node node, AnalysisUnit unit, string name, bool addRef)
        {
            var          prototypes = protoStart.GetPrototype(unit.ProjectEntry);
            IAnalysisSet protovalue = AnalysisSet.Empty;

            if (prototypes != null)
            {
                try {
                    foreach (var proto in prototypes)
                    {
                        if (PushProtoLookup(proto.Value))
                        {
                            var property = proto.Value.GetProperty(node, unit, name);
                            if (property != null)
                            {
                                var value = property.GetValue(
                                    node,
                                    unit,
                                    proto.Value.DeclaringModule,
                                    this.SelfSet,
                                    addRef
                                    );
                                protovalue = protovalue.Union(value);
                                if (property.IsEphemeral)
                                {
                                    protovalue = protovalue.Union(GetRecurse(proto.Value, node, unit, name, addRef));
                                }
                            }
                            else
                            {
                                // keep searching the prototype chain...
                                protovalue = protovalue.Union(GetRecurse(proto.Value, node, unit, name, addRef));
                            }
                        }
                    }
                } finally {
                    foreach (var proto in prototypes)
                    {
                        PopProtoLookup(proto.Value);
                    }
                }
            }

            return(protovalue);
        }
        internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength)
        {
            var combined = _indexTypes.Union(((av as LazyIndexableInfo)?._indexTypes).MaybeEnumerate().Where(v => !ReferenceEquals(v, this)));

            if (!combined.SetEquals(_indexTypes))
            {
                return(new LazyIndexableInfo(Node, combined, _fallback));
            }
            return(this);
        }
Example #9
0
 private IAnalysisSet ChooseBest(IAnalysisSet x, IAnalysisSet y)
 {
     if (x == null || x.IsObjectOrUnknown())
     {
         return((y == null || y.IsObjectOrUnknown()) ? AnalysisSet.Empty : y);
     }
     if (y == null || y.IsObjectOrUnknown())
     {
         return(AnalysisSet.Empty);
     }
     return(x.Union(y));
 }
Example #10
0
        private static void TestImmutableSet(IAnalysisSet emptySet)
        {
            int count = emptySet.Count;

            var projectEntry = CreateProjectEntry();
            var value        = new TestAnalysisValue(projectEntry);

            var newSet = emptySet.Add(value.Proxy);

            Assert.AreNotEqual(emptySet, newSet);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            bool wasChanged;

            newSet = emptySet.Add(value.Proxy, out wasChanged);
            Assert.AreNotEqual(emptySet, newSet);
            Assert.IsTrue(wasChanged);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            newSet = emptySet.Union(new[] { value.Proxy });
            Assert.AreNotEqual(emptySet, newSet);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            newSet = emptySet.Union(new[] { value.Proxy }, out wasChanged);
            Assert.IsTrue(wasChanged);
            Assert.AreNotEqual(emptySet, newSet);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            Assert.AreEqual(emptySet, emptySet.Clone());

            Assert.IsFalse(emptySet.Contains(value.Proxy));
        }
Example #11
0
        /// <summary>
        /// Merges all the types in <paramref name="sets" /> into this set.
        /// </summary>
        /// <param name="sets">The sets to merge into this set.</param>
        /// <param name="wasChanged">Returns True if the contents of the
        /// returned set are different to the original set.</param>
        public static IAnalysisSet UnionAll(this IAnalysisSet set, IEnumerable <IAnalysisSet> sets, out bool wasChanged)
        {
            bool changed;

            wasChanged = false;
            foreach (var s in sets)
            {
                var newSet = set.Union(s, out changed);
                if (changed)
                {
                    wasChanged = true;
                }
                set = newSet;
            }
            return(set);
        }
Example #12
0
        internal static IAnalysisSet Resolve(this IAnalysisSet self, AnalysisUnit unit, ResolutionContext context, out bool changed)
        {
            // The vast majority of the time, no values are resolved
            // So we want to quickly validate and get out without allocating
            // or changing anything.

            if (!context.Push())
            {
                changed = false;
                return(self);
            }
            try {
                List <AnalysisValue> removed = null;
                IAnalysisSet         added   = null;
                foreach (var ns in self)
                {
                    var r = ns.Resolve(unit, context);
                    if (!ReferenceEquals(r, ns))
                    {
                        if (removed == null)
                        {
                            removed = new List <AnalysisValue>(self.Count);
                        }
                        removed.Add(ns);
                        added = added?.Union(r) ?? r;
                    }
                }

                if (removed == null)
                {
                    changed = false;
                    return(self);
                }

                self.Split(removed.Contains, out _, out var unchanged);
                var res = unchanged.Union(added, out changed);
                if (changed && res.SetEquals(self))
                {
                    changed = false;
                    return(self);
                }
                return(res);
            } finally {
                context.Pop();
            }
        }
Example #13
0
 private bool TryInvokeMethod(Node node, AnalysisUnit unit, string name, IAnalysisSet[] args, out IAnalysisSet res) {
     res = AnalysisSet.Empty;
     bool invoked = false;
     var members = GetTypeMember(node, unit, name);
     foreach (var member in members) {
         if (ShouldInvokeMethod(member, name)) {
             invoked = true;
             res = res.Union(
                 member.Call(
                     node,
                     unit,
                     args,
                     ExpressionEvaluator.EmptyNames
                 )
             );
         }
     }
     return invoked;
 }
Example #14
0
 protected override void EnsureUnionType()
 {
     if (_unionType == null)
     {
         IAnalysisSet unionType = AnalysisSet.EmptyUnion;
         if (Push())
         {
             try {
                 foreach (var set in _indexTypes)
                 {
                     unionType = unionType.Union(set.TypesNoCopy);
                 }
             } finally {
                 Pop();
             }
         }
         _unionType = unionType;
     }
 }
Example #15
0
        private void RecomputeBaseSpecialization()
        {
            IAnalysisSet builtinClassSet = AnalysisSet.Empty;

            foreach (var classInfo in _mro)
            {
                BuiltinClassInfo builtin = classInfo as BuiltinClassInfo;
                if (builtin != null && builtin.TypeId != BuiltinTypeId.Object)
                {
                    var builtinType = _projectState.GetBuiltinType(builtin.PythonType);

                    if (builtinType.GetType() != typeof(BuiltinClassInfo))
                    {
                        // we have a specialized built-in class, we want its behavior too...
                        builtinClassSet = builtinClassSet.Union(builtinType.SelfSet, true);
                    }
                }
            }
            _baseSpecialization = builtinClassSet;
        }
Example #16
0
 protected override void EnsureUnionType()
 {
     if (_unionType.IsObjectOrUnknown())
     {
         IAnalysisSet unionType = AnalysisSet.EmptyUnion;
         if (Push())
         {
             try {
                 foreach (var set in IndexTypes)
                 {
                     unionType = unionType.Union(set.TypesNoCopy);
                 }
             } finally {
                 Pop();
             }
         }
         unionType.Split(this.Equals, out _, out unionType);
         _unionType = unionType;
     }
 }
Example #17
0
            public IAnalysisSet GetValue(Node node, AnalysisUnit unit, ProjectEntry declaringScope, IAnalysisSet @this, bool addRef)
            {
                IAnalysisSet res = AnalysisSet.Empty;

                foreach (var prototype in _instance._prototypes)
                {
                    if (prototype.Value.Push())
                    {
                        try {
                            var value = prototype.Value.GetProperty(node, unit, _name);
                            if (value != null)
                            {
                                res = res.Union(value.GetValue(node, unit, declaringScope, @this, addRef));
                            }
                        } finally {
                            prototype.Value.Pop();
                        }
                    }
                }
                return(res);
            }
        public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name)
        {
            var          members = base.GetMember(node, unit, name);
            IAnalysisSet res     = AnalysisSet.Empty;
            bool         found   = false;

            foreach (var member in members)
            {
                if (ShouldInvokeMethod(member, name))
                {
                    found = true;
                    res   = res.Union(member.SelfSet);
                }
            }
            if (found)
            {
                return(res);
            }

            return(_instances.GetMember(node, unit, name));
        }
        private bool TryInvokeMethod(Node node, AnalysisUnit unit, string name, IAnalysisSet[] args, out IAnalysisSet res)
        {
            res = AnalysisSet.Empty;
            bool invoked = false;
            var  members = GetTypeMember(node, unit, name);

            foreach (var member in members)
            {
                if (ShouldInvokeMethod(member, name))
                {
                    invoked = true;
                    res     = res.Union(
                        member.Call(
                            node,
                            unit,
                            args,
                            ExpressionEvaluator.EmptyNames
                            )
                        );
                }
            }
            return(invoked);
        }
Example #20
0
        public static IAnalysisSet Union(this IAnalysisSet set, IEnumerable <AnalysisProxy> items)
        {
            bool dummy;

            return(set.Union(items, out dummy));
        }
Example #21
0
 public void AddPrototypes(IAnalysisSet values)
 {
     _prototypes = _prototypes.Union(values);
 }
        private static void TestImmutableSet(IAnalysisSet emptySet) {
            int count = emptySet.Count;

            var projectEntry = CreateProjectEntry();
            var value = new TestAnalysisValue(projectEntry);

            var newSet = emptySet.Add(value.Proxy);
            Assert.AreNotEqual(emptySet, newSet);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            bool wasChanged;
            newSet = emptySet.Add(value.Proxy, out wasChanged);
            Assert.AreNotEqual(emptySet, newSet);
            Assert.IsTrue(wasChanged);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            newSet = emptySet.Union(new[] { value.Proxy });
            Assert.AreNotEqual(emptySet, newSet);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            newSet = emptySet.Union(new[] { value.Proxy }, out wasChanged);
            Assert.IsTrue(wasChanged);
            Assert.AreNotEqual(emptySet, newSet);
            Assert.AreEqual(count, emptySet.Count);
            Assert.AreEqual(count + 1, newSet.Count);

            Assert.AreEqual(emptySet, emptySet.Clone());

            Assert.IsFalse(emptySet.Contains(value.Proxy));
        }
Example #23
0
        public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name)
        {
            // __getattribute__ takes precedence over everything.
            IAnalysisSet getattrRes   = AnalysisSet.Empty;
            var          getAttribute = _classInfo.GetMemberNoReferences(node, unit.CopyForEval(), "__getattribute__");

            if (getAttribute.Count > 0)
            {
                foreach (var getAttrFunc in getAttribute)
                {
                    var func = getAttrFunc as BuiltinMethodInfo;
                    if (func != null && func.Function.DeclaringType.TypeId == BuiltinTypeId.Object)
                    {
                        continue;
                    }
                    // TODO: We should really do a get descriptor / call here
                    getattrRes = getattrRes.Union(getAttrFunc.Call(node, unit, new[] { SelfSet, ProjectState.ClassInfos[BuiltinTypeId.Str].Instance.SelfSet }, ExpressionEvaluator.EmptyNames));
                }
            }

            // ok, it must be an instance member, or it will become one later
            VariableDef def;

            if (_instanceAttrs == null)
            {
                _instanceAttrs = new Dictionary <string, VariableDef>();
            }
            if (!_instanceAttrs.TryGetValue(name, out def))
            {
                _instanceAttrs[name] = def = new EphemeralVariableDef();
            }
            def.AddReference(node, unit);
            def.AddDependency(unit);

            // now check class members
            var res = GetTypeMember(node, unit, name);

            res = res.Union(def.Types);

            // check and see if it's defined in a base class instance as well...
            foreach (var b in _classInfo.Bases)
            {
                foreach (var ns in b)
                {
                    if (ns.Push())
                    {
                        try {
                            ClassInfo baseClass = ns as ClassInfo;
                            if (baseClass != null &&
                                baseClass.Instance._instanceAttrs != null &&
                                baseClass.Instance._instanceAttrs.TryGetValue(name, out def))
                            {
                                res = res.Union(def.GetTypesNoCopy(unit, DeclaringModule));
                            }
                        } finally {
                            ns.Pop();
                        }
                    }
                }
            }

            if (res.Count == 0)
            {
                // and if that doesn't exist fall back to __getattr__
                var getAttr = _classInfo.GetMemberNoReferences(node, unit, "__getattr__");
                if (getAttr.Count > 0)
                {
                    foreach (var getAttrFunc in getAttr)
                    {
                        getattrRes = getattrRes.Union(getAttr.Call(node, unit, new[] { SelfSet, _classInfo.AnalysisUnit.State.ClassInfos[BuiltinTypeId.Str].Instance.SelfSet }, ExpressionEvaluator.EmptyNames));
                    }
                }
                return(getattrRes);
            }
            return(res);
        }
Example #24
0
        private static bool IsSpecialRequire(AnalysisUnit unit, CallNode n, ref IAnalysisSet res) {
            bool hitLiteral = false;
            if (n.Arguments.Length == 1) {
                var ee = new ExpressionEvaluator(unit);

                foreach (var name in ee.MergeStringLiterals(n.Arguments[0])) {
                    hitLiteral = true;
                    res = res.Union(
                        unit.Analyzer.Modules.RequireModule(
                            n,
                            unit,
                            name,
                            unit.DeclaringModuleEnvironment.Name
                        )
                    );
                }
            }

            return hitLiteral;
        }