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)); }
public override void VisitAssign(BoundAssignEx x) { // Template: <x> = <x> if (x.Target is BoundVariableRef lvar && lvar.Variable is BoundLocal lloc && x.Value is BoundVariableRef rvar && rvar.Variable is BoundLocal rloc && lloc.Name == rloc.Name && !string.IsNullOrEmpty(lloc.Name) && x.PhpSyntax != null) { // Assignment made to same variable _diagnostics.Add(_routine, x.PhpSyntax, ErrorCode.WRN_AssigningSameVariable); } // base.VisitAssign(x); }
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); } // return(base.VisitAssign(x)); }
public override object VisitAssign(BoundAssignEx x) { // A = A <binOp> <right> if (x.Target is BoundVariableRef trg && MatchExprSkipCopy(x.Value, out BoundBinaryEx binOp, isCopied: out _) && binOp.Left is BoundVariableRef valLeft && trg.Variable == valLeft.Variable) { var newTrg = new BoundVariableRef(trg.Name) .WithAccess(trg.Access.WithRead()) .WithSyntax(trg.PhpSyntax); // A = A +/- 1; => ++A; / --A; if ((binOp.Operation == Ast.Operations.Add || binOp.Operation == Ast.Operations.Sub) && binOp.Right.ConstantValue.IsInteger(out long rightVal) && rightVal == 1) { TransformationCount++; return(new BoundIncDecEx(newTrg, binOp.Operation == Ast.Operations.Add, false).WithAccess(x)); } // A = A & B => A &= B; // &, |, ^, <<, >>, +, -, *, /, %, **, . switch (binOp.Operation) { case Ast.Operations.BitAnd: case Ast.Operations.BitOr: case Ast.Operations.BitXor: case Ast.Operations.ShiftLeft: case Ast.Operations.ShiftRight: case Ast.Operations.Add: case Ast.Operations.Sub: case Ast.Operations.Mul: case Ast.Operations.Div: case Ast.Operations.Mod: case Ast.Operations.Pow: case Ast.Operations.Concat: TransformationCount++; var compoundOp = AstUtils.BinaryToCompoundOp(binOp.Operation); return(new BoundCompoundAssignEx(newTrg, binOp.Right, compoundOp).WithAccess(x)); } } return(base.VisitAssign(x)); }
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); } // Following is commented since it does not have any effect on the compiler and the type check also needs to be improved. // Currently it is very inaccurate: //// 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); }
public override VoidStruct VisitAssign(BoundAssignEx assign) { ProcessAssignment(assign); return(default);
public override object VisitAssign(BoundAssignEx x) { return(x.Update( (BoundReferenceExpression)Accept(x.Target), (BoundExpression)Accept(x.Value))); }