Example #1
0
        public override INamedTypeSymbol GetTypeSymbol(PhpCompilation compilation)
        {
            var resolved = (NamedTypeSymbol)compilation.GetTypeByMetadataName(MetadataHelpers.ComposeAritySuffixedMetadataName(QualifiedName.ClrName(), Arity));

            if (resolved.IsValidType())
            {
                // TODO: check _typeArguments are bound (no ErrorSymbol)

                var boundTypeArgs = _typeArguments.SelectAsArray(tref => (TypeSymbol)tref.GetTypeSymbol(compilation));

                return(resolved.Construct(boundTypeArgs));
            }
            else
            {
                return(compilation.CoreTypes.Object.Symbol);
            }
        }
Example #2
0
        public override ITypeSymbol ResolveTypeSymbol(PhpCompilation compilation)
        {
            if (ResolvedType.IsValidType() && !ResolvedType.IsUnreachable)
            {
                return(ResolvedType);
            }

            TypeSymbol type = null;

            if (_self != null)
            {
                if (_self.FullName == ClassName)
                {
                    type = _self;
                }
                else if (_self.BaseType != null && _self.BaseType.PhpQualifiedName() == ClassName)
                {
                    type = _self.BaseType;
                }
            }

            if (type == null)
            {
                type = (_arity <= 0)
                 ? (TypeSymbol)compilation.GlobalSemantics.ResolveType(ClassName)
                       // generic types only exist in external references, use this method to resolve the symbol including arity (needs metadataname instead of QualifiedName)
                 : compilation.GlobalSemantics.GetTypeFromNonExtensionAssemblies(MetadataHelpers.ComposeAritySuffixedMetadataName(ClassName.ClrName(), _arity));
            }

            var containingFile = _routine?.ContainingFile ?? _self?.ContainingFile;

            if (type is AmbiguousErrorTypeSymbol ambiguous && containingFile != null)
            {
                TypeSymbol best = null;

                // choose the one declared in this file unconditionally
                foreach (var x in ambiguous
                         .CandidateSymbols
                         .Cast <TypeSymbol>()
                         .Where(t => !t.IsUnreachable)
                         .Where(x => x is SourceTypeSymbol srct && !srct.Syntax.IsConditional && srct.ContainingFile == containingFile))
                {
                    if (best == null)
                    {
                        best = x;
                    }
                    else
                    {
                        best = null;
                        break;
                    }
                }

                if (best != null)
                {
                    type = (NamedTypeSymbol)best;
                }
            }

            // translate trait prototype to constructed trait type
            if (type.IsTraitType())
            {
                // <!TSelf> -> <T<Object>>
                var t = (NamedTypeSymbol)type;
                type = t.Construct(t.Construct(compilation.CoreTypes.Object));
            }

            //
            return(ResolvedType = type);
        }