}                             // For de-serializer from JSON

        protected CallableModel(IPythonType callable, IServiceContainer services)
        {
            var functions = new List <FunctionModel>();
            var classes   = new List <ClassModel>();

            foreach (var name in callable.GetMemberNames())
            {
                var m = callable.GetMember(name);

                // Only take members from this class, skip members from bases.
                using (_processing.Push(m, out var reentered)) {
                    if (reentered)
                    {
                        continue;
                    }
                    switch (m)
                    {
                    case IPythonFunctionType ft1 when ft1.IsLambda():
                        break;

                    case IPythonFunctionType ft2:
                        functions.Add(new FunctionModel(ft2, services));
                        break;

                    case IPythonClassType cls:
                        classes.Add(new ClassModel(cls, services));
                        break;
                    }
                }
            }

            Id   = callable.Name.GetStableHash();
            Name = callable.Name;
            DeclaringModuleId = callable.DeclaringModule.GetUniqueId(services);
            QualifiedName     = callable.QualifiedName;
            Documentation     = callable.Documentation;
            Classes           = classes.ToArray();
            Functions         = functions.ToArray();
            IndexSpan         = callable.Location.IndexSpan.ToModel();

            Attributes = FunctionAttributes.Normal;
            if (callable.IsAbstract)
            {
                Attributes |= FunctionAttributes.Abstract;
            }
            if (callable is IPythonFunctionType ft)
            {
                if (ft.IsClassMethod)
                {
                    Attributes |= FunctionAttributes.ClassMethod;
                }
                if (ft.IsStatic)
                {
                    Attributes |= FunctionAttributes.Static;
                }
            }
        }
        public static void AddMemberReference(this IPythonType type, string name, IExpressionEvaluator eval, Location location)
        {
            var m = type.GetMember(name);

            if (m is LocatedMember lm)
            {
                lm.AddReference(location);
            }
            else if (type is IPythonClassType cls)
            {
                using (eval.OpenScope(cls.DeclaringModule, cls.ClassDefinition)) {
                    eval.LookupNameInScopes(name, out _, out var v, LookupOptions.Local);
                    v?.AddReference(location);
                }
            }
        }
Пример #3
0
        private static IEnumerable <IPythonFunction> GetTestCaseMembers(IPythonType cls, IModuleContext context)
        {
            var methodFunctions = cls.GetMemberNames(context).Select(n => cls.GetMember(context, n))
                                  .OfType <IPythonFunction>()
                                  .ToArray();

            var tests   = methodFunctions.Where(v => v.Name.StartsWithOrdinal("test"));
            var runTest = methodFunctions.Where(v => v.Name.Equals("runTest"));

            if (tests.Any())
            {
                return(tests);
            }
            else
            {
                return(runTest);
            }
        }
        public static void AddMemberReference(this IPythonType type, string name, IExpressionEvaluator eval, Location location)
        {
            var m = type.GetMember(name);

            if (m is LocatedMember lm)
            {
                lm.AddReference(location);
            }
            else if (type is IPythonClassType cls)
            {
                using (eval.OpenScope(cls)) {
                    eval.LookupNameInScopes(name, out _, out var v, LookupOptions.Local);
                    v?.AddReference(location);
                }
            }
            else if (type is IPythonModule module && module.GlobalScope != null && module.GlobalScope.Variables.TryGetVariable(name, out var variable))
            {
                variable.AddReference(location);
            }
        }
Пример #5
0
        internal static IList <IPythonType> CalculateMro(IPythonType cls, HashSet <IPythonType> recursionProtection = null)
        {
            if (cls == null)
            {
                return(Array.Empty <IPythonType>());
            }
            if (recursionProtection == null)
            {
                recursionProtection = new HashSet <IPythonType>();
            }
            if (!recursionProtection.Add(cls))
            {
                return(Array.Empty <IPythonType>());
            }
            try {
                var mergeList = new List <List <IPythonType> > {
                    new List <IPythonType>()
                };
                var finalMro = new List <IPythonType> {
                    cls
                };

                var bases = (cls as AstPythonType)?.Bases ??
                            (cls.GetMember(null, "__bases__") as IPythonSequenceType)?.IndexTypes ??
                            Array.Empty <IPythonType>();

                foreach (var b in bases)
                {
                    var b_mro = new List <IPythonType>();
                    b_mro.AddRange(CalculateMro(b, recursionProtection));
                    mergeList.Add(b_mro);
                }

                while (mergeList.Any())
                {
                    // Next candidate is the first head that does not appear in
                    // any other tails.
                    var nextInMro = mergeList.FirstOrDefault(mro => {
                        var m = mro.FirstOrDefault();
                        return(m != null && !mergeList.Any(m2 => m2.Skip(1).Contains(m)));
                    })?.FirstOrDefault();

                    if (nextInMro == null)
                    {
                        // MRO is invalid, so return just this class
                        return(new IPythonType[] { cls });
                    }

                    finalMro.Add(nextInMro);

                    // Remove all instances of that class from potentially being returned again
                    foreach (var mro in mergeList)
                    {
                        mro.RemoveAll(ns => ns == nextInMro);
                    }

                    // Remove all lists that are now empty.
                    mergeList.RemoveAll(mro => !mro.Any());
                }

                return(finalMro);
            } finally {
                recursionProtection.Remove(cls);
            }
        }
        /// <summary>
        /// Calculates MRO according to https://www.python.org/download/releases/2.3/mro/
        /// </summary>
        internal static IReadOnlyList <IPythonType> CalculateMro(IPythonType type, HashSet <IPythonType> recursionProtection = null)
        {
            if (type == null)
            {
                return(Array.Empty <IPythonType>());
            }
            recursionProtection = recursionProtection ?? new HashSet <IPythonType>();
            if (!recursionProtection.Add(type))
            {
                return(Array.Empty <IPythonType>());
            }

            var bases = (type as IPythonClassType)?.Bases;

            if (bases == null)
            {
                var members = (type.GetMember("__bases__") as IPythonCollection)?.Contents ?? Array.Empty <IMember>();
                bases = members.Select(m => m.GetPythonType()).ToArray();
            }

            try {
                var mergeList = new List <List <IPythonType> > {
                    new List <IPythonType>()
                };
                var finalMro = new List <IPythonType> {
                    type
                };

                var mros = bases.Select(b => CalculateMro(b, recursionProtection).ToList());
                mergeList.AddRange(mros);

                while (mergeList.Any())
                {
                    // Next candidate is the first head that does not appear in any other tails.
                    var nextInMro = mergeList.FirstOrDefault(mro => {
                        var m = mro.FirstOrDefault();
                        return(m != null && !mergeList.Any(m2 => m2.Skip(1).Contains(m)));
                    })?.FirstOrDefault();

                    if (nextInMro == null)
                    {
                        // MRO is invalid, so return just this class
                        return(new[] { type });
                    }

                    finalMro.Add(nextInMro);

                    // Remove all instances of that class from potentially being returned again
                    foreach (var mro in mergeList)
                    {
                        mro.RemoveAll(ns => ns == nextInMro);
                    }

                    // Remove all lists that are now empty.
                    mergeList.RemoveAll(mro => !mro.Any());
                }

                return(finalMro);
            } finally {
                recursionProtection.Remove(type);
            }
        }
