コード例 #1
0
        private void AnalyzeType(SourceTypeSymbol type)
        {
            // resolves base types in here
            var btype = type.BaseType;

            // ...
        }
コード例 #2
0
        /// <summary>
        /// Creates type context for a method within given type, determines naming, type context.
        /// </summary>
        public static TypeRefContext /*!*/ CreateTypeRefContext(SourceTypeSymbol /*!*/ containingType)
        {
            Contract.ThrowIfNull(containingType);

            var typeDecl = containingType.Syntax;

            return(new TypeRefContext(typeDecl.ContainingSourceUnit, containingType));
        }
コード例 #3
0
        /// <summary>
        /// Creates type context for a method within given type, determines naming, type context.
        /// </summary>
        public static TypeRefContext /*!*/ CreateTypeRefContext(SourceTypeSymbol /*!*/ containingType)
        {
            Contract.ThrowIfNull(containingType);

            return(new TypeRefContext(
                       containingType, // scope
                       thisType: containingType.IsTrait?null: containingType));
        }
コード例 #4
0
        void WriteType(SourceTypeSymbol type)
        {
            _writer.WriteLine($"<member name=\"{CommentIdResolver.GetId(type)}\">");
            var phpdoc = type.Syntax?.PHPDoc;

            if (phpdoc != null)
            {
                WriteSummary(phpdoc.Summary);
            }
            _writer.WriteLine("</member>");

            //
            // fields
            //

            foreach (var field in type.GetMembers().OfType <SourceFieldSymbol>())
            {
                if ((phpdoc = field.PhpDocBlock) != null)
                {
                    var summary = phpdoc.Summary;
                    var value   = string.Empty;
                    if (string.IsNullOrEmpty(summary))
                    {
                        // try @var or @staticvar:
                        var vartag = field.FindPhpDocVarTag();
                        if (vartag != null)
                        {
                            summary = vartag.Description;

                            if (!string.IsNullOrEmpty(vartag.TypeNames))
                            {
                                value = string.Format("<value>{0}</value>", XmlEncode(vartag.TypeNames));
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(summary))
                    {
                        _writer.WriteLine($"<member name=\"{CommentIdResolver.GetId(field)}\">");
                        WriteSummary(summary);
                        _writer.WriteLine(value);
                        _writer.WriteLine("</member>");
                    }
                }
            }

            //
            // .ctor
            //
            foreach (var ctor in type.InstanceConstructors)
            {
                if (ctor is SynthesizedPhpCtorSymbol synctor && synctor.PhpConstructor is SourceRoutineSymbol phpctor)
                {
                    WriteRoutine(CommentIdResolver.GetId(synctor), phpctor);
                }
            }
        }
コード例 #5
0
ファイル: BoundTypeRef.cs プロジェクト: emtee40/peachpie
        public BoundClassTypeRef(QualifiedName qname, SourceRoutineSymbol routine, SourceTypeSymbol self)
        {
            if (qname.IsReservedClassName)
            {
                throw new ArgumentException();
            }

            _qname   = qname;
            _routine = routine;
            _self    = self;
        }
コード例 #6
0
        void WriteType(SourceTypeSymbol type)
        {
            _writer.WriteLine($"<member name=\"{CommentIdResolver.GetId(type)}\">");
            var phpdoc = type.Syntax?.PHPDoc;

            if (phpdoc != null)
            {
                WriteSummary(phpdoc.Summary);
            }
            _writer.WriteLine("</member>");
        }
コード例 #7
0
 internal BoundTypeDeclStatement Update(SourceTypeSymbol type)
 {
     if (type == _type)
     {
         return(this);
     }
     else
     {
         return(new BoundTypeDeclStatement(type));
     }
 }
コード例 #8
0
ファイル: SourceCompiler.cs プロジェクト: tyty999/peachpie
 /// <summary>
 /// Enqueues initializers of a class fields and constants.
 /// </summary>
 void EnqueueFieldsInitializer(SourceTypeSymbol type)
 {
     type.GetDeclaredMembers().OfType <SourceFieldSymbol>().ForEach(f =>
     {
         if (f.Initializer != null)
         {
             EnqueueExpression(
                 f.Initializer,
                 f.EnsureTypeRefContext());
         }
     });
 }
コード例 #9
0
 /// <summary>
 /// Enqueues initializers of a class fields and constants.
 /// </summary>
 void EnqueueFieldsInitializer(SourceTypeSymbol type)
 {
     type.GetMembers().OfType <SourceFieldSymbol>().Foreach(f =>
     {
         if (f.Initializer != null)
         {
             EnqueueExpression(
                 f.Initializer,
                 TypeRefFactory.CreateTypeRefContext(type), //the context will be lost, analysis resolves constant values only and types are temporary
                 NameUtils.GetNamingContext(type.Syntax));
         }
     });
 }
コード例 #10
0
ファイル: SourceCompiler.cs プロジェクト: dlob/peachpie
        /// <summary>
        /// Enqueues initializers of a class fields and constants, and type custom attributes.
        /// </summary>
        void EnqueueType(SourceTypeSymbol type)
        {
            type.GetDeclaredMembers().OfType <SourceFieldSymbol>().ForEach(f =>
            {
                if (f.Initializer != null)
                {
                    EnqueueExpression(
                        f.Initializer,
                        f.EnsureTypeRefContext());
                }

                EnqueueAttributes(f.SourceAttributes);
            });

            EnqueueAttributes(type.SourceAttributes.OfType <SourceCustomAttribute>());
        }
コード例 #11
0
        void WalkTypes(Action <SourceTypeSymbol> action)
        {
            SourceTypeSymbol current = null;

            try
            {
                foreach (SourceTypeSymbol s in _compilation.SourceSymbolCollection.GetTypes())
                {
                    current = s;
                    action.Invoke(s);
                }
            }
            catch (Exception e)
            {
                L.Error(e, "Exception thrown analyzing source type {0} in file {1}.", current.Name, current.ContainingFile.SyntaxTree.FilePath);
            }
            _compilation.SourceSymbolCollection.GetTypes().Foreach(action);
        }
コード例 #12
0
        /// <summary>
        /// Binds <see cref="AST.TypeRef"/> to a type symbol.
        /// </summary>
        /// <param name="tref">Type reference.</param>
        /// <param name="selfHint">Optional.
        /// Current type scope for better <paramref name="tref"/> resolution since <paramref name="tref"/> might be ambiguous</param>
        /// <param name="nullable">Whether the resulting type must be able to contain NULL. Default is <c>false</c>.</param>
        /// <returns>Resolved symbol.</returns>
        internal TypeSymbol GetTypeFromTypeRef(AST.TypeRef tref, SourceTypeSymbol selfHint = null, bool nullable = false)
        {
            if (tref == null)
            {
                return(null);
            }

            var t = this.TypeRefFactory.CreateFromTypeRef(tref, null, selfHint);

            var symbol = t.ResolveRuntimeType(this);

            if (t.IsNullable || nullable)
            {
                // TODO: for value types -> Nullable<T>
                symbol = MergeNull(symbol);
            }

            return(symbol);
        }
コード例 #13
0
ファイル: PhpCompilation.Types.cs プロジェクト: dlob/peachpie
        /// <summary>
        /// Binds <see cref="AST.TypeRef"/> to a type symbol.
        /// </summary>
        /// <param name="tref">Type reference.</param>
        /// <param name="selfHint">Optional.
        /// Current type scope for better <paramref name="tref"/> resolution since <paramref name="tref"/> might be ambiguous</param>
        /// <param name="nullable">Whether the resulting type must be able to contain NULL. Default is <c>false</c>.</param>
        /// <param name="phpLang">PHP semantic - specifies how to treat <c>int</c> and <c>string</c> special types.</param>
        /// <returns>Resolved symbol.</returns>
        internal TypeSymbol GetTypeFromTypeRef(AST.TypeRef tref, SourceTypeSymbol selfHint = null, bool nullable = false, bool phpLang = false)
        {
            if (tref == null)
            {
                return(null);
            }

            var t = this.TypeRefFactory.CreateFromTypeRef(tref, self: selfHint, phpLang: phpLang);

            var symbol = t.ResolveRuntimeType(this);

            if (t.IsNullable || nullable)
            {
                // TODO: asSystemNullable: true // to generate strongly typed function signatures
                symbol = MergeNull(symbol, asSystemNullable: false);
            }

            return(symbol);
        }
コード例 #14
0
        void WriteType(SourceTypeSymbol type)
        {
            _writer.WriteLine($"<member name=\"{CommentIdResolver.GetId(type)}\">");
            var phpdoc = type.Syntax?.PHPDoc;

            if (phpdoc != null)
            {
                WriteSummary(_writer, phpdoc.Summary);
            }
            _writer.WriteLine("</member>");

            //
            // fields
            //

            foreach (var field in type.GetMembers().OfType <SourceFieldSymbol>())
            {
                if ((phpdoc = field.PHPDocBlock) != null)
                {
                    var summary = phpdoc.Summary;
                    var value   = string.Empty;
                    if (string.IsNullOrEmpty(summary))
                    {
                        // try @var or @staticvar:
                        var vartag = field.FindPhpDocVarTag();
                        if (vartag != null)
                        {
                            summary = vartag.Description;

                            if (!string.IsNullOrEmpty(vartag.TypeNames))
                            {
                                value = string.Format("<value>{0}</value>", XmlEncode(vartag.TypeNames));
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(summary))
                    {
                        _writer.WriteLine($"<member name=\"{CommentIdResolver.GetId(field)}\">");
                        WriteSummary(_writer, summary);
                        _writer.WriteLine(value);
                        _writer.WriteLine("</member>");
                    }
                }
            }

            //
            // .ctor
            //
            var ctors = type.InstanceConstructors;

            for (int i = 0; i < ctors.Length; i++)
            {
                // find __construct()
                if (ctors[i] is SynthesizedPhpCtorSymbol synctor && synctor.PhpConstructor is SourceRoutineSymbol php_construct)
                {
                    // annotate all generated .ctor() methods:
                    for (int j = 0; j < ctors.Length; j++)
                    {
                        var ctor_id = CommentIdResolver.GetId(ctors[j]);

                        if (ctors[j].IsFieldsOnlyConstructor())
                        {
                            // annotate special .ctor that initializes only fields
                            _writer.WriteLine($"<member name=\"{ctor_id}\">");
                            WriteSummary(_writer, Peachpie.CodeAnalysis.PhpResources.XmlDoc_FieldsOnlyCtor);
                            _writer.WriteLine("</member>");
                        }
                        else
                        {
                            WriteRoutine(ctor_id, php_construct);
                        }
                    }

                    break;
                }
            }
        }
コード例 #15
0
 internal TypeRefContext(SourceTypeSymbol selfType)
     : this(selfType, thisType : selfType)
 {
 }
コード例 #16
0
ファイル: TypeRefContext.cs プロジェクト: radtek/peachpie
 internal TypeRefContext(PhpCompilation compilation, SourceTypeSymbol selfType)
     : this(compilation, selfType, thisType : selfType)
 {
 }
コード例 #17
0
 protected private virtual void OnUnreachableTypeFound(SourceTypeSymbol type)
 {
 }
コード例 #18
0
 public static IBoundTypeRef Create(QualifiedName qname, SourceTypeSymbol self) => new BoundClassTypeRef(qname, null, self);
コード例 #19
0
ファイル: TypeRefContext.cs プロジェクト: radtek/peachpie
 internal TypeRefContext(PhpCompilation compilation, SourceTypeSymbol selfType, SourceTypeSymbol thisType)
 {
     _compilation = compilation ?? throw ExceptionUtilities.ArgumentNull(nameof(compilation));
     _selfType    = selfType;
     _thisType    = thisType;
 }
コード例 #20
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());
 }
コード例 #21
0
        /// <summary>
        /// Binds <see cref="AST.TypeRef"/> to a type symbol.
        /// </summary>
        /// <param name="tref">Type reference.</param>
        /// <param name="selfHint">Optional.
        /// Current type scope for better <paramref name="tref"/> resolution since <paramref name="tref"/> might be ambiguous</param>
        /// <param name="nullable">Whether the resulting type must be able to contain NULL. Default is <c>false</c>.</param>
        /// <returns>Resolved symbol.</returns>
        internal TypeSymbol GetTypeFromTypeRef(AST.TypeRef tref, SourceTypeSymbol selfHint = null, bool nullable = false)
        {
            if (tref == null)
            {
                return(null);
            }

            if (nullable)
            {
                return(MergeNull(GetTypeFromTypeRef(tref, selfHint, nullable: false))); // TODO: Nullable<T>
            }

            if (tref is AST.PrimitiveTypeRef)
            {
                switch (((AST.PrimitiveTypeRef)tref).PrimitiveTypeName)
                {
                case AST.PrimitiveTypeRef.PrimitiveType.@int: return(CoreTypes.Long);

                case AST.PrimitiveTypeRef.PrimitiveType.@float: return(CoreTypes.Double);

                case AST.PrimitiveTypeRef.PrimitiveType.@string: return(CoreTypes.String);      // TODO: PhpString ?

                case AST.PrimitiveTypeRef.PrimitiveType.@bool: return(CoreTypes.Boolean);

                case AST.PrimitiveTypeRef.PrimitiveType.array: return(CoreTypes.PhpArray);

                case AST.PrimitiveTypeRef.PrimitiveType.callable: return(CoreTypes.PhpValue);    // array|string|object

                case AST.PrimitiveTypeRef.PrimitiveType.@void: return(CoreTypes.Void);

                case AST.PrimitiveTypeRef.PrimitiveType.iterable: return(CoreTypes.PhpValue);   // array|Traversable

                case AST.PrimitiveTypeRef.PrimitiveType.@object: return(CoreTypes.Object);      // Object

                default: throw new ArgumentException();
                }
            }
            else if (tref is AST.INamedTypeRef namedtref)
            {
                if (selfHint != null)
                {
                    if (namedtref.ClassName == selfHint.FullName)
                    {
                        return(selfHint);
                    }
                    if (selfHint.BaseType is IPhpTypeSymbol phpt && namedtref.ClassName == phpt.FullName)
                    {
                        return(selfHint.BaseType);
                    }
                }

                var t = (NamedTypeSymbol)GlobalSemantics.ResolveType(namedtref.ClassName);
                return(t.IsErrorTypeOrNull()
                    ? CoreTypes.Object.Symbol   // TODO: merge candidates if any
                    : t);
            }
            else if (tref is AST.ReservedTypeRef)
            {
                throw new ArgumentException();                                   // NOTE: should be translated by parser to AliasedTypeRef
            }
            else if (tref is AST.AnonymousTypeRef)
            {
                return((NamedTypeSymbol)GlobalSemantics.ResolveType(((AST.AnonymousTypeRef)tref).TypeDeclaration.GetAnonymousTypeQualifiedName()));
            }
            else if (tref is AST.MultipleTypeRef)
            {
                TypeSymbol result = null;
                foreach (var x in ((AST.MultipleTypeRef)tref).MultipleTypes)
                {
                    var resolved = GetTypeFromTypeRef(x, selfHint);
                    result = (result != null) ? Merge(result, resolved) : resolved;
                }
                return(result);
            }
            else if (tref is AST.NullableTypeRef nullableref)
            {
                return(GetTypeFromTypeRef(nullableref.TargetType, selfHint, nullable: true));
            }
            else if (tref is AST.GenericTypeRef)
            {
                throw new NotImplementedException();                                  //((AST.GenericTypeRef)tref).TargetType
            }
            else if (tref is AST.IndirectTypeRef)
            {
                throw new NotImplementedException();
            }

            throw ExceptionUtilities.UnexpectedValue(tref);
        }
コード例 #22
0
 private protected override void OnUnreachableTypeFound(SourceTypeSymbol type)
 {
     _delayedTransformations.UnreachableTypes.Add(type);
 }
コード例 #23
0
 internal TypeRefContext(SourceTypeSymbol selfType, SourceTypeSymbol thisType)
 {
     _typeRefs = new List <ITypeRef>();
     _selfType = selfType;
     _thisType = thisType;
 }
コード例 #24
0
 internal TypeRefContext(SourceUnit sourceUnit, SourceTypeSymbol containingType)
 {
     _sourceUnit     = sourceUnit;
     _typeRefs       = new List <ITypeRef>();
     _containingType = containingType;
 }
コード例 #25
0
ファイル: BoundTypeRefFactory.cs プロジェクト: dlob/peachpie
        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);
            }));
        }
コード例 #26
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);
            }
        }
コード例 #27
0
 private void DiagnoseType(SourceTypeSymbol type)
 {
     type.GetDiagnostics(_diagnostics);
 }
コード例 #28
0
 internal TypeRefContext(SourceTypeSymbol selfType, SourceTypeSymbol thisType)
 {
     _selfType = selfType;
     _thisType = thisType;
 }
コード例 #29
0
 public BoundReservedTypeRef(ReservedType type, SourceTypeSymbol self = null)
 {
     _type = type;
     _self = self;
 }
コード例 #30
0
ファイル: BoundTypeRefFactory.cs プロジェクト: dlob/peachpie
        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);
            }
        }