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