Пример #1
0
        public IAnalysisSet Finalize(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return(null);
            }

            switch (name)
            {
            case "Callable": return(ClassInfo[BuiltinTypeId.Function]);

            case "Tuple": return(ClassInfo[BuiltinTypeId.Tuple]);

            case "Container": return(ClassInfo[BuiltinTypeId.List]);

            case "ItemsView": return(ClassInfo[BuiltinTypeId.DictItems]);

            case "Iterable":
            case "Iterator": {
                var p = new ProtocolInfo(Entry, State);
                p.AddReference(_node, _unit);
                p.AddProtocol(name == "Iterable" ? (Protocol) new IterableProtocol(p, AnalysisSet.Empty) : new IteratorProtocol(p, AnalysisSet.Empty));
                return(p);
            }

            case "KeysView": return(ClassInfo[BuiltinTypeId.DictKeys]);

            case "Mapping": return(ClassInfo[BuiltinTypeId.Dict]);

            case "MappingView": return(ClassInfo[BuiltinTypeId.Dict]);

            case "MutableMapping": return(ClassInfo[BuiltinTypeId.Dict]);

            case "MutableSequence": return(ClassInfo[BuiltinTypeId.List]);

            case "MutableSet": return(ClassInfo[BuiltinTypeId.Set]);

            case "Sequence": return(ClassInfo[BuiltinTypeId.List]);

            case "ValuesView": return(ClassInfo[BuiltinTypeId.DictValues]);

            case "Dict": return(ClassInfo[BuiltinTypeId.Dict]);

            case "List": return(ClassInfo[BuiltinTypeId.List]);

            case "Set": return(ClassInfo[BuiltinTypeId.Set]);

            case "FrozenSet": return(ClassInfo[BuiltinTypeId.FrozenSet]);

            case "NamedTuple": return(ClassInfo[BuiltinTypeId.Tuple]);

            case "Generator": return(ClassInfo[BuiltinTypeId.Generator]);

            case "NoReturn": return(AnalysisSet.Empty);

            case " List": return(null);
            }

            return(null);
        }
Пример #2
0
        public override Protocol Clone(ProtocolInfo newSelf)
        {
            var np = new NamespaceProtocol(newSelf, _name);

            _values.CopyTo(np._values);
            return(np);
        }
Пример #3
0
        private IAnalysisSet MakeIterable(IAnalysisSet values)
        {
            var pi = new ProtocolInfo(DeclaringModule, Self.State);

            pi.AddProtocol(new IterableProtocol(pi, values));
            return(pi);
        }
        private IAnalysisSet NewType_Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames)
        {
            return(unit.InterpreterScope.GetOrMakeNodeValue(node, Analyzer.NodeValueKind.TypeAnnotation, n => {
                var name = PythonAnalyzer.GetArg(args, keywordArgNames, null, 0).GetConstantValueAsString().FirstOrDefault(x => !string.IsNullOrEmpty(x));
                var baseType = PythonAnalyzer.GetArg(args, keywordArgNames, null, 1) ?? unit.State.ClassInfos[BuiltinTypeId.Object].Instance;
                if (string.IsNullOrEmpty(name))
                {
                    return baseType;
                }
                var instPi = new ProtocolInfo(unit.ProjectEntry, unit.State);
                var np = new NameProtocol(instPi, name, memberType: PythonMemberType.Instance);
                var cls = new NamespaceProtocol(instPi, "__class__");
                instPi.AddProtocol(np);
                instPi.AddProtocol(cls);

                var pi = new ProtocolInfo(unit.ProjectEntry, unit.State);
                pi.AddProtocol(new NameProtocol(pi, name));
                pi.AddProtocol(new InstanceProtocol(pi, Array.Empty <IAnalysisSet>(), instPi));
                pi.AddReference(n, unit);

                cls.SetMember(n, unit, null, pi);

                return pi;
            }));
        }
Пример #5
0
        protected IAnalysisSet MakeMethod(string qualname, IReadOnlyList <IAnalysisSet> arguments, IAnalysisSet returnValue)
        {
            var v = new ProtocolInfo(Self.DeclaringModule, Self.State);

            v.AddProtocol(new CallableProtocol(v, qualname, arguments, returnValue, PythonMemberType.Method));
            return(v);
        }
