internal ResidualMethod(AnnotatedMethod method, MemoState memo, Value[] args, PointerValue[] ptrs) { this.AnnotatedMethod = method; this.memo = memo; this.Arguments = args; this.Pointers = ptrs; }
public override String nameForSetterMethod(MapperConfig <Q> config, AnnotatedMethod method, String defaultName) { if (skip(defaultName, method)) { return(defaultName); } return(toPascalCasing(defaultName)); }
private bool skip(String name, AnnotatedMethod method) { if (method.getAnnotationCount() > 0) { return(true); } return(false); }
public override String nameForGetterMethod(MapperConfig <Q> config, AnnotatedMethod method, String defaultName) { if (skip(defaultName, method)) { return(defaultName); } if (method.getName().startsWith("is")) { return(toPascalCasing(method.getName())); } return(toPascalCasing(defaultName)); }
void ProcessMethodChildren(TypeDefinition type, MethodDefinition method, XPathNodeIterator iterator) { ArrayBuilder <Attribute> attributes = ProcessAttributes(iterator); ArrayBuilder <(string, ArrayBuilder <Attribute>)> parameterAnnotations = ProcessParameters(type, method, iterator.Current.SelectChildren("parameter", string.Empty)); ArrayBuilder <ArrayBuilder <Attribute> > returnParameterAnnotations = ProcessReturnParameters(type, method, iterator.Current.SelectChildren("return", string.Empty)); var parameterAnnotation = new ArrayBuilder <(string ParamName, DynamicallyAccessedMemberTypes Annotation)> (); DynamicallyAccessedMemberTypes returnAnnotation = 0; if (parameterAnnotations.Count > 0) { foreach (var parameter in parameterAnnotations.ToArray()) { DynamicallyAccessedMemberTypes paramAnnotation = GetMemberTypesForDynamicallyAccessedMemberAttribute(parameter.Item2, _context, _xmlDocumentLocation); if (paramAnnotation != 0) { parameterAnnotation.Add((parameter.Item1, paramAnnotation)); } } } if (returnParameterAnnotations.Count == 1) { foreach (var returnparameter in returnParameterAnnotations.ToArray()) { DynamicallyAccessedMemberTypes returnparamAnnotation = GetMemberTypesForDynamicallyAccessedMemberAttribute(returnparameter, _context, _xmlDocumentLocation); if (returnparamAnnotation != 0) { returnAnnotation = returnparamAnnotation; } } } else { _context.LogMessage(MessageContainer.CreateWarningMessage(_context, $"There is more than one return parameter specified for '{method.Name}' in '{_xmlDocumentLocation}'", 2023, _xmlDocumentLocation)); } if (returnAnnotation != 0 || parameterAnnotation.Count > 0) { _methods[method] = new AnnotatedMethod(returnAnnotation, parameterAnnotation.ToArray()); } }
protected override void VisitNewObject(NewObject downNode, object o) { PointerToNode ptrUpNode = (o as Data).PointerToNode; AnnotatedMethod method = Annotation.GetAnnotatedMethod(downNode); Node upNode; ArrayList list = new ArrayList(); for (int i = method.ParamVals.Count - 1; i > 0; i--) { if (Annotation.GetValueBTType(method.ParamVals[i].Val) == BTType.Static) { list.Add(this.state.Stack.Pop()); } } if (Annotation.GetValueBTType(method.ParamVals[0].Val) == BTType.Static) { Type objtype = downNode.Constructor.DeclaringType; ObjectReferenceValue obj = new ObjectReferenceValue(FormatterServices.GetUninitializedObject(objtype)); FieldInfo[] fldInfos = ReflectionUtils.GetAllFields(objtype); BTType[] btTypes = Annotation.GetObjectFieldBTTypes(downNode); for (int i = 0; i < fldInfos.Length; i++) { if (btTypes[i] == BTType.Dynamic) { Variable varUp = this.mbbUp.Variables.CreateVar(fldInfos[i].FieldType, VariableKind.Local); this.varsHash[new PointerToObjectFieldValue(obj.Obj, fldInfos[i])] = varUp; ptrUpNode = SpecializingVisitor.initVariable(varUp, ptrUpNode); } } list.Add(obj); this.state.Stack.Push(obj); upNode = new CallMethod(downNode.Constructor, false, false); } else { upNode = new NewObject(downNode.Constructor); } list.Reverse(); Value[] args = list.ToArray(typeof(Value)) as Value[]; this.callMethod(downNode, method, ptrUpNode, upNode, args); }
public virtual String nameForSetterMethod(MapperConfig <Q> config, AnnotatedMethod method, String defaultName) { return(null); }
private void callMethod(Node downNode, AnnotatedMethod method, PointerToNode ptrUpNode, Node upNode, Value[] args) { if (method.SourceMethod.IsDefined(typeof(InlineAttribute), false) && !(upNode is NewObject)) { MethodBodyBlock mbbDown = this.holder.AnnotatedHolder[method]; SpecState state = new SpecState(mbbDown.Variables.Count); int varCount = 0; int argCount = 0; foreach (Variable varDown in mbbDown.Variables.ParameterMapper) { state.Pool[varDown] = new Location(varDown.Type); Variable varUp = this.mbbUp.Variables.CreateVar(varDown.Type, VariableKind.Local); this.varsHash[new PointerToLocationValue(state.Pool[varDown])] = varUp; if (Annotation.GetValueBTType(method.ParamVals[varCount++].Val) == BTType.Static) { state.Pool[varDown].Val = args[argCount]; state.Stack.Push(args[argCount++]); } else { Node upNext = new StoreVar(varUp); Node upPrevNext = ptrUpNode.Node; ptrUpNode.Node = upNext; upNext.Next = upPrevNext; } } while (ptrUpNode.Node != null) { ptrUpNode = new PointerToNode(ptrUpNode.Node); } foreach (Variable varDown in mbbDown.Variables) { if (!state.Pool.ContainsVar(varDown)) { state.Pool[varDown] = new Location(varDown.Type); Variable varUp = this.mbbUp.Variables.CreateVar(varDown.Type, VariableKind.Local); this.varsHash[new PointerToLocationValue(state.Pool[varDown])] = varUp; ptrUpNode = SpecializingVisitor.initVariable(varUp, ptrUpNode); } } int depth = state.Stack.Count + 1; GraphProcessor graphProc = new GraphProcessor(); SpecializingVisitor visitor = new SpecializingVisitor(graphProc, this.holder, this.mbbUp, state, this.varsHash); visitor.AddTask(mbbDown.Next, ptrUpNode); graphProc.Process(); foreach (Data newData in visitor.exitData) { state.Recall(newData.MemoSpecState, newData.ObjectHashtable); if (state.Stack.Count == depth) { this.state.Stack.Push(state.Stack.Pop()); } this.AddTask(downNode.Next, newData.PointerToNode); } } else { ObjectHashtable objHash = new ObjectHashtable(); MemoState memoArgs = new MemoState(args, objHash); PointerValue[] ptrs = this.varsHash.GetPointers(objHash); for (int i = 0; i < ptrs.Length; i++) { ptrUpNode = new PointerToNode(ptrUpNode.Node = new LoadVarAddr(this.varsHash[ptrs[i]])); } ptrUpNode = new PointerToNode(ptrUpNode.Node = upNode); ResidualMethod callMethod = new ResidualMethod(method, memoArgs, args, ptrs); Specialization.SetResidualMethod(upNode, callMethod); this.holder.SpecializeMethod(callMethod); this.AddTask(downNode.Next, ptrUpNode); } }
private void Initialize(LinkContext context, string jsonFile) { // Need "using" because JsonDocument won't close this as part of Dispose(). using FileStream jsonFileStream = File.OpenRead(jsonFile); // We only support UTF-8 using JsonDocument jsonDoc = JsonDocument.Parse(jsonFileStream, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip }); // TODO: need to also check the document is structurally sound. foreach (var assemblyElement in jsonDoc.RootElement.EnumerateObject()) { var assembly = context.Resolve(new AssemblyNameReference(assemblyElement.Name, new Version())); if (assembly == null) { context.LogMessage($"Assembly {assemblyElement.Name} couldn't be resolved"); continue; } foreach (var ns in assemblyElement.Value.EnumerateObject()) { string namespaceName = ns.Name; foreach (var typeElement in ns.Value.EnumerateObject()) { string typeName = typeElement.Name; var type = assembly.MainModule.GetType(namespaceName, typeName); if (type == null) { context.LogMessage($"Type {namespaceName}.{typeName} couldn't be resolved"); continue; } foreach (var member in typeElement.Value.EnumerateObject()) { string memberName = member.Name; // Technically, '(' is a valid character in both method and field names, // but the existing PreserveDependencyAttribute parser has a limitation in supporting // that anyway, so we will use '(' to distinguish methods from fields/properties. if (memberName.Contains("(")) { // This is a method // Parser uses same format as PreserveDependencyAttribute string[] signature = null; memberName = memberName.Replace(" ", ""); var sign_start = memberName.IndexOf('('); var sign_end = memberName.LastIndexOf(')'); if (sign_start > 0 && sign_end > sign_start) { var parameters = memberName.Substring(sign_start + 1, sign_end - sign_start - 1); signature = string.IsNullOrEmpty(parameters) ? Array.Empty <string> () : parameters.Split(','); memberName = memberName.Substring(0, sign_start); } MethodDefinition method = null; foreach (var candidate in type.Methods) { if (candidate.Name != memberName) { continue; } if (signature != null) { if (candidate.Parameters.Count != signature.Length) { continue; } bool sigMatch = true; for (int i = 0; i < candidate.Parameters.Count; i++) { if (candidate.Parameters[i].ParameterType.FullName != signature[i].ToCecilName()) { sigMatch = false; break; } } if (!sigMatch) { continue; } } if (method != null) { context.LogMessage($"Multiple matches for method {memberName}"); } method = candidate; } if (method == null) { context.LogMessage($"No match for {memberName}"); continue; } DynamicallyAccessedMemberKinds returnAnnotation = 0; var parameterAnnotations = new ArrayBuilder <(string ParamName, DynamicallyAccessedMemberKinds Annotation)> (); foreach (var parameter in member.Value.EnumerateObject()) { if (parameter.Name == "return") { returnAnnotation = ParseKinds(parameter.Value); } else { DynamicallyAccessedMemberKinds paramAnnotation = ParseKinds(parameter.Value); if (paramAnnotation != 0) { parameterAnnotations.Add((parameter.Name, paramAnnotation)); } } } if (returnAnnotation != 0 || parameterAnnotations.Count > 0) { _methods[method] = new AnnotatedMethod(returnAnnotation, parameterAnnotations.ToArray()); } } else { // This is a field or property FieldDefinition field = null; foreach (var candidate in type.Fields) { if (candidate.Name != memberName) { continue; } // IL allows overloaded fields, but not worth adding messages for that... field = candidate; break; } if (field != null) { DynamicallyAccessedMemberKinds fieldAnnotation = ParseKinds(member.Value); if (fieldAnnotation != 0) { _fields[field] = fieldAnnotation; } continue; } PropertyDefinition property = null; foreach (var candidate in type.Properties) { if (candidate.Name != memberName) { continue; } // IL allows overloaded properties, but not worth adding messages for that... property = candidate; break; } if (property != null) { DynamicallyAccessedMemberKinds propertyAnnotation = ParseKinds(member.Value); if (propertyAnnotation != 0) { _properties[property] = propertyAnnotation; } } if (field == null && property == null) { context.LogMessage($"No match for field or property {memberName}"); } } } } } } }