示例#1
0
    internal static Method GetMethodInstanceReference(Method methodOfGenericType, TypeNode instantiatedParentType)
    {
      //F:
      Contract.Requires(methodOfGenericType != null);
      Contract.Requires(instantiatedParentType != null);

      return (Method)GetMemberInstanceReference(methodOfGenericType, instantiatedParentType);
#if false
      int index = MemberIndexInTypeMembers(methodOfGenericType);

      // now try to find same index in instance wrapper type

      Method instMethod = null;
      var members = instantiatedParentType.Members;
      if (index < members.Count)
      {
        instMethod = members[index] as Method;
        Debug.Assert(instMethod == null || instMethod.Name.UniqueIdKey == methodOfGenericType.Name.UniqueIdKey);
      }
      if (instMethod == null)
      {
        // instantiation order did not work out, so we need to fake it.
        Duplicator dup = new Duplicator(this.assemblyBeingRewritten, instantiatedParentType);
        dup.RecordOriginalAsTemplate = true;
        instMethod = dup.VisitMethod(methodOfGenericType);
        var spec = TypeParameterSpecialization(methodOfGenericType.DeclaringType, instantiatedParentType);
        instMethod = spec.VisitMethod(instMethod);
        instMethod.DeclaringType = instantiatedParentType;
        AddMemberAtIndex(index, instantiatedParentType, instMethod);
      }
      return instMethod;
#endif
    }
        private static void AddInterfaceImplementationWrapper(Class Class, Method intfMethod, Method baseMethod)
        {
            var d = new Duplicator(Class.DeclaringModule, Class);
            
            d.SkipBodies = true;

            var copy = d.VisitMethod(baseMethod);
            
            copy.Flags = MethodFlags.Private | MethodFlags.HideBySig | MethodFlags.Virtual | MethodFlags.NewSlot |
                         MethodFlags.Final;
            
            copy.ImplementedInterfaceMethods = new MethodList(intfMethod);
            copy.Name = Identifier.For("InheritedInterfaceImplementationContractWrapper$" + intfMethod.Name.Name);
            copy.ClearBody();
            copy.ThisParameter.Type = Class;
            
            var bodyBlock = new Block(new StatementList());
            copy.Body = new Block(new StatementList(bodyBlock));

            // add call to baseMethod
            var calledMethod = (baseMethod.TemplateParameters != null && baseMethod.TemplateParameters.Count > 0)
                ? baseMethod.GetTemplateInstance(Class, copy.TemplateParameters)
                : baseMethod;

            var argList = new ExpressionList();
            for (int i = 0; i < copy.Parameters.Count; i++)
            {
                argList.Add(copy.Parameters[i]);
            }

            var callExpression = new MethodCall(new MemberBinding(copy.ThisParameter, calledMethod), argList);
            if (HelperMethods.IsVoidType(intfMethod.ReturnType))
            {
                bodyBlock.Statements.Add(new ExpressionStatement(callExpression));
            }
            else
            {
                bodyBlock.Statements.Add(new Return(callExpression));
            }
            
            Class.Members.Add(copy);
        }
示例#3
0
        public virtual Method/*!*/ GetTemplateInstance(TypeNode referringType, TypeNodeList typeArguments)
        {
            if(referringType == null || this.DeclaringType == null) { Debug.Assert(false); return this; }
            if(this.IsGeneric)
                referringType = this.DeclaringType;
            if(referringType != this.DeclaringType && referringType.DeclaringModule == this.DeclaringType.DeclaringModule)
                return this.GetTemplateInstance(this.DeclaringType, typeArguments);
            if(referringType.structurallyEquivalentMethod == null)
                referringType.structurallyEquivalentMethod = new TrivialHashtableUsingWeakReferences();
            Module module = referringType.DeclaringModule;
            if(module == null)
                return this;
            int n = typeArguments == null ? 0 : typeArguments.Count;
            if(n == 0 || typeArguments == null)
                return this;
            StringBuilder sb = new StringBuilder(this.Name.ToString());
            sb.Append('<');
            for(int i = 0; i < n; i++)
            {
                TypeNode ta = typeArguments[i];
                if(ta == null)
                    continue;
                sb.Append(ta.FullName);
                if(i < n - 1)
                    sb.Append(',');
            }
            sb.Append('>');
            Identifier mangledName = Identifier.For(sb.ToString());
            lock(this)
            {
                Method m = (Method)referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey];
                int counter = 1;
                while(m != null)
                {
                    if(m.template == this && Method.TypeListsAreEquivalent(m.TemplateArguments, typeArguments))
                        return m;
                    mangledName = Identifier.For(mangledName.ToString() + counter++);
                    m = (Method)referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey];
                }
                Duplicator duplicator = new Duplicator(referringType.DeclaringModule, referringType);
                duplicator.RecordOriginalAsTemplate = true;
                duplicator.SkipBodies = true;
                Method result = duplicator.VisitMethod(this);
                //^ assume result != null;
                result.Attributes = this.Attributes; //These do not get specialized, but may need to get normalized
                result.Name = mangledName;
                result.fullName = null;
                result.template = this;
                result.TemplateArguments = typeArguments;
                TypeNodeList templateParameters = result.TemplateParameters;
                result.TemplateParameters = null;

                result.IsNormalized = true;

                if(!this.IsGeneric)
                {
                    ParameterList pars = this.Parameters;
                    ParameterList rpars = result.Parameters;
                    if(pars != null && rpars != null && rpars.Count >= pars.Count)
                        for(int i = 0, count = pars.Count; i < count; i++)
                        {
                            Parameter p = pars[i];
                            Parameter rp = rpars[i];
                            if(p == null || rp == null)
                                continue;
                            rp.Attributes = p.Attributes; //These do not get specialized, but may need to get normalized
                        }
                }

                if(!this.IsGeneric && !(result.IsStatic) && this.DeclaringType != referringType)
                {
                    result.Flags &= ~(MethodFlags.Virtual | MethodFlags.NewSlot);
                    result.Flags |= MethodFlags.Static;
                    result.CallingConvention &= ~CallingConventionFlags.HasThis;
                    result.CallingConvention |= CallingConventionFlags.ExplicitThis;

                    ParameterList pars = result.Parameters;

                    if(pars == null)
                        result.Parameters = pars = new ParameterList();

                    Parameter thisPar = new Parameter(StandardIds.This, this.DeclaringType);
                    pars.Add(thisPar);

                    for(int i = pars.Count - 1; i > 0; i--)
                        pars[i] = pars[i - 1];

                    pars[0] = thisPar;
                }

                referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey] = result;
                Specializer specializer = new Specializer(module, templateParameters, typeArguments);
                specializer.VisitMethod(result);
                if(this.IsGeneric) { result.DeclaringType = this.DeclaringType; return result; }
                if(this.IsAbstract)
                    return result;
                referringType.Members.Add(result);
                return result;
            }
        }