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; })); }
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); }
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); }
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); }
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); }
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); }
private IAnalysisSet MakeIterable(IAnalysisSet values) { var pi = new ProtocolInfo(DeclaringModule, Self.State); pi.AddProtocol(new IterableProtocol(pi, values)); return(pi); }
private IAnalysisSet MakeTuple(params IAnalysisSet[] types) { var p = new ProtocolInfo(Entry, State); var tp = new TupleProtocol(p, types); p.AddProtocol(tp); return(p); }
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; }
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; }
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); }
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; })); }
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); }
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); }
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); }
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); }
/// <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); }