Ejemplo n.º 1
0
 internal ResidualMethod(AnnotatedMethod method, MemoState memo, Value[] args, PointerValue[] ptrs)
 {
     this.AnnotatedMethod = method;
     this.memo            = memo;
     this.Arguments       = args;
     this.Pointers        = ptrs;
 }
Ejemplo n.º 2
0
 public override String nameForSetterMethod(MapperConfig <Q> config, AnnotatedMethod method, String defaultName)
 {
     if (skip(defaultName, method))
     {
         return(defaultName);
     }
     return(toPascalCasing(defaultName));
 }
Ejemplo n.º 3
0
 private bool skip(String name, AnnotatedMethod method)
 {
     if (method.getAnnotationCount() > 0)
     {
         return(true);
     }
     return(false);
 }
Ejemplo n.º 4
0
 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));
 }
Ejemplo n.º 5
0
        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());
            }
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
 public virtual String nameForSetterMethod(MapperConfig <Q> config, AnnotatedMethod method, String defaultName)
 {
     return(null);
 }
Ejemplo n.º 8
0
        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);
            }
        }
Ejemplo n.º 9
0
        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}");
                                }
                            }
                        }
                    }
                }
            }
        }