示例#1
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
      }
    }
示例#2
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));

            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));
            }

            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());

            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);

                //Could happen if the expression is a template parameter
                if (cExpr.Expression is Literal lit)
                {
                    return(lit.Value as TypeNode);
                }

                cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
                return(cExpr);
            }

            case NodeType.ClassParameter:
            case NodeType.TypeParameter:
                int key = type.UniqueKey;
                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 (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.
                        return(args[i]);
                    }
                }
                return(type);

            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);

            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);

            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);

            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);
                }

                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));
            }

            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);

            default:
                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 ||
                                                        (this.CurrentType != null && type.DeclaringModule == this.CurrentType.DeclaringModule)))
                    {
                        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 = new TypeNodeList(targs);

                        for (int i = 0; i < numArgs; i++)
                        {
                            TypeNode targ = targs[i];

                            if (targ is ITypeParameter tparg)
                            {
                                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)
                                    {
                                        if (!(pars[j] is ITypeParameter par))
                                        {
                                            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);
                    }

                    return(type.Template.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, targs));
                }

                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;
                        }
                    }
                }
                return(type.GetTemplateInstance(this.TargetModule, this.CurrentType, this.VisitTypeReference(type.DeclaringType), tArgs));
            }
        }
示例#3
0
 public virtual TypeNode GetDummyInstance(TypeNode t){
   if (t == null){Debug.Assert(false); return null;}
   if (this.currentTypeInstance != null){
     TypeNode nt = this.GetTypeView(this.currentTypeInstance).GetNestedType(t.Name);
     if (nt == null){Debug.Assert(false); return null;}
     if (nt.TemplateParameters == null || nt.TemplateParameters.Count == 0) return nt;
     t = nt;
   }
   return t.GetTemplateInstance(this.currentModule, null, t.DeclaringType, t.TemplateParameters);
 }
