public BoundTypeRef CreateFromTypeRef(Ast.TypeRef tref, SemanticsBinder binder = null, SourceTypeSymbol self = null, bool objectTypeInfoSemantic = false) { if (tref is Ast.PrimitiveTypeRef pt) { switch (pt.PrimitiveTypeName) { case Ast.PrimitiveTypeRef.PrimitiveType.@int: return(LongTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@float: return(DoubleTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@string: return(StringTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@bool: return(BoolTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.array: return(ArrayTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.callable: return(CallableTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@void: return(VoidTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.iterable: return(IterableTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@object: return(ObjectTypeRef); default: throw ExceptionUtilities.UnexpectedValue(pt.PrimitiveTypeName); } } else if (tref is Ast.INamedTypeRef named) { if (named.ClassName == NameUtils.SpecialNames.System_Object) { return(ObjectTypeRef); } //if (named.ClassName == NameUtils.SpecialNames.stdClass) return StdClassTypeRef; if (named is Ast.TranslatedTypeRef tt && self != null && tt.OriginalType is Ast.ReservedTypeRef reserved) { // keep self,parent,static not translated - better in cases where the type is ambiguous return(CreateFromTypeRef(reserved, binder, self, objectTypeInfoSemantic)); } return(new BoundClassTypeRef(named.ClassName, binder?.Routine, self ?? binder?.Self)); } else if (tref is Ast.ReservedTypeRef reserved) { return(new BoundReservedTypeRef(reserved.Type, self)); } else if (tref is Ast.AnonymousTypeRef at) { return(new BoundTypeRefFromSymbol(at.TypeDeclaration.GetProperty <SourceTypeSymbol>())); } else if (tref is Ast.MultipleTypeRef mt) { return(new BoundMultipleTypeRef(Create(mt.MultipleTypes, binder, self))); } else if (tref is Ast.NullableTypeRef nullable) { var t = CreateFromTypeRef(nullable.TargetType, binder, self, objectTypeInfoSemantic); t.IsNullable = true; return(t); } else if (tref is Ast.GenericTypeRef gt) { return(new BoundGenericClassTypeRef( CreateFromTypeRef(gt.TargetType, binder, self, objectTypeInfoSemantic), Create(gt.GenericParams, binder, self))); } else if (tref is Ast.IndirectTypeRef it) { return(new BoundIndirectTypeRef( binder.BindWholeExpression(it.ClassNameVar, BoundAccess.Read).SingleBoundElement(), objectTypeInfoSemantic)); } else { throw ExceptionUtilities.UnexpectedValue(tref); } }
public BoundTypeRef CreateFromTypeRef(Ast.TypeRef tref, SemanticsBinder binder = null, SourceTypeSymbol self = null, bool objectTypeInfoSemantic = false, int arity = -1, bool phpLang = false) { if (tref is Ast.PrimitiveTypeRef pt) { switch (pt.PrimitiveTypeName) { case Ast.PrimitiveTypeRef.PrimitiveType.@int: return(LongTypeRef); // CONSIDER: phpLang ? LongTypeRef : Create(Int32); case Ast.PrimitiveTypeRef.PrimitiveType.@float: return(DoubleTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@string: return(phpLang ? WritableStringRef : StringTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@bool: return(BoolTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.array: return(ArrayTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.callable: return(CallableTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@void: return(VoidTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.iterable: return(IterableTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.@object: return(ObjectTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.mixed: return(MixedTypeRef); case Ast.PrimitiveTypeRef.PrimitiveType.never: return(VoidTypeRef); default: throw ExceptionUtilities.UnexpectedValue(pt.PrimitiveTypeName); } } else if (tref is Ast.INamedTypeRef named) { if (named.ClassName == NameUtils.SpecialNames.System_Object) { return(ObjectTypeRef); } //if (named.ClassName == NameUtils.SpecialNames.stdClass) return StdClassTypeRef; if (named is Ast.TranslatedTypeRef tt && self != null && tt.OriginalType is Ast.ReservedTypeRef reserved) { // keep self,parent,static not translated - better in cases where the type is ambiguous return(CreateFromTypeRef(reserved, binder, self, objectTypeInfoSemantic, phpLang: phpLang)); } return(new BoundClassTypeRef(named.ClassName, binder?.Routine, self ?? binder?.Self, arity)); } else if (tref is Ast.ReservedTypeRef reserved) { return(new BoundReservedTypeRef(reserved.Type, self)); } else if (tref is Ast.AnonymousTypeRef at) { return(new BoundTypeRefFromSymbol(at.TypeDeclaration.GetProperty <SourceTypeSymbol>())); } else if (tref is Ast.MultipleTypeRef mt) { return(new BoundMultipleTypeRef(Create(mt.MultipleTypes, binder, self, nullClassSemantic: true, phpLang: phpLang))); } else if (tref is Ast.NullableTypeRef nullable) { var t = CreateFromTypeRef(nullable.TargetType, binder, self, objectTypeInfoSemantic, phpLang: phpLang); if (t.IsNullable != true) { if (t is BoundPrimitiveTypeRef bpt) { // do not change the cached singleton // https://github.com/peachpiecompiler/peachpie/issues/455 t = new BoundPrimitiveTypeRef(bpt.TypeCode); } t.IsNullable = true; } return(t); } else if (tref is Ast.GenericTypeRef gt) { return(new BoundGenericClassTypeRef( CreateFromTypeRef(gt.TargetType, binder, self, objectTypeInfoSemantic, arity: gt.GenericParams.Count, phpLang: phpLang), Create(gt.GenericParams, binder, self, phpLang: false))); } else if (tref is Ast.IndirectTypeRef it) { return(new BoundIndirectTypeRef( binder.BindWholeExpression(it.ClassNameVar, BoundAccess.Read).SingleBoundElement(), objectTypeInfoSemantic)); } else { throw ExceptionUtilities.UnexpectedValue(tref); } }