Beispiel #1
0
 public virtual TypeNode InferTypeOfUnaryExpression(TypeNode origType, UnaryExpression unaryExpression){
   if (unaryExpression == null) return origType;
   TypeNode t = this.typeSystem.Unwrap(origType);
   if (this.typeSystem.IsNullableType(t)) return this.typeSystem.CreateNullableWrapper(this.currentType, InferTypeOfUnaryExpression(this.typeSystem.RemoveNullableWrapper(t), unaryExpression));
   switch (unaryExpression.NodeType){
     case NodeType.AddressOf: return origType.GetPointerType();
     case NodeType.OutAddress: 
     case NodeType.RefAddress: return origType.GetReferenceType();
     case NodeType.Ldftn: return SystemTypes.IntPtr;
     case NodeType.LogicalNot: return SystemTypes.Boolean;
     case NodeType.UnaryPlus:
     case NodeType.Neg:
     case NodeType.Not:
       switch(t.TypeCode){
         case TypeCode.SByte:
         case TypeCode.Byte:
         case TypeCode.Int16:
         case TypeCode.UInt16:
         case TypeCode.Char:
           return SystemTypes.Int32;
         case TypeCode.UInt32:
           if (unaryExpression.NodeType == NodeType.Neg)
             return SystemTypes.Int64;
           break;
       }
       break;
     case NodeType.Parentheses:
     case NodeType.SkipCheck:
     case NodeType.Ckfinite:
       if (unaryExpression.Operand == null){
         unaryExpression.IsErroneous = true;
         return t;
       }
       return unaryExpression.Operand.Type;
     case NodeType.DefaultValue:
       Literal lit = unaryExpression.Operand as Literal;
       if (lit == null){
         unaryExpression.IsErroneous = true;
         return SystemTypes.Object;
       }
       TypeNode lt = lit.Value as TypeNode;
       if (lt == null){
         unaryExpression.IsErroneous = true;
         return SystemTypes.Object;
       }
       return lt;
     case NodeType.Sizeof:
       return SystemTypes.Int32;
     case NodeType.Typeof:
       return !this.NonNullChecking ? SystemTypes.Type : (TypeNode)OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Type);
   }
   return t;
 }
Beispiel #2
0
 private Expression GetAddressOf(Expression targetOb, TypeNode tObType) {
   MemberBinding tgtmb = targetOb as MemberBinding;
   if (tgtmb != null && tgtmb.BoundMember is Field && ((Field)tgtmb.BoundMember).IsInitOnly) {
     StatementList stats = new StatementList(2);
     Local loc = new Local(targetOb.Type);
     stats.Add(new AssignmentStatement(loc, targetOb));
     stats.Add(new ExpressionStatement(new UnaryExpression(loc, NodeType.AddressOf, tObType.GetReferenceType())));
     return new BlockExpression(new Block(stats));
   } else
     return new UnaryExpression(targetOb, NodeType.AddressOf, tObType.GetReferenceType(), targetOb.SourceContext);
 }