示例#4
0
        /// <summary>
        /// Creates a new instance of this class that contains the CCI nodes for contract class.
        /// </summary>
        /// <param name="errorHandler">Delegate receiving errors. If null, errors are thrown as exceptions.</param>
        ///
        private ContractNodes(AssemblyNode assembly, Action <System.CodeDom.Compiler.CompilerError> errorHandler)
        {
            if (errorHandler != null)
            {
                this.ErrorFound += errorHandler;
            }

            AssemblyNode assemblyContainingContractClass = null;

            #region Get the contract class and all of its members
            assemblyContainingContractClass = assembly;
            ContractClass = assembly.GetType(ContractNamespace, Identifier.For("Contract")) as Class;
            if (ContractClass == null)
            {
                // This is not a candidate, no warning as we try to find the right place where contracts live
                return;
            }
            ContractHelperClass = assembly.GetType(ContractInternalNamespace, Identifier.For("ContractHelper")) as Class;
            if (ContractHelperClass == null || !ContractHelperClass.IsPublic) // look in alternate location
            {
                var alternateNs = Identifier.For("System.Diagnostics.Contracts.Internal");
                ContractHelperClass = assembly.GetType(alternateNs, Identifier.For("ContractHelper")) as Class;
            }

            #region Get ContractFailureKind
            ContractFailureKind = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractFailureKind")) as EnumNode;
            #endregion Get ContractFailureKind

            #region Look for each member of the contract class
            var requiresMethods = ContractClass.GetMethods(Identifier.For("Requires"), SystemTypes.Boolean);
            for (int i = 0; i < requiresMethods.Count; i++)
            {
                var method = requiresMethods[i];
                if (method.TemplateParameters != null && method.TemplateParameters.Count == 1)
                {
                    // Requires<E>
                    RequiresExceptionMethod = method;
                }
                else if (method.TemplateParameters == null || method.TemplateParameters.Count == 0)
                {
                    RequiresMethod = method;
                }
            }
            // early test to see if the ContractClass we found has a Requires(bool) method. If it doesn't, we
            // silently think that this is not the right place.
            // We use this because contract reference assemblies have a Contract class, but it is not the right one, as it holds
            // just the 3 argument versions of all the contract methods.
            if (RequiresMethod == null)
            {
                ContractClass = null;
                return;
            }

            var requiresMethodsWithMsg = ContractClass.GetMethods(Identifier.For("Requires"), SystemTypes.Boolean, SystemTypes.String);
            for (int i = 0; i < requiresMethodsWithMsg.Count; i++)
            {
                var method = requiresMethodsWithMsg[i];
                if (method.TemplateParameters != null && method.TemplateParameters.Count == 1)
                {
                    // Requires<E>
                    RequiresExceptionWithMsgMethod = method;
                }
                else if (method.TemplateParameters == null || method.TemplateParameters.Count == 0)
                {
                    RequiresWithMsgMethod = method;
                }
            }
            EnsuresMethod                 = ContractClass.GetMethod(Identifier.For("Ensures"), SystemTypes.Boolean);
            EnsuresWithMsgMethod          = ContractClass.GetMethod(Identifier.For("Ensures"), SystemTypes.Boolean, SystemTypes.String);
            EnsuresOnThrowTemplate        = ContractClass.GetMethod(Identifier.For("EnsuresOnThrow"), SystemTypes.Boolean);
            EnsuresOnThrowWithMsgTemplate = ContractClass.GetMethod(Identifier.For("EnsuresOnThrow"), SystemTypes.Boolean, SystemTypes.String);
            InvariantMethod               = ContractClass.GetMethod(Identifier.For("Invariant"), SystemTypes.Boolean);
            InvariantWithMsgMethod        = ContractClass.GetMethod(Identifier.For("Invariant"), SystemTypes.Boolean, SystemTypes.String);

            AssertMethod        = ContractClass.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean);
            AssertWithMsgMethod = ContractClass.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean, SystemTypes.String);
            AssumeMethod        = ContractClass.GetMethod(Identifier.For("Assume"), SystemTypes.Boolean);
            AssumeWithMsgMethod = ContractClass.GetMethod(Identifier.For("Assume"), SystemTypes.Boolean, SystemTypes.String);

            ResultTemplate = ContractClass.GetMethod(ResultName);

            TypeNode GenericPredicate = SystemTypes.SystemAssembly.GetType(
                Identifier.For("System"),
                Identifier.For("Predicate" + TargetPlatform.GenericTypeNamesMangleChar + "1")
                );
            if (GenericPredicate != null)
            {
                ForAllGenericTemplate = ContractClass.GetMethod(ForallName, SystemTypes.GenericIEnumerable, GenericPredicate);
                ExistsGenericTemplate = ContractClass.GetMethod(ExistsName, SystemTypes.GenericIEnumerable, GenericPredicate);
                if (ForAllGenericTemplate == null)
                {
                    // The problem might be that we are in the pre 4.0 scenario and using an out-of-band contract for mscorlib
                    // in which case the contract library is defined in that out-of-band contract assembly.
                    // If so, then ForAll and Exists are defined in terms of the System.Predicate defined in the out-of-band assembly.
                    var tempGenericPredicate = assemblyContainingContractClass.GetType(
                        Identifier.For("System"),
                        Identifier.For("Predicate" + TargetPlatform.GenericTypeNamesMangleChar + "1")
                        );
                    if (tempGenericPredicate != null)
                    {
                        GenericPredicate = tempGenericPredicate;
                        TypeNode genericIEnum = assemblyContainingContractClass.GetType(Identifier.For("System.Collections.Generic"),
                                                                                        Identifier.For("IEnumerable" + TargetPlatform.GenericTypeNamesMangleChar + "1"));
                        ForAllGenericTemplate = ContractClass.GetMethod(Identifier.For("ForAll"), genericIEnum, GenericPredicate);
                        ExistsGenericTemplate = ContractClass.GetMethod(Identifier.For("Exists"), genericIEnum, GenericPredicate);
                    }
                }
                TypeNode PredicateOfInt = GenericPredicate.GetTemplateInstance(ContractClass, SystemTypes.Int32);
                if (PredicateOfInt != null)
                {
                    ForAllTemplate = ContractClass.GetMethod(Identifier.For("ForAll"), SystemTypes.Int32, SystemTypes.Int32, PredicateOfInt);
                    ExistsTemplate = ContractClass.GetMethod(Identifier.For("Exists"), SystemTypes.Int32, SystemTypes.Int32, PredicateOfInt);
                }
            }
            foreach (Member member in ContractClass.GetMembersNamed(ValueAtReturnName))
            {
                Method method = member as Method;
                if (method != null && method.Parameters.Count == 1)
                {
                    Reference reference = method.Parameters[0].Type as Reference;
                    if (reference != null && reference.ElementType.IsTemplateParameter)
                    {
                        ParameterTemplate = method;
                        break;
                    }
                }
            }
            foreach (Member member in ContractClass.GetMembersNamed(OldName))
            {
                Method method = member as Method;
                if (method != null && method.Parameters.Count == 1 && method.Parameters[0].Type.IsTemplateParameter)
                {
                    OldTemplate = method;
                    break;
                }
            }

            EndContract = ContractClass.GetMethod(Identifier.For("EndContractBlock"));
            if (this.ContractFailureKind != null)
            {
                if (ContractHelperClass != null)
                {
                    RaiseFailedEventMethod = ContractHelperClass.GetMethod(ContractNodes.RaiseContractFailedEventName, this.ContractFailureKind, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);
                    TriggerFailureMethod   = ContractHelperClass.GetMethod(ContractNodes.TriggerFailureName, this.ContractFailureKind, SystemTypes.String, SystemTypes.String, SystemTypes.String, SystemTypes.Exception);
                }
            }
            #endregion Look for each member of the contract class
            #endregion Get the contract class and all of its members
            #region Get the attributes
            PureAttribute              = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("PureAttribute")) as Class;
            InvariantMethodAttribute   = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractInvariantMethodAttribute")) as Class;
            ContractClassAttribute     = assemblyContainingContractClass.GetType(ContractNamespace, ContractClassAttributeName) as Class;
            ContractClassForAttribute  = assemblyContainingContractClass.GetType(ContractNamespace, ContractClassForAttributeName) as Class;
            VerifyAttribute            = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractVerificationAttribute")) as Class;
            SpecPublicAttribute        = assemblyContainingContractClass.GetType(ContractNamespace, SpecPublicAttributeName) as Class;
            ReferenceAssemblyAttribute = assemblyContainingContractClass.GetType(ContractNamespace, Identifier.For("ContractReferenceAssemblyAttribute")) as Class;
            IgnoreAtRuntimeAttribute   = assemblyContainingContractClass.GetType(ContractNamespace, RuntimeIgnoredAttributeName) as Class;
            #endregion
            #region Check that every field in this class has been set
            foreach (System.Reflection.FieldInfo field in typeof(ContractNodes).GetFields())
            {
                if (field.GetValue(this) == null)
                {
                    string   sig      = null;
                    bool     required = false;
                    object[] cas      = field.GetCustomAttributes(typeof(RepresentationFor), false);
                    for (int i = 0, n = cas.Length; i < n; i++) // should be exactly one
                    {
                        RepresentationFor rf = cas[i] as RepresentationFor;
                        if (rf != null)
                        {
                            sig      = rf.runtimeName;
                            required = rf.required;
                            break;
                        }
                    }
                    if (!required)
                    {
                        continue;
                    }
                    string msg = "Could not find contract node for '" + field.Name + "'";
                    if (sig != null)
                    {
                        msg = "Could not find the method/type '" + sig + "'";
                    }
                    if (ContractClass != null && ContractClass.DeclaringModule != null)
                    {
                        msg += " in assembly '" + ContractClass.DeclaringModule.Location + "'";
                    }
                    Module dm = ContractClass.DeclaringModule;
                    ClearFields();
                    CallErrorFound(dm, msg);
                    return;
                }
            }
            #region Check that ContractFailureKind is okay
            if (this.ContractFailureKind.GetField(Identifier.For("Assert")) == null ||
                this.ContractFailureKind.GetField(Identifier.For("Assume")) == null ||
                this.ContractFailureKind.GetField(Identifier.For("Invariant")) == null ||
                this.ContractFailureKind.GetField(Identifier.For("Postcondition")) == null ||
                this.ContractFailureKind.GetField(Identifier.For("Precondition")) == null
                )
            {
                Module dm = ContractClass.DeclaringModule;
                ClearFields();
                CallErrorFound(dm, "The enum ContractFailureKind must have the values 'Assert', 'Assume', 'Invariant', 'Postcondition', and 'Precondition'.");
            }

            #endregion
            #endregion Check that every field in this class has been set
        }
