diff options
author | 2017-05-04 18:00:59 +0200 | |
---|---|---|
committer | 2017-05-04 23:05:35 +0200 | |
commit | 25da19da81e9eaf06632349ad41ef9910940e33f (patch) | |
tree | b95a160f0145bd004e319f02d417a828481227ee /src/main/java/com | |
parent | 444b86319a901603a1030c484dac9f87501bad9d (diff) |
Implement a flag for extend-like behavior of the `+=` operator for lists
Usage: --incompatible_list_plus_equals=true (the default value is false).
PiperOrigin-RevId: 155084916
Diffstat (limited to 'src/main/java/com')
4 files changed, 32 insertions, 21 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java index c11722469e..d869abae86 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java @@ -14,8 +14,6 @@ package com.google.devtools.build.lib.syntax; -import com.google.devtools.build.lib.events.Location; - /** Syntax node for an augmented assignment statement. */ public final class AugmentedAssignmentStatement extends Statement { @@ -54,8 +52,7 @@ public final class AugmentedAssignmentStatement extends Statement { @Override void doExec(Environment env) throws EvalException, InterruptedException { - Location loc = getLocation(); - lvalue.assign(env, loc, expression, operator); + lvalue.assign(env, getLocation(), expression, operator); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java index e6d37905c5..ec81e07219 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java @@ -92,19 +92,14 @@ public final class BinaryOperatorExpression extends Expression { } } - /** - * Helper method. Reused from AugmentedAssignmentStatement class which falls back to this method - * in most of the cases. - */ + /** Helper method. Reused from the LValue class. */ public static Object evaluate( - Operator operator, Expression lhs, Expression rhs, Environment env, Location location) - throws EvalException, InterruptedException { - Object lval = lhs.eval(env); - return evaluate(operator, lval, rhs, env, location); - } - - public static Object evaluate( - Operator operator, Object lval, Expression rhs, Environment env, Location location) + Operator operator, + Object lval, + Expression rhs, + Environment env, + Location location, + boolean isAugmented) throws EvalException, InterruptedException { // Short-circuit operators if (operator == Operator.AND) { @@ -127,7 +122,7 @@ public final class BinaryOperatorExpression extends Expression { switch (operator) { case PLUS: - return plus(lval, rval, env, location); + return plus(lval, rval, env, location, isAugmented); case PIPE: return pipe(lval, rval, location); @@ -175,7 +170,7 @@ public final class BinaryOperatorExpression extends Expression { @Override Object doEval(Environment env) throws EvalException, InterruptedException { - return evaluate(operator, lhs, rhs, env, getLocation()); + return evaluate(operator, lhs.eval(env), rhs, env, getLocation(), false); } @Override @@ -190,7 +185,8 @@ public final class BinaryOperatorExpression extends Expression { } /** Implements Operator.PLUS. */ - private static Object plus(Object lval, Object rval, Environment env, Location location) + private static Object plus( + Object lval, Object rval, Environment env, Location location, boolean isAugmented) throws EvalException { // int + int if (lval instanceof Integer && rval instanceof Integer) { @@ -213,6 +209,12 @@ public final class BinaryOperatorExpression extends Expression { } if ((lval instanceof MutableList) && (rval instanceof MutableList)) { + if (isAugmented && env.getSemantics().incompatibleListPlusEquals) { + @SuppressWarnings("unchecked") + MutableList<Object> list = (MutableList) lval; + list.addAll((MutableList<?>) rval, location, env); + return list; + } return MutableList.concat((MutableList) lval, (MutableList) rval, env); } diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java index ecc72073fe..1b7278b6a7 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java @@ -53,7 +53,8 @@ public class LValue implements Serializable { public void assign(Environment env, Location loc, Expression rhs, Operator operator) throws EvalException, InterruptedException { if (expr instanceof Identifier) { - Object result = BinaryOperatorExpression.evaluate(operator, expr, rhs, env, loc); + Object result = + BinaryOperatorExpression.evaluate(operator, expr.eval(env), rhs, env, loc, true); assign(env, loc, (Identifier) expr, result); return; } @@ -64,7 +65,8 @@ public class LValue implements Serializable { Object evaluatedLhsObject = indexExpression.getObject().eval(env); Object evaluatedLhs = indexExpression.eval(env, evaluatedLhsObject); Object key = indexExpression.getKey().eval(env); - Object result = BinaryOperatorExpression.evaluate(operator, evaluatedLhs, rhs, env, loc); + Object result = + BinaryOperatorExpression.evaluate(operator, evaluatedLhs, rhs, env, loc, true); assignItem(env, loc, evaluatedLhsObject, key, result); return; } diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java index 0c83c25760..5909ea7155 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java @@ -58,4 +58,14 @@ public class SkylarkSemanticsOptions extends OptionsBase implements Serializable help = "If set to true, disables the keyword-only argument syntax in function definition." ) public boolean incompatibleKeywordOnlySyntax; + + @Option( + name = "incompatible_list_plus_equals", + defaultValue = "false", + category = "incompatible changes", + help = + "If set to true, `+=` on lists works like the `extend` method mutating the original " + + "list. Otherwise it copies the original list without mutating it." + ) + public boolean incompatibleListPlusEquals; } |