Esempio n. 1
0
 public Specializer(Module targetModule, TypeNodeList pars, TypeNodeList args){
   Debug.Assert(pars != null && pars.Count > 0);
   Debug.Assert(args != null && args.Count > 0);
   this.pars = pars;
   this.args = args;
   this.TargetModule = targetModule;
 }
Esempio n. 2
0
 public virtual TypeNodeList VisitTypeNodeList(TypeNodeList types){
   if (types == null) return null;
   for (int i = 0; i < types.Count; i++) //Visiting a type may result in a new type being appended to this list
     types[i] = (TypeNode)this.Visit(types[i]);
   return types;
 }
Esempio n. 3
0
 public MethodBodySpecializer(Module module, TypeNodeList pars, TypeNodeList args)
   : base(module, pars, args){
   //^ base;
 }
Esempio n. 4
0
    public override TypeNode VisitTypeReference(TypeNode type){ //TODO: break up this method
      if (type == null) return null;
      TypeNodeList pars = this.pars;
      TypeNodeList args = this.args;
      switch (type.NodeType){
        case NodeType.ArrayType:
          ArrayType arrType = (ArrayType)type;
          TypeNode elemType = this.VisitTypeReference(arrType.ElementType);
          if (elemType == arrType.ElementType || elemType == null) return arrType;
          if (arrType.IsSzArray()) return elemType.GetArrayType(1);
          return elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds);
#if !MinimalReader
        case NodeType.DelegateNode:{
          FunctionType ftype = type as FunctionType;
          if (ftype == null) goto default;
          TypeNode referringType = ftype.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(ftype.DeclaringType);
          return FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), referringType);}
#endif
        case NodeType.Pointer:
          Pointer pType = (Pointer)type;
          elemType = this.VisitTypeReference(pType.ElementType);
          if (elemType == pType.ElementType || elemType == null) return pType;
          return elemType.GetPointerType();
        case NodeType.Reference:
          Reference rType = (Reference)type;
          elemType = this.VisitTypeReference(rType.ElementType);
          if (elemType == rType.ElementType || elemType == null) return rType;
          return elemType.GetReferenceType();
#if ExtendedRuntime
        case NodeType.TupleType:{
          TupleType tType = (TupleType)type;
          bool reconstruct = false;
          MemberList members = tType.Members;
          int n = members == null ? 0 : members.Count;
          FieldList fields = new FieldList(n);
          for (int i = 0; i < n; i++){
            //^ assert members != null;
            Field f = members[i] as Field;
            if (f == null) continue;
            f = (Field)f.Clone();
            fields.Add(f);
            TypeNode oft = f.Type;
            TypeNode ft = f.Type = this.VisitTypeReference(f.Type);
            if (ft != oft) reconstruct = true;
          }
          if (!reconstruct) return tType;
          TypeNode referringType = tType.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(tType.DeclaringType);
          return TupleType.For(fields, referringType);}
        case NodeType.TypeIntersection:{
          TypeIntersection tIntersect = (TypeIntersection)type;
          TypeNode referringType = tIntersect.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(tIntersect.DeclaringType);
          return TypeIntersection.For(this.VisitTypeReferenceList(tIntersect.Types), referringType);}
        case NodeType.TypeUnion:{
          TypeUnion tUnion = (TypeUnion)type;
          TypeNode referringType = tUnion.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(tUnion.DeclaringType);
          TypeNodeList types = this.VisitTypeReferenceList(tUnion.Types);
          if (referringType == null || types == null) { Debug.Fail(""); return null; }
          return TypeUnion.For(types, referringType);}
#endif
#if !MinimalReader        
        case NodeType.ArrayTypeExpression:
          ArrayTypeExpression aExpr = (ArrayTypeExpression)type;
          aExpr.ElementType = this.VisitTypeReference(aExpr.ElementType);
          return aExpr;
        case NodeType.BoxedTypeExpression:
          BoxedTypeExpression bExpr = (BoxedTypeExpression)type;
          bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType);
          return bExpr;
        case NodeType.ClassExpression:{
          ClassExpression cExpr = (ClassExpression)type;
          cExpr.Expression = this.VisitTypeExpression(cExpr.Expression);
          Literal lit = cExpr.Expression as Literal; //Could happen if the expression is a template parameter
          if (lit != null) return lit.Value as TypeNode;
          cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
          return cExpr;}
#endif
        case NodeType.ClassParameter:
        case NodeType.TypeParameter:
          int key = type.UniqueKey;
          var mappedTarget = this.forwarding[key] as TypeNode;
          if (mappedTarget != null) return mappedTarget;
          for (int i = 0, n = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; i < n && i < m; i++){
            //^ assert pars != null && args != null;
            TypeNode tp = pars[i];
            if (tp == null) continue;
            if (tp.UniqueKey == key) return args[i];
#if false
            if (tp.Name.UniqueIdKey == type.Name.UniqueIdKey && (tp is ClassParameter && type is TypeParameter)) {
              //This shouldn't really happen, but in practice it does. Hack past it.
              Debug.Assert(false);
              return args[i];
            }
#endif
          }
          return type;
