public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name)
        {
            IAnalysisSet res = null;

            switch (name)
            {
            case "Any":
                res = AnalysisSet.Empty;
                break;

            case "Callable":
            case "Generic":
            case "Optional":
            case "Tuple":
            case "Union":
            case "Container":
            case "ItemsView":
            case "Iterable":
            case "Iterator":
            case "KeysView":
            case "Mapping":
            case "MappingView":
            case "MutableMapping":
            case "MutableSequence":
            case "MutableSet":
            case "Sequence":
            case "ValuesView":
            case "Dict":
            case "List":
            case "Set":
            case "FrozenSet":
            case "NamedTuple":
            case "Generator":
            case "ClassVar":
                res = new TypingTypeInfo(name, _inner.GetMember(node, unit, name)?.FirstOrDefault());
                break;

            case "AbstractSet": break;

            case "GenericMeta": break;

            // As our purposes are purely informational, it's okay to
            // "round up" to the nearest type. That said, proper protocol
            // support would be nice to implement.
            case "ContextManager": break;

            case "Hashable": break;

            case "Reversible": break;

            case "SupportsAbs": break;

            case "SupportsBytes": res = GetBuiltin(BuiltinTypeId.Bytes); break;

            case "SupportsComplex": res = GetBuiltin(BuiltinTypeId.Complex); break;

            case "SupportsFloat": res = GetBuiltin(BuiltinTypeId.Float); break;

            case "SupportsInt": res = GetBuiltin(BuiltinTypeId.Int); break;

            case "SupportsRound": break;

            case "Sized": break;

            case "Counter": res = Import("collections", "Counter", node, unit); break;

            case "Deque": res = Import("collections", "deque", node, unit); break;

            case "DefaultDict": res = Import("collections", "defaultdict", node, unit); break;

            case "Type": res = GetBuiltin(BuiltinTypeId.Type); break;

            case "ByteString": res = GetBuiltin(BuiltinTypeId.Bytes); break;

            case "AnyStr": res = GetBuiltin(BuiltinTypeId.Unicode).Union(GetBuiltin(BuiltinTypeId.Bytes), canMutate: false); break;

            case "Text": res = GetBuiltin(BuiltinTypeId.Str); break;

            // TypeVar is not actually a synonym for NewType, but it is close enough for our purposes
            case "TypeVar":
            case "NewType": res = GetFunction(node, unit, name, NewType_Call); break;

                // The following are added depending on presence
                // of their non-generic counterparts in stdlib:
                // Awaitable
                // AsyncIterator
                // AsyncIterable
                // Coroutine
                // Collection
                // AsyncGenerator
                // AsyncContextManager
            }

            return(res ?? _inner.GetMember(node, unit, name));
        }
Example #2
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);
        }