Beispiel #3
0
    protected virtual Expression StandardExplicitCoercionHelper(ErrorHandler savedErrorHandler, Expression source, bool sourceIsNonNullType, TypeNode sourceType, bool targetIsNonNullType, TypeNode targetType,
      TypeNode originalTargetType, TypeViewer typeViewer){
      //Identity coercion
      if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))){
        if (sourceType.IsPrimitiveNumeric){
          Expression e = this.ExplicitPrimitiveCoercionHelper(source, sourceType, targetType);
          if (e == null) return source;
          e.Type = targetType;
          return e;
        }
        return source;
      }
      //Dereference source
      Reference sr = sourceType as Reference;
      if (sr != null && targetType is Pointer) return source;
      if (sr != null && source.NodeType != NodeType.AddressOf){
        sourceType = sr.ElementType;
        source = new AddressDereference(source, sourceType, source.SourceContext);
        sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NonNullType);
      }
      //Get rid of Nullable wrapper
      if (this.IsNullableType(sourceType)){
        Method getValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(Identifier.For("get_Value"));
        sourceType = this.RemoveNullableWrapper(sourceType);
        source = new MethodCall(new MemberBinding(source, getValue), null, NodeType.Call, sourceType, source.SourceContext);
      }
      //Identity coercion after dereference
      if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))){
        if (sourceType.IsPrimitiveNumeric){
          source = this.ExplicitPrimitiveCoercionHelper(source, sourceType, targetType);
          if (source == null) return null;
          source.Type = targetType;
        }
        return source;
      }
      //Special case for type union
      if (sourceType.NodeType == NodeType.TypeUnion)
        return this.CoerceFromTypeUnion(source, (TypeUnion)sourceType, targetType, true, originalTargetType, typeViewer);
      //Special case for null literal
      if (source.NodeType == NodeType.Literal && ((Literal)source).Value == null){
        if (targetType.IsTemplateParameter && !targetType.IsReferenceType) {
          // Check for reference constraint
          //this.HandleError(source, Error.TypeVarCantBeNull, targetType.Name.Name);
          return null;
        }
        if (targetIsNonNullType) {
          //savedErrorHandler.HandleError(source, Error.CannotCoerceNullToNonNullType, savedErrorHandler.GetTypeName(targetType));
          return ExplicitNonNullCoercion(source, originalTargetType);
        }

        if (targetType is ITypeParameter && sourceType == SystemTypes.Object && this.useGenerics)
          return new BinaryExpression(source, new Literal(targetType, SystemTypes.Type), NodeType.UnboxAny);
        if (!targetType.IsValueType || targetType.Template == SystemTypes.GenericBoxed) 
          return new Literal(null, targetType, source.SourceContext);
        TypeAlias tAlias = targetType as TypeAlias;
        if (tAlias != null){
          source = this.ExplicitCoercion(source, tAlias.AliasedType, typeViewer);
          if (source == null) return null;
          Method coercion = this.UserDefinedExplicitCoercionMethod(source, tAlias.AliasedType, targetType, false, originalTargetType, typeViewer);
          if (coercion != null){
            ExpressionList args = new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
            return new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType);
          }
        }
        return null;
      }
      //Explicit reference coercions
      if (TypeViewer.GetTypeView(typeViewer, sourceType).IsAssignableTo(targetType)){
        //Handling for non null types
        if (targetIsNonNullType && !sourceIsNonNullType && !sourceType.IsValueType) {
          //savedErrorHandler.HandleError(source, Error.CoercionToNonNullTypeMightFail, savedErrorHandler.GetTypeName(targetType));
          return ExplicitNonNullCoercion(source, originalTargetType);
        }
        if (targetType == SystemTypes.Object && sourceType.Template == SystemTypes.GenericIEnumerable)
          return this.CoerceStreamToObject(source, sourceType, typeViewer);
        if (sourceType.IsValueType && !targetType.IsValueType){
          if (sourceType.NodeType == NodeType.TypeUnion){
            Debug.Assert(targetType == SystemTypes.Object);
            return this.CoerceTypeUnionToObject(source, typeViewer);
          }
          if (sourceType is TupleType){
            if (targetType == SystemTypes.Object)
              return this.TupleCoercion(source, sourceType, targetType, true, typeViewer);
          }else if (this.GetStreamElementType(sourceType, typeViewer) != sourceType)
            return this.ExplicitCoercion(this.CoerceStreamToObject(source, sourceType, typeViewer), targetType, typeViewer);
          return new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, targetType);
        }else if (this.useGenerics && sourceType is ITypeParameter){
          source = new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, sourceType);
          if (targetType == SystemTypes.Object) return source;
          return new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.UnboxAny, targetType);
        }else
          return source;
      }
      //Special case for typed streams
      Expression streamCoercion = this.StreamCoercion(source, sourceType, targetType, true, originalTargetType, typeViewer);
      if (streamCoercion != null) return streamCoercion;
      //Down casts
      if (!targetType.IsPointerType && !sourceType.IsPointerType && TypeViewer.GetTypeView(typeViewer, targetType).IsAssignableTo(sourceType)){
        if (!sourceType.IsValueType){
          if (targetType.NodeType == NodeType.TypeUnion)
            return this.CoerceObjectToTypeUnion(source, (TypeUnion)targetType, typeViewer);
          if (source.NodeType == NodeType.Literal && ((Literal)source).Value == null)
            return source;
          if (targetType.IsValueType){
            Expression e = new AddressDereference(new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.Unbox, targetType.GetReferenceType()), targetType);
            e.Type = targetType;
            return e;
          }else{
            NodeType op = this.useGenerics && (targetType is ClassParameter || targetType is TypeParameter) ? NodeType.UnboxAny : NodeType.Castclass;
            Expression e = new BinaryExpression(source, new MemberBinding(null, targetType), op, source.SourceContext);
            e.Type = originalTargetType;
            //Handling for non null types
            if (targetIsNonNullType && !sourceIsNonNullType){
              //savedErrorHandler.HandleError(source, Error.CoercionToNonNullTypeMightFail, savedErrorHandler.GetTypeName(targetType));
              return ExplicitNonNullCoercion(e, originalTargetType);
            }
            return e;
          }
        }
      }
      //Special case for casts to and from interfaces
      if ((sourceType.NodeType == NodeType.Interface && !targetType.IsSealed) ||
        (targetType.NodeType == NodeType.Interface && !(sourceType.IsSealed || (sourceType is Pointer) || 
        (sourceType is ArrayType && this.GetStreamElementType(targetType, typeViewer) == targetType)))){
        Expression e = new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.Castclass, source.SourceContext);
        e.Type = targetType;
        return e;
      }
      //Explicit numeric coercions + explicit enumeration coercions + explicit constant expression coercions
      Expression primitiveConversion = this.ExplicitPrimitiveCoercion(source, sourceType, targetType);
      if (primitiveConversion != null) return primitiveConversion;
      //Special case for decimal
      if (targetType == SystemTypes.Decimal && this.ImplicitCoercionFromTo(sourceType, targetType, typeViewer))
        return this.ImplicitCoercion(source, targetType, typeViewer);
      //Special case for delegates
      if (targetType is DelegateNode)
        return this.CoerceToDelegate(source, sourceType, (DelegateNode)targetType, true, typeViewer);
      //Special case for type union
      if (targetType.NodeType == NodeType.TypeUnion)
        return this.CoerceToTypeUnion(source, sourceType, (TypeUnion)targetType, typeViewer);
      //Special case for Type intersection target type
      if (targetType.NodeType == NodeType.TypeIntersection)
        return this.CoerceToTypeIntersection(source, sourceType, (TypeIntersection)targetType, false, typeViewer);
      //Tuple coercion
      return this.TupleCoercion(source, sourceType, targetType, true, typeViewer);
    }
	void PType(out TypeNode c) {
		c = null; TypeNode modifier=null, modified=null; 
		switch (la.kind) {
		case 6: {
			Get();
			c = SystemTypes.Object; 
			break;
		}
		case 7: {
			Get();
			c = SystemTypes.String; 
			break;
		}
		case 8: {
			Get();
			c = SystemTypes.Char; 
			break;
		}
		case 9: {
			Get();
			c = SystemTypes.Void; 
			break;
		}
		case 10: {
			Get();
			c = SystemTypes.Boolean; 
			break;
		}
		case 11: {
			Get();
			c = SystemTypes.Int8; 
			break;
		}
		case 12: {
			Get();
			c = SystemTypes.Int16; 
			break;
		}
		case 13: {
			Get();
			c = SystemTypes.Int32; 
			break;
		}
		case 14: {
			Get();
			c = SystemTypes.Int64; 
			break;
		}
		case 15: {
			Get();
			c = SystemTypes.UInt8; 
			break;
		}
		case 16: {
			Get();
			c = SystemTypes.UInt16; 
			break;
		}
		case 17: {
			Get();
			c = SystemTypes.UInt32; 
			break;
		}
		case 18: {
			Get();
			c = SystemTypes.UInt64; 
			break;
		}
		case 19: {
			Get();
			c = SystemTypes.Single; 
			break;
		}
		case 20: {
			Get();
			c = SystemTypes.Double; 
			break;
		}
		case 21: {
			Get();
			Expect(22);
			PType(out modifier);
			Expect(23);
			PType(out modified);
			Expect(24);
			c = OptionalModifier.For(modifier,modified); 
			break;
		}
		case 25: {
			Get();
			Expect(22);
			string id; 
			Ident(out id);
			Expect(24);
			c = LookupTypeParameter(id); 
			break;
		}
		case 26: {
			Get();
			Expect(22);
			string id; 
			Ident(out id);
			Expect(24);
			c = LookupMethodTypeParameter(id); 
			break;
		}
		case 1: case 28: case 35: {
			PTypeRef(out c);
			break;
		}
		default: SynErr(109); break;
		}
		if (StartOf(1)) {
			if (la.kind == 27) {
				Get();
				c = c.GetReferenceType(); 
			} else if (la.kind == 28) {
				Get();
				Expect(29);
				c = c.GetArrayType(1); 
				while (la.kind == 28) {
					Get();
					Expect(29);
					c = c.GetArrayType(1); 
				}
			} else if (la.kind == 22) {
				Get();
				PType(out c);
				while (la.kind == 23) {
					Get();
					PType(out c);
				}
				Expect(24);
			} else {
				Get();
				c = c.GetPointerType(); 
			}
		}
	}
        public void Parse_UnsafeReturnWithAssignment_ReturnsProblem()
        {
            TypeNode stringTypeNode = IntrospectionUtility.TypeNodeFactory <string>();
            Method   sample         = TestHelper.GetSample <CallByReferenceSample> ("UnsafeReturnWithAssignment", stringTypeNode.GetReferenceType());

            _typeParser.Parse(sample);
            ProblemCollection result = _typeParser.Problems;

            Assert.That(TestHelper.ContainsProblemID(c_InjectionCopRuleId, result), Is.True);
        }
        public void Parse_FragmentRefParameterSafeReturn_NoProblem()
        {
            TypeNode stringTypeNode = IntrospectionUtility.TypeNodeFactory <string>();
            Method   sample         = TestHelper.GetSample <CallByReferenceSample> ("FragmentRefParameterSafeReturn", stringTypeNode.GetReferenceType());

            _typeParser.Parse(sample);
            ProblemCollection result = _typeParser.Problems;

            Assert.That(TestHelper.ContainsProblemID(c_InjectionCopRuleId, result), Is.False);
        }