#if ExtendedRuntime
        case NodeType.ConstrainedType:{
          ConstrainedType conType = (ConstrainedType)type;
          TypeNode referringType = conType.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(conType.DeclaringType);
          TypeNode underlyingType = this.VisitTypeReference(conType.UnderlyingType);
          Expression constraint = this.VisitExpression(conType.Constraint);
          if (referringType == null || underlyingType == null || constraint == null) { Debug.Fail(""); return null; }
          return new ConstrainedType(underlyingType, constraint, referringType);}
#endif
#if !MinimalReader
        case NodeType.FlexArrayTypeExpression:
          FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type;
          flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType);
          return flExpr;
        case NodeType.FunctionTypeExpression:
          FunctionTypeExpression ftExpr = (FunctionTypeExpression)type;
          ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters);
          ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType);
          return ftExpr;
        case NodeType.InvariantTypeExpression:
          InvariantTypeExpression invExpr = (InvariantTypeExpression)type;
          invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType);
          return invExpr;
#endif
        case NodeType.InterfaceExpression:
          InterfaceExpression iExpr = (InterfaceExpression)type;
          if (iExpr.Expression == null) goto default;
          iExpr.Expression = this.VisitTypeExpression(iExpr.Expression);
          iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments);
          return iExpr;
#if !MinimalReader
        case NodeType.NonEmptyStreamTypeExpression:
          NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type;
          neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType);
          return neExpr;
        case NodeType.NonNullTypeExpression:
          NonNullTypeExpression nnExpr = (NonNullTypeExpression)type;
          nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType);
          return nnExpr;
        case NodeType.NonNullableTypeExpression:
          NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type;
          nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType);
          return nbExpr;
        case NodeType.NullableTypeExpression:
          NullableTypeExpression nuExpr = (NullableTypeExpression)type;
          nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType);
          return nuExpr;
#endif
        case NodeType.OptionalModifier:{
          TypeModifier modType = (TypeModifier)type;
          TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType);
          TypeNode modifierType = this.VisitTypeReference(modType.Modifier);
          if (modifiedType == null || modifierType == null) { return type; }
#if ExtendedRuntime
          if (modifierType != null && modifierType == SystemTypes.NullableType){
            if (modifiedType.IsValueType) return modifiedType;
            if (TypeNode.HasModifier(modifiedType, SystemTypes.NonNullType))
              modifiedType = TypeNode.StripModifier(modifiedType, SystemTypes.NonNullType);
            if (modifiedType.IsTemplateParameter) {
              return OptionalModifier.For(modifierType, modifiedType);
            }
            return modifiedType;
          }
          if (modifierType == SystemTypes.NonNullType) {
            if (modifiedType.IsValueType) return modifiedType;
            modifiedType = TypeNode.StripModifier(modifiedType, SystemTypes.NonNullType);
          }
          //^ assert modifiedType != null;
#endif
          return OptionalModifier.For(modifierType, modifiedType);
        }
        case NodeType.RequiredModifier:{
          TypeModifier modType = (TypeModifier)type;
          TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType);
          TypeNode modifierType = this.VisitTypeReference(modType.Modifier);
          if (modifiedType == null || modifierType == null) { Debug.Fail(""); return type; }
          return RequiredModifier.For(modifierType, modifiedType);
        }
#if !MinimalReader && !CodeContracts
        case NodeType.OptionalModifierTypeExpression:
          OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type;
          optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType);
          optmodType.Modifier = this.VisitTypeReference(optmodType.Modifier);
          return optmodType;
        case NodeType.RequiredModifierTypeExpression:
          RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type;
          reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType);
          reqmodType.Modifier = this.VisitTypeReference(reqmodType.Modifier);
          return reqmodType;
        case NodeType.PointerTypeExpression:
          PointerTypeExpression pExpr = (PointerTypeExpression)type;
          pExpr.ElementType = this.VisitTypeReference(pExpr.ElementType);
          return pExpr;
        case NodeType.ReferenceTypeExpression:
          ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type;
          rExpr.ElementType = this.VisitTypeReference(rExpr.ElementType);
          return rExpr;
        case NodeType.StreamTypeExpression:
          StreamTypeExpression sExpr = (StreamTypeExpression)type;
          sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType);
          return sExpr;
        case NodeType.TupleTypeExpression:
          TupleTypeExpression tuExpr = (TupleTypeExpression)type;
          tuExpr.Domains = this.VisitFieldList(tuExpr.Domains);
          return tuExpr;
        case NodeType.TypeExpression:{
          TypeExpression tExpr = (TypeExpression)type;
          tExpr.Expression = this.VisitTypeExpression(tExpr.Expression);
          if (tExpr.Expression is Literal) return type;
          tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments);
          return tExpr;}
        case NodeType.TypeIntersectionExpression:
          TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type;
          tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types);
          return tiExpr;
        case NodeType.TypeUnionExpression:
          TypeUnionExpression tyuExpr = (TypeUnionExpression)type;
          tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types);
          return tyuExpr;