Пример #6
0
        private IAnalysisSet MakeTuple(params IAnalysisSet[] types)
        {
            var p  = new ProtocolInfo(Entry, State);
            var tp = new TupleProtocol(p, types);

            p.AddProtocol(tp);
            return(p);
        }
Пример #7
0
        public virtual Protocol Clone(ProtocolInfo newSelf)
        {
            var p = ((Protocol)MemberwiseClone());

            p._members = null;
            p.Self     = Self;
            return(p);
        }
Пример #8
0
        public IterableProtocol(ProtocolInfo self, IAnalysisSet yielded) : base(self)
        {
            _yielded = yielded;

            var iterator = new ProtocolInfo(Self.DeclaringModule as ProjectEntry);

            iterator.AddProtocol(new IteratorProtocol(iterator, _yielded));
            _iterator = iterator;
        }
Пример #9
0
        internal override IAnalysisSet Resolve(AnalysisUnit unit, ResolutionContext context)
        {
            VariableDef[] newTypes;
            if (context.CallSite == null)
            {
                // No ability to come back to this instance later, so resolve and return
                // imitation type
                var  union   = AnalysisSet.Empty;
                bool changed = false;
                if (Push())
                {
                    try {
                        union = UnionType.Resolve(unit, context, out changed);
                    } finally {
                        Pop();
                    }
                }

                var pi = new ProtocolInfo(DeclaringModule, ProjectState);
                pi.AddProtocol(new IterableProtocol(pi, union));
                if (ClassInfo.TypeId == BuiltinTypeId.Tuple)
                {
                    newTypes = VariableDef.Generator.Take(IndexTypes.Length).ToArray();
                    changed |= ResolveIndexTypes(unit, context, newTypes);
                    if (newTypes.Length == 1)
                    {
                        pi.AddProtocol(new GetItemProtocol(pi, unit.State.ClassInfos[BuiltinTypeId.Int], newTypes[0].TypesNoCopy));
                    }
                    else if (newTypes.Length > 1)
                    {
                        pi.AddProtocol(new TupleProtocol(pi, newTypes.Select(t => t.TypesNoCopy)));
                    }
                }

                return(changed ? (AnalysisValue)pi : this);
            }

            if (unit.Scope.TryGetNodeValue(context.CallSite, NodeValueKind.Sequence, out var newSeq))
            {
                newTypes = (newSeq as IterableValue)?.IndexTypes;
                if (newTypes != null)
                {
                    ResolveIndexTypes(unit, context, newTypes);
                }
                return(newSeq);
            }
            else
            {
                newTypes = VariableDef.Generator.Take(Math.Max(1, IndexTypes.Length)).ToArray();
                if (ResolveIndexTypes(unit, context, newTypes))
                {
                    return(unit.Scope.GetOrMakeNodeValue(context.CallSite, NodeValueKind.Sequence, n => CreateWithNewTypes(n, newTypes)));
                }
            }

            return(this);
        }
Пример #10
0
 public CallableProtocol(ProtocolInfo self, string qualname, IReadOnlyList <IAnalysisSet> arguments, IAnalysisSet returnType, PythonMemberType memberType = PythonMemberType.Function)
     : base(self)
 {
     Name       = qualname ?? "callable";
     Arguments  = arguments;
     ReturnType = returnType.AsUnion(1);
     _overloads = new Lazy <OverloadResult[]>(GenerateOverloads);
     MemberType = memberType;
 }
Пример #11
0
        public IterableProtocol(ProtocolInfo self, IAnalysisSet yielded) : base(self)
        {
            _yielded = yielded.AsUnion(1);

            var iterator = new ProtocolInfo(Self.DeclaringModule, Self.State);

            iterator.AddProtocol(new IteratorProtocol(iterator, _yielded));
            _iterator = iterator;
        }
Пример #12
0
 public NameProtocol(ProtocolInfo self, IPythonType type) : base(self)
 {
     _name            = type.Name;
     _doc             = type.Documentation;
     _typeId          = type.TypeId;
     _richDescription = new List <KeyValuePair <string, string> > {
         new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Type, _name)
     };
 }
