private ASClass GetMessageParser() { ABCFile abc = Class.GetABC(); ASInstance instance = Class.Instance; ASInstance superInstance = abc.GetInstance(instance.Super); if (superInstance == null) { superInstance = instance; } ASMethod parserGetterMethod = superInstance.GetGetter("parser")?.Method; if (parserGetterMethod == null) { return(null); } IEnumerable <ASMethod> methods = instance.GetMethods(); foreach (ASMethod method in methods.Concat(new[] { instance.Constructor })) { ASCode code = method.Body.ParseCode(); foreach (ASInstruction instruction in code) { ASMultiname multiname = null; if (instruction.OP == OPCode.FindPropStrict) { var findPropStrictIns = (FindPropStrictIns)instruction; multiname = findPropStrictIns.PropertyName; } else if (instruction.OP == OPCode.GetLex) { var getLexIns = (GetLexIns)instruction; multiname = getLexIns.TypeName; } else { continue; } foreach (ASClass refClass in abc.GetClasses(multiname)) { ASInstance refInstance = refClass.Instance; if (refInstance.ContainsInterface(parserGetterMethod.ReturnType.Name)) { return(refClass); } } } } return(null); }
/// <summary> /// Returns the Incoming message's parser class. /// </summary> /// <param name="messageClass">The Incoming message class to extract the parser class from.</param> /// <returns></returns> public ASClass GetIncomingMessageParser(ASClass messageClass) { if (_messageParsers.ContainsKey(messageClass)) { return(_messageParsers[messageClass]); } ABCFile abc = messageClass.ABC; ASClass incomingMsgParserClass = null; ASInstance incomingMsgInstance = messageClass.Instance; try { ASInstance incomingMsgSuperInstance = abc.FindFirstInstanceByName( incomingMsgInstance.SuperType.Name); ASMultiname parserReturnType = incomingMsgSuperInstance .FindFirstGetter("parser", null).ReturnType; List <ASMethod> methods = incomingMsgInstance.FindMethodGetterSetterTraits() .Select(mgsTrait => mgsTrait.Method).ToList(); methods.Add(incomingMsgInstance.Constructor); foreach (ASMethod method in methods) { var referencedClasses = new List <ASClass>(); using (var inCode = new FlashReader(method.Body.Bytecode)) { while (inCode.IsDataAvailable) { OPCode op = 0; object[] values = inCode.ReadValuesUntilEither(out op, OPCode.FindPropStrict, OPCode.GetLex); if (values == null) { break; } var typeIndex = (int)values[0]; ASMultiname type = abc.Constants.Multinames[typeIndex]; List <ASClass> instances = abc.FindClassesByName(type.Name); referencedClasses.AddRange(instances); } } foreach (ASClass referencedClass in referencedClasses) { ASInstance referencedInstance = referencedClass.Instance; if (referencedInstance.ContainsInterface(parserReturnType.Name)) { incomingMsgParserClass = referencedClass; return(incomingMsgParserClass); } } } } finally { if (incomingMsgParserClass != null) { _messageParsers[messageClass] = incomingMsgParserClass; } } return(incomingMsgParserClass); }