#endif
        default:
          if (type.Template != null)
          {
            Debug.Assert(TypeNode.IsCompleteTemplate(type.Template));
            // map consolidated arguments
            bool mustSpecializeFurther = false;
            TypeNodeList targs = type.ConsolidatedTemplateArguments;
            int numArgs = targs == null ? 0 : targs.Count;
            if (targs != null)
            {
              targs = targs.Clone();
              for (int i = 0; i < numArgs; i++)
              {
                TypeNode targ = targs[i];
                targs[i] = this.VisitTypeReference(targ);
                if (targ != targs[i]) { mustSpecializeFurther = true; }
              }
            }
            if (targs == null || !mustSpecializeFurther) return type;
            TypeNode t = type.Template.GetGenericTemplateInstance(this.TargetModule, targs);
            return t;
          }
          return type;
#if OLD
          TypeNode declaringType = this.VisitTypeReference(type.DeclaringType);
          if (declaringType != null){
            Identifier tname = type.Name;
            if (type.Template != null && type.IsGeneric) tname = type.Template.Name;
            TypeNode nt = declaringType.GetNestedType(tname);
            if (nt != null){
              TypeNodeList arguments = type.TemplateArguments;
              type = nt;
              if (TargetPlatform.UseGenerics) {
                if (arguments != null && arguments.Count > 0 && nt.ConsolidatedTemplateParameters != null && nt.ConsolidatedTemplateParameters.Count > 0)
                  type = nt.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, arguments);
              }
            }
          }
          if (type.Template != null && (type.ConsolidatedTemplateParameters == null || type.ConsolidatedTemplateParameters.Count == 0)){
            if (!type.IsNotFullySpecialized && !type.IsNormalized) return type;
            //Type is a template instance, but some of its arguments were themselves parameters.
            //See if any of these parameters are to be specialized by this specializer.
            bool mustSpecializeFurther = false;
            TypeNodeList targs = type.TemplateArguments;
            int numArgs = targs == null ? 0 : targs.Count;
            if (targs != null) {
              targs = targs.Clone();
              for (int i = 0; i < numArgs; i++) {
                TypeNode targ = targs[i];
                ITypeParameter tparg = targ as ITypeParameter;
                if (tparg != null) {
                  for (int j = 0, np = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; j < np && j < m; j++) {
                    //^ assert pars != null && args != null;
                    if (TargetPlatform.UseGenerics) {
                      ITypeParameter par = pars[j] as ITypeParameter;
                      if (par == null) continue;
                      if (tparg == par || (tparg.ParameterListIndex == par.ParameterListIndex && tparg.DeclaringMember == par.DeclaringMember)) {
                        targ = this.args[j]; break;
                      }
                    }
                    else {
                      if (targ == pars[j]) { targ = this.args[j]; break; }
                    }
                  }
                } else {
                  if (targ != type)
                    targ = this.VisitTypeReference(targ);
                  if (targ == type) continue;
                }
                mustSpecializeFurther |= targs[i] != targ;
                targs[i] = targ;
              }
            }
            if (targs == null || !mustSpecializeFurther) return type;
            TypeNode t = type.Template.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, targs);
#if ExtendedRuntime
            if (this.CurrentType != null) {
              if (this.CurrentType.ReferencedTemplateInstances == null) this.CurrentType.ReferencedTemplateInstances = new TypeNodeList();
              this.CurrentType.ReferencedTemplateInstances.Add(t);
            }
#endif
            return t;
          }
          TypeNodeList tPars = type.TemplateParameters;
          if (tPars == null || tPars.Count == 0) return type; //Not a parameterized type. No need to get an instance.
          TypeNodeList tArgs = new TypeNodeList();
          for (int i = 0, n = tPars.Count; i < n; i++) {
            TypeNode tPar = tPars[i];
            tArgs.Add(tPar); //Leave parameter in place if there is no match
            if (tPar == null || tPar.Name == null) continue;
            int idKey = tPar.Name.UniqueIdKey;
            for (int j = 0, m = pars == null ? 0 : pars.Count, k = args == null ? 0 : args.Count; j < m && j < k; j++) {
              //^ assert pars != null && args != null;
              TypeNode par = pars[j];
              if (par == null || par.Name == null) continue;
              if (par.Name.UniqueIdKey == idKey) {
                tArgs[i] = args[j];
                break;
              }
            }
          }
          TypeNode ti = type.GetTemplateInstance(this.TargetModule, this.CurrentType, this.VisitTypeReference(type.DeclaringType), tArgs);
#if ExtendedRuntime
          if (this.CurrentType != null) {
            if (this.CurrentType.ReferencedTemplateInstances == null) this.CurrentType.ReferencedTemplateInstances = new TypeNodeList();
            this.CurrentType.ReferencedTemplateInstances.Add(ti);
          }
#endif
          return ti;
#endif
      }
    }
Esempio n. 5
0
 public virtual void VisitTypeReferenceList(TypeNodeList typeReferences)
 {
   if (typeReferences == null) return;
   for (int i = 0, n = typeReferences.Count; i < n; i++)
     this.VisitTypeReference(typeReferences[i]);
 }