Пример #13
0
 public NameProtocol(ProtocolInfo self, string name, string documentation = null, BuiltinTypeId typeId = BuiltinTypeId.Object) : base(self)
 {
     _name            = name;
     _doc             = documentation;
     _typeId          = typeId;
     _richDescription = new List <KeyValuePair <string, string> > {
         new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Type, _name)
     };
 }
Пример #14
0
        private IAnalysisSet MakeView(IPythonType type, IAnalysisSet values)
        {
            var pi = new ProtocolInfo(DeclaringModule, Self.State);
            var np = new NameProtocol(pi, type);
            var ip = new IterableProtocol(pi, values);

            np.ExtendDescription(ip.GetRichDescription());
            pi.AddProtocol(np);
            pi.AddProtocol(ip);
            return(pi);
        }
Пример #15
0
        private IAnalysisSet MakeTuple(params IAnalysisSet[] types)
        {
            var p  = new ProtocolInfo(Entry, State);
            var np = new NameProtocol(p, Types[BuiltinTypeId.Tuple]);
            var tp = new TupleProtocol(p, types);

            np.ExtendDescription(tp.GetRichDescription());
            p.AddProtocol(np);
            p.AddProtocol(tp);
            return(p);
        }
Пример #16
0
        internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength)
        {
            if (strength < 2)
            {
                return(this);
            }

            var pi = new ProtocolInfo(DeclaringModule, State);

            pi.AddProtocol(new NameProtocol(pi, Name));
            return(pi);
        }
        internal override IAnalysisSet Resolve(AnalysisUnit unit, ResolutionContext context)
        {
            IAnalysisSet yields, returns, sends;

            if (Push())
            {
                try {
                    bool anyChange = false, changed;
                    yields     = Yields.Types.Resolve(unit, context, out changed);
                    anyChange |= changed;
                    returns    = Returns.Types.Resolve(unit, context, out changed);
                    anyChange |= changed;
                    sends      = Sends.Types.Resolve(unit, context, out changed);
                    anyChange |= changed;
                    if (!anyChange)
                    {
                        return(this);
                    }
                } finally {
                    Pop();
                }
            }
            else
            {
                return(this);
            }

            if (context.CallSite == null)
            {
                // No ability to come back to this instance later, so return imitation type
                var pi = new ProtocolInfo(DeclaringModule, ProjectState);
                pi.AddProtocol(new GeneratorProtocol(pi, yields, sends, returns));
                return(pi);
            }

            var gi = unit.InterpreterScope.GetOrMakeNodeValue(context.CallSite, NodeValueKind.Sequence, n => new GeneratorInfo(unit.State, unit.ProjectEntry)) as GeneratorInfo;

            if (gi != null)
            {
                gi.Yields.AddTypes(unit, yields);
                gi.Returns.AddTypes(unit, returns);
                gi.Sends.AddTypes(unit, sends);
                return(gi);
            }

            return(this);
        }
Пример #18
0
 internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength)
 {
     if (av is ProtocolInfo other)
     {
         var pi = new ProtocolInfo(DeclaringModule);
         foreach (var p in _protocols.Concat(other._protocols).GroupBy(p => p.GetType()))
         {
             var newP = p.FirstOrDefault()?.Clone(pi);
             if (newP != null)
             {
                 pi.AddProtocol(newP);
             }
         }
         return(pi);
     }
     return(this);
 }
