예제 #1
0
 public SpecializedInstanceInfo(ClassInfo klass, IAnalysisSet instances) : base(klass)
 {
     _instances = instances;
 }
예제 #2
0
 public InstanceInfo(ClassInfo classInfo)
 {
     _classInfo = classInfo;
 }
예제 #3
0
 public SuperInfo(ClassInfo classInfo, IAnalysisSet instances = null)
 {
     _classInfo = classInfo;
     _instances = instances ?? AnalysisSet.Empty;
 }
예제 #4
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);

            // __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.TypesNoCopy);
                            }
                        } 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.ProjectState.ClassInfos[BuiltinTypeId.Str].Instance.SelfSet }, ExpressionEvaluator.EmptyNames));
                    }
                }
                return(getattrRes);
            }
            return(res);
        }
예제 #5
0
        public override IDictionary <string, IAnalysisSet> GetAllMembers(IModuleContext moduleContext, GetMemberOptions options = GetMemberOptions.None)
        {
            var res = new Dictionary <string, IAnalysisSet>();

            if (_instanceAttrs != null)
            {
                foreach (var kvp in _instanceAttrs)
                {
                    var types = kvp.Value.TypesNoCopy;
                    var key   = kvp.Key;
                    if (!options.ForEval())
                    {
                        kvp.Value.ClearOldValues();
                    }
                    if (kvp.Value.VariableStillExists)
                    {
                        MergeTypes(res, key, types);
                    }
                }
            }

            // check and see if it's defined in a base class instance as well...
            if (!options.HasFlag(GetMemberOptions.DeclaredOnly))
            {
                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)
                                {
                                    foreach (var kvp in baseClass.Instance._instanceAttrs)
                                    {
                                        if (!options.ForEval())
                                        {
                                            kvp.Value.ClearOldValues();
                                        }
                                        if (kvp.Value.VariableStillExists)
                                        {
                                            MergeTypes(res, kvp.Key, kvp.Value.TypesNoCopy);
                                        }
                                    }
                                }
                            } finally {
                                ns.Pop();
                            }
                        }
                    }
                }

                foreach (var classMem in _classInfo.GetAllMembers(moduleContext, options))
                {
                    MergeTypes(res, classMem.Key, classMem.Value);
                }
            }
            return(res);
        }
 public IEnumerable <IReferenceable> GetDefinitions(string name)
 {
     return(ClassInfo.GetDefinitions(name));
 }
        internal override bool UnionEquals(AnalysisValue ns, int strength)
        {
            var dict = ProjectState.ClassInfos[BuiltinTypeId.Dict];

            if (strength < MergeStrength.IgnoreIterableNode && (this is DictionaryInfo || this == dict.Instance))
            {
                if (ns is DictionaryInfo || ns == dict.Instance)
                {
                    return(true);
                }

                if (ns is ConstantInfo ci && ci.ClassInfo == dict)
                {
                    return(true);
                }
                return(false);
            }

            if (strength >= MergeStrength.ToObject)
            {
                if (TypeId == BuiltinTypeId.NoneType || ns.TypeId == BuiltinTypeId.NoneType)
                {
                    // BII + BII(None) => do not merge
                    // Unless both types are None, since they could be various
                    // combinations of BuiltinInstanceInfo or ConstantInfo that
                    // need to be merged.
                    return(TypeId == BuiltinTypeId.NoneType && ns.TypeId == BuiltinTypeId.NoneType);
                }

                var type = ProjectState.ClassInfos[BuiltinTypeId.Type];
                if (ClassInfo == type)
                {
                    // CI + BII(type) => BII(type)
                    // BCI + BII(type) => BII(type)
                    return(ns is ClassInfo || ns is BuiltinClassInfo || ns == type.Instance);
                }
                else if (ns == type.Instance)
                {
                    return(false);
                }

                if (TypeId == BuiltinTypeId.Function)
                {
                    // FI + BII(function) => BII(function)
                    return(ns is FunctionInfo || ns is BuiltinFunctionInfo ||
                           (ns is BuiltinInstanceInfo && ns.TypeId == BuiltinTypeId.Function));
                }
                if (ns.TypeId == BuiltinTypeId.Function)
                {
                    return(false);
                }

                // BII + II => BII(object)
                // BII + BII(!function) => BII(object)
                return(ns is InstanceInfo ||
                       (ns is BuiltinInstanceInfo && ns.TypeId != BuiltinTypeId.Function));
            }

            if (strength >= MergeStrength.ToBaseClass)
            {
                if (ns is BuiltinInstanceInfo bii)
                {
                    return(ClassInfo.UnionEquals(bii.ClassInfo, strength));
                }

                if (ns is InstanceInfo ii)
                {
                    return(ClassInfo.UnionEquals(ii.ClassInfo, strength));
                }
            }
            else if (ns is BuiltinInstanceInfo bii)
            {
                // ConI + BII => BII if CIs match
                return(ClassInfo.Equals(bii.ClassInfo));
            }

            return(base.UnionEquals(ns, strength));
        }
예제 #8
0
 internal override int UnionHashCode(int strength)
 {
     return(ClassInfo.UnionHashCode(strength));
 }