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

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

            // 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 EphemeralVariableDef();
            }
            def.AddReference(node, unit);
            def.AddDependency(unit);

            // check and see if it's defined in a base class instance as well...
            var res = def.Types;
            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) {
                        // 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 }, ExpressionEvaluator.EmptyNames));
                    }
                }
                return getattrRes;
            }
            return res;
        }