Example #1
0
 public void Write(ASContainer container, bool includeTraits)
 {
     Write(container.IsStatic);
     if (includeTraits)
     {
         Write(container.Traits.Count);
         container.Traits.ForEach(Write);
     }
 }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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++;
                }
            }
        }