public void Write(ASContainer container, bool includeTraits) { Write(container.IsStatic); if (includeTraits) { Write(container.Traits.Count); container.Traits.ForEach(Write); } }
private ASMultiname GetTraitType(ASContainer container, ASMultiname traitName) { if (container == null) { return(traitName); } return(container.GetTraits(TraitKind.Slot, TraitKind.Constant, TraitKind.Getter) .FirstOrDefault(t => t.QName == traitName)?.Type); }
private List <HReference> FindMessageReferences(ASClass fromClass, ASContainer fromContainer, ASMethod fromMethod) { int instructionRank = 0; ABCFile abc = fromMethod.GetABC(); Stack <ASMultiname> nameStack = new Stack <ASMultiname>(); List <HReference> references = new List <HReference>(); ASContainer container = null; ASCode code = fromMethod.Body.ParseCode(); for (int i = 0; i < code.Count; i++) { ASInstruction instruction = code[i]; switch (instruction.OP) { default: continue; case OPCode.NewFunction: { NewFunctionIns newFunction = (NewFunctionIns)instruction; references.AddRange(FindMessageReferences(fromClass, fromContainer, newFunction.Method)); continue; } case OPCode.GetProperty: { GetPropertyIns getProperty = (GetPropertyIns)instruction; nameStack.Push(getProperty.PropertyName); continue; } case OPCode.GetLex: { GetLexIns getLex = (GetLexIns)instruction; container = abc.GetClass(getLex.TypeName.Name); continue; } case OPCode.GetLocal_0: { container = fromContainer; continue; } case OPCode.ConstructProp: { ConstructPropIns constructProp = (ConstructPropIns)instruction; nameStack.Push(constructProp.PropertyName); break; } } ASMultiname messageQName = nameStack.Pop(); if (string.IsNullOrWhiteSpace(messageQName.Name)) { continue; } ASClass messageClass = abc.GetClass(messageQName.Name); if (messageClass == null) { continue; } if (!_messages.TryGetValue(messageClass, out HMessage message)) { continue; } if (message.References.Any(r => r.FromMethod == fromMethod)) { continue; } HReference reference = new HReference(); message.References.Add(reference); if (message.IsOutgoing) { reference.FromClass = fromClass; reference.FromMethod = fromMethod; reference.InstructionRank = ++instructionRank; reference.IsAnonymous = (!fromMethod.IsConstructor && fromMethod.Trait == null); references.Add(reference); } else { ASMultiname methodName = nameStack.Pop(); ASMethod callbackMethod = fromContainer.GetMethod(methodName.Name); if (callbackMethod == null) { callbackMethod = container.GetMethod(methodName.Name); if (callbackMethod == null) { ASMultiname slotName = nameStack.Pop(); ASTrait hostTrait = container.GetTraits(TraitKind.Slot) .FirstOrDefault(st => st.QName == slotName); container = abc.GetInstance(hostTrait.Type.Name); callbackMethod = container.GetMethod(methodName.Name); } } reference.FromMethod = callbackMethod; } } return(references); }
private void FindMessagesReferences() { int classRank = 1; ABCFile abc = ABCFiles.Last(); foreach (ASClass @class in abc.Classes) { ASInstance instance = @class.Instance; if (_messages.ContainsKey(@class)) { continue; } if (instance.Flags.HasFlag(ClassFlags.Interface)) { continue; } IEnumerable <ASMethod> methods = (new[] { @class.Constructor, instance.Constructor }) .Concat(instance.GetMethods()) .Concat(@class.GetMethods()); int methodRank = 0; foreach (ASMethod fromMethod in methods) { bool isStatic = (fromMethod.Trait?.IsStatic ?? @class.Constructor == fromMethod); ASContainer fromContainer = (isStatic ? (ASContainer)@class : instance); List <HReference> refernces = FindMessageReferences(@class, fromContainer, fromMethod); if (refernces.Count > 0) { methodRank++; } foreach (HReference reference in refernces) { reference.IsStatic = isStatic; reference.ClassRank = classRank; reference.MethodRank = methodRank; reference.GroupCount = refernces.Count; } } if (methodRank > 0) { classRank++; } } Dictionary <ASContainer, List <HReference> > froms = new Dictionary <ASContainer, List <HReference> >(); foreach (HMessage incomingMsg in InMessages.Values) { foreach (HReference reference in incomingMsg.References) { if (!froms.TryGetValue(reference.FromMethod.Container, out List <HReference> references)) { references = new List <HReference>(); froms.Add(reference.FromMethod.Container, references); } if (!references.Contains(reference)) { references.Add(reference); } } } classRank = 1; foreach (ASClass @class in abc.Classes) { ASContainer container = null; if (froms.TryGetValue(@class, out List <HReference> references)) { container = @class; } else if (froms.TryGetValue(@class.Instance, out references)) { container = @class.Instance; } if (container != null) { Dictionary <ASMethod, List <HReference> > methodReferenceGroups = new Dictionary <ASMethod, List <HReference> >(); foreach (HReference reference in references) { reference.FromClass = @class; reference.InstructionRank = -1; reference.ClassRank = classRank; reference.IsStatic = container.IsStatic; reference.GroupCount = references.Count; if (!methodReferenceGroups.TryGetValue(reference.FromMethod, out List <HReference> methodReferences)) { methodReferences = new List <HReference>(); methodReferenceGroups.Add(reference.FromMethod, methodReferences); } methodReferences.Add(reference); } int methodRank = 1; foreach (ASMethod method in container.GetMethods()) { if (methodReferenceGroups.TryGetValue(method, out List <HReference> methodReferences)) { foreach (HReference reference in methodReferences) { reference.MethodRank = methodRank; } methodRank++; } } classRank++; } } }