Esempio n. 6
0
    /// <summary>
    /// Assumes the list itself was cloned by the duplicator.
    /// </summary>
    private TypeNodeList FreshTypeParameterListIfNecessary(TypeNodeList typeNodeList)
    {
        if (typeNodeList == null) return null;

        for (int i = 0; i < typeNodeList.Count; i++)
        {
            var tp = typeNodeList[i];
            if (tp == null) continue;
            if (tp.Interfaces != null && tp.Interfaces.Count > 0 || tp is ClassParameter)
            {
                typeNodeList[i] = FreshTypeParameterIfNecessary(tp);
            }
        }
        return this.VisitTypeParameterList(typeNodeList);
    }
Esempio n. 7
0
 public override TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences)
 {
     if (typeReferences == null) return null;
     return base.VisitTypeReferenceList(typeReferences.Clone());
 }
Esempio n. 8
0
 public virtual void FindTypesToBeDuplicated(TypeNodeList types){
   if (types == null) return;
   for (int i = 0, n = types.Count; i < n; i++){
     TypeNode t = types[i];
     RegisterTypeToBeDuplicated(t);
   }
 }
Esempio n. 9
0
 public override TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters)
 {
     if (typeParameters == null) return null;
     return base.VisitTypeParameterList(typeParameters.Clone());
 }
Esempio n. 10
0
 public virtual void FindTypesToBeDuplicated(TypeNodeList types)
 {
     if (types == null) return;
     for (int i = 0, n = types.Count; i < n; i++)
     {
         TypeNode t = types[i];
         if (t == null) continue;
         this.TypesToBeDuplicated[t.UniqueKey] = t;
         this.FindTypesToBeDuplicated(t.NestedTypes);
         this.FindTypesToBeDuplicated(t.TemplateParameters);
     }
 }
Esempio n. 11
0
 public override TypeNodeList VisitTypeNodeList(TypeNodeList types)
 {
     if (types == null) return null;
     types = base.VisitTypeNodeList(types.Clone());
     if (this.TargetModule == null) return types;
     if (types == null) return null;
     if (this.TargetModule.Types == null) this.TargetModule.Types = new TypeNodeList();
     for (int i = 0, n = types.Count; i < n; i++)
         this.TargetModule.Types.Add(types[i]);
     return types;
 }
Esempio n. 12
0
 public virtual TypeNodeList VisitNestedTypes(TypeNode/*!*/ declaringType, TypeNodeList types)
 {
     if (types == null) return null;
     TypeNodeList dupTypes = types.Clone();
     for (int i = 0, n = types.Count; i < n; i++)
     {
         TypeNode nt = types[i];
         if (nt == null) continue;
         TypeNode ntdup;
         if (TargetPlatform.UseGenerics)
         {
             ntdup = dupTypes[i] = this.VisitTypeNode(nt, null, null, null, true);
         }
         else
         {
             ntdup = dupTypes[i] = this.VisitTypeReference(nt);
         }
         if (ntdup != nt && ntdup != null)
         {
             if (this.RecordOriginalAsTemplate) ntdup.Template = nt;
             ntdup.DeclaringType = declaringType;
             ntdup.DeclaringModule = declaringType.DeclaringModule;
         }
     }
     for (int i = 0, n = types.Count; i < n; i++)
     {
         TypeNode nt = types[i];
         if (nt == null) continue;
         TypeNodeList nestedTypes = nt.NestedTypes;
         if (nestedTypes == null || nestedTypes.Count == 0) continue;
         TypeNode ntDup = dupTypes[i];
         if (ntDup == null) { Debug.Fail(""); continue; }
         this.VisitNestedTypes(ntDup, nestedTypes);
     }
     return dupTypes;
 }
