Ejemplo n.º 1
0
        public override IAnalysisSet GetTypeMember(Node node, AnalysisUnit unit, string name)
        {
            var result   = AnalysisSet.Empty;
            var classMem = _classInfo.GetMemberNoReferences(node, unit, name);

            if (classMem.Count > 0)
            {
                result = classMem.GetDescriptor(node, this, _classInfo, unit);
                if (result.Count > 0)
                {
                    // TODO: Check if it's a data descriptor...
                }
                return(result);
            }
            else
            {
                // if the class gets a value later we need to be re-analyzed
                _classInfo.Scope.CreateEphemeralVariable(node, unit, name, false).AddDependency(unit);
            }

            return(result);
        }
Ejemplo n.º 2
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)
                {
                    if (getAttrFunc is BuiltinMethodInfo f && f.Function.DeclaringType.TypeId == BuiltinTypeId.Object ||
                        getAttrFunc is BuiltinFunctionInfo)
                    {
                        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);
        }
Ejemplo n.º 3
0
        public override ISet <Namespace> GetMember(Node node, AnalysisUnit unit, string name)
        {
            // __getattribute__ takes precedence over everything.
            ISet <Namespace> getattrRes = EmptySet <Namespace> .Instance;
            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.Overloads.Count == 1 && func.Function.DeclaringType == ProjectState.Types.Object)
                    {
                        continue;
                    }
                    // TODO: We should really do a get descriptor / call here
                    // FIXME: new string[0]
                    getattrRes = getattrRes.Union(getAttrFunc.Call(node, unit, new[] { SelfSet, ProjectState._stringType.Instance.SelfSet }, new string[0]));
                }
                if (getattrRes.Count > 0)
                {
                    return(getattrRes);
                }
            }

            // then check class members
            var classMem = _classInfo.GetMemberNoReferences(node, unit, name).GetDescriptor(this, unit);

            if (classMem.Count > 0)
            {
                // TODO: Check if it's a data descriptor...
                return(classMem);
            }

            // ok, it most be an instance member...
            if (_instanceAttrs == null)
            {
                _instanceAttrs = new Dictionary <string, VariableDef>();
            }
            VariableDef def;

            if (!_instanceAttrs.TryGetValue(name, out def))
            {
                _instanceAttrs[name] = def = new VariableDef();
            }
            def.AddReference(node, unit);
            def.AddDependency(unit);

            var res = def.Types;

            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)
                    {
                        // TODO: We should really do a get descriptor / call here
                        //FIXME: new string[0]
                        getattrRes = getattrRes.Union(getAttrFunc.Call(node, unit, new[] { SelfSet, _classInfo._analysisUnit.ProjectState._stringType.Instance.SelfSet }, new string[0]));
                    }
                }
                return(getattrRes);
            }
            return(res);
        }