Better support for number ranges, still not perfect

This commit is contained in:
Andrey Breslav
2011-04-07 18:30:18 +04:00
parent 53e4c863e7
commit fde6a6f60f
2 changed files with 32 additions and 10 deletions
@@ -23,18 +23,23 @@ public class JetConstantExpression extends JetExpression {
String nodeText = getNode().getText(); String nodeText = getNode().getText();
if (elementType == JetNodeTypes.INTEGER_CONSTANT) { if (elementType == JetNodeTypes.INTEGER_CONSTANT) {
if (nodeText.startsWith("0x") || nodeText.startsWith("0X")) { try {
String hexString = nodeText.substring(2); if (nodeText.startsWith("0x") || nodeText.startsWith("0X")) {
long longValue = Long.parseLong(hexString, 16); String hexString = nodeText.substring(2);
if (Integer.MIN_VALUE <= longValue && longValue <= Integer.MAX_VALUE) { int length = hexString.length();
return (int) longValue; if (length > 8) {
return Long.parseLong(hexString);
}
return getRangedValue(Long.parseLong(hexString, 16));
} }
return longValue; if (nodeText.startsWith("0b") || nodeText.startsWith("0B")) {
return getRangedValue(Long.parseLong(nodeText.substring(2), 2));
}
return getRangedValue(Long.parseLong(nodeText));
} }
if (nodeText.startsWith("0b") || nodeText.startsWith("0B")) { catch (NumberFormatException e) {
return Integer.parseInt(nodeText.substring(2), 2); return null;
} }
return Integer.parseInt(nodeText);
} }
else if (elementType == JetNodeTypes.LONG_CONSTANT) { else if (elementType == JetNodeTypes.LONG_CONSTANT) {
if (nodeText.endsWith("l") || nodeText.endsWith("L")) { if (nodeText.endsWith("l") || nodeText.endsWith("L")) {
@@ -73,4 +78,17 @@ public class JetConstantExpression extends JetExpression {
throw new IllegalArgumentException("Unsupported constant: " + this); throw new IllegalArgumentException("Unsupported constant: " + this);
} }
} }
private Object getRangedValue(long longValue) {
if (Byte.MIN_VALUE <= longValue && longValue <= Byte.MAX_VALUE) {
return (byte) longValue;
}
if (Short.MIN_VALUE <= longValue && longValue <= Short.MAX_VALUE) {
return (short) longValue;
}
if (Integer.MIN_VALUE <= longValue && longValue <= Integer.MAX_VALUE) {
return (int) longValue;
}
return longValue;
}
} }
@@ -502,7 +502,11 @@ public class JetTypeInferrer {
IElementType elementType = expression.getNode().getElementType(); IElementType elementType = expression.getNode().getElementType();
JetStandardLibrary standardLibrary = semanticServices.getStandardLibrary(); JetStandardLibrary standardLibrary = semanticServices.getStandardLibrary();
if (elementType == JetNodeTypes.INTEGER_CONSTANT) { if (elementType == JetNodeTypes.INTEGER_CONSTANT) {
if (expression.getValue() instanceof Long) { Object value = expression.getValue();
if (value == null) {
semanticServices.getErrorHandler().genericError(expression.getNode(), "Number is of range for Long");
}
else if (value instanceof Long) {
result = standardLibrary.getLongType(); result = standardLibrary.getLongType();
} }
else { else {