Пример #19
0
        internal override IAnalysisSet Resolve(AnalysisUnit unit, ResolutionContext context)
        {
            if (context.CallSite == null)
            {
                // No ability to come back to this instance later, so resolve and return
                // imitation type
                if (Push())
                {
                    try {
                        var union = UnionType.Resolve(unit, context, out var changed);
                        if (!changed)
                        {
                            return(this);
                        }
                        var pi = new ProtocolInfo(DeclaringModule, ProjectState);
                        pi.AddProtocol(new IterableProtocol(pi, union));
                        return(pi);
                    } finally {
                        Pop();
                    }
                }
                return(this);
            }

            VariableDef[] newTypes;
            if (unit.Scope.TryGetNodeValue(context.CallSite, NodeValueKind.Sequence, out var newSeq))
            {
                newTypes = (newSeq as IterableValue)?.IndexTypes;
                if (newTypes != null)
                {
                    ResolveIndexTypes(unit, context, newTypes);
                }
                return(newSeq);
            }
            else
            {
                newTypes = VariableDef.Generator.Take(Math.Max(1, IndexTypes.Length)).ToArray();
                if (ResolveIndexTypes(unit, context, newTypes))
                {
                    return(unit.Scope.GetOrMakeNodeValue(context.CallSite, NodeValueKind.Sequence, n => CreateWithNewTypes(n, newTypes)));
                }
            }

            return(this);
        }
Пример #20
0
        private IAnalysisSet NewType_Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames)
        {
            return(unit.InterpreterScope.GetOrMakeNodeValue(node, Analyzer.NodeValueKind.TypeAnnotation, n => {
                if (args.Length == 0)
                {
                    return AnalysisSet.Empty; // No arguments given
                }

                var arg = PythonAnalyzer.GetArg(args, keywordArgNames, null, 0);
                var name = arg.GetConstantValueAsString().FirstOrDefault(x => !string.IsNullOrEmpty(x));
                var baseTypeSet = PythonAnalyzer.GetArg(args, keywordArgNames, null, 1) ?? unit.State.ClassInfos[BuiltinTypeId.Object].Instance;
                if (string.IsNullOrEmpty(name))
                {
                    return baseTypeSet;
                }

                var instPi = new ProtocolInfo(unit.ProjectEntry, unit.State);
                var np = new NameProtocol(instPi, name, memberType: PythonMemberType.Instance, typeId: BuiltinTypeId.Type);
                var cls = new NamespaceProtocol(instPi, "__class__"); // Declares class type
                instPi.AddProtocol(np);
                instPi.AddProtocol(cls);

                // Add base delegate so we can see actual type members
                var baseType = baseTypeSet.FirstOrDefault();
                if (baseType != null)
                {
                    var bt = new TypeDelegateProtocol(instPi, baseType);
                    instPi.AddProtocol(bt);
                }

                var pi = new ProtocolInfo(unit.ProjectEntry, unit.State);
                pi.AddProtocol(new NameProtocol(pi, name, memberType: PythonMemberType.Instance, typeId: BuiltinTypeId.Type));
                pi.AddProtocol(new InstanceProtocol(pi, Array.Empty <IAnalysisSet>(), instPi));
                pi.AddReference(n, unit);

                cls.SetMember(n, unit, null, pi);

                return pi;
            }));
        }
Пример #21
0
 public TupleProtocol(ProtocolInfo self, IEnumerable <IAnalysisSet> values) : base(self, AnalysisSet.UnionAll(values))
 {
     _values = values.ToArray();
 }
Пример #22
0
 public MappingProtocol(ProtocolInfo self, IAnalysisSet keys, IAnalysisSet values, IAnalysisSet items) : base(self, keys)
 {
     _keyType   = keys;
     _valueType = values;
     _itemType  = items;
 }
Пример #23
0
 public GeneratorProtocol(ProtocolInfo self, IAnalysisSet yields, IAnalysisSet sends, IAnalysisSet returns) : base(self, yields)
 {
     _sent     = sends;
     _returned = returns;
 }
Пример #24
0
 public Protocol(ProtocolInfo self)
 {
     Self = self;
 }
Пример #25
0
 public NameProtocol(ProtocolInfo self, string name) : base(self)
 {
     _name = name;
 }
Пример #26
0
 public NamespaceProtocol(ProtocolInfo self, string name) : base(self)
 {
     _name   = name;
     _values = new VariableDef();
 }
 public NameProtocol(ProtocolInfo self, IPythonType type)
     : this(self, type.Name, type.Documentation, type.TypeId, type.MemberType)
 {
 }
