public override T VisitAssign(BoundAssignEx x) { // Template: <x> = <x> if (x.Target is BoundVariableRef lvar && lvar.Variable is LocalVariableReference lloc && x.Value is BoundVariableRef rvar && rvar.Variable is LocalVariableReference rloc && lloc.BoundName == rloc.BoundName && x.PhpSyntax != null) { // Assignment made to same variable _diagnostics.Add(_routine, x.PhpSyntax, ErrorCode.WRN_AssigningSameVariable); } // Check the type of the value assigned to a field against its PHPDoc var valMask = x.Value.TypeRefMask; if (!valMask.IsAnyType && !valMask.IsRef && x.Target is BoundFieldRef fr && fr.BoundReference.Symbol is SourceFieldSymbol fieldSymbol && fieldSymbol.FindPhpDocVarTag() is PHPDocBlock.TypeVarDescTag fieldDoc && fieldDoc.TypeNamesArray.Length != 0) { var namingCtx = NameUtils.GetNamingContext(fieldSymbol.PhpDocBlock.ContainingType); var fieldMask = PHPDoc.GetTypeMask(TypeCtx, fieldDoc.TypeNamesArray, namingCtx); if (!TypeCtx.CanBeSameType(fieldMask, valMask)) { // The value can't be of the type specified in PHPDoc _diagnostics.Add(_routine, x.PhpSyntax, ErrorCode.WRN_FieldPhpDocAssignIncompatible, TypeCtx.ToString(valMask), fieldSymbol, fieldDoc.TypeNames); } } // return(base.VisitAssign(x)); }
/// <summary> /// Enqueues initializers of a class fields and constants. /// </summary> void EnqueueFieldsInitializer(SourceTypeSymbol type) { type.GetMembers().OfType <SourceFieldSymbol>().Foreach(f => { if (f.Initializer != null) { EnqueueExpression( f.Initializer, TypeRefFactory.CreateTypeRefContext(type), //the context will be lost, analysis resolves constant values only and types are temporary NameUtils.GetNamingContext(type.Syntax)); } }); }
internal override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { // TODO: HHVM TypeHint // if ((IsConst || IsReadOnly) && Initializer != null) { // resolved type symbol if possible if (Initializer.ResultType != null) { return(Initializer.ResultType); } // resolved value type if possible var cvalue = Initializer.ConstantValue; if (cvalue.HasValue) { var specialType = (cvalue.Value != null) ? cvalue.ToConstantValueOrNull()?.SpecialType : SpecialType.System_Object; // NULL if (specialType.HasValue && specialType != SpecialType.None) { return(DeclaringCompilation.GetSpecialType(specialType.Value)); } } // //return DeclaringCompilation.GetTypeFromTypeRef(typectx, Initializer.TypeRefMask); } // PHPDoc @var type var vartag = _phpDoc?.GetElement <PHPDocBlock.VarTag>(); if (vartag != null && vartag.TypeNamesArray.Length != 0) { var dummyctx = TypeRefFactory.CreateTypeRefContext(_containingType); var tmask = PHPDoc.GetTypeMask(dummyctx, vartag.TypeNamesArray, NameUtils.GetNamingContext(_containingType.Syntax)); return(DeclaringCompilation.GetTypeFromTypeRef(dummyctx, tmask)); } // default return(DeclaringCompilation.CoreTypes.PhpValue); }
internal override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { // TODO: PHP 7.4 typed properties // https://github.com/peachpiecompiler/peachpie/issues/766 // if ((IsConst || IsReadOnly) && Initializer != null) { // resolved type symbol if possible if (Initializer.ResultType != null) { return(Initializer.ResultType); } // resolved value type if possible var cvalue = Initializer.ConstantValue; if (cvalue.HasValue) { var specialType = (cvalue.Value != null) ? cvalue.ToConstantValueOrNull()?.SpecialType : SpecialType.System_Object; // NULL if (specialType.HasValue && specialType != SpecialType.None) { return(DeclaringCompilation.GetSpecialType(specialType.Value)); } } // //return DeclaringCompilation.GetTypeFromTypeRef(typectx, Initializer.TypeRefMask); } // PHPDoc @var type if ((DeclaringCompilation.Options.PhpDocTypes & PhpDocTypes.FieldTypes) != 0) { var vartag = FindPhpDocVarTag(); if (vartag != null && vartag.TypeNamesArray.Length != 0) { var dummyctx = TypeRefFactory.CreateTypeRefContext(_containingType); var tmask = PHPDoc.GetTypeMask(dummyctx, vartag.TypeNamesArray, NameUtils.GetNamingContext(_containingType.Syntax)); return(DeclaringCompilation.GetTypeFromTypeRef(dummyctx, tmask)); } } // default return(DeclaringCompilation.CoreTypes.PhpValue); }
protected override TypeRefContext CreateTypeRefContext() => new TypeRefContext(NameUtils.GetNamingContext(_syntax.Namespace, _syntax.SourceUnit.Ast), _syntax.SourceUnit, null);