Beispiel #7
0
 public TypeNode ManagedPointer(TypeNode type)
 {
     return(type.GetReferenceType());
 }
        public void Parse_UnsafeFragmentOutParameterInsideWhile_ReturnsProblem()
        {
            TypeNode stringTypeNode = IntrospectionUtility.TypeNodeFactory <string>();
            Method   sample         = TestHelper.GetSample <OutSample> ("UnsafeFragmentOutParameterInsideWhile", stringTypeNode.GetReferenceType());

            _typeParser.Parse(sample);
            ProblemCollection result = _typeParser.Problems;

            Assert.That(TestHelper.ContainsProblemID(c_InjectionCopRuleId, result), Is.True);
        }
Beispiel #9
0
 private static Expression/*!*/ ParseTypeCheck(Expression operand, TypeNode type, NodeType typeOfCheck)
 {
     TypeNode etype = type;
     if (typeOfCheck == NodeType.Unbox) etype = type.GetReferenceType();
     Expression expr = new BinaryExpression(operand, new Literal(type, CoreSystemTypes.Type), typeOfCheck, etype);
     return expr;
 }
Beispiel #10
0
 private Expression Unbox(Expression x, TypeNode type) {
   if (type.IsValueType) {
     BinaryExpression be = new BinaryExpression(x, new Literal(type, SystemTypes.Type), NodeType.Unbox);
     be.Type = type.GetReferenceType();
     return new AddressDereference(be, type);
   }else if (this.useGenerics && type is ITypeParameter){
     BinaryExpression be = new BinaryExpression(x, new Literal(type, SystemTypes.Type), NodeType.UnboxAny);
     be.Type = type;
     return be;
   }else{
     BinaryExpression be = new BinaryExpression(x, new Literal(type, SystemTypes.Type), NodeType.Castclass);
     be.Type = type;
     return be;
   }
 }