示例#5
0
	void PTypeRef(out TypeNode tn) {
		Module assem = null;
		string ns, tname, nestedname;
		ArrayList/*<string>*/ typeNames;
		TypeNodeList templateArgs = null;
		
		if (la.kind == 28) {
			Assembly(out assem);
		}
		QualName(out ns, out tname);
		NestedTypeName(out typeNames, out nestedname);
		if (la.kind == 31) {
			Get();
			TypeNode arg; 
			PType(out arg);
			templateArgs = new TypeNodeList(); templateArgs.Add(arg); 
			while (la.kind == 23) {
				Get();
				PType(out arg);
				templateArgs.Add(arg); 
			}
			Expect(32);
		}
		if ( assem == null ){
		 assem = currentAssembly;
		}
		#if !WHIDBEY
		if (templateArgs != null){
		 /* then need to create the pseudo-generic name */
		 string pseudoGenericName = tname;
		 /*pseudoGenericName += SystemTypes.GenericTypeNamesMangleChar;*/
		 /*pseudoGenericName += templateArgs.Count.ToString();*/
		 pseudoGenericName += "<";
		 for (int i = 0, n = templateArgs.Count; i < n; i++){
		   if (i > 0)
		     pseudoGenericName += ",";
		   pseudoGenericName += templateArgs[i].FullName;
		 }
		 pseudoGenericName += ">";
		 tname = pseudoGenericName;
		}
		#endif
		tn = assem.GetType(Identifier.For(ns),Identifier.For(tname));
		if (tn == null) {
		 this.errors.SemErr(t.filename, t.line, t.col,
		               String.Format("could not resolve namespace {0}, type {1}", ns, tname));
		 throw new Exception("cannot continue"); //Errors.Exception("cannot continue");
		}
		// now do nested types
		for (int i=0; i<typeNames.Count; i++){
		 tn = tn.GetNestedType(Identifier.For((string)typeNames[i]));
		}
		if (tn == null) {
		 this.errors.SemErr(t.filename, t.line, t.col,
		               String.Format("could not resolve namespace {0} type {1} nesting {2}", ns, tname, nestedname));
		 throw new Exception("cannot continue"); //Errors.Exception("cannot continue");
		}
		#if WHIDBEY
		/* Pre-Whidbey, templateArgs are used to construct a pseudo-generic name */
		if (templateArgs != null)
		{
		 tn = tn.GetTemplateInstance(assem, null, null, templateArgs);
		}
		#endif
		
	}
        /// <summary>
        /// Returns correct version of the ContinueWith method.
        /// </summary>
        private static Method GetContinueWithMethod(Class closureClass, TypeNode taskTemplate, TypeNode taskType)
        {
            var continueWithCandidates = taskTemplate.GetMembersNamed(Identifier.For("ContinueWith"));

            for (int i = 0; i < continueWithCandidates.Count; i++)
            {
                var cand = continueWithCandidates[i] as Method;
                if (cand == null)
                {
                    continue;
                }

                // For non-generic version we're looking for ContinueWith(Action<Task>)

                //if (taskType.TemplateArgumentsCount() == 0)
                if (!taskType.IsGeneric)
                {
                    if (cand.IsGeneric)
                    {
                        continue;
                    }

                    if (cand.ParameterCount != 1)
                    {
                        continue;
                    }

                    if (cand.Parameters[0].Type.GetMetadataName() != "Action`1")
                    {
                        continue;
                    }

                    return(cand);
                }

                // For generic version we're looking for ContinueWith(Func<Task, T>)
                if (!cand.IsGeneric)
                {
                    continue;
                }

                if (cand.TemplateParameters.Count != 1)
                {
                    continue;
                }

                if (cand.ParameterCount != 1)
                {
                    continue;
                }

                if (cand.Parameters[0].Type.GetMetadataName() != "Func`2")
                {
                    continue;
                }

                // now create instance, first of task
                var taskInstance = taskTemplate.GetTemplateInstance(
                    closureClass.DeclaringModule,
                    taskType.TemplateArguments[0]);

                // ST: some black magic is happening, but it seems it is required to get ContinueWith
                // from generic instantiated version of the task
                var candMethod = (Method)taskInstance.GetMembersNamed(Identifier.For("ContinueWith"))[i];

                // Candidate method would have following signature:
                // Task<T> ContinueWith(Task<T> t) for generic version
                return(candMethod.GetTemplateInstance(null, taskType));
            }

            return(null);
        }
