示例#1
0
 public override object VisitTypeRef(BoundTypeRef x)
 {
     return(x.Update(
                (BoundExpression)Accept(x.TypeExpression),
                x.TypeRef,
                x.ObjectTypeInfoSemantic,
                x.HasClassNameRestriction));;
 }
示例#2
0
 public override void VisitTypeRef(BoundTypeRef typeRef)
 {
     if (typeRef != null)
     {
         CheckUndefinedType(typeRef);
         base.VisitTypeRef(typeRef);
     }
 }
示例#3
0
 private void CheckUndefinedType(BoundTypeRef typeRef)
 {
     // Ignore indirect types (e.g. $foo = new $className())
     if (typeRef.IsDirect && (typeRef.ResolvedType == null || typeRef.ResolvedType.IsErrorType()))
     {
         var name = typeRef.TypeRef.QualifiedName?.ToString();
         _diagnostics.Add(this._routine, typeRef.TypeRef, ErrorCode.WRN_UndefinedType, name);
     }
 }
 internal static ImmutableArray <BoundTypeRef> Flattern(BoundTypeRef tref)
 {
     if (tref is BoundMultipleTypeRef mtref)
     {
         return(mtref.BoundTypes);
     }
     else
     {
         return(ImmutableArray.Create(tref));
     }
 }
