public override TypeNode VisitTypeReference(TypeNode type, bool addNonNullWrapperIfNeeded) { if (type == null) { return(null); } // begin change by drunje (allow pointers to managed structures) if (this.AllowPointersToManagedStructures && (type.NodeType == NodeType.PointerTypeExpression)) { PointerTypeExpression ptrExpr = (PointerTypeExpression)type; TypeNode et = this.VisitTypeReference(ptrExpr.ElementType); if ((et != null) && (et.Name != Looker.NotFound) && (!et.IsUnmanaged) && (et.IsValueType)) { return(et.GetPointerType()); } } // end of change by drunje ClassParameter cp = this.typeParamToClassParamMap[type.UniqueKey] as ClassParameter; if (cp != null) { return(cp); } return(base.VisitTypeReference(type, addNonNullWrapperIfNeeded)); }
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 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; }
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(); } } }