示例#7
0
 public virtual TypeNode GetDummyInstance(TypeNode t){
   if (t == null || t.ConsolidatedTemplateParameters == null || t.ConsolidatedTemplateParameters.Count == 0) return t;
   if (t.DeclaringType != null){
     TypeNode dt = this.GetDummyInstance(t.DeclaringType);
     if (dt != null){
       t = this.GetTypeView(dt).GetNestedType(t.Name);
       if (t == null || t.TemplateParameters == null || t.TemplateParameters.Count == 0) return t;
     }
   }
   t = t.GetTemplateInstance(this.currentType, t.TemplateParameters);
   this.AddTemplateInstanceToList(t);
   return t;
 }
示例#8
0
        public This ThisExpression(TypeNode type)
        {
            var result = new This();
            result.Type =
                type.IsGeneric && type.TemplateParameters != null ?
                    type.GetTemplateInstance(type, type.TemplateParameters.ToArray()) :
                    type;

            return result;
        }
示例#9
0
 public Expression FirstOrderTypeOfExpression(TypeNode hkType)
 {
     var classTypeParameters = default(Seq<TypeNode>);
     ExplodeTypeAbstraction(hkType, out classTypeParameters);
     if (classTypeParameters == null || classTypeParameters.Count == 0)
         return TypeOfExpression(hkType);
     else
     {
         var types = new TypeNode[classTypeParameters.Count];
         classTypeParameters.CopyTo(types, 0);
         var type = hkType.GetTemplateInstance(hkType, types);
         return TypeOfExpression(type);
     }
 }