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); } }
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); }