Пример #28
0
        private IAnalysisSet CreateNamedTuple(Node node, AnalysisUnit unit, IAnalysisSet namedTupleName, IAnalysisSet namedTupleArgs)
        {
            var args = namedTupleArgs == null ? null : TypingTypeInfo.ToTypeList(namedTupleArgs);

            var res = new ProtocolInfo(unit.ProjectEntry, unit.State);

            string name;
            var    description = new List <KeyValuePair <string, string> >();

            if (args != null && args.Any())
            {
                var tupleItem = new List <IAnalysisSet>();
                foreach (var a in args)
                {
                    // each arg is going to be either a union containing a string literal and type,
                    // or a list with string literal and type.
                    IAnalysisSet nameSet = a, valueSet = a;
                    if (a is TypingTypeInfo tti)
                    {
                        var list = tti.ToTypeList();
                        if (list != null && list.Count >= 2)
                        {
                            nameSet  = list[0];
                            valueSet = AnalysisSet.UnionAll(list.Skip(1));
                        }
                    }

                    if (!nameSet.Split(out IReadOnlyList <ConstantInfo> names, out var rest))
                    {
                        names = a.OfType <ConstantInfo>().ToArray();
                    }
                    name = names.Select(n => n.GetConstantValueAsString()).FirstOrDefault(n => !string.IsNullOrEmpty(n)) ?? "unnamed";

                    var p = new NamespaceProtocol(res, name);
                    var value = ToInstance(valueSet);
                    p.SetMember(node, unit, name, value);
                    tupleItem.Add(value);
                    res.AddProtocol(p);

                    if (description.Any())
                    {
                        description.Add(new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Comma, ", "));
                    }
                    description.AddRange(p.GetRichDescription());
                }

                res.AddProtocol(new TupleProtocol(res, tupleItem));
            }

            name = namedTupleName?.GetConstantValueAsString().FirstOrDefault() ?? "tuple";
            var np = new NameProtocol(res, name);

            if (description.Any())
            {
                np.ExtendDescription(new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Misc, "("));
                np.ExtendDescription(description);
                np.ExtendDescription(new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Misc, ")"));
            }
            res.AddProtocol(np);

            return(res);
        }