Beispiel #11
0
        internal Method/*!*/ GetMethodFromDef(int index, TypeNode declaringType)
        {
            TypeNodeList savedCurrentMethodTypeParameters = this.currentMethodTypeParameters;
            TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
            MethodRow[] methodDefs = this.tables.MethodTable;
            MethodRow meth = methodDefs[index - 1];
            if (meth.Method != null) return meth.Method;
            if (declaringType == null)
            {
                int indx = index;
                MethodPtrRow[] methodPtrs = this.tables.MethodPtrTable;
                int n = methodPtrs.Length, i = 0, j = n - 1;
                bool sorted = (this.sortedTablesMask >> (int)TableIndices.MethodPtr) % 2 == 1;
                if (sorted)
                {
                    while (i < j)
                    {
                        int k = (i + j) / 2;
                        if (methodPtrs[k].Method < index)
                            i = k + 1;
                        else
                            j = k;
                    }
                    while (i > 0 && methodPtrs[i - 1].Method == index) i--;
                }
                for (; i < n; i++)
                {
                    if (methodPtrs[i].Method == index)
                    {
                        indx = i + 1; break;
                    }
                }
                TypeDefRow[] typeDefs = this.tables.TypeDefTable;
                n = typeDefs.Length; i = 0; j = n - 1;
                sorted = (this.sortedTablesMask >> (int)TableIndices.TypeDef) % 2 == 1;
                if (sorted)
                {
                    while (i < j)
                    {
                        int k = (i + j) / 2;
                        if (typeDefs[k].MethodList < indx)
                            i = k + 1;
                        else
                            j = k;
                    }
                    j = i;
                    while (j < n - 1 && typeDefs[j + 1].MethodList == indx) j++;
                }
                for (; j >= 0; j--)
                {
                    if (typeDefs[j].MethodList <= indx)
                    {
                        declaringType = this.GetTypeFromDef(j + 1);
                        break;
                    }
                }
            }
            Method.MethodBodyProvider provider = new Method.MethodBodyProvider(this.GetMethodBody);
            Identifier name = tables.GetIdentifier(meth.Name);
            Method method;
            if ((((MethodFlags)meth.Flags) & MethodFlags.SpecialName) != 0 &&
              (((MethodFlags)meth.Flags) & MethodFlags.SpecialName) != 0)
            {
                if (name.Name == ".ctor")
                    method = methodDefs[index - 1].Method = new InstanceInitializer(provider, index);
                else if (name.Name == ".cctor")
                    method = methodDefs[index - 1].Method = new StaticInitializer(provider, index);
                else
                    method = methodDefs[index - 1].Method = new Method(provider, index);
            }
            else
                method = methodDefs[index - 1].Method = new Method(provider, index);
            method.ProvideMethodAttributes = new Method.MethodAttributeProvider(this.GetMethodAttributes);
            //method.Attributes = this.GetCustomAttributesFor((index << 5)|0); //TODO: get attributes lazily
            method.Flags = (MethodFlags)meth.Flags;
            method.ImplFlags = (MethodImplFlags)meth.ImplFlags;
            method.Name = name;
            if (declaringType != null && declaringType.IsGeneric)
            {
                if (declaringType.Template != null)
                    this.currentTypeParameters = declaringType.ConsolidatedTemplateArguments;
                else
                    this.currentTypeParameters = declaringType.ConsolidatedTemplateParameters;
            }

            tables.GetSignatureLength(meth.Signature);
            MemoryCursor sigReader = this.tables.GetNewCursor();
            method.CallingConvention = (CallingConventionFlags)sigReader.ReadByte();
            if (method.IsGeneric = (method.CallingConvention & CallingConventionFlags.Generic) != 0)
            {
                int numTemplateParameters = sigReader.ReadCompressedInt();
                this.currentMethodTypeParameters = new TypeNodeList();
                this.currentMethodTypeParameters = method.TemplateParameters = this.GetTypeParametersFor((index << 1) | 1, method);
                this.GetTypeParameterConstraints((index << 1) | 1, method.TemplateParameters);
            }
            int numParams = sigReader.ReadCompressedInt();
            method.ReturnType = this.ParseTypeSignature(sigReader);
            if (declaringType != null && declaringType.IsValueType)
                method.ThisParameter = new This(declaringType.GetReferenceType());
            else
                method.ThisParameter = new This(declaringType);

            ParameterList paramList = method.Parameters = new ParameterList();

            if(numParams > 0)
            {
                int offset = method.IsStatic ? 0 : 1;
                for (int i = 0; i < numParams; i++)
                {
                    Parameter param = new Parameter();
                    param.ParameterListIndex = i;
                    param.ArgumentListIndex = i + offset;
                    param.Type = this.ParseTypeSignature(sigReader);
                    param.DeclaringMethod = method;
                    paramList.Add(param);
                }
                int end = this.tables.ParamTable.Length + 1;
                if (index < methodDefs.Length) end = methodDefs[index].ParamList;
                this.AddMoreStuffToParameters(method, paramList, meth.ParamList, end);
                for (int i = 0; i < numParams; i++)
                {
                    Parameter param = paramList[i];
                    if (param.Name == null)
                        param.Name = Identifier.For("param" + (i));
                }
            }
            else if (method.ReturnType != CoreSystemTypes.Void)
            {
                //check for custom attributes and marshaling information on return value
                int i = meth.ParamList;
                ParamPtrRow[] parPtrs = this.tables.ParamPtrTable; //TODO: why use ParamPtrTable in the branch and not the one above? Factor this out.
                ParamRow[] pars = this.tables.ParamTable;
                int n = methodDefs.Length;
                int m = pars.Length;
                if (index < n) m = methodDefs[index].ParamList - 1;
                if (parPtrs.Length > 0)
                {
                    if (pars != null && 0 < i && i <= m)
                    {
                        int j = parPtrs[i - 1].Param;
                        ParamRow pr = pars[j - 1];
                        if (pr.Sequence == 0)
                            this.AddMoreStuffToParameters(method, null, j, j + 1);
                    }
                }
                else
                {
                    if (pars != null && 0 < i && i <= m)
                    {
                        ParamRow pr = pars[i - 1];
                        if (pr.Sequence == 0)
                            this.AddMoreStuffToParameters(method, null, i, i + 1);
                    }
                }
            }

            //if ((method.Flags & MethodFlags.HasSecurity) != 0)
            //  method.SecurityAttributes = this.GetSecurityAttributesFor((index << 2)|1);

            if ((method.Flags & MethodFlags.PInvokeImpl) != 0)
            {
                ImplMapRow[] implMaps = this.tables.ImplMapTable;
                int n = implMaps.Length, i = 0, j = n - 1;
                bool sorted = (this.sortedTablesMask >> (int)TableIndices.ImplMap) % 2 == 1;
                if (sorted)
                {
                    while (i < j)
                    {
                        int k = (i + j) / 2;
                        if ((implMaps[k].MemberForwarded >> 1) < index)
                            i = k + 1;
                        else
                            j = k;
                    }
                    while (i > 0 && (implMaps[i - 1].MemberForwarded >> 1) == index) i--;
                }
                for (; i < n; i++)
                {
                    ImplMapRow imr = implMaps[i];
                    if (imr.MemberForwarded >> 1 == index)
                    {
                        method.PInvokeFlags = (PInvokeFlags)imr.MappingFlags;
                        method.PInvokeImportName = tables.GetString(imr.ImportName);
                        method.PInvokeModule = this.module.ModuleReferences[imr.ImportScope - 1].Module;
                        break;
                    }
                }
            }
            method.DeclaringType = declaringType;
            this.currentMethodTypeParameters = savedCurrentMethodTypeParameters;
            this.currentTypeParameters = savedCurrentTypeParameters;
            return method;
        }
