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