Пример #29
0
        /// <summary>
        /// Given type name and type arguments provides value
        /// based on the actual type to use in analysis.
        /// </summary>
        public IAnalysisSet Finalize(string name, IReadOnlyList <IAnalysisSet> args)
        {
            if (string.IsNullOrEmpty(name) || args == null || args.Count == 0)
            {
                return(null);
            }

            NameProtocol np;
            IPythonType  realType;
            IAnalysisSet keyTypes, valueTypes;

            switch (name)
            {
            case "Union":
                return(AnalysisSet.UnionAll(args.Select(a => Finalize(a))));

            case "Optional":
                return(Finalize(args[0]).Add(NoneType));

            case "Tuple":
                if (!args.SelectMany(a => a).Any(a => a.TypeId == BuiltinTypeId.Ellipsis))
                {
                    return(MakeTuple(args.Select(ToInstance).ToArray()));
                }
                goto case "List";

            case "List":
            case "Container":
            case "MutableSequence":
            case "Sequence":
            case "MutableSet":
            case "Set":
            case "FrozenSet":
            case "KeysView":
            case "ValuesView":
            case "ItemsView":
                if (GetSequenceTypes(name, args, out realType, out keyTypes, out valueTypes))
                {
                    var p = new ProtocolInfo(Entry, State);
                    p.AddReference(_node, _unit);

                    np = realType == null ? new NameProtocol(p, name) : new NameProtocol(p, realType);
                    np.ExtendDescription(valueTypes.GetRichDescriptions(unionPrefix: "[", unionSuffix: "]", alwaysUsePrefixSuffix: true));
                    p.AddProtocol(np);

                    var actualType = State.GetAnalysisValueFromObjects(realType);
                    p.AddProtocol(new ListProtocol(p, actualType, valueTypes));
                    if (keyTypes != null)
                    {
                        p.AddProtocol(new GetItemProtocol(p, keyTypes, valueTypes));
                    }
                    return(p);
                }
                break;

            case "Mapping":
            case "MappingView":
            case "MutableMapping":
            case "Dict":
                if (GetSequenceTypes(name, args, out realType, out keyTypes, out valueTypes))
                {
                    var p = new ProtocolInfo(Entry, State);
                    p.AddReference(_node, _unit);

                    np = realType == null ? new NameProtocol(p, name) : new NameProtocol(p, realType);
                    np.ExtendDescription(new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Misc, "["));
                    np.ExtendDescription(keyTypes.GetRichDescriptions(unionPrefix: "[", unionSuffix: "]", defaultIfEmpty: "Any"));
                    np.ExtendDescription(new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Comma, ", "));
                    np.ExtendDescription(valueTypes.GetRichDescriptions(unionPrefix: "[", unionSuffix: "]", defaultIfEmpty: "Any"));
                    np.ExtendDescription(new KeyValuePair <string, string>(WellKnownRichDescriptionKinds.Misc, "]"));
                    p.AddProtocol(np);

                    var actualType = State.GetAnalysisValueFromObjects(realType);
                    p.AddProtocol(new DictProtocol(p, actualType, keyTypes, valueTypes, MakeTuple(keyTypes, valueTypes)));
                    return(p);
                }
                break;

            case "Callable":
                if (args.Count > 0)
                {
                    var p = new ProtocolInfo(Entry, State);
                    p.AddReference(_node, _unit);
                    np = new NameProtocol(p, Types[BuiltinTypeId.Function]);
                    var call = new CallableProtocol(
                        p,
                        null,
                        GetTypeList(args[0]).Select(ToInstance).ToArray(),
                        ToInstance(args.ElementAtOrDefault(1) ?? AnalysisSet.Empty)
                        );
                    np.ExtendDescription(call.GetRichDescription());
                    p.AddProtocol(np);
                    p.AddProtocol(call);
                    return(p);
                }
                break;

            case "Iterable":
                if (args.Count > 0)
                {
                    var p = new ProtocolInfo(Entry, State);
                    p.AddReference(_node, _unit);
                    np = new NameProtocol(p, "iterable", memberType: PythonMemberType.Class);
                    var ip = new IterableProtocol(p, AnalysisSet.UnionAll(args.Select(ToInstance)));
                    np.ExtendDescription(ip.GetRichDescription());
                    p.AddProtocol(np);
                    p.AddProtocol(ip);
                    return(p);
                }
                break;

            case "Iterator":
                if (args.Count > 0)
                {
                    var p = new ProtocolInfo(Entry, State);
                    p.AddReference(_node, _unit);
                    np = new NameProtocol(p, "iterator", memberType: PythonMemberType.Class);
                    var ip = new IteratorProtocol(p, AnalysisSet.UnionAll(args.Select(ToInstance)));
                    np.ExtendDescription(ip.GetRichDescription());
                    p.AddProtocol(np);
                    p.AddProtocol(ip);
                    return(p);
                }
                break;

            case "Generator":
                if (args.Count > 0)
                {
                    var p = new ProtocolInfo(Entry, State);
                    p.AddReference(_node, _unit);
                    np = new NameProtocol(p, Types[BuiltinTypeId.Generator]);
                    var yielded  = ToInstance(args[0]);
                    var sent     = args.Count > 1 ? ToInstance(args[1]) : AnalysisSet.Empty;
                    var returned = args.Count > 2 ? ToInstance(args[2]) : AnalysisSet.Empty;
                    var gp       = new GeneratorProtocol(p, yielded, sent, returned);
                    np.ExtendDescription(gp.GetRichDescription());
                    p.AddProtocol(np);
                    p.AddProtocol(gp);
                    return(p);
                }
                break;

            case "NamedTuple":
                return(CreateNamedTuple(_node, _unit, args.ElementAtOrDefault(0), args.ElementAtOrDefault(1)));

            case "Type":
                // Return class rather than instance
                return(args.Count > 0 ? Finalize(args[0]) : AnalysisSet.Empty);

            case " List":
                return(AnalysisSet.UnionAll(args.Select(ToInstance)));
            }

            return(null);
        }
Пример #30
0
 public IteratorProtocol(ProtocolInfo self, IAnalysisSet yielded) : base(self)
 {
     _yielded = yielded;
 }