Exemple #1
0
        /// <summary>
        /// Creates type reference from a given qualified name.
        /// The given name will be translated using current naming context.
        /// </summary>
        public TypeRef CreateTypeRef(QualifiedNameRef tname, bool allowPrimitiveTypes = false)
        {
            var qname = tname.QualifiedName;
            var span  = tname.Span;

            // primitive type name ?
            if (qname.IsSimpleName)
            {
                if (ReservedTypeRef.ReservedTypes.TryGetValue(qname.Name, out ReservedTypeRef.ReservedType reserved))
                {
                    var reservedRef = _astFactory.ReservedTypeReference(span, reserved);
                    if (IsInClassContext)
                    {
                        var context = ClassContexts.Peek();
                        switch (reserved)
                        {
                        case ReservedTypeRef.ReservedType.parent:
                            if (context.Base != null)
                            {
                                reservedRef = _astFactory.AliasedTypeReference(span, context.Base.QualifiedName.Value, reservedRef);
                            }
                            else if (context.Attributes.IsTrait())
                            {
                                // keep unbound
                                // {parent} refers to actual class where the trait is used
                            }
                            else
                            {
                                this.ErrorSink.Error(span, FatalErrors.ParentAccessedInParentlessClass);
                            }
                            break;

                        case ReservedTypeRef.ReservedType.self:

                            if (context.Attributes.IsTrait())
                            {
                                // keep unbound
                                // {self} refers to actual class where the trait is used
                            }
                            else if (context.Name.Name == Name.AnonymousClassName)
                            {
                                // we don't translate {self} in the context of an anonymous type name
                                // since the translated name is platform specific and may differ from how it is handled by caller
                            }
                            else
                            {
                                reservedRef = _astFactory.AliasedTypeReference(span, context.Name, reservedRef);
                            }
                            break;

                        case ReservedTypeRef.ReservedType.@static:
                            // keep unbound
                            break;

                        default:
                            throw new ArgumentException();
                        }
                    }
                    else
                    {
                        // TODO: Error: self|parent|static used outside a class context
                        // NOTE: allowed in global code
                    }

                    return(reservedRef);
                }

                if (allowPrimitiveTypes && PrimitiveTypes.TryGetValue(qname, out PrimitiveTypeRef.PrimitiveType primitive))
                {
                    return(_astFactory.PrimitiveTypeReference(span, primitive));
                }
            }

            // direct type reference
            return(CreateNamedTypeRef(span, tname));
        }
Exemple #2
0
        TypeRef CreateTypeRef(Span span, QualifiedNameRef tname)
        {
            var qname = tname.QualifiedName;

            // primitive type name ?
            if (qname.IsSimpleName)
            {
                ReservedTypeRef.ReservedType   reserved;
                PrimitiveTypeRef.PrimitiveType primitive;
                if ((_languageFeatures.HasFeature(LanguageFeatures.Php71Set)) && PHP71PrimitiveTypes.TryGetValue(qname, out primitive))
                {
                    return(_astFactory.PrimitiveTypeReference(span, primitive));
                }
                if ((_languageFeatures.HasFeature(LanguageFeatures.Php70Set)) && PHP70PrimitiveTypes.TryGetValue(qname, out primitive))
                {
                    return(_astFactory.PrimitiveTypeReference(span, primitive));
                }
                if ((_languageFeatures.HasFeature(LanguageFeatures.Php56Set)) && PHP56PrimitiveTypes.TryGetValue(qname, out primitive))
                {
                    return(_astFactory.PrimitiveTypeReference(span, primitive));
                }
                if (ReservedTypeRef.ReservedTypes.TryGetValue(qname.Name, out reserved))
                {
                    var reservedRef = _astFactory.ReservedTypeReference(span, reserved);
                    if (IsInClassContext)
                    {
                        var context = ClassContexts.Peek();
                        switch (reserved)
                        {
                        case ReservedTypeRef.ReservedType.parent:
                            if (context.Base != null)
                            {
                                reservedRef = _astFactory.AliasedTypeReference(span, context.Base.QualifiedName.Value, reservedRef);
                            }
                            else
                            {
                                this.ErrorSink.Error(span, FatalErrors.ParentAccessedInParentlessClass);
                            }
                            break;

                        case ReservedTypeRef.ReservedType.self:

                            // we don't translate {self} in the context of an anonymous type name
                            // since the translated name is platform specific and may differ from how it is handled by caller

                            if (context.Name.Name != Name.AnonymousClassName)
                            {
                                reservedRef = _astFactory.AliasedTypeReference(span, context.Name, reservedRef);
                            }
                            break;

                        case ReservedTypeRef.ReservedType.@static:
                            // keep unbound
                            break;

                        default:
                            throw new ArgumentException();
                        }
                    }
                    else
                    {
                        // TODO: Error: self|parent|static used outside a class context
                    }

                    return(reservedRef);
                }
            }

            // direct type reference
            return(CreateNamedTypeRef(span, tname));
        }