Fix loop over a range literal up to MAX_VALUE

#KT-492 In Progress

For Byte, Char and Short explicit casting from Int is removed -- loop parameter
is already stored in an Int anyway. For Int and Long comparison "i < end" at
the beginning of the loop is replaced to "i != end" at the end of the loop + a
special check for an empty loop
This commit is contained in:
Alexander Udalov
2013-06-17 21:47:41 +04:00
parent f1a6d27d35
commit 33d6347876
10 changed files with 561 additions and 31 deletions
@@ -19,11 +19,15 @@ package org.jetbrains.jet.generators.tests;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.LineSeparator;
import com.intellij.util.containers.ContainerUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -58,22 +62,29 @@ public class GenerateRangesCodegenTestData {
" }\n" +
"\n";
private static final Map<String, String> ELEMENT_TYPE_KNOWN_SUBSTRINGS = new ContainerUtil.ImmutableMapBuilder<String, String>()
.put("'", "Char")
.put("\"", "Char")
.put("Float.NaN", "Float")
.put("Double.NaN", "Double")
.put("MaxB", "Byte")
.put("MaxS", "Short")
.put("MaxL", "Long")
.put("MaxC", "Char")
.build();
private static String detectElementType(String rangeExpression) {
Matcher matcher = Pattern.compile("\\.to(\\w+)").matcher(rangeExpression);
if (matcher.find()) {
return matcher.group(1);
}
if (rangeExpression.contains("'") || rangeExpression.contains("\"")) {
return "Char";
}
if (Pattern.compile("\\d\\.\\d").matcher(rangeExpression).find()) {
return "Double";
}
if (rangeExpression.contains("Float.NaN")) {
return "Float";
}
if (rangeExpression.contains("Double.NaN")) {
return "Double";
for (String substring : ELEMENT_TYPE_KNOWN_SUBSTRINGS.keySet()) {
if (rangeExpression.contains(substring)) {
return ELEMENT_TYPE_KNOWN_SUBSTRINGS.get(substring);
}
}
return "Int";
}
@@ -89,7 +100,9 @@ public class GenerateRangesCodegenTestData {
.replace("\n", LineSeparator.getSystemLineSeparator().getSeparatorString());
}
private static void writeToFile(File file, CharSequence generatedBody) {
private static final List<String> INTEGER_PRIMITIVES = Arrays.asList("Integer", "Byte", "Short", "Long", "Character");
private static void writeToFile(File file, String generatedBody) {
PrintWriter out;
try {
//noinspection IOResourceOpenedButNotSafelyClosed
@@ -102,6 +115,14 @@ public class GenerateRangesCodegenTestData {
out.println("// Auto-generated by " + GenerateRangesCodegenTestData.class.getName() + ". DO NOT EDIT!");
out.println("import java.util.ArrayList");
out.println("import java.lang as j");
if (generatedBody.contains("Max") || generatedBody.contains("Min")) {
// Import min/max values, but only in case when the generated test case actually uses them (not to clutter tests which don't)
out.println();
for (String primitive : INTEGER_PRIMITIVES) {
out.println("import java.lang." + primitive + ".MAX_VALUE as Max" + primitive.charAt(0));
out.println("import java.lang." + primitive + ".MIN_VALUE as Min" + primitive.charAt(0));
}
}
out.println();
out.println("fun box(): String {");
out.print(generatedBody);
@@ -146,8 +167,8 @@ public class GenerateRangesCodegenTestData {
}
String fileName = testFunName + ".kt";
writeToFile(new File(AS_LITERAL_DIR, fileName), asLiteralBody);
writeToFile(new File(AS_EXPRESSION_DIR, fileName), asExpressionBody);
writeToFile(new File(AS_LITERAL_DIR, fileName), asLiteralBody.toString());
writeToFile(new File(AS_EXPRESSION_DIR, fileName), asExpressionBody.toString());
}
}