Esempio n. 13
0
        internal TypeNode VisitTypeNode(TypeNode type, Identifier mangledName, TypeNodeList templateArguments, TypeNode template, bool delayVisitToNestedTypes)
        {
            if (type == null) return null;
            TypeNode dup = (TypeNode)this.DuplicateFor[type.UniqueKey];
            if (dup != null) return dup;
            this.DuplicateFor[type.UniqueKey] = dup = (TypeNode)type.Clone();
            if (mangledName != null)
            {
                this.TargetModule.StructurallyEquivalentType[mangledName.UniqueIdKey] = dup;
                dup.TemplateArguments = templateArguments;
            }
            dup.arrayTypes = null;
            dup.constructors = null;
            dup.consolidatedTemplateArguments = null;
            dup.consolidatedTemplateParameters = null;
#if DEBUG && !MinimalReader
            dup.DebugLabel = null;
#endif
#if !NoXml
            dup.DocumentationId = null;
            if (this.CopyDocumentation) dup.Documentation = type.Documentation;
#endif
            dup.defaultMembers = null;
#if !MinimalReader
            dup.explicitCoercionFromTable = null;
            dup.explicitCoercionMethods = null;
            dup.implicitCoercionFromTable = null;
            dup.implicitCoercionMethods = null;
            dup.implicitCoercionToTable = null;
#endif
            dup.memberCount = 0;
            dup.memberTable = null;
            dup.modifierTable = null;
            dup.NestedTypes = null;
            dup.pointerType = null;
            dup.ProviderHandle = null;
            dup.ProvideTypeAttributes = null;
            dup.ProvideTypeMembers = null;
            dup.ProvideNestedTypes = null;
            dup.referenceType = null;
#if !NoReflection
            dup.runtimeType = null;
#endif
            dup.structurallyEquivalentMethod = null;
            TypeParameter tp = dup as TypeParameter;
            if (tp != null) tp.structuralElementTypes = null;
            ClassParameter cp = dup as ClassParameter;
            if (cp != null) cp.structuralElementTypes = null;
            dup.szArrayTypes = null;
            if (this.RecordOriginalAsTemplate) dup.Template = type;
            dup.TemplateArguments = null;
            dup.TemplateInstances = null;
            dup.DeclaringModule = this.TargetModule;
            dup.DeclaringType = this.TargetType;
            TypeNode savedTargetType = this.TargetType;
            this.TargetType = dup;
            dup.Attributes = this.VisitAttributeList(type.Attributes);
            dup.SecurityAttributes = this.VisitSecurityAttributeList(type.SecurityAttributes);
            Class c = dup as Class;
            if (c != null) c.BaseClass = (Class)this.VisitTypeReference(c.BaseClass);
            dup.Interfaces = this.VisitInterfaceReferenceList(dup.Interfaces);
            dup.TemplateParameters = this.VisitTypeReferenceList(type.TemplateParameters);
            dup.consolidatedTemplateParameters = null;
#if !MinimalReader
            if (dup is MethodScope)
                dup.members = this.VisitMemberList(type.members);
            else
#endif
                if (!this.RecordOriginalAsTemplate)
                {
                    if (!delayVisitToNestedTypes)
                        dup.nestedTypes = this.VisitNestedTypes(dup, type.NestedTypes);
                    dup.members = null;
                    dup.ProvideTypeMembers = new TypeNode.TypeMemberProvider(this.ProvideTypeMembers);
                    dup.ProviderHandle = type;
                }
                else
                {
                    dup.members = null;
                    dup.ProvideNestedTypes = new TypeNode.NestedTypeProvider(this.ProvideNestedTypes);
                    dup.ProvideTypeMembers = new TypeNode.TypeMemberProvider(this.ProvideTypeMembers);
                    dup.ProviderHandle = type;
                }
            DelegateNode delegateNode = dup as DelegateNode;
            if (delegateNode != null)
            {
#if !MinimalReader
                if (!delegateNode.IsNormalized || !this.RecordOriginalAsTemplate)
                {
                    if (!delegateNode.IsNormalized)
                        ((DelegateNode)type).ProvideMembers();
                    delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
                    delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
                }
                else
#endif
                {
                    delegateNode.Parameters = null;
                    delegateNode.ReturnType = null;
                }
            }
            dup.membersBeingPopulated = false;
            this.TargetType = savedTargetType;
            return dup;
        }
Esempio n. 14
0
 public virtual TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters){
   if (typeParameters == null) return null;
   for (int i = 0, n = typeParameters.Count; i < n; i++)
     typeParameters[i] = this.VisitTypeParameter(typeParameters[i]);
   return typeParameters;
 }
Esempio n. 15
0
 public virtual void VisitTypeParameterList(TypeNodeList typeParameters)
 {
   if (typeParameters == null) return;
   for (int i = 0, n = typeParameters.Count; i < n; i++)
     this.VisitTypeParameter(typeParameters[i]);
 }
Esempio n. 16
0
 public virtual TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences){
   if (typeReferences == null) return null;
   for (int i = 0, n = typeReferences.Count; i < n; i++)
     typeReferences[i] = this.VisitTypeReference(typeReferences[i]);
   return typeReferences;
 } 
Esempio n. 17
0
    public override TypeNode VisitTypeReference(TypeNode type){
      if (type == null) return null;
      TypeNode dup = (TypeNode)this.DuplicateFor[type.UniqueKey];
      if (dup != null && (dup.Template != type || this.RecordOriginalAsTemplate)) return dup;
      if (this.RecordOriginalAsTemplate) {
          // [11/1/12 MAF: There was a bug that made it not possible to skip the copy here because generic methods have 
          // type parameters that needed to be duplicated including types instantiated with these type parameters, 
          // e.g.,  Task<T> Foo<T>().
          // Returning here had left Task<T> whereas the method has been changed to Task<T'>
          // Fixing this required not copying the generic method parameters when creating an instance, and instead copying
          // the template parameters during specializing. This fixed some bugs in the specializer too where we lost constraints
          // or mistakenly updated constraints of the generic type rather than the instance.
        return type; // mapping will be done by Specializer
      }
      switch (type.NodeType){
        case NodeType.ArrayType:
          ArrayType arrType = (ArrayType)type;
          TypeNode elemType = this.VisitTypeReference(arrType.ElementType);
          if (elemType == arrType.ElementType) return arrType;
          if (elemType == null) { Debug.Fail(""); return null; }
          //this.TypesToBeDuplicated[arrType.UniqueKey] = arrType;
          dup = elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds);
          break;
        case NodeType.ClassParameter:
        case NodeType.TypeParameter:
          if (this.RecordOriginalAsTemplate) return type;
          if (this.TypesToBeDuplicated[type.UniqueKey] == null) return type;
          dup = this.VisitTypeNode(type);
          break;
#if !MinimalReader
        case NodeType.DelegateNode:{
          FunctionType ftype = type as FunctionType;
          if (ftype == null) goto default;
          dup = FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), this.TargetType);
          break;}