Пример #7
0
 public IMember GetMember(IModuleContext context, string name)
 {
     return(_type.GetMember(context, name));
 }
        private void MergeClass(IVariable v, IPythonClassType sourceClass, IPythonType stubType, CancellationToken cancellationToken)
        {
            // Transfer documentation first so we get class documentation
            // that comes from the class definition win over one that may
            // come from __init__ during the member merge below.
            TransferDocumentationAndLocation(sourceClass, stubType);

            // Replace the class entirely since stub members may use generic types
            // and the class definition is important. We transfer missing members
            // from the original class to the stub.
            _eval.DeclareVariable(v.Name, v.Value, v.Source);

            // First pass: go through source class members and pick those
            // that are not present in the stub class.
            foreach (var name in sourceClass.GetMemberNames().ToArray())
            {
                cancellationToken.ThrowIfCancellationRequested();

                var sourceMember = sourceClass.GetMember(name);
                if (sourceMember.IsUnknown())
                {
                    continue; // Do not add unknowns to the stub.
                }
                var sourceMemberType = sourceMember?.GetPythonType();
                if (sourceMemberType is IPythonClassMember cm && cm.DeclaringType != sourceClass)
                {
                    continue; // Only take members from this class and not from bases.
                }
                if (!IsFromThisModuleOrSubmodules(sourceMemberType))
                {
                    continue; // Member does not come from module or its submodules.
                }

                var stubMember     = stubType.GetMember(name);
                var stubMemberType = stubMember.GetPythonType();

                // Get documentation from the current type, if any, since stubs
                // typically do not contain documentation while scraped code does.
                TransferDocumentationAndLocation(sourceMemberType, stubMemberType);

                // If stub says 'Any' but we have better type, use member from the original class.
                if (stubMember != null && !(stubType.DeclaringModule is TypingModule && stubType.Name == "Any"))
                {
                    continue; // Stub already have the member, don't replace.
                }

                (stubType as PythonType)?.AddMember(name, stubMember, overwrite: true);
            }

            // Second pass: go through stub class members and if they don't have documentation
            // or location, check if source class has same member and fetch it from there.
            // The reason is that in the stub sometimes members are specified all in one
            // class while in source they may come from bases. Example: datetime.
            foreach (var name in stubType.GetMemberNames().ToArray())
            {
                cancellationToken.ThrowIfCancellationRequested();

                var stubMember = stubType.GetMember(name);
                if (stubMember.IsUnknown())
                {
                    continue;
                }
                var stubMemberType = stubMember.GetPythonType();
                if (stubMemberType is IPythonClassMember cm && cm.DeclaringType != stubType)
                {
                    continue; // Only take members from this class and not from bases.
                }

                var sourceMember = sourceClass.GetMember(name);
                if (sourceMember.IsUnknown())
                {
                    continue;
                }

                var sourceMemberType = sourceMember.GetPythonType();
                if (sourceMemberType.Location.IsValid && !stubMemberType.Location.IsValid)
                {
                    TransferDocumentationAndLocation(sourceMemberType, stubMemberType);
                }
            }
        }
Пример #9
0
 public IMember GetMember(string name) => _type.GetMember(name);
Пример #10
0
 public IMember GetMember(IModuleContext context, string name) => _sequenceType?.GetMember(context, name) ?? null;
 public IMember GetMember(IModuleContext context, string name) => _type.GetMember(context, name);
Пример #12
0
 public IMember GetMember(IModuleContext context, string name) => _lookupType?.GetMember(context, name) ?? null;