// A method was called by our inspected method. We use the collected information (our environment) // to extract information about the type (and fields). public static void SerializeOnCall(CallInfo info, List <byte> writtenBytes, List <IRClassProperty> properties) { if (!info.Method.Name.StartsWith("Write") || info.Method.Name.StartsWith("WriteTo")) { // We are in no relevant method. return; } if (info.Method.Name.Equals("WriteRawTag")) { // Used to write tag information. return; } // Name of the type of the proto equivalent of the property. var type = info.Method.Name.Substring(5); // Name of the property var propName = info.Arguments[1].ToString(); propName = propName.Substring(propName.IndexOf("get_") + 4); // Cut of parenthesis. propName = propName.Substring(0, propName.Length - 2); // Locate property from property list var property = properties.First(p => p.Name.Equals(propName)); // Get more specific type. var specificType = InspectorTools.LiteralTypeMapper(type); property.Type = specificType; // Label and fieldTag are already set! }
public static void SerializeOnCall(CallInfo info, List <string> property_names, List <FieldDefinition> allFields, List <IRClassProperty> properties, List <TypeDefinition> references) { if (!info.Method.Name.StartsWith("Write") || info.Method.Name.Equals("WriteUntil")) { // We are in no relevant method. return; } var fieldNameArg = info.Arguments[2].ToString(); var bracketIdx = fieldNameArg.LastIndexOf("["); var bracketLastIdx = fieldNameArg.LastIndexOf("]"); var fieldNameRef = UInt32.Parse(fieldNameArg.Substring(bracketIdx + 1, bracketLastIdx - bracketIdx - 1)); var fieldName = property_names[(int)fieldNameRef]; var type = info.Method.Name.Substring(5); var packedIdx = type.IndexOf("Packed"); var isPacked = false; if (packedIdx > -1) { Debug.Assert(packedIdx == 0); isPacked = true; type = type.Substring(6); } var specificType = InspectorTools.LiteralTypeMapper(type); var fieldIdx = (int)info.Arguments[1]; var label = FieldLabel.REQUIRED; if (info.Conditions.Any(c => c.Lhs.Contains("get_Count"))) { label = FieldLabel.REPEATED; } else if (info.Conditions.Any(c => c.Lhs.Contains("has"))) { label = FieldLabel.OPTIONAL; } // Construct IR reference placeholder. IRTypeNode irReference = null; if (specificType == PropertyTypeKind.TYPE_REF) { TypeReference fieldReference; if (info.Method.IsGenericInstance) { var method = info.Method as GenericInstanceMethod; fieldReference = method.GenericArguments[0]; } else { // Find out definition from arguments var cleanFieldName = fieldName.ToLower().Replace("_", ""); var fieldRef = allFields.OrderBy(f => f.Name.Length).First(field => field.Name.ToLower().Contains(cleanFieldName)); fieldReference = fieldRef.FieldType; } if (label == FieldLabel.REPEATED && fieldReference.IsGenericInstance) { var genericField = fieldReference as GenericInstanceType; fieldReference = genericField.GenericArguments[0]; } var fieldDefinition = fieldReference.Resolve(); irReference = InspectorTools.ConstructIRType(fieldDefinition); Debug.Assert(!fieldDefinition.FullName.Equals("System.UInt32")); // And save the reference TYPEDEFINITION for the caller to process. references.Add(fieldDefinition); } var newProperty = new IRClassProperty() { Name = fieldName, Type = specificType, ReferencedType = irReference, Options = new IRClassProperty.ILPropertyOptions() { Label = label, PropertyOrder = fieldIdx, IsPacked = isPacked, } }; properties.Add(newProperty); return; }