Binds syntax nodes (AST.LangElement) to semantic nodes (IOperation).
Esempio n. 1
0
        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);
            }));
        }
Esempio n. 2
0
 ImmutableArray <BoundTypeRef> Create(IList <Ast.TypeRef> trefs, SemanticsBinder binder, SourceTypeSymbol self)
 {
     return(trefs
            .Select(t => CreateFromTypeRef(t, binder, self, objectTypeInfoSemantic: false).WithSyntax(t))
            .AsImmutable());
 }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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));
                }
            }
        }
Esempio n. 5
0
        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);
            }
        }