#endif
        case NodeType.Pointer:
          Pointer pType = (Pointer)type;
          elemType = this.VisitTypeReference(pType.ElementType);
          if (elemType == pType.ElementType) return pType;
          if (elemType == null) { Debug.Fail(""); return null; }
          dup = elemType.GetPointerType();
          break;
        case NodeType.Reference:
          Reference rType = (Reference)type;
          elemType = this.VisitTypeReference(rType.ElementType);
          if (elemType == rType.ElementType) return rType;
          if (elemType == null) { Debug.Fail(""); return null; }
          dup = elemType.GetReferenceType();
          break;
#if ExtendedRuntime    
        case NodeType.TupleType:{
          TupleType tType = (TupleType)type;
          bool reconstruct = false;
          MemberList members = tType.Members;
          int n = members == null ? 0 : members.Count;
          FieldList fields = new FieldList(n);
          for (int i = 0; i < n; i++){
            //^ assert members != null;
            Field f = members[i] as Field;
            if (f == null) continue;
            f = (Field)f.Clone();
            fields.Add(f);
            TypeNode oft = f.Type;
            TypeNode ft = f.Type = this.VisitTypeReference(f.Type);
            if (ft != oft) reconstruct = true;
          }
          if (!reconstruct) return tType;
          dup = TupleType.For(fields, this.TargetType);
          break;}
        case NodeType.TypeIntersection:
          TypeIntersection tIntersect = (TypeIntersection)type;
          dup = TypeIntersection.For(this.VisitTypeReferenceList(tIntersect.Types), this.TargetType);
          break;
        case NodeType.TypeUnion:
          TypeUnion tUnion = (TypeUnion)type;
          TypeNodeList types = this.VisitTypeReferenceList(tUnion.Types);
          if (types == null) { Debug.Fail(""); return null; }
          if (this.TargetType == null)
            dup = TypeUnion.For(types, TargetModule);
          else
            dup = TypeUnion.For(types, this.TargetType);
          break;
#endif
#if !MinimalReader
        //These types typically have only one reference and do not have pointer identity. Just duplicate them.
        case NodeType.ArrayTypeExpression:
          ArrayTypeExpression aExpr = (ArrayTypeExpression)type.Clone();
          elemType = this.VisitTypeReference(aExpr.ElementType);
          if (elemType == null) { Debug.Fail(""); return aExpr; }
          aExpr.ElementType = elemType;
          return aExpr;
        case NodeType.BoxedTypeExpression:
          BoxedTypeExpression bExpr = (BoxedTypeExpression)type.Clone();
          bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType);
          return bExpr;
        case NodeType.ClassExpression:
          ClassExpression cExpr = (ClassExpression)type.Clone();
          cExpr.Expression = this.VisitExpression(cExpr.Expression);
          cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
          return cExpr;   
#endif
#if ExtendedRuntime
        case NodeType.ConstrainedType:
          ConstrainedType conType = (ConstrainedType)type;
          TypeNode underlyingType = this.VisitTypeReference(conType.UnderlyingType);
          Expression constraint = this.VisitExpression(conType.Constraint);
          if (underlyingType == null || constraint == null) { Debug.Fail(""); return null; }
          if (this.TargetType == null)
            return null;
          else
            return new ConstrainedType(underlyingType, constraint, this.TargetType);
#endif
#if !MinimalReader        
        case NodeType.FlexArrayTypeExpression:
          FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type.Clone();
          flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType);
          return flExpr;
#endif
        case NodeType.FunctionPointer:
          FunctionPointer funcPointer = (FunctionPointer)type.Clone();
          funcPointer.ParameterTypes = this.VisitTypeReferenceList(funcPointer.ParameterTypes);
          funcPointer.ReturnType = this.VisitTypeReference(funcPointer.ReturnType);
          return funcPointer;
#if !MinimalReader
        case NodeType.FunctionTypeExpression:
          FunctionTypeExpression ftExpr = (FunctionTypeExpression)type.Clone();
          ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters);
          ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType);
          return ftExpr;
        case NodeType.InvariantTypeExpression:
          InvariantTypeExpression invExpr = (InvariantTypeExpression)type.Clone();
          invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType);
          return invExpr;
#endif
        case NodeType.InterfaceExpression:
          InterfaceExpression iExpr = (InterfaceExpression)type.Clone();
          iExpr.Expression = this.VisitExpression(iExpr.Expression);
          iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments);
          return iExpr;
