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); }
public override ITypeSymbol ResolveTypeSymbol(PhpCompilation compilation) { if (ResolvedType.IsValidType() && !ResolvedType.IsUnreachable) { return(ResolvedType); } TypeSymbol type = null; if (_self != null) { if (_self.FullName == _qname) { type = _self; } else if (_self.BaseType is IPhpTypeSymbol phpt && phpt.FullName == _qname) { type = _self.BaseType; } } if (type == null) { type = (TypeSymbol)compilation.GlobalSemantics.ResolveType(_qname); } if (type is AmbiguousErrorTypeSymbol ambiguous && _routine != 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 == _routine.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); }