In painless suggest a long constant if int won't do (#21415)

In painless we prefer explicit types over implicit ones whereas
groovy is the other way around. Take this groovy code:

```
> 86400000.class
java.lang.Integer
> 864000000000.class
java.lang.Long
```

Painless accepts `86400000` just fine because that is a valid `int`
in the jvm. It rejects `864000000000` as an invlid `int` constant
because, in painless as in java, `long` constants always end in `L`
or `l`.

To ease the transition from groovy to painless, this changes the
compilation error returned from these invalid constants from:

```
Invalid int constant [864000000000].
```

to

```
Invalid int constant [864000000000]. If you want a long constant then change it to [864000000000L].
```

Inspired by #21313
This commit is contained in:
Nik Everett 2016-11-12 11:08:18 -05:00 committed by GitHub
parent 404b9afeca
commit a26b5a113c
2 changed files with 24 additions and 0 deletions

View File

@ -104,6 +104,14 @@ public final class ENumeric extends AExpression {
actual = Definition.INT_TYPE;
}
} catch (NumberFormatException exception) {
try {
// Check if we can parse as a long. If so then hint that the user might prefer that.
Long.parseLong(value, radix);
throw createError(new IllegalArgumentException("Invalid int constant [" + value + "]. If you want a long constant "
+ "then change it to [" + value + "L]."));
} catch (NumberFormatException longNoGood) {
// Ignored
}
throw createError(new IllegalArgumentException("Invalid int constant [" + value + "]."));
}
}

View File

@ -245,4 +245,20 @@ public class WhenThingsGoWrongTests extends ScriptTestCase {
() -> exec("", null, singletonMap(CompilerSettings.REGEX_ENABLED.getKey(), "true"), null, false));
assertEquals("[painless.regex.enabled] can only be set on node startup.", e.getMessage());
}
public void testInvalidIntConstantSuggestsLong() {
IllegalArgumentException e = expectScriptThrows(IllegalArgumentException.class, () -> exec("return 864000000000"));
assertEquals("Invalid int constant [864000000000]. If you want a long constant then change it to [864000000000L].", e.getMessage());
assertEquals(864000000000L, exec("return 864000000000L"));
e = expectScriptThrows(IllegalArgumentException.class, () -> exec("return -864000000000"));
assertEquals("Invalid int constant [-864000000000]. If you want a long constant then change it to [-864000000000L].",
e.getMessage());
assertEquals(-864000000000L, exec("return -864000000000L"));
// If it isn't a valid long we don't give any suggestions
e = expectScriptThrows(IllegalArgumentException.class, () -> exec("return 92233720368547758070"));
assertEquals("Invalid int constant [92233720368547758070].", e.getMessage());
e = expectScriptThrows(IllegalArgumentException.class, () -> exec("return -92233720368547758070"));
assertEquals("Invalid int constant [-92233720368547758070].", e.getMessage());
}
}