#if !MinimalReader
        case NodeType.NonEmptyStreamTypeExpression:
          NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type.Clone();
          neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType);
          return neExpr;
        case NodeType.NonNullTypeExpression:
          NonNullTypeExpression nnExpr = (NonNullTypeExpression)type.Clone();
          nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType);
          return nnExpr;
        case NodeType.NonNullableTypeExpression:
          NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type.Clone();
          nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType);
          return nbExpr;
        case NodeType.NullableTypeExpression:
          NullableTypeExpression nuExpr = (NullableTypeExpression)type.Clone();
          nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType);
          return nuExpr;
#endif
        case NodeType.OptionalModifier:
          TypeModifier modType = (TypeModifier)type;
          TypeNode modified = this.VisitTypeReference(modType.ModifiedType);
          TypeNode modifier = this.VisitTypeReference(modType.Modifier);
          if (modified == null || modifier == null) { Debug.Fail(""); return null; }
          return OptionalModifier.For(modifier, modified);
        case NodeType.RequiredModifier:
          modType = (TypeModifier)type;
          modified = this.VisitTypeReference(modType.ModifiedType);
          modifier = this.VisitTypeReference(modType.Modifier);
          if (modified == null || modifier == null) { Debug.Fail(""); return null; }
          return RequiredModifier.For(modifier, modified);
#if !MinimalReader && !CodeContracts
        case NodeType.OptionalModifierTypeExpression:
          OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type.Clone();
          optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType);
          optmodType.Modifier = this.VisitTypeReference(optmodType.Modifier);
          return optmodType;
        case NodeType.RequiredModifierTypeExpression:
          RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type.Clone();
          reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType);
          reqmodType.Modifier = this.VisitTypeReference(reqmodType.Modifier);
          return reqmodType;
        case NodeType.PointerTypeExpression:
          PointerTypeExpression pExpr = (PointerTypeExpression)type.Clone();
          elemType = this.VisitTypeReference(pExpr.ElementType);
          if (elemType == null) { Debug.Fail(""); return pExpr; }
          pExpr.ElementType = elemType;
          return pExpr;
        case NodeType.ReferenceTypeExpression:
          ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type.Clone();
          elemType = this.VisitTypeReference(rExpr.ElementType);
          if (elemType == null) { Debug.Fail(""); return rExpr; }
          rExpr.ElementType = elemType;
          return rExpr;
        case NodeType.StreamTypeExpression:
          StreamTypeExpression sExpr = (StreamTypeExpression)type.Clone();
          sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType);
          return sExpr;
        case NodeType.TupleTypeExpression:
          TupleTypeExpression tuExpr = (TupleTypeExpression)type.Clone();
          tuExpr.Domains = this.VisitFieldList(tuExpr.Domains);
          return tuExpr;
        case NodeType.TypeExpression:
          TypeExpression tExpr = (TypeExpression)type.Clone();
          tExpr.Expression = this.VisitExpression(tExpr.Expression);
          tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments);
          return tExpr;
        case NodeType.TypeIntersectionExpression:
          TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type.Clone();
          tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types);
          return tiExpr;
        case NodeType.TypeUnionExpression:
          TypeUnionExpression tyuExpr = (TypeUnionExpression)type.Clone();
          tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types);
          return tyuExpr;
#endif
        default:
          if (type.Template != null)
          {
            var templ = type.Template;
            Debug.Assert(TypeNode.IsCompleteTemplate(templ));
            if (!this.RecordOriginalAsTemplate)
            {
              templ = this.VisitTemplateTypeReference(type.Template);
              Debug.Assert(templ.DeclaringType == null || type.Template.DeclaringType != null);
              Debug.Assert(templ.DeclaringType != null || type.Template.DeclaringType == null);
              Debug.Assert(TypeNode.IsCompleteTemplate(templ));
            }
            bool duplicateReference = templ != type.Template;
            var originalConsolidatedParameterCount = type.Template.ConsolidatedTemplateParameters.Count;
            var newConsolidatedParameterCount = templ.ConsolidatedTemplateParameters.Count;
            TypeNodeList targs;
            if (newConsolidatedParameterCount != originalConsolidatedParameterCount)
            {
              var missing = newConsolidatedParameterCount - originalConsolidatedParameterCount;
              Debug.Assert(missing > 0);
              Debug.Assert(duplicateReference);
              // prefill with new template parameters
              targs = new TypeNodeList(newConsolidatedParameterCount);
              for (int i = 0; i < newConsolidatedParameterCount; i++)
              {
                if (i < missing)
                {
                  targs.Add(templ.ConsolidatedTemplateParameters[i]);
                }
                else
                {
                  targs.Add(this.VisitTypeReference(type.ConsolidatedTemplateArguments[i - missing]));
                }
              }
            }
            else
            {
              targs = type.ConsolidatedTemplateArguments == null ? new TypeNodeList() : type.ConsolidatedTemplateArguments.Clone();
              for (int i = 0, n = targs == null ? 0 : targs.Count; i < n; i++)
              {
                TypeNode targ = targs[i];
                if (targ == null) continue;
                TypeNode targDup = this.VisitTypeReference(targ);
                if (targ != targDup) duplicateReference = true;
                targs[i] = targDup;
              }
            }
            if (!duplicateReference)
            {
              // cache translation
              Debug.Assert(this.TypesToBeDuplicated[type.UniqueKey] == null);
              this.DuplicateFor[type.UniqueKey] = type;
              return type;
            }
            dup = templ.GetGenericTemplateInstance(this.TargetModule, targs);
            Debug.Assert(dup != type);
            this.DuplicateFor[type.UniqueKey] = dup;
            return dup;
            
          }
          // old
