aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar laurentlb <laurentlb@google.com>2017-07-12 22:12:04 +0200
committerGravatar László Csomor <laszlocsomor@google.com>2017-07-13 09:56:32 +0200
commita752d8b83ff3a241076b121dff989eb3def9cfb6 (patch)
tree2c8919801d13f1c7306a11ef3352461eb87e5338 /src/main/java/com
parent5f36bf8a0716434348042c088da838728dc6dcdc (diff)
New flag --incompatible_string_is_not_iterable to forbid iteration over strings.
RELNOTES: None. PiperOrigin-RevId: 161706309
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java13
2 files changed, 23 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index 7ef2eb3641..e6e9089f43 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -348,7 +348,7 @@ public final class EvalUtils {
if (o instanceof String) {
// This is not as efficient as special casing String in for and dict and list comprehension
// statements. However this is a more unified way.
- return split((String) o);
+ return split((String) o, loc, env);
} else if (o instanceof SkylarkNestedSet) {
return nestedSetToCollection((SkylarkNestedSet) o, loc, env);
} else if (o instanceof Iterable) {
@@ -401,7 +401,15 @@ public final class EvalUtils {
}
}
- private static ImmutableList<String> split(String value) {
+ private static ImmutableList<String> split(String value, Location loc, @Nullable Environment env)
+ throws EvalException {
+ if (env != null && env.getSemantics().incompatibleStringIsNotIterable) {
+ throw new EvalException(
+ loc,
+ "type 'string' is not iterable. You may still use `len` and string indexing. Use "
+ + "--incompatible_string_is_not_iterable=false to temporarily disable this check.");
+ }
+
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
for (char c : value.toCharArray()) {
builder.add(String.valueOf(c));
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 b73b0a4cea..2bfb51b22d 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
@@ -161,6 +161,19 @@ public class SkylarkSemanticsOptions extends OptionsBase implements Serializable
public boolean incompatibleDepsetIsNotIterable;
@Option(
+ name = "incompatible_string_is_not_iterable",
+ defaultValue = "false",
+ category = "incompatible changes",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE},
+ help =
+ "If set to true, iterating over a string will throw an error. String indexing and `len` "
+ + "are still allowed."
+ )
+ public boolean incompatibleStringIsNotIterable;
+
+ @Option(
name = "incompatible_dict_literal_has_no_duplicates",
defaultValue = "false",
category = "incompatible changes",