Beispiel #12
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);
                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);
            }

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

                    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));
            }
        }
Beispiel #13
0
        public void Parse_RefReturnPreconditionConditionalWithReturnAfterIf_ReturnConditionIsAddedToReturnBlock()
        {
            TypeNode   stringTypeNode           = IntrospectionUtility.TypeNodeFactory <string>();
            Method     sampleMethod             = TestHelper.GetSample <BlockParserSample> ("RefReturnPreconditionConditionalWithReturnAfterIf", stringTypeNode.GetReferenceType());
            Block      returnBlock              = sampleMethod.Body.Statements[2] as Block;
            BasicBlock returnBasicBlock         = _blockParser.Parse(returnBlock);
            string     preConditionSymbol       = returnBasicBlock.PreConditions[0].Symbol;
            var        preConditionFragmentType = returnBasicBlock.PreConditions[0].Fragment;
            bool       correctPrecondition      = preConditionSymbol == _returnPreCondition.Symbol &&
                                                  preConditionFragmentType == _returnPreCondition.Fragment;

            Assert.That(correctPrecondition, Is.True);
        }
Beispiel #14
0
        public void Parse_RefReturnPreconditionCheckSafeLiteralAssignment_NoProblem()
        {
            TypeNode stringTypeNode = IntrospectionUtility.TypeNodeFactory <string>();
            Method   sampleMethod   = TestHelper.GetSample <BlockParserSample> ("RefReturnPreconditionCheckSafeLiteralAssignment", stringTypeNode.GetReferenceType());
            Block    sample         = sampleMethod.Body.Statements[0] as Block;

            _blockParser.Parse(sample);
            bool noProblemsArised = _problemPipeStub.Problems.Count == 0;

            Assert.That(noProblemsArised, Is.True);
        }
Beispiel #15
0
        public void Parse_OutReturnPreconditionCheckUnSafe_ReturnsProblem()
        {
            TypeNode stringTypeNode = IntrospectionUtility.TypeNodeFactory <string>();
            Method   sampleMethod   = TestHelper.GetSample <BlockParserSample> ("OutReturnPreconditionCheckUnSafe", stringTypeNode.GetReferenceType());
            Block    sample         = sampleMethod.Body.Statements[0] as Block;

            _blockParser.Parse(sample);
            bool problemFound = _problemPipeStub.Problems.Count != 0;

            Assert.That(problemFound, Is.True);
        }