#if false
          if (type.Template != null && type.Template != type && (type.TemplateArguments != null || 
          (!this.RecordOriginalAsTemplate && type.ConsolidatedTemplateArguments != null && type.ConsolidatedTemplateArguments.Count > 0))) {
            TypeNode templ = this.VisitTypeReference(type.Template);
            //^ assume templ != null;
            if (TargetPlatform.UseGenerics) {
              if (templ.Template != null) {
                if (this.RecordOriginalAsTemplate)
                  templ = templ.Template;
                else
                  templ = this.VisitTypeReference(templ.Template);
                //^ assume templ != null;
              }
              if (type.DeclaringType != null) {
                TypeNode declType = this.VisitTypeReference(type.DeclaringType);
                if (declType != null) {
                  TypeNode typeDup = declType.GetNestedType(type.Template.Name);
                  if (typeDup == null) {
                    //Can happen when templ is nested in a type that is still being duplicated
                    typeDup = (TypeNode)templ.Clone();
                    typeDup.DeclaringModule = this.TargetModule;
                    typeDup.Template = templ;
                    declType.NestedTypes.Add(typeDup);
                    templ = typeDup;
                  } else {
                    templ = typeDup;
                    if (templ.Template != null) {
                      if (this.RecordOriginalAsTemplate)
                        templ = templ.Template;
                      else {
                        if (templ.Template.DeclaringType == null)
                          templ.Template.DeclaringType = templ.DeclaringType.Template;
                        templ = this.VisitTypeReference(templ.Template);
                      }
                      //^ assume templ != null;
                    }
                  }
                }
              }
            }
            else
            {
              if (templ.Template != null)
              {
                // cache translation
                this.DuplicateFor[type.UniqueKey] = type;
                return type;
              }
            }
            bool duplicateReference = templ != type.Template;
            TypeNodeList targs = type.TemplateArguments == null ? new TypeNodeList() : type.TemplateArguments.Clone();
            if (!this.RecordOriginalAsTemplate)
              targs = type.ConsolidatedTemplateArguments == null ? new TypeNodeList() : type.ConsolidatedTemplateArguments.Clone();
            for (int i = 0, n = targs == null ? 0 : targs.Count; i < n; i++) {
              TypeNode targ = targs[i];
              if (targ == null) continue;
              TypeNode targDup = this.VisitTypeReference(targ);
              if (targ != targDup) duplicateReference = true;
              targs[i] = targDup;
            }
            if (!duplicateReference)
            {
              // cache translation
              this.DuplicateFor[type.UniqueKey] = type;
              return type;
            }
            if (!this.RecordOriginalAsTemplate)
              dup = templ.GetGenericTemplateInstance(this.TargetModule, targs);
            else
              dup = templ.GetTemplateInstance(this.TargetModule, this.TargetType, type.DeclaringType, targs);
            this.DuplicateFor[type.UniqueKey] = dup;
            return dup;
          }
#endif
          // Must be ground and not copied, so just return it.
          Debug.Assert(this.TypesToBeDuplicated[type.UniqueKey] == null);

          return type;
#if false
          Debug.Assert(type.DeclaringType == null || type.DeclaringType.Template == null);
          var declaringType = this.VisitTypeReference(type.DeclaringType);
          Debug.Assert(declaringType == null || declaringType.Template == null || this.RecordOriginalAsTemplate);

          if (declaringType != null && declaringType.Template != null)
          {
            // we are refering to a nested type that we are instantiating. This means the reference must be
            // used as a template and it stays as is.
            return type;
          }
          dup = (TypeNode)this.DuplicateFor[type.UniqueKey];
          if (dup != null) break;
          // deal with non-generic nested type
          if (declaringType != null && declaringType != type.DeclaringType)
          {
            dup = declaringType.GetNestedType(type.Name);
            if (dup != null) break;
          }
          if (this.TypesToBeDuplicated[type.UniqueKey] == null)
          {
            dup = type;
            break;
          }
          // need to duplicate, but haven't yet
          TypeNode savedTargetType = this.TargetType;
          if (declaringType != null)
          {
            if (declaringType == type.DeclaringType) {
              //Trying to duplicate a nested type into a type that is not the duplicate of the declaring type.
              //In this case, type is being duplicated into the original target type.
              declaringType = this.OriginalTargetType;
            }
          }
          this.TargetType = declaringType;
          dup = (TypeNode)this.Visit(type);
          this.TargetType = savedTargetType;
          break;
#endif
      }
      Debug.Assert(this.TypesToBeDuplicated[type.UniqueKey] == null || type != dup);
      this.DuplicateFor[type.UniqueKey] = dup;
      return dup;
    }