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); }
/// <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); }