ImmutableArray <BoundTypeRef> Create(IList <Ast.TypeRef> trefs, SemanticsBinder binder, SourceTypeSymbol self, bool nullClassSemantic = false, bool phpLang = false) { return(trefs.SelectAsArray(t => { if (nullClassSemantic && t.IsNullClass()) { return NullTypeRef; } return CreateFromTypeRef(t, binder, self, objectTypeInfoSemantic: false, phpLang: phpLang).WithSyntax(t); })); }
ImmutableArray <BoundTypeRef> Create(IList <Ast.TypeRef> trefs, SemanticsBinder binder, SourceTypeSymbol self) { return(trefs .Select(t => CreateFromTypeRef(t, binder, self, objectTypeInfoSemantic: false).WithSyntax(t)) .AsImmutable()); }
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); } }
IEnumerable<FieldSymbol> LoadFields() { var binder = new SemanticsBinder(null); // fields foreach (var flist in _syntax.Members.OfType<FieldDeclList>()) { var fkind = (flist.Modifiers & PhpMemberAttributes.Static) == 0 ? SourceFieldSymbol.KindEnum.InstanceField : SourceFieldSymbol.KindEnum.StaticField; foreach (var f in flist.Fields) { yield return new SourceFieldSymbol(this, f.Name.Value, flist.Modifiers.GetAccessibility(), f.PHPDoc ?? flist.PHPDoc, fkind, (f.Initializer != null) ? binder.BindExpression(f.Initializer, BoundAccess.Read) : null); } } // constants foreach (var clist in _syntax.Members.OfType<ConstDeclList>()) { foreach (var c in clist.Constants) { yield return new SourceFieldSymbol(this, c.Name.Name.Value, Accessibility.Public, c.PHPDoc ?? clist.PHPDoc, SourceFieldSymbol.KindEnum.ClassConstant, binder.BindExpression(c.Initializer, BoundAccess.Read)); } } }
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); } }