示例#5
0
        public override T VisitTypeRef(BoundTypeRef typeRef)
        {
            if (typeRef.HasClassNameRestriction && typeRef.TypeRef is Devsense.PHP.Syntax.Ast.PrimitiveTypeRef)
            {
                // error: use of primitive type {0} is misused // primitive type does not make any sense in this context
                _diagnostics.Add(_routine, typeRef.TypeRef, ErrorCode.ERR_PrimitiveTypeNameMisused, typeRef.TypeRef);
            }
            else
            {
                CheckUndefinedType(typeRef);
                base.VisitTypeRef(typeRef);
            }

            return(default);
示例#6
0
 internal CatchBlock Update(BoundTypeRef typeRef, BoundVariableRef variable, List <BoundStatement> statements, Edge nextEdge)
 {
     if (typeRef == _typeRef && variable == _variable && statements == Statements && nextEdge == NextEdge)
     {
         return(this);
     }
     else
     {
         return(new CatchBlock(typeRef, variable, statements)
         {
             NextEdge = nextEdge
         }
                .WithLocalPropertiesFrom(this));
     }
 }
示例#7
0
        static TypeSymbol ResolveTypeSymbol(BoundTypeRef tref, PhpCompilation compilation)
        {
            var type = (TypeSymbol)tref.ResolveTypeSymbol(compilation);

            // special case, static
            if (type == null)
            {
                if (tref.IsStatic())
                {
                    return(compilation.GetSpecialType(SpecialType.System_Object));
                }
                // else we get NullRefException ¯\_(ツ)_/¯
            }

            return(type);
        }
示例#8
0
        public override void VisitTypeRef(BoundTypeRef x)
        {
            if (x != null)
            {
                if (x.Symbol != null)
                {
                    if (x.TypeRef is AnonymousTypeRef)
                    {
                        // nada
                    }
                    else
                    {
                        _result.Add(new SymbolStat(_tctx, x.TypeRef.Span, null, x.Symbol));
                    }
                }

                base.VisitTypeRef(x);
            }
        }
示例#9
0
        private void CheckUndefinedType(BoundTypeRef typeRef)
        {
            var type = typeRef.ResolvedType;

            // Ignore indirect types (e.g. $foo = new $className())
            if (type.IsErrorTypeOrNull() && !(typeRef is BoundIndirectTypeRef))
            {
                var errtype = typeRef.ResolvedType as ErrorTypeSymbol;
                if (errtype != null && errtype.CandidateReason == CandidateReason.Ambiguous)
                {
                    // type is declared but ambiguously,
                    // warning with declaration ambiguity was already reported, we may skip following
                    return;
                }

                if (typeRef is BoundReservedTypeRef)
                {
                    // unresolved parent, self ?
                }
                else
                {
                    _diagnostics.Add(_routine, typeRef.PhpSyntax, ErrorCode.WRN_UndefinedType, typeRef.ToString());
                }
            }

            // undefined "parent"
            if (typeRef is BoundReservedTypeRef reservedType && reservedType.ReservedType == ReservedTypeRef.ReservedType.parent && typeRef.PhpSyntax != null)
            {
                var typeCtx = _routine.ContainingType as SourceTypeSymbol;
                if ((typeCtx != null && typeCtx.IsTrait) || _routine.IsGlobalScope)
                {
                    // global code or trait -> resolved at run time
                }
                else if (typeCtx == null || typeCtx.Syntax.BaseClass == null)
                {
                    // in a global function or a class without parent -> error
                    Add(typeRef.PhpSyntax.Span, Devsense.PHP.Errors.FatalErrors.ParentAccessedInParentlessClass);
                }
            }
        }
示例#10
0
        internal override T VisitTypeRef(BoundTypeRef typeRef)
        {
            CheckUndefinedType(typeRef);

            // Check that the right case of a class name is used
            if (typeRef.IsObject && typeRef is BoundClassTypeRef ct && ct.Type != null)
            {
                string refName = ct.ClassName.Name.Value;

                if (ct.Type.Kind != SymbolKind.ErrorType)
                {
                    var symbolName = ct.Type.Name;

                    if (IsLetterCasingMismatch(refName, symbolName))
                    {
                        // Wrong class name case
                        _diagnostics.Add(_routine, typeRef.PhpSyntax, ErrorCode.INF_TypeNameCaseMismatch, refName, symbolName);
                    }
                }
            }

            return base.VisitTypeRef(typeRef);
        }
示例#11
0
        internal override T VisitTypeRef(BoundTypeRef typeRef)
        {
            CheckUndefinedType(typeRef);

            // Check that the right case of a class name is used
            if (typeRef.IsObject && typeRef is BoundClassTypeRef ct && ct.Type != null)
            {
                string refName = ct.ClassName.Name.Value;

                if (ct.Type.Kind != SymbolKind.ErrorType)
                {
                    string symbolName = ct.Type.Name;

                    if (refName != symbolName && refName.Equals(symbolName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        // Wrong class name case
                        _diagnostics.Add(_routine, typeRef.PhpSyntax, ErrorCode.INF_ClassNameWrongCase, refName, symbolName);
                    }
                }
            }

            return(base.VisitTypeRef(typeRef));
        }
示例#12
0
        private void CheckUndefinedType(BoundTypeRef typeRef)
        {
            // Ignore indirect types (e.g. $foo = new $className())
            if (typeRef.IsDirect && (typeRef.ResolvedType == null || typeRef.ResolvedType.IsErrorType()))
            {
                var errtype = typeRef.ResolvedType as ErrorTypeSymbol;
                if (errtype != null && errtype.CandidateReason == CandidateReason.Ambiguous)
                {
                    // type is declared but ambiguously,
                    // warning with declaration ambiguity was already reported, we may skip following
                    return;
                }

                if (typeRef.TypeRef is ReservedTypeRef)
                {
                    // unresolved parent, self ?
                }
                else
                {
                    var name = typeRef.TypeRef.QualifiedName?.ToString();
                    _diagnostics.Add(this._routine, typeRef.TypeRef, ErrorCode.WRN_UndefinedType, name);
                }
            }
        }
示例#13
0
        void EmitTypeCheck(CodeGenerator cg, BoundTypeRef tref)
        {
            var il = cg.Builder;

            // STACK : object

            if (tref.ResolvedType.IsErrorTypeOrNull())
            {
                // Template: filter(Operators.IsInstanceOf(<stack>, type))
                tref.EmitLoadTypeInfo(cg, false);
                cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.IsInstanceOf_Object_PhpTypeInfo)
                .Expect(SpecialType.System_Boolean);
            }
            else
            {
                // Template: filter (<stack> is Interface)
                il.EmitOpCode(ILOpCode.Isinst);
                cg.EmitSymbolToken(tref.ResolvedType, null);
                il.EmitNullConstant();
                il.EmitOpCode(ILOpCode.Cgt_un); // value > null : bool
            }

            // STACK: i4 (boolean)
        }
示例#14
0
 void CannotInstantiate(IPhpOperation op, string kind, BoundTypeRef t)
 {
     _diagnostics.Add(_routine, op.PhpSyntax, ErrorCode.ERR_CannotInstantiateType, kind, t.ResolvedType);
 }
示例#15
0
 public CatchBlock(BoundTypeRef typeRef, BoundVariableRef variable)
 {
     _typeRef  = typeRef;
     _variable = variable;
 }
示例#16
0
 public CatchBlock(BoundTypeRef typeRef, BoundVariableRef variable)
     : this(typeRef, variable, new List <BoundStatement>())
 {
 }
示例#17
0
 /// <summary>Template: new TargetTypeParam(PhpTypeInfo)</summary>
 public TypeSymbol EmitTargetTypeParam(BoundTypeRef tref)
 => tref != null?EmitWrapParam(_cg.CoreTypes.Dynamic_TargetTypeParam, tref.EmitLoadTypeInfo(_cg, true)) : null;
示例#18
0
 internal override T VisitTypeRef(BoundTypeRef typeRef)
 {
     CheckUndefinedType(typeRef);
     return(base.VisitTypeRef(typeRef));
 }
示例#19
0
 private CatchBlock(BoundTypeRef typeRef, BoundVariableRef variable, List <BoundStatement> statements)
     : base(statements)
 {
     _typeRef  = typeRef;
     _variable = variable;
 }