From 9edd865a9c951608bf7a0f5ccc3ee3191fb0d902 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 23 Nov 2011 11:15:49 +0400 Subject: [PATCH 01/22] More puzzlers --- docs/exPuzzlers/kotlin/std.kt | 2 +- .../_13_Animal_Farm/AnimalFarm.kt | 2 +- .../_48_All_I_Get_Is_Static/Bark.kt | 2 +- .../_06_classy/_53_Do_Your_Thing/MyThing.java | 24 +++++++++++++++++ .../_06_classy/_53_Do_Your_Thing/MyThing.kt | 14 ++++++++++ .../_06_classy/_53_Do_Your_Thing/Thing.java | 7 +++++ .../_06_classy/_54_Null_and_Void/Null.java | 11 ++++++++ .../src/_06_classy/_54_Null_and_Void/Null.kt | 19 ++++++++++++++ .../src/_06_classy/_55_Creationism/BUG | 0 .../_06_classy/_55_Creationism/Creator.java | 21 +++++++++++++++ .../src/_06_classy/_55_Creationism/Creator.kt | 21 +++++++++++++++ .../src/_07_library/_56_Big_Problem/BUG | 0 .../_56_Big_Problem/BigProblem.java | 18 +++++++++++++ .../_07_library/_56_Big_Problem/BigProblem.kt | 26 +++++++++++++++++++ .../_07_library/_59_Whats_the_Difference/BUG | 0 .../_59_Whats_the_Difference/Differences.java | 15 +++++++++++ .../_59_Whats_the_Difference/Differences.kt | 20 ++++++++++++++ 17 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.java create mode 100644 docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.kt create mode 100644 docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/Thing.java create mode 100644 docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.java create mode 100644 docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.kt create mode 100644 docs/exPuzzlers/src/_06_classy/_55_Creationism/BUG create mode 100644 docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.java create mode 100644 docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.kt create mode 100644 docs/exPuzzlers/src/_07_library/_56_Big_Problem/BUG create mode 100644 docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.java create mode 100644 docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.kt create mode 100644 docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/BUG create mode 100644 docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.java create mode 100644 docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.kt diff --git a/docs/exPuzzlers/kotlin/std.kt b/docs/exPuzzlers/kotlin/std.kt index 9ad7308aae7..31cd9bf4f8f 100644 --- a/docs/exPuzzlers/kotlin/std.kt +++ b/docs/exPuzzlers/kotlin/std.kt @@ -9,7 +9,7 @@ inline fun array(vararg array : Long) = array inline fun array(vararg array : Double) = array inline fun array(vararg array : Float) = array -fun Any?.identityEquals(other : Any?) = this === other +//fun Any?.identityEquals(other : Any?) = this === other inline fun T?.sure() : T { if (this == null) diff --git a/docs/exPuzzlers/src/_03_character/_13_Animal_Farm/AnimalFarm.kt b/docs/exPuzzlers/src/_03_character/_13_Animal_Farm/AnimalFarm.kt index fe0c51d44a9..7dd33235955 100644 --- a/docs/exPuzzlers/src/_03_character/_13_Animal_Farm/AnimalFarm.kt +++ b/docs/exPuzzlers/src/_03_character/_13_Animal_Farm/AnimalFarm.kt @@ -12,5 +12,5 @@ fun main(args : Array) { println("Animals are equal: " + (pig == dog)); // Note: - println("Animals are equal: " + (pig identityEquals dog)); + println("Animals are equal: " + (pig identityEquals dog)) } \ No newline at end of file diff --git a/docs/exPuzzlers/src/_06_classy/_48_All_I_Get_Is_Static/Bark.kt b/docs/exPuzzlers/src/_06_classy/_48_All_I_Get_Is_Static/Bark.kt index 2cf523b8e1b..4c2fbb0bc40 100644 --- a/docs/exPuzzlers/src/_06_classy/_48_All_I_Get_Is_Static/Bark.kt +++ b/docs/exPuzzlers/src/_06_classy/_48_All_I_Get_Is_Static/Bark.kt @@ -25,4 +25,4 @@ fun main(args : Array) { // nipper.bark() Dog.bark() Basenji.bark() -} \ No newline at end of file +} diff --git a/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.java b/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.java new file mode 100644 index 00000000000..89a6cf15dab --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.java @@ -0,0 +1,24 @@ +package _06_classy._53_Do_Your_Thing; + +public class MyThing extends Thing { + private final int arg; + + /* + * This constructor is illegal. Rewrite it so that it has the same + * effect but is legal. + */ + public MyThing() { + this((int)System.currentTimeMillis()); + } + + /* + * This constructor is illegal. Rewrite it so that it has the same + * effect but is legal. + */ + public MyThing(int arg) { + super(arg); + this.arg = arg; + } + + +} diff --git a/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.kt b/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.kt new file mode 100644 index 00000000000..ff06e855549 --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/MyThing.kt @@ -0,0 +1,14 @@ +namespace `do`.your.thing + +import std.io.* +import std.* +import _06_classy._53_Do_Your_Thing.Thing + +class MyThing(val arg : Int) : Thing(arg) { + +} + + +fun main(args : Array) { + println(MyThing(10).arg) +} \ No newline at end of file diff --git a/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/Thing.java b/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/Thing.java new file mode 100644 index 00000000000..85111834f2e --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_53_Do_Your_Thing/Thing.java @@ -0,0 +1,7 @@ +package _06_classy._53_Do_Your_Thing; + +// This is meant to represent a library class. You must not modify it. +public class Thing { + public Thing(int i) { + } +} diff --git a/docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.java b/docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.java new file mode 100644 index 00000000000..409aa3392c6 --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.java @@ -0,0 +1,11 @@ +package _06_classy._54_Null_and_Void; + +public class Null { + public static void greet() { + System.out.println("Hello world!"); + } + + public static void main(String[] args) { + ((Null) null).greet(); + } +} diff --git a/docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.kt b/docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.kt new file mode 100644 index 00000000000..e73e94f3f1e --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_54_Null_and_Void/Null.kt @@ -0,0 +1,19 @@ +namespace `null`.and.void + +import std.io.* +import std.* + +class Null() { + class object { + fun greet() { + println("Hello world!") + } + } +} + + +fun main(args : Array) { +// The problemati code does not compile: +// (null as Null).greet() + Null.greet() +} \ No newline at end of file diff --git a/docs/exPuzzlers/src/_06_classy/_55_Creationism/BUG b/docs/exPuzzlers/src/_06_classy/_55_Creationism/BUG new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.java b/docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.java new file mode 100644 index 00000000000..1c6d57869bd --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.java @@ -0,0 +1,21 @@ +package _06_classy._55_Creationism; + +public class Creator { + public static void main(String[] args) { +// for (int i = 0; i < 100; i++) +// Creature creature = new Creature(); + System.out.println(Creature.numCreated()); + } +} + +class Creature { + private static long numCreated = 0; + + public Creature() { + numCreated++; + } + + public static long numCreated() { + return numCreated; + } +} diff --git a/docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.kt b/docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.kt new file mode 100644 index 00000000000..ca14d6e801a --- /dev/null +++ b/docs/exPuzzlers/src/_06_classy/_55_Creationism/Creator.kt @@ -0,0 +1,21 @@ +namespace creationism + +import std.io.* +import std.* + +class Creature() { + class object { + var numCreated = 0 + private set + } + + { +// Creature.numCreated++ + } +} + + +fun main(args : Array) { +// for (i in 1..100) +// val creature = Creature() +} \ No newline at end of file diff --git a/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BUG b/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BUG new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.java b/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.java new file mode 100644 index 00000000000..4c49110c285 --- /dev/null +++ b/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.java @@ -0,0 +1,18 @@ +package _07_library._56_Big_Problem; + +import java.math.BigInteger; + +public class BigProblem { + public static void main(String[] args) { + BigInteger fiveThousand = new BigInteger("5000"); + BigInteger fiftyThousand = new BigInteger("50000"); + BigInteger fiveHundredThousand + = new BigInteger("500000"); + + BigInteger total = BigInteger.ZERO; + total.add(fiveThousand); + total.add(fiftyThousand); + total.add(fiveHundredThousand); + System.out.println(total); + } +} diff --git a/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.kt b/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.kt new file mode 100644 index 00000000000..815ffe9b105 --- /dev/null +++ b/docs/exPuzzlers/src/_07_library/_56_Big_Problem/BigProblem.kt @@ -0,0 +1,26 @@ +namespace big.problem + +import std.io.* +import std.* +import java.math.BigInteger + +fun main(args : Array) { + val fiveThousand = "5000".bi() + val fiftyThousand = "50000".bi() + val fiveHundredThousand = "500000".bi() + + val total : BigInteger = "0".bi()//BigInteger.ZERO + total + fiveThousand + total + fiftyThousand + total + fiveHundredThousand + println(total) // No surprise + + var total1 : BigInteger = "0".bi()//BigInteger.ZERO + total1 += fiveThousand + total1 += fiftyThousand + total1 += fiveHundredThousand + println(total1) // Works +} + +inline fun String.bi() : BigInteger = BigInteger(this) +inline fun BigInteger.plus(other : BigInteger) = this add other \ No newline at end of file diff --git a/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/BUG b/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/BUG new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.java b/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.java new file mode 100644 index 00000000000..3f2bc5cdc8f --- /dev/null +++ b/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.java @@ -0,0 +1,15 @@ +package _07_library._59_Whats_the_Difference; + +import java.util.*; + +public class Differences { + public static void main(String[] args) { + int vals[] = { 789, 678, 567, 456, 345, 234, 123, 012 }; + Set diffs = new HashSet(); + + for (int i = 0; i < vals.length; i++) + for (int j = i; j < vals.length; j++) + diffs.add(vals[i] - vals[j]); + System.out.println(diffs.size()); + } +} diff --git a/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.kt b/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.kt new file mode 100644 index 00000000000..c1afb5184f6 --- /dev/null +++ b/docs/exPuzzlers/src/_07_library/_59_Whats_the_Difference/Differences.kt @@ -0,0 +1,20 @@ +namespace whats.the.difference + +import std.io.* +import std.* +import java.util.* + +fun iarray(vararg a : Int) = a // BUG + +fun main(args : Array) { + // Problematic code does not compile +// val vals = iarray(789, 678, 567, 456, 345, 234, 123, 012) + val vals = iarray(789, 678, 567, 456, 345, 234, 123, 12) + val diffs = HashSet + for (i in vals.indices) + for (j in i..vals.lastIndex()) + diffs.add(vals[i] - vals[j]) + println(diffs.size()) +} + +fun IntArray.lastIndex() = size - 1 \ No newline at end of file From cb37f7b56f9679279cc9f83864eb7067abadb0d9 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 23 Nov 2011 09:56:20 +0200 Subject: [PATCH 02/22] ability to test stdlib --- .../jet/codegen/GenerationState.java | 14 ++++ .../jet/compiler/CompileSession.java | 5 ++ .../testData/codegen/inputStreamIterator.jet | 13 +--- .../org/jetbrains/jet/JetLiteFixture.java | 2 +- .../jet/codegen/CodegenTestCase.java | 17 ++--- .../org/jetbrains/jet/codegen/StdlibTest.java | 67 ++++++++++++++++--- stdlib/ktSrc/StandardLibrary.kt | 17 ++--- 7 files changed, 94 insertions(+), 41 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 52e37842318..56b432cf2c9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -157,4 +157,18 @@ public class GenerationState { }); } + public String createText() { + StringBuilder answer = new StringBuilder(); + + final ClassFileFactory factory = getFactory(); + List files = factory.files(); + for (String file : files) { + if (!file.startsWith("std/")) { + answer.append("@").append(file).append('\n'); + answer.append(factory.asText(file)); + } + } + + return answer.toString(); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java index 7f643b90d14..e90fda9eb8a 100644 --- a/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java +++ b/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java @@ -99,4 +99,9 @@ public class CompileSession { return generationState.getFactory(); } + public String generateText() { + GenerationState generationState = new GenerationState(myEnvironment.getProject(), ClassBuilderFactory.TEXT); + generationState.compileCorrectNamespaces(myBindingContext, mySourceFileNamespaces); + return generationState.createText(); + } } diff --git a/compiler/testData/codegen/inputStreamIterator.jet b/compiler/testData/codegen/inputStreamIterator.jet index 2c1d4e89857..7be02b077f2 100644 --- a/compiler/testData/codegen/inputStreamIterator.jet +++ b/compiler/testData/codegen/inputStreamIterator.jet @@ -1,16 +1,7 @@ +import std.io.* + import java.io.* -val ByteArray.inputStream : ByteArrayInputStream - get() = ByteArrayInputStream(this) - -fun InputStream.iterator() : ByteIterator = - object: ByteIterator() { - override val hasNext : Boolean - get() = available() > 0 - - override fun nextByte() = read().byt - } - fun box() : String { val x = ByteArray (10) diff --git a/compiler/tests/org/jetbrains/jet/JetLiteFixture.java b/compiler/tests/org/jetbrains/jet/JetLiteFixture.java index f975ba79778..3ed62e38ddb 100644 --- a/compiler/tests/org/jetbrains/jet/JetLiteFixture.java +++ b/compiler/tests/org/jetbrains/jet/JetLiteFixture.java @@ -28,7 +28,7 @@ public abstract class JetLiteFixture extends UsefulTestCase { @NonNls protected final String myFullDataPath; protected JetFile myFile; - private JetCoreEnvironment myEnvironment; + protected JetCoreEnvironment myEnvironment; public JetLiteFixture(@NonNls String dataPath) { myFullDataPath = getTestDataPath() + "/" + dataPath; diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 45723092fcd..8c584e9cc26 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -93,25 +93,16 @@ public abstract class CodegenTestCase extends JetLiteFixture { final JetNamespace namespace = myFile.getRootNamespace(); String fqName = NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace)).replace("/", "."); Class namespaceClass = loader.loadClass(fqName); - Method method = namespaceClass.getMethod("box"); - return (String) method.invoke(null); - } + Method method = namespaceClass.getMethod("box"); + return (String) method.invoke(null); + } protected String generateToText() { GenerationState state = new GenerationState(getProject(), ClassBuilderFactory.TEXT); AnalyzingUtils.checkForSyntacticErrors(myFile); state.compile(myFile); - StringBuilder answer = new StringBuilder(); - - final ClassFileFactory factory = state.getFactory(); - List files = factory.files(); - for (String file : files) { - answer.append("@").append(file).append('\n'); - answer.append(factory.asText(file)); - } - - return answer.toString(); + return state.createText(); } protected Class generateNamespaceClass() { diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index 1e3f514a26a..14ee5b98b5b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -1,25 +1,76 @@ package org.jetbrains.jet.codegen; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import org.jetbrains.jet.compiler.CompileSession; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.parsing.JetParsingTest; -import java.lang.reflect.Method; +import java.io.File; +import java.io.IOException; +import java.util.List; /** * @author alex.tkachman */ public class StdlibTest extends CodegenTestCase { - public void testLib () throws ClassNotFoundException { + @Override + protected void setUp() throws Exception { + super.setUp(); createEnvironmentWithFullJdk(); - loadFile("../../../stdlib/ktSrc/StandardLibrary.kt"); - ClassFileFactory codegens = generateClassesInFile(); - GeneratedClassLoader loader = new GeneratedClassLoader(codegens); + } + + protected String generateToText() { + CompileSession session = new CompileSession(myEnvironment); - final JetNamespace namespace = myFile.getRootNamespace(); - String fqName = NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace)).replace("/", "."); - Class namespaceClass = loader.loadClass(fqName); + session.addSources(myFile.getVirtualFile()); + try { + session.addSources(addStdLib()); + } catch (IOException e) { + throw new RuntimeException(e); + } + + if (!session.analyze(System.out)) { + return null; + } + + return session.generateText(); + } + + protected ClassFileFactory generateClassesInFile() { + try { + CompileSession session = new CompileSession(myEnvironment); + + session.addSources(myFile.getVirtualFile()); + session.addSources(addStdLib()); + + if (!session.analyze(System.out)) { + return null; + } + + return session.generate(); + } catch (RuntimeException e) { + System.out.println(generateToText()); + throw e; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private VirtualFile addStdLib() throws IOException { + String text = FileUtil.loadFile(new File(JetParsingTest.getTestDataDir() + "/../../stdlib/ktSrc/StandardLibrary.kt"), CharsetToolkit.UTF8).trim(); + text = StringUtil.convertLineSeparators(text); + PsiFile stdLibFile = createFile("StandardLibrary.kt", text); + return stdLibFile.getVirtualFile(); } public void testInputStreamIterator () { blackBoxFile("inputStreamIterator.jet"); + System.out.println(generateToText()); } } diff --git a/stdlib/ktSrc/StandardLibrary.kt b/stdlib/ktSrc/StandardLibrary.kt index 3fc3bffbcf0..86d4b033c29 100644 --- a/stdlib/ktSrc/StandardLibrary.kt +++ b/stdlib/ktSrc/StandardLibrary.kt @@ -30,7 +30,15 @@ namespace io { val ByteArray.inputStream : ByteArrayInputStream get() = ByteArrayInputStream(this) - inline fun ByteArray.inputStream(offset: Int, length: Int) : ByteArrayInputStream = ByteArrayInputStream(this, offset, length) +// inline fun ByteArray.inputStream(offset: Int, length: Int) = ByteArrayInputStream(this, offset, length) + + fun InputStream.iterator() : ByteIterator = + object: ByteIterator() { + override val hasNext : Boolean + get() = available() > 0 + + override fun nextByte() = read().byt + } val InputStream.buffered : BufferedInputStream get() = if(this is BufferedInputStream) this else BufferedInputStream(this) @@ -53,13 +61,6 @@ namespace io { inline fun InputStream.reader(charsetDecoder: CharsetDecoder) = InputStreamReader(this, charsetDecoder) */ - fun InputStream.iterator() : ByteIterator = object: ByteIterator() { - override val hasNext : Boolean - get() = available() > 0 - - override fun nextByte() = read().byt - } - // val Reader.buffered : BufferedReader // get() = if(this instanceof BufferedReader) this else BufferedReader(this) From 1c6c5d2bdcd09741b615c89e4c33e01a0e25f1d1 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 23 Nov 2011 10:14:13 +0200 Subject: [PATCH 03/22] test for unreproducable kt533 --- .../testData/codegen/regressions/kt533.kt | 134 ++++++++++++++++++ .../org/jetbrains/jet/codegen/StdlibTest.java | 4 + stdlib/ktSrc/StandardLibrary.kt | 6 +- 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt533.kt diff --git a/compiler/testData/codegen/regressions/kt533.kt b/compiler/testData/codegen/regressions/kt533.kt new file mode 100644 index 00000000000..05e55878b81 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt533.kt @@ -0,0 +1,134 @@ +namespace mask + +import std.io.* +import java.io.* +import java.util.* + +fun box() : String { + val input = StringReader("/Users/abreslav/work/jet/docs/luhnybin/src/test") + + val luhny = Luhny() + input.forEachChar { + luhny.charIn(it) + } + luhny.printAll() + return "OK" + +} + +class Luhny() { + val buffer = LinkedList() + val digits = LinkedList() + + var toBeMasked = 0 + + fun charIn(it : Char) { + buffer.push(it) + when (it) { + .isDigit() => digits.push(it.int - '0'.int) + ' ', '-' => {} + else => { + printAll() + digits.clear() + } + } + if (digits.size() > 16) + printOneDigit() + check() + } + + fun check() { + if (digits.size() < 14) return + val sum = digits.sum { i, d => + if (i % 2 != 0) + d * 2 / 10 + d * 2 % 10 + else d + } + if (sum % 10 == 0) toBeMasked = digits.size() + } + + fun printOneDigit() { + while (!buffer.isEmpty()) { + val c = buffer.pop() + out(c) + if (c.isDigit()) { + digits.pop() + return + } + } + } + + fun printAll() { + while (!buffer.isEmpty()) + out(buffer.pop()) + } + + fun out(c : Char) { + if (toBeMasked > 0) { + print('X') + toBeMasked-- + } + else { + print(c) + } + } +} + +fun LinkedList.sum(f : fun(Int, Int) : Int) : Int { + var sum = 0 + var i = 0 + for (d in backwards()) { + sum += f(i, d) + i++ + } + return sum +} + +fun List.backwards() : Iterable = object : Iterable { + override fun iterator() : Iterator = + object : Iterator { + var current = size() + override fun next() : T = get(--current) + override val hasNext : Boolean get() = current > 0 + } +} + +fun Char.isDigit() = Character.isDigit(this) + +//class Queue(initialBufSize : Int) { +// +// private var bufSize = initialBufSize +// private val buf = Array(initialBufSize) +// private var head = 0 +// private var tail = 0 +// private var size = 0 +// +// val empty : Boolean get() = size == 0 +// +// private fun prev(i : Int) = (bufSize + i - 1) % bufSize +// private fun next(i : Int) = (i + 1) % bufSize +// +// fun push(c : T) { +// buf[tail] = c +// tail = prev(tail) +// size++ +// } +// +// fun pop() : T { +// if (size == 0) throw IllegalStateException() +// size-- +// val result = buf[head] +// head = prev(head) +// return result +// } +// +// fun clear() {} +//} + +fun Reader.forEachChar(body : fun(Char) : Unit) { + do { + var i = read(); + if (i == -1) break + body(i.chr) + } while(true) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index 14ee5b98b5b..d0a46de0a7c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -73,4 +73,8 @@ public class StdlibTest extends CodegenTestCase { blackBoxFile("inputStreamIterator.jet"); System.out.println(generateToText()); } + + public void testKt533 () { + blackBoxFile("regressions/kt533.kt"); + } } diff --git a/stdlib/ktSrc/StandardLibrary.kt b/stdlib/ktSrc/StandardLibrary.kt index 86d4b033c29..999cecbad2c 100644 --- a/stdlib/ktSrc/StandardLibrary.kt +++ b/stdlib/ktSrc/StandardLibrary.kt @@ -48,8 +48,8 @@ namespace io { val InputStream.reader : InputStreamReader get() = InputStreamReader(this) -// val InputStream.bufferedReader : BufferedReader -// get() = buffered.reader + val InputStream.bufferedReader : BufferedReader + get() = BufferedReader(reader) /* inline fun InputStream.reader(charset: Charset) : InputStreamReader = InputStreamReader(this, charset) @@ -66,6 +66,8 @@ namespace io { // inline fun Reader.buffered(bufferSize: Int) = BufferedReader(this, bufferSize) +// val String.reader = StringReader(this) + private val stdin : BufferedReader = BufferedReader(InputStreamReader(object : InputStream() { override fun read() : Int { return System.`in`?.read() ?: -1 From 8c842a6d5cbb21f900e56f54253059f2872835f3 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 23 Nov 2011 11:20:33 +0200 Subject: [PATCH 04/22] KT-529 wrong naming of anonimous classes --- .../jetbrains/jet/codegen/ClosureCodegen.java | 2 +- .../jet/codegen/ExpressionCodegen.java | 5 +- .../jetbrains/jet/codegen/JetTypeMapper.java | 5 + .../testData/codegen/regressions/kt529.kt | 98 +++++++++++++++++++ .../org/jetbrains/jet/codegen/StdlibTest.java | 4 + stdlib/ktSrc/StandardLibrary.kt | 10 ++ 6 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt529.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index c38fa4541cf..9fdb7b1f309 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -224,7 +224,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { int i = 0; if (captureThis) { - argTypes[i++] = Type.getObjectType(context.getThisDescriptor().getName()); + argTypes[i++] = state.getTypeMapper().mapType(context.getThisDescriptor().getDefaultType()); } if (captureReceiver != null) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1167da9c208..e69555a882b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -608,17 +608,20 @@ public class ExpressionCodegen extends JetVisitor { final Method cons = closure.getConstructor(); + int k = 0; if (closure.isCaptureThis()) { + k++; v.load(0, JetTypeMapper.TYPE_OBJECT); } if (closure.isCaptureReceiver() != null) { + k++; v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0: 1, closure.isCaptureReceiver()); } for (int i = 0; i < closure.getArgs().size(); i++) { StackValue arg = closure.getArgs().get(i); - arg.put(cons.getArgumentTypes()[i], v); + arg.put(cons.getArgumentTypes()[i+k], v); } v.invokespecial(closure.getClassname(), "", cons.getDescriptor()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 16a4a1b2430..9e5dbb5637f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -173,6 +173,11 @@ public class JetTypeMapper { public String getFQName(DeclarationDescriptor descriptor) { descriptor = descriptor.getOriginal(); + + if(descriptor instanceof FunctionDescriptor) { + return getFQName(descriptor.getContainingDeclaration()); + } + DeclarationDescriptor container = descriptor.getContainingDeclaration(); String name = descriptor.getName(); if(JetPsiUtil.NO_NAME_PROVIDED.equals(name)) { diff --git a/compiler/testData/codegen/regressions/kt529.kt b/compiler/testData/codegen/regressions/kt529.kt new file mode 100644 index 00000000000..66487f37509 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt529.kt @@ -0,0 +1,98 @@ +namespace mask + +import std.io.* +import java.io.* +import java.util.* + +fun box() : String { + val input = StringReader("/Users/abreslav/work/jet/docs/luhnybin/src/test") + + val luhny = Luhny() + input.forEachChar { + luhny.process(it) + } + luhny.printAll() + return "OK" +} + +class Luhny() { + private val buffer = ArrayDeque() + private val digits = ArrayDeque(16) + + private var toBeMasked = 0 + + fun process(it : Char) { + buffer.addLast(it) + when (it) { + .isDigit() => digits.addLast(it.int - '0'.int) + ' ', '-' => {} + else => printAll() + } + if (digits.size() > 16) + printOneDigit() + check() + } + + private fun check() { + val size = digits.size() + if (size < 14) return + val sum = digits.sum {i, d => + if (i % 2 == size % 2) double(d) else d + } +// var sum = 0 +// var i = 0 +// for (d in digits) { +// sum += if (i % 2 == size % 2) double(d) else d +// i++ +// } + if (sum % 10 == 0) toBeMasked = digits.size() + } + + private fun double(d : Int) = d * 2 / 10 + d * 2 % 10 + + private fun printOneDigit() { + while (!buffer.isEmpty()) { + val c = buffer.removeFirst() + print(c) + if (c.isDigit()) { + digits.removeFirst() + return + } + } + } + + private fun printAll() { + while (!buffer.isEmpty()) + print(buffer.removeFirst()) + digits.clear() + } + + private fun print(c : Char) { + if (c.isDigit() && toBeMasked > 0) { + std.io.print('X') + toBeMasked-- + } else { + std.io.print(c) + } + } +} + +fun Char.isDigit() = Character.isDigit(this) + +fun java.lang.Iterable.sum(f : fun(index : Int, value : Int) : Int) : Int { + var sum = 0 + var i = 0 + for (d in this) { + sum += f(i, d) + i++ + } + return sum +} + +fun Reader.forEachChar(body : fun(Char) : Unit) { + do { + var i = read(); + if (i == -1) break + body(i.chr) + } while(true) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index d0a46de0a7c..86a7f1d1e31 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -77,4 +77,8 @@ public class StdlibTest extends CodegenTestCase { public void testKt533 () { blackBoxFile("regressions/kt533.kt"); } + + public void testKt529 () { + blackBoxFile("regressions/kt529.kt"); + } } diff --git a/stdlib/ktSrc/StandardLibrary.kt b/stdlib/ktSrc/StandardLibrary.kt index 999cecbad2c..53d594e313a 100644 --- a/stdlib/ktSrc/StandardLibrary.kt +++ b/stdlib/ktSrc/StandardLibrary.kt @@ -1,5 +1,15 @@ namespace std +namespace util { + import java.util.* + + val Collection.size : Int + get() = size() + + val Collection.empty : Boolean + get() = isEmpty() +} + namespace io { import java.io.* import java.nio.charset.* From b8f942857b184141639d350c1dd84c0c29f9644b Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 23 Nov 2011 11:56:47 +0200 Subject: [PATCH 05/22] KT-594 Array.get/set intrinsic --- .../jetbrains/jet/codegen/JetTypeMapper.java | 2 +- .../jet/codegen/intrinsics/ArrayGet.java | 28 +++++++++++++++++ .../jet/codegen/intrinsics/ArraySet.java | 30 +++++++++++++++++++ .../codegen/intrinsics/IntrinsicMethods.java | 22 ++++++++++++++ .../testData/codegen/regressions/kt594.jet | 16 ++++++++++ .../jetbrains/jet/codegen/ArrayGenTest.java | 6 ++++ 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java create mode 100644 compiler/testData/codegen/regressions/kt594.jet diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 9e5dbb5637f..16a49a0d746 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -129,7 +129,7 @@ public class JetTypeMapper { return type; } - static Type correctElementType(Type type) { + public static Type correctElementType(Type type) { String internalName = type.getInternalName(); assert internalName.charAt(0) == '['; return Type.getType(internalName.substring(1)); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java new file mode 100644 index 00000000000..6099a85aa08 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java @@ -0,0 +1,28 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.JetTypeMapper; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; + +import java.util.List; + +/** + * @author alex.tkachman + */ +public class ArrayGet implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { + receiver.put(JetTypeMapper.TYPE_OBJECT, v); + Type type = JetTypeMapper.correctElementType(receiver.type); + + codegen.gen(arguments.get(0), Type.INT_TYPE); + + v.aload(type); + + return StackValue.onStack(type); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java new file mode 100644 index 00000000000..08443a994f7 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.jet.codegen.CodegenUtil; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.JetTypeMapper; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; + +import java.util.List; + +/** + * @author alex.tkachman + */ +public class ArraySet implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { + receiver.put(JetTypeMapper.TYPE_OBJECT, v); + Type type = JetTypeMapper.correctElementType(receiver.type); + + codegen.gen(arguments.get(0), Type.INT_TYPE); + codegen.gen(arguments.get(1), type); + + v.astore(type); + + return StackValue.none(); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 66551a76349..a75db2d5a37 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -36,6 +36,8 @@ public class IntrinsicMethods { public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices(); public static final Equals EQUALS = new Equals(); public static final IteratorNext ITERATOR_NEXT = new IteratorNext(); + public static final ArraySet ARRAY_SET = new ArraySet(); + public static final ArrayGet ARRAY_GET = new ArrayGet(); private final Project myProject; private final JetStandardLibrary myStdLib; @@ -122,6 +124,26 @@ public class IntrinsicMethods { declareIntrinsicProperty("CharArray", "indices", ARRAY_INDICES); declareIntrinsicProperty("BooleanArray", "indices", ARRAY_INDICES); + declareIntrinsicFunction("Array", "set", 2, ARRAY_SET); + declareIntrinsicFunction("ByteArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("ShortArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("IntArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("LongArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("FloatArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("DoubleArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("CharArray", "set", 2, ARRAY_SET); + declareIntrinsicFunction("BooleanArray", "set", 2, ARRAY_SET); + + declareIntrinsicFunction("Array", "get", 1, ARRAY_GET); + declareIntrinsicFunction("ByteArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("ShortArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("IntArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("LongArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("FloatArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("DoubleArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("CharArray", "get", 1, ARRAY_GET); + declareIntrinsicFunction("BooleanArray", "get", 1, ARRAY_GET); + declareIterator(myStdLib.getArray()); declareIterator(myStdLib.getByteArrayClass()); declareIterator(myStdLib.getShortArrayClass()); diff --git a/compiler/testData/codegen/regressions/kt594.jet b/compiler/testData/codegen/regressions/kt594.jet new file mode 100644 index 00000000000..70d94715100 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt594.jet @@ -0,0 +1,16 @@ +namespace array_test + +fun box() : String { + var array : IntArray? = IntArray(10) + array?.set(0, 3) + if(array?.get(0) != 3) return "fail" + + var a = Array?>(5) + var b = Array(1) + b.set(0, "239") + a?.set(0, b) + + if(a?.get(0)?.get(0) != "239") return "fail" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java index c611dad097d..80063a36516 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java @@ -275,4 +275,10 @@ public class ArrayGenTest extends CodegenTestCase { public void testKt503() { blackBoxFile("regressions/kt503.jet"); } + + public void testKt594() throws Exception { + loadFile("regressions/kt594.jet"); + System.out.println(generateToText()); + blackBox(); + } } From ba700ebdbe9ed173cce08b4648f936d41ead92ab Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 23 Nov 2011 12:19:43 +0200 Subject: [PATCH 06/22] test for unreproducable KT-528 --- .../testData/codegen/regressions/kt528.kt | 118 ++++++++++++++++++ .../org/jetbrains/jet/codegen/StdlibTest.java | 4 + 2 files changed, 122 insertions(+) create mode 100644 compiler/testData/codegen/regressions/kt528.kt diff --git a/compiler/testData/codegen/regressions/kt528.kt b/compiler/testData/codegen/regressions/kt528.kt new file mode 100644 index 00000000000..456f55d04be --- /dev/null +++ b/compiler/testData/codegen/regressions/kt528.kt @@ -0,0 +1,118 @@ +namespace mask + +import std.io.* +import java.io.* +import java.util.* +import java.util.Iterator as It +import java.lang.Iterable as Itl + +fun box() : String { + val input = StringReader("/Users/abreslav/work/jet/docs/luhnybin/src/test") + + val luhny = Luhny() + input.forEachChar { + luhny.charIn(it) + } + luhny.printAll() + return "OK" +} + +class Luhny() { + val buffer = LinkedList() + val digits = LinkedList() + + var toBeMasked = 0 + + fun charIn(it : Char) { + buffer.addLast(it) + when (it) { + .isDigit() => digits.addLast(it.int - '0'.int) + ' ', '-' => {} + else => { + printAll() + digits.clear() + } + } + if (digits.size() > 16) + printOneDigit() + check() + } + + fun check() { + if (digits.size() < 14) return + print("check") + val sum = digits.sum { i, d => +// println("$i -> $d") + if (i % 2 == digits.size()) { + val f = d * 2 / 10 + val s = d * 2 % 10 +// println("$d: f = $f, s = $s") + (f + s).pr { +// println("to be doubled: $i -> $d : $it") + } + } else d + } +// println(sum) + if (sum % 10 == 0) {print("s"); toBeMasked = digits.size()} + } + + fun printOneDigit() { + while (!buffer.isEmpty()) { + val c = buffer.removeFirst() + out(c) + if (c.isDigit()) { + digits.removeFirst() + return + } + } + } + + fun printAll() { + while (!buffer.isEmpty()) + out(buffer.removeFirst()) + } + + fun out(c : Char) { + if (toBeMasked > 0) { + print('X') + toBeMasked-- + } + else { + print(c) + } + } +} + +fun T.pr(f : fun(T) : Unit) : T { + f(this) + return this +} + +fun LinkedList.sum(f : fun(Int, Int ): Int): Int { + var sum = 0 + for (i in 1..size()) { + val j = size() - i + sum += f(j, get(j)) + } + return sum +} + +//fun List.backwards() : Itl = object : Itl { +// override fun iterator() : It = +// object : It { +// var current = size() +// override fun next() : T = get(--current) +// override fun hasNext() : Boolean = current > 0 +// override fun remove() {throw UnsupportedOperationException()} +// } +//} + +fun Char.isDigit() = Character.isDigit(this) + +fun Reader.forEachChar(body : fun(Char) : Unit) { + do { + var i = read(); + if (i == -1) break + body(i.chr) + } while(true) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index 86a7f1d1e31..fdfbbecfa5b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -81,4 +81,8 @@ public class StdlibTest extends CodegenTestCase { public void testKt529 () { blackBoxFile("regressions/kt529.kt"); } + + public void testKt528 () { + blackBoxFile("regressions/kt528.kt"); + } } From e33af7f7295aadab2e9cdc2941bbb57d6113bfdd Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 23 Nov 2011 16:40:50 +0400 Subject: [PATCH 07/22] KT-328 Local function in function literals cause exceptions === fun bar() = { bar() } === --- .../jet/lang/resolve/BodyResolver.java | 17 +++++++++++++++-- .../jet/resolve/DescriptorRenderer.java | 1 + .../full/RecursiveTypeInference.jet | 10 +++++----- .../quick/regressions/kt328.jet | 3 +++ .../quick/regressions/kt328Complex.jet | 3 +++ .../regressions/kt328DuplicatedByKt329.jet | 7 +++++++ .../testData/checker/RecursiveTypeInference.jet | 12 ++++++------ 7 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/kt328.jet create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/kt328Complex.jet create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/kt328DuplicatedByKt329.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index ef5e309947f..7637f611a8e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -82,7 +82,7 @@ public class BodyResolver { resolveSecondaryConstructorBodies(); resolveFunctionBodies(); - computeDeferredTypes(); + computeDeferredTypes(); } private void resolveDelegationSpecifierLists() { @@ -501,6 +501,18 @@ public class BodyResolver { for (Map.Entry entry : this.context.getFunctions().entrySet()) { JetNamedFunction declaration = entry.getKey(); FunctionDescriptor descriptor = entry.getValue(); + + if (descriptor.getReturnType() instanceof DeferredType) { + // handle type inference loop: function body contains a closure that calls that function + // + // fun f() = { f() } + // + // function type resolution must be started before function body resolution + // + + DeferredType returnType = (DeferredType) descriptor.getReturnType(); + returnType.getActualType(); + } JetScope declaringScope = this.context.getDeclaringScopes().get(declaration); assert declaringScope != null; @@ -545,7 +557,8 @@ public class BodyResolver { private void computeDeferredTypes() { Collection> deferredTypes = context.getTrace().getKeys(DEFERRED_TYPE); if (deferredTypes != null) { - final Queue queue = new Queue(deferredTypes.size()); + // +1 is a work around agains new Queue(0).addLast(...) bug // stepan.koltsov@ 2011-11-21 + final Queue queue = new Queue(deferredTypes.size() + 1); context.getTrace().addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler, Boolean>() { @Override public void handleRecord(WritableSlice, Boolean> deferredTypeKeyDeferredTypeWritableSlice, Box key, Boolean value) { diff --git a/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java b/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java index b744988a594..a378e31d39b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java +++ b/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java @@ -222,6 +222,7 @@ public class DescriptorRenderer implements Renderer { renderName(descriptor, builder); renderValueParameters(descriptor, builder); + // TODO: getReturnType may be uninitialized and throw IllegalStateException // stepan.koltsov@ 2011-11-21 builder.append(" : ").append(escape(renderType(descriptor.getReturnType()))); return super.visitFunctionDescriptor(descriptor, builder); } diff --git a/compiler/testData/checkerWithErrorTypes/full/RecursiveTypeInference.jet b/compiler/testData/checkerWithErrorTypes/full/RecursiveTypeInference.jet index 11eb880a193..0a6a5b1e2e7 100644 --- a/compiler/testData/checkerWithErrorTypes/full/RecursiveTypeInference.jet +++ b/compiler/testData/checkerWithErrorTypes/full/RecursiveTypeInference.jet @@ -5,15 +5,15 @@ namespace a { } namespace b { - fun foo() = bar() + fun foo() = bar() - fun bar() = foo() + fun bar() = foo() } namespace c { - fun bazz() = bar() + fun bazz() = bar() - fun foo() = bazz() + fun foo() = bazz() fun bar() = foo() } @@ -39,4 +39,4 @@ namespace ok { fun bar() = foo() } -} \ No newline at end of file +} diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328.jet new file mode 100644 index 00000000000..2593c440b51 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328.jet @@ -0,0 +1,3 @@ +fun bar() = { + bar() +} diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328Complex.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328Complex.jet new file mode 100644 index 00000000000..9caa6193206 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328Complex.jet @@ -0,0 +1,3 @@ +fun bar() = { + fun foo() = bar() +} diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328DuplicatedByKt329.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328DuplicatedByKt329.jet new file mode 100644 index 00000000000..35a66da2884 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt328DuplicatedByKt329.jet @@ -0,0 +1,7 @@ +// http://youtrack.jetbrains.net/issue/KT-329 + +fun block(f : fun() : Unit) = f() + +fun bar() = block{ foo() // <-- missing closing curly bracket +fun foo() = block{ bar() } + diff --git a/idea/testData/checker/RecursiveTypeInference.jet b/idea/testData/checker/RecursiveTypeInference.jet index a73cf01cc0e..c8e0006f350 100644 --- a/idea/testData/checker/RecursiveTypeInference.jet +++ b/idea/testData/checker/RecursiveTypeInference.jet @@ -1,19 +1,19 @@ namespace a { - val foo = bar() + val foo = bar() fun bar() = foo } namespace b { - fun foo() = bar() + fun foo() = bar() - fun bar() = foo() + fun bar() = foo() } namespace c { - fun bazz() = bar() + fun bazz() = bar() - fun foo() = bazz() + fun foo() = bazz() fun bar() = foo() } @@ -39,4 +39,4 @@ namespace ok { fun bar() = foo() } -} \ No newline at end of file +} From 8222011874d6177e1e24f0750518271d6213758c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 23 Nov 2011 17:08:47 +0400 Subject: [PATCH 08/22] +-JDK and -NOSTDLIB options FullJetPsiCheckerTest has -JDK option QuickJetPsiCheckerTest has +JDK option FullJetPsiCheckerTest = QuickJetPsiCheckerTest with +JDK QuickJetPsiCheckerTest = FullJetPsiCheckerTest with -JDK --- .../jet/codegen/GenerationState.java | 4 +- .../jet/compiler/CompileSession.java | 2 +- .../jet/lang/resolve/java/AnalyzerFacade.java | 2 +- .../jet/lang/JetSemanticServices.java | 6 ++- .../jet/lang/resolve/AnalyzingUtils.java | 10 ++-- .../jet/lang/types/JetStandardLibrary.java | 50 ++++++++++++++----- .../checkerWithErrorTypes/full/Casts.jet | 4 +- .../jet/checkers/CheckerTestUtilTest.java | 2 +- .../jet/checkers/FullJetPsiCheckerTest.java | 11 +++- .../jet/checkers/QuickJetPsiCheckerTest.java | 8 ++- .../jetbrains/jet/resolve/JetResolveTest.java | 2 +- .../jet/plugin/compiler/JetCompiler.java | 2 +- .../jet/plugin/java/JavaElementFinder.java | 2 +- 13 files changed, 77 insertions(+), 28 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 56b432cf2c9..c106eeaed70 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -30,7 +30,7 @@ public class GenerationState { public GenerationState(Project project, ClassBuilderFactory builderFactory) { this.project = project; - this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project); + this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project, true); this.factory = new ClassFileFactory(builderFactory, this); this.intrinsics = new IntrinsicMethods(project, standardLibrary); } @@ -82,7 +82,7 @@ public class GenerationState { public void compile(JetFile psiFile) { final JetNamespace namespace = psiFile.getRootNamespace(); - final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY); + final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY); AnalyzingUtils.throwExceptionOnErrors(bindingContext); compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace)); // NamespaceCodegen codegen = forNamespace(namespace); diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java index e90fda9eb8a..43f4661b726 100644 --- a/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java +++ b/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java @@ -84,7 +84,7 @@ public class CompileSession { } return false; } - final AnalyzingUtils instance = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS); + final AnalyzingUtils instance = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true); List allNamespaces = new ArrayList(mySourceFileNamespaces); allNamespaces.addAll(myLibrarySourceFileNamespaces); myBindingContext = instance.analyzeNamespaces(myEnvironment.getProject(), allNamespaces, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java index 6ad38396927..9be40fce997 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java @@ -34,7 +34,7 @@ public class AnalyzerFacade { } }; - private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS); + private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true); private final static Key> BINDING_CONTEXT = Key.create("BINDING_CONTEXT"); private static final Object lock = new Object(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java index 5a73728db37..c666125cd19 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java @@ -17,7 +17,11 @@ public class JetSemanticServices { } public static JetSemanticServices createSemanticServices(Project project) { - return new JetSemanticServices(JetStandardLibrary.getJetStandardLibrary(project)); + return createSemanticServices(project, true); + } + + public static JetSemanticServices createSemanticServices(Project project, boolean loadFullLibrary) { + return new JetSemanticServices(JetStandardLibrary.getJetStandardLibrary(project, loadFullLibrary)); } private final JetStandardLibrary standardLibrary; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index 483a5673739..2eb18914627 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -28,8 +28,8 @@ import java.util.*; * @author abreslav */ public class AnalyzingUtils { - public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy) { - return new AnalyzingUtils(importingStrategy); + public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy, boolean loadStdlib) { + return new AnalyzingUtils(importingStrategy, loadStdlib); } public static void checkForSyntacticErrors(@NotNull PsiElement root) { @@ -53,9 +53,11 @@ public class AnalyzingUtils { } private final ImportingStrategy importingStrategy; + private final boolean loadStdlib; - private AnalyzingUtils(ImportingStrategy importingStrategy) { + private AnalyzingUtils(ImportingStrategy importingStrategy, boolean loadStdlib) { this.importingStrategy = importingStrategy; + this.loadStdlib = loadStdlib; } public BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { @@ -71,7 +73,7 @@ public class AnalyzingUtils { @NotNull Predicate filesToAnalyzeCompletely, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { BindingTraceContext bindingTraceContext = new BindingTraceContext(); - JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project); + JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, loadStdlib); JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope(); ModuleDescriptor owner = new ModuleDescriptor(""); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index 62923713125..c90e935e043 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -29,16 +29,24 @@ import java.util.Set; public class JetStandardLibrary { // TODO : consider releasing this memory - private static JetStandardLibrary cachedLibrary = null; + private static JetStandardLibrary cachedFullLibrary = null; + private static JetStandardLibrary cachedQuickLibrary = null; // private static final Map standardLibraryCache = new HashMap(); // TODO : double checked locking synchronized - public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project) { - if (cachedLibrary == null) { - cachedLibrary = new JetStandardLibrary(project); + public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project, boolean loadFullLibrary) { + if (loadFullLibrary) { + if (cachedFullLibrary == null) { + cachedFullLibrary = new JetStandardLibrary(project, true); + } + return cachedFullLibrary; + } else { + if (cachedQuickLibrary == null) { + cachedQuickLibrary = new JetStandardLibrary(project, false); + } + return cachedQuickLibrary; } - return cachedLibrary; // JetStandardLibrary standardLibrary = standardLibraryCache.get(project); // if (standardLibrary == null) { // standardLibrary = new JetStandardLibrary(project); @@ -47,6 +55,12 @@ public class JetStandardLibrary { // return standardLibrary; } + public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project) { + return getJetStandardLibrary(project, true); + } + + private final boolean loadFullLibrary; + private JetScope libraryScope; private ClassDescriptor numberClass; @@ -122,20 +136,27 @@ public class JetStandardLibrary { private NamespaceDescriptor typeInfoNamespace; private Set typeInfoFunction; - private JetStandardLibrary(@NotNull Project project) { - // TODO : review - InputStream stream = JetStandardClasses.class.getClassLoader().getResourceAsStream("jet/Library.jet"); + private JetStandardLibrary(@NotNull Project project, boolean loadFullLibrary) { + this.loadFullLibrary = loadFullLibrary; + try { - //noinspection IOResourceOpenedButNotSafelyClosed - JetFile file = (JetFile) PsiFileFactory.getInstance(project).createFileFromText("Library.jet", - JetFileType.INSTANCE, FileUtil.loadTextAndClose(new InputStreamReader(stream))); + JetFile file = null; + if (loadFullLibrary) { + // TODO : review + InputStream stream = JetStandardClasses.class.getClassLoader().getResourceAsStream("jet/Library.jet"); + //noinspection IOResourceOpenedButNotSafelyClosed + file = (JetFile) PsiFileFactory.getInstance(project).createFileFromText("Library.jet", + JetFileType.INSTANCE, FileUtil.loadTextAndClose(new InputStreamReader(stream))); + } JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this); BindingTraceContext bindingTraceContext = new BindingTraceContext(); WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.THROW_EXCEPTION).setDebugName("Root bootstrap scope"); // this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations()); // bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations()); - TopDownAnalyzer.processStandardLibraryNamespace(bootstrappingSemanticServices, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace()); + if (loadFullLibrary) { + TopDownAnalyzer.processStandardLibraryNamespace(bootstrappingSemanticServices, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace()); + } // this.libraryScope = JetStandardClasses.STANDARD_CLASSES_NAMESPACE.getMemberScope(); AnalyzingUtils.throwExceptionOnErrors(bindingTraceContext.getBindingContext()); @@ -153,6 +174,11 @@ public class JetStandardLibrary { private void initStdClasses() { if(libraryScope == null) { this.libraryScope = JetStandardClasses.STANDARD_CLASSES_NAMESPACE.getMemberScope(); + + if (!loadFullLibrary) { + return; + } + this.numberClass = (ClassDescriptor) libraryScope.getClassifier("Number"); this.byteClass = (ClassDescriptor) libraryScope.getClassifier("Byte"); this.charClass = (ClassDescriptor) libraryScope.getClassifier("Char"); diff --git a/compiler/testData/checkerWithErrorTypes/full/Casts.jet b/compiler/testData/checkerWithErrorTypes/full/Casts.jet index 163619fd4d0..e34a90b945a 100644 --- a/compiler/testData/checkerWithErrorTypes/full/Casts.jet +++ b/compiler/testData/checkerWithErrorTypes/full/Casts.jet @@ -1,3 +1,5 @@ +// -JDK + fun test() : Unit { var x : Int? = 0 var y : Int = 0 @@ -13,4 +15,4 @@ fun test() : Unit { x as? Int? : Int? y as? Int? : Int? () -} \ No newline at end of file +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java b/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java index 06ffed74d04..8663cc4d9fc 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java @@ -81,7 +81,7 @@ public class CheckerTestUtilTest extends JetLiteFixture { } public void test(PsiFile psiFile) { - BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); + BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE, true), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString(); List diagnosedRanges = Lists.newArrayList(); diff --git a/compiler/tests/org/jetbrains/jet/checkers/FullJetPsiCheckerTest.java b/compiler/tests/org/jetbrains/jet/checkers/FullJetPsiCheckerTest.java index 986f6501d10..5b4646d207e 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/FullJetPsiCheckerTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/FullJetPsiCheckerTest.java @@ -8,8 +8,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.ImportingStrategy; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; +import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import java.util.List; @@ -42,7 +45,13 @@ public class FullJetPsiCheckerTest extends JetLiteFixture { String clearText = CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges); myFile = createPsiFile(myName, clearText); - BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(myFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); + + boolean loadStdlib = !expectedText.contains("-STDLIB"); + boolean importJdk = !expectedText.contains("-JDK"); + + ImportingStrategy importingStrategy = importJdk ? JavaDefaultImports.JAVA_DEFAULT_IMPORTS : ImportingStrategy.NONE; + + BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(importingStrategy, loadStdlib), myFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() { @Override diff --git a/compiler/tests/org/jetbrains/jet/checkers/QuickJetPsiCheckerTest.java b/compiler/tests/org/jetbrains/jet/checkers/QuickJetPsiCheckerTest.java index d6ead64cdf1..a69f04a21c7 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/QuickJetPsiCheckerTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/QuickJetPsiCheckerTest.java @@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.ImportingStrategy; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; +import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import java.util.List; @@ -40,7 +41,12 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture { createAndCheckPsiFile(name, clearText); JetFile jetFile = (JetFile) myFile; - BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), jetFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); + boolean loadStdlib = !expectedText.contains("-STDLIB"); + boolean importJdk = expectedText.contains("+JDK"); + + ImportingStrategy importingStrategy = importJdk ? JavaDefaultImports.JAVA_DEFAULT_IMPORTS : ImportingStrategy.NONE; + + BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(importingStrategy, loadStdlib), jetFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() { @Override diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java index ca206ae88c0..f4bf68958a1 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -44,7 +44,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase { @Override protected ExpectedResolveData getExpectedResolveData() { Project project = getProject(); - JetStandardLibrary lib = JetStandardLibrary.getJetStandardLibrary(project); + JetStandardLibrary lib = JetStandardLibrary.getJetStandardLibrary(project, true); Map nameToDescriptor = new HashMap(); nameToDescriptor.put("std::Int.plus(Int)", standardFunction(lib.getInt(), "plus", lib.getIntType())); FunctionDescriptor descriptorForGet = standardFunction(lib.getArray(), Collections.singletonList(new TypeProjection(lib.getIntType())), "get", lib.getIntType()); diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java index 0a16cb56f58..0a34294d80f 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java @@ -80,7 +80,7 @@ public class JetCompiler implements TranslatingCompiler { } } - BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces( + BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true).analyzeNamespaces( compileContext.getProject(), namespaces, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); diff --git a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java index 7cfa0fe1b86..1967f70b22e 100644 --- a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java +++ b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java @@ -211,7 +211,7 @@ public class JavaElementFinder extends PsiElementFinder { if (dirty.size() > 0) { - final BindingContext context = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).shallowAnalyzeFiles(dirty); + final BindingContext context = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true).shallowAnalyzeFiles(dirty); state.compileCorrectNamespaces(context, AnalyzingUtils.collectRootNamespaces(dirty)); state.getFactory().files(); } From fed075b0cafcdae2ea97bf780bd06ed69df675f3 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 23 Nov 2011 17:25:36 +0400 Subject: [PATCH 09/22] fix DescriptionRenderer failure if FunctionDescriptor.getReturnType returns null --- .../jet/lang/descriptors/CallableDescriptor.java | 4 ++++ .../jet/lang/descriptors/FunctionDescriptorImpl.java | 6 ++++++ .../jet/lang/descriptors/PropertyDescriptor.java | 5 +++++ .../jet/lang/descriptors/PropertyGetterDescriptor.java | 6 ++++++ .../jet/lang/descriptors/PropertySetterDescriptor.java | 5 +++++ .../jet/lang/descriptors/VariableDescriptorImpl.java | 6 ++++++ .../org/jetbrains/jet/resolve/DescriptorRenderer.java | 9 ++++++--- 7 files changed, 38 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java index 4e78d2c81f5..afc9560badb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.descriptors; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; @@ -24,6 +25,9 @@ public interface CallableDescriptor extends DeclarationDescriptor { @NotNull JetType getReturnType(); + @Nullable + JetType getReturnTypeSafe(); + @NotNull @Override CallableDescriptor getOriginal(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java index ef3ab5aefa0..7f8a7943a88 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java @@ -125,6 +125,12 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements return unsubstitutedReturnType; } + @Override + @Nullable + public JetType getReturnTypeSafe() { + return unsubstitutedReturnType; + } + @NotNull @Override public FunctionDescriptor getOriginal() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java index 354979ecac9..1205e95477d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java @@ -118,6 +118,11 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab return getOutType(); } + @Override + @Nullable + public JetType getReturnTypeSafe() { + return getOutType(); + } public boolean isVar() { return isVar; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java index 01bde2bf062..753d0cd4923 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyGetterDescriptor.java @@ -45,6 +45,12 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor { return returnType; } + @Override + @Nullable + public JetType getReturnTypeSafe() { + return returnType; + } + @Override public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitPropertyGetterDescriptor(this, data); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java index d5f2038a282..365aa645651 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertySetterDescriptor.java @@ -53,6 +53,11 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor { return JetStandardClasses.getUnitType(); } + @Override + public JetType getReturnTypeSafe() { + return getReturnType(); + } + @Override public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitPropertySetterDescriptor(this, data); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java index 6daefbce285..827fcbeab9a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableDescriptorImpl.java @@ -89,4 +89,10 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i public JetType getReturnType() { return getOutType(); } + + @Override + @Nullable + public JetType getReturnTypeSafe() { + return getOutType(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java b/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java index a378e31d39b..8b2ccbd024a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java +++ b/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java @@ -73,7 +73,11 @@ public class DescriptorRenderer implements Renderer { } public String renderType(JetType type) { - return escape(type.toString()); + if (type == null) { + return escape(""); + } else { + return escape(type.toString()); + } } protected String escape(String s) { @@ -222,8 +226,7 @@ public class DescriptorRenderer implements Renderer { renderName(descriptor, builder); renderValueParameters(descriptor, builder); - // TODO: getReturnType may be uninitialized and throw IllegalStateException // stepan.koltsov@ 2011-11-21 - builder.append(" : ").append(escape(renderType(descriptor.getReturnType()))); + builder.append(" : ").append(escape(renderType(descriptor.getReturnTypeSafe()))); return super.visitFunctionDescriptor(descriptor, builder); } From 5d2dfcd48f5bf89ba8d5cb436914169a65b1628e Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 23 Nov 2011 18:15:37 +0400 Subject: [PATCH 10/22] more check for casts KT-445 (Don't allow deep instanceof for erased parameters) and more see new tests in compiler/testData/checkerWithErrorTypes/full/cast --- .../jet/lang/diagnostics/Errors.java | 6 ++- .../BasicExpressionTypingVisitor.java | 50 +++++++++++++++++++ .../PatternMatchingTypingVisitor.java | 32 +++++++++++- .../full/cast/AsErasedError.jet | 4 ++ .../full/cast/AsErasedFine.jet | 4 ++ .../full/cast/AsErasedStar.jet | 4 ++ .../full/cast/AsErasedWarning.jet | 3 ++ .../full/cast/IsErasedAllow.jet | 5 ++ .../cast/IsErasedAllowParameterSubtype.jet | 9 ++++ .../full/cast/IsErasedDisallowFromAny.jet | 3 ++ .../cast/IsErasedDisallowFromParameter.jet | 5 ++ .../full/cast/IsErasedStar.jet | 3 ++ .../full/cast/IsReified.jet | 3 ++ .../full/cast/IsReifiedDisallow.jet | 3 ++ .../full/cast/IsTraits.jet | 4 ++ .../full/cast/WhenErasedDisallowFromAny.jet | 6 +++ .../testData/codegen/patternMatching/is.jet | 4 +- 17 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/AsErasedError.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/AsErasedFine.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/AsErasedStar.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/AsErasedWarning.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllow.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllowParameterSubtype.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromAny.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromParameter.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsErasedStar.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsReified.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsReifiedDisallow.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet create mode 100644 compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index da7edd9d6fe..785e9abbae6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -16,6 +16,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Iterator; +import java.util.List; import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR; import static org.jetbrains.jet.lang.diagnostics.Severity.WARNING; @@ -275,7 +276,10 @@ public interface Errors { ParameterizedDiagnosticFactory2 TYPE_MISMATCH_IN_TUPLE_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "Type mismatch: subject is of type {0} but the pattern is of type Tuple{1}"); // TODO: message ParameterizedDiagnosticFactory2 TYPE_MISMATCH_IN_BINDING_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "{0} must be a supertype of {1}. Use 'is' to match against {0}"); ParameterizedDiagnosticFactory2 INCOMPATIBLE_TYPES = ParameterizedDiagnosticFactory2.create(ERROR, "Incompatible types: {0} and {1}"); - + + ParameterizedDiagnosticFactory1 CANNOT_CHECK_FOR_ERASED = ParameterizedDiagnosticFactory1.create(ERROR, "Cannot check for instance of erased type: {0}"); + ParameterizedDiagnosticFactory2 UNCHECKED_CAST = ParameterizedDiagnosticFactory2.create(WARNING, "Unchecked cast: {0} to {1}"); + ParameterizedDiagnosticFactory3> INCONSISTENT_TYPE_PARAMETER_VALUES = new ParameterizedDiagnosticFactory3>(ERROR, "Type parameter {0} of {1} has inconsistent values: {2}") { @Override protected String makeMessageForA(@NotNull TypeParameterDescriptor typeParameterDescriptor) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 0446105d479..10c3ca8cae5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.types.expressions; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; @@ -8,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker; @@ -245,10 +247,58 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { else { if (typeChecker.isSubtypeOf(actualType, targetType)) { context.trace.report(USELESS_CAST.on(expression, expression.getOperationSign())); + } else { + if (isCastErased(actualType, targetType)) { + context.trace.report(Errors.UNCHECKED_CAST.on(expression, actualType, targetType)); + } } } } + /** + * Check if assignment from ActualType to TargetType is erased. + * It is an error in "is" statement and warning in "as". + */ + public static boolean isCastErased(JetType actualType, JetType targetType) { + + JetType targetTypeClerared = TypeUtils.makeUnsubstitutedType( + (ClassDescriptor) targetType.getConstructor().getDeclarationDescriptor(), null); + + Multimap clearTypeSubstitutionMap = + TypeUtils.buildDeepSubstitutionMultimap(targetTypeClerared); + + Set clearSubstituted = new HashSet(); + + for (int i = 0; i < actualType.getConstructor().getParameters().size(); ++i) { + TypeParameterDescriptor subjectTypeParameterDescriptor = actualType.getConstructor().getParameters().get(i); + + Collection subst = clearTypeSubstitutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor()); + for (TypeProjection proj : subst) { + clearSubstituted.add(proj.getType()); + } + } + + for (int i = 0; i < targetType.getConstructor().getParameters().size(); ++i) { + TypeParameterDescriptor typeParameter = targetType.getConstructor().getParameters().get(i); + TypeProjection typeProjection = targetType.getArguments().get(i); + + if (typeParameter.isReified()) { + continue; + } + + // "is List<*>" + if (typeProjection.equals(TypeUtils.makeStarProjection(typeParameter))) { + continue; + } + + // if parameter is mapped to nothing then it is erased + if (!clearSubstituted.contains(typeParameter.getDefaultType())) { + return true; + } + } + return false; + } + @Override public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) { List entries = expression.getEntries(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java index 6b8b8d0630c..86bc4e82677 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java @@ -1,11 +1,14 @@ package org.jetbrains.jet.lang.types.expressions; +import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Ref; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue; @@ -17,8 +20,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; import org.jetbrains.jet.lang.types.*; -import java.util.List; -import java.util.Set; +import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.ensureBooleanResultWithCustomSubject; @@ -245,6 +247,9 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { } } + /* + * (a: SubjectType) is Type + */ private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) { // TODO : Take auto casts into account? if (type == null) { @@ -253,6 +258,29 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) { // context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType); context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType)); + return; + } + + { + // check parameters compatible + Multimap typeSubstritutionMap = TypeUtils.buildDeepSubstitutionMultimap(type); + + for (int i = 0; i < subjectType.getConstructor().getParameters().size(); ++i) { + TypeParameterDescriptor subjectTypeParameterDescriptor = subjectType.getConstructor().getParameters().get(i); + TypeProjection subjectParameterType = subjectType.getArguments().get(i); + + Collection xxy = typeSubstritutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor()); + for (TypeProjection proj : xxy) { + if (!context.semanticServices.getTypeChecker().isSubtypeOf(subjectParameterType.getType(), proj.getType())) { + context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType)); + continue; + } + } + } + } + + if (BasicExpressionTypingVisitor.isCastErased(subjectType, type)) { + context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(reportErrorOn, type)); } } diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedError.jet b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedError.jet new file mode 100644 index 00000000000..bff067d20ee --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedError.jet @@ -0,0 +1,4 @@ +import java.util.List; +import java.util.Collection; + +fun ff(c: Collection) = c as List diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedFine.jet b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedFine.jet new file mode 100644 index 00000000000..341f370d108 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedFine.jet @@ -0,0 +1,4 @@ +import java.util.List; +import java.util.Collection; + +fun ff(c: Collection) = c as List diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedStar.jet b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedStar.jet new file mode 100644 index 00000000000..b9c2faf0d9a --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedStar.jet @@ -0,0 +1,4 @@ +import java.util.List; + +fun ff(l: Any) = l as List<*> + diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedWarning.jet b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedWarning.jet new file mode 100644 index 00000000000..a55f6b7d58b --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/AsErasedWarning.jet @@ -0,0 +1,3 @@ +import java.util.List; + +fun ff(a: Any) = a as List diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllow.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllow.jet new file mode 100644 index 00000000000..7f32b79eba2 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllow.jet @@ -0,0 +1,5 @@ +import java.util.Collection; +import java.util.List; + +fun ff(l: Collection) = l is List + diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllowParameterSubtype.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllowParameterSubtype.jet new file mode 100644 index 00000000000..d1694229dc6 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedAllowParameterSubtype.jet @@ -0,0 +1,9 @@ +import java.util.Collection; +import java.util.List; + +open class A + +class B : A + +fun ff(l: Collection) = l is List + diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromAny.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromAny.jet new file mode 100644 index 00000000000..eb3b402ccc7 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromAny.jet @@ -0,0 +1,3 @@ +import java.util.List; + +fun ff(l: Any) = l is List diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromParameter.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromParameter.jet new file mode 100644 index 00000000000..a70b5932999 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedDisallowFromParameter.jet @@ -0,0 +1,5 @@ +import java.util.List; +import java.util.Collection; + +fun ff(l: Collection) = l is List + diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedStar.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedStar.jet new file mode 100644 index 00000000000..404d8f8f3b0 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsErasedStar.jet @@ -0,0 +1,3 @@ +import java.util.List; + +fun ff(l: Any) = l is List<*> diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsReified.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsReified.jet new file mode 100644 index 00000000000..247196d6e84 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsReified.jet @@ -0,0 +1,3 @@ +class MyList + +fun ff(a: Any) = a is MyList diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsReifiedDisallow.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsReifiedDisallow.jet new file mode 100644 index 00000000000..9abceb5f1e6 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsReifiedDisallow.jet @@ -0,0 +1,3 @@ +class MyList + +fun ff(l: MyList) = l is MyList diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet new file mode 100644 index 00000000000..99656c2ab24 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet @@ -0,0 +1,4 @@ +trait Aaa +trait Bbb + +fun f(a: Aaa) = a is Bbb diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet b/compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet new file mode 100644 index 00000000000..f38a4b14fbe --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet @@ -0,0 +1,6 @@ +import java.util.List; + +fun ff(l: Any) = when(l) { + is List => 1 + else 2 +} diff --git a/compiler/testData/codegen/patternMatching/is.jet b/compiler/testData/codegen/patternMatching/is.jet index a5b5f33195f..9fac50c586b 100644 --- a/compiler/testData/codegen/patternMatching/is.jet +++ b/compiler/testData/codegen/patternMatching/is.jet @@ -1,6 +1,6 @@ fun typeName(a: Any?) : String { return when(a) { - is java.util.ArrayList => "array list" + is java.util.ArrayList<*> => "array list" else => "no idea" } } @@ -8,4 +8,4 @@ fun typeName(a: Any?) : String { fun box() : String { if(typeName(java.util.ArrayList ()) != "array list") return "array list failed" return "OK" -} \ No newline at end of file +} From 9cb0cc9fa6be92fca044e2579ff2075fa8c57da5 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 23 Nov 2011 20:27:38 +0300 Subject: [PATCH 11/22] KT-394 Make class object members visible inside the owning class KT-588 Unresolved static method --- .../descriptors/MutableClassDescriptor.java | 25 +++++++++++++++---- .../lang/resolve/calls/TaskPrioritizer.java | 12 +++++++-- .../resolve/scopes/WritableScopeImpl.java | 18 ++++++------- .../scopes/WritableScopeWithImports.java | 15 +++++++++++ .../ClosureExpressionsTypingVisitor.java | 9 +------ .../quick/regressions/kt394.jet | 11 ++++++++ .../quick/regressions/kt588.jet | 12 +++++++++ 7 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/kt394.jet create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/kt588.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 872cb0e9b97..669af46b9ae 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -5,7 +5,9 @@ import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; @@ -43,10 +45,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme private JetType superclassType; private ClassReceiver implicitReceiver; -// public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) { -// this(trace, containingDeclaration, outerScope, ClassKind.CLASS); -// } - public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) { super(containingDeclaration); TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace); @@ -66,6 +64,23 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme } assert classObjectDescriptor.getKind() == ClassKind.OBJECT; this.classObjectDescriptor = classObjectDescriptor; + + // Members of the class object are accessible from the class + // The scope must be lazy, because classObjectDescriptor may not by fully built yet + scopeForMemberResolution.importScope(new AbstractScopeAdapter() { + @NotNull + @Override + protected JetScope getWorkerScope() { + return MutableClassDescriptor.this.classObjectDescriptor.getDefaultType().getMemberScope(); + } + + @NotNull + @Override + public ReceiverDescriptor getImplicitReceiver() { + return MutableClassDescriptor.this.classObjectDescriptor.getImplicitReceiver(); + } + } + ); return ClassObjectStatus.OK; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java index 2edca62eb75..872781fb28b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java @@ -98,8 +98,16 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor } doComputeTasks(scope, explicitReceiver, call, name, result, AutoCastService.NO_AUTO_CASTS); - ReceiverDescriptor receiverToCast = explicitReceiver.exists() ? explicitReceiver : scope.getImplicitReceiver(); - if (receiverToCast.exists()) { + List receivers; + if (explicitReceiver.exists()) { + receivers = Collections.singletonList(explicitReceiver); + } + else { + receivers = Lists.newArrayList(); + scope.getImplicitReceiversHierarchy(receivers); + } + for (ReceiverDescriptor receiverToCast : receivers) { + assert receiverToCast.exists(); doComputeTasks(scope, receiverToCast, call, name, result, new AutoCastServiceImpl(dataFlowInfo, bindingContext)); } return result; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 81ee15a1873..37de89a17ca 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -232,15 +232,6 @@ public class WritableScopeImpl extends WritableScopeWithImports { return super.getClassifier(name); } - @NotNull - @Override - public ReceiverDescriptor getImplicitReceiver() { - if (implicitReceiver == null) { - return super.getImplicitReceiver(); - } - return implicitReceiver; - } - @Override public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); @@ -272,6 +263,15 @@ public class WritableScopeImpl extends WritableScopeWithImports { return super.getNamespace(name); } + @NotNull + @Override + public ReceiverDescriptor getImplicitReceiver() { + if (implicitReceiver == null) { + return super.getImplicitReceiver(); + } + return implicitReceiver; + } + @Override public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) { if (this.implicitReceiver != null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java index ba957519c14..97cdb1df602 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java @@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.ArrayList; import java.util.Collections; @@ -50,6 +51,20 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement currentIndividualImportScope = null; } + @Override + public void getImplicitReceiversHierarchy(@NotNull List result) { + super.getImplicitReceiversHierarchy(result); + // Imported scopes come with their receivers + // Example: class member resolution scope imports a scope of it's class object + // members of the class object must be able to find it as an implicit receiver + for (JetScope scope : getImports()) { + ReceiverDescriptor definedReceiver = scope.getImplicitReceiver(); + if (definedReceiver.exists()) { + result.add(0, definedReceiver); + } + } + } + @Override public VariableDescriptor getVariable(@NotNull String name) { // Meaningful lookup goes here diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java index 41f0705f6aa..8add070d296 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java @@ -111,13 +111,6 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { private FunctionDescriptorImpl createFunctionDescriptor(JetFunctionLiteralExpression expression, ExpressionTypingContext context, boolean functionTypeExpected) { JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef(); - final JetType receiverType; - if (receiverTypeRef != null) { - receiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef); - } else { - ReceiverDescriptor implicitReceiver = context.scope.getImplicitReceiver(); - receiverType = implicitReceiver.exists() ? implicitReceiver.getType() : null; - } FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl( context.scope.getContainingDeclaration(), Collections.emptyList(), ""); @@ -133,7 +126,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } } else { - effectiveReceiverType = receiverType; + effectiveReceiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef); } functionDescriptor.initialize(effectiveReceiverType, NO_RECEIVER, Collections.emptyList(), valueParameterDescriptors, null, Modality.FINAL, Visibility.LOCAL); context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor); diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt394.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt394.jet new file mode 100644 index 00000000000..8e58588f4b0 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt394.jet @@ -0,0 +1,11 @@ +// KT-394 Make class object members visible inside the owning class + +class X() { +// class Y {} + + class object{ + class Y() {} + } + + val y : Y = Y() +} \ No newline at end of file diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt588.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt588.jet new file mode 100644 index 00000000000..2b4b4d86ff4 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt588.jet @@ -0,0 +1,12 @@ +// KT-588 Unresolved static method +class Test() : Thread("Test") { + class object { + fun init2() { + + } + } + override fun run() { + init2() // unresolved + Test.init2() // ok + } +} \ No newline at end of file From 6eea1716d3fce637653fabcedc5b53c122cf6f6c Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 23 Nov 2011 21:29:36 +0400 Subject: [PATCH 12/22] Bytecode viewer, initial --- idea/src/META-INF/plugin.xml | 3 + .../codewindow/BytecodeToolwindow.java | 162 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index e767fd35eb3..fe7b457af02 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -58,5 +58,8 @@ + diff --git a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java new file mode 100644 index 00000000000..58d672f6d67 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java @@ -0,0 +1,162 @@ +/* + * @author max + */ +package org.jetbrains.jet.plugin.internal.codewindow; + +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.ui.content.ContentFactory; +import com.intellij.util.Alarm; +import org.jetbrains.jet.codegen.ClassBuilderFactory; +import org.jetbrains.jet.codegen.ClassFileFactory; +import org.jetbrains.jet.codegen.GenerationState; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; + +import javax.swing.*; +import java.awt.*; + +public class BytecodeToolwindow extends JPanel { + private static final int UPDATE_DELAY = 500; + private final Editor myEditor; + private final Alarm myUpdateAlarm; + private Location myCurrentLocation; + private final Project myProject; + + + public BytecodeToolwindow(Project project) { + super(new BorderLayout()); + myProject = project; + myEditor = EditorFactory.getInstance().createEditor(EditorFactory.getInstance().createDocument(""), project, JavaFileType.INSTANCE, true); + add(myEditor.getComponent()); + myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + myUpdateAlarm.addRequest(new Runnable() { + @Override + public void run() { + Location location = Location.fromEditor(FileEditorManager.getInstance(myProject).getSelectedTextEditor()); + if (!Comparing.equal(location, myCurrentLocation)) { + myCurrentLocation = location; + updateBytecode(location); + } + myUpdateAlarm.addRequest(this, UPDATE_DELAY); + } + }, UPDATE_DELAY); + } + + private void updateBytecode(Location location) { + Editor editor = location.editor; + + if (editor == null) { + setText(""); + } + else { + VirtualFile vFile = ((EditorEx) editor).getVirtualFile(); + if (vFile == null) { + setText(""); + return; + } + + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); + if (!(psiFile instanceof JetFile)) { + setText(""); + return; + } + + setText(generateToText((JetFile) psiFile)); + } + } + + private void setText(final String text) { + new WriteCommandAction(myProject) { + @Override + protected void run(Result result) throws Throwable { + myEditor.getDocument().setText(text); + } + }.execute(); + } + + protected String generateToText(JetFile file) { + GenerationState state = new GenerationState(myProject, ClassBuilderFactory.TEXT); + try { + AnalyzingUtils.checkForSyntacticErrors(file); + state.compile(file); + } catch (Exception e) { + return e.toString(); + } + + + StringBuilder answer = new StringBuilder(); + + final ClassFileFactory factory = state.getFactory(); + for (String filename : factory.files()) { + answer.append("// ================ "); + answer.append(filename); + answer.append(" =================\n"); + answer.append(factory.asText(filename)).append("\n\n"); + } + + return answer.toString(); + } + + + public static class Factory implements ToolWindowFactory { + @Override + public void createToolWindowContent(Project project, ToolWindow toolWindow) { + toolWindow.getContentManager().addContent(ContentFactory.SERVICE.getInstance().createContent(new BytecodeToolwindow(project), "", false)); + } + } + + private static class Location { + final Editor editor; + final long modificationStamp; + final int startOffset; + final int endOffset; + + private Location(Editor editor) { + this.editor = editor; + modificationStamp = editor != null ? editor.getDocument().getModificationStamp() : 0; + startOffset = editor != null ? editor.getSelectionModel().getSelectionStart() : 0; + endOffset = editor != null ? editor.getSelectionModel().getSelectionEnd() : 0; + } + + public static Location fromEditor(Editor editor) { + return new Location(editor); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Location)) return false; + + Location location = (Location) o; + + if (endOffset != location.endOffset) return false; + if (modificationStamp != location.modificationStamp) return false; + if (startOffset != location.startOffset) return false; + if (editor != null ? !editor.equals(location.editor) : location.editor != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = editor != null ? editor.hashCode() : 0; + result = 31 * result + (int) (modificationStamp ^ (modificationStamp >>> 32)); + result = 31 * result + startOffset; + result = 31 * result + endOffset; + return result; + } + } +} From 1c147182145e881469ddf8ad48981bc03d6b7028 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 23 Nov 2011 20:37:22 +0300 Subject: [PATCH 13/22] Class renamed to better reflect it's purpose --- .idea/compiler.xml | 2 +- .../jet/lang/JetSemanticServices.java | 6 +++--- .../jet/lang/resolve/BodyResolver.java | 8 ++++---- .../jet/lang/resolve/DeclarationResolver.java | 14 ++++++------- .../jet/lang/resolve/DeclarationsChecker.java | 2 +- ...rResolver.java => DescriptorResolver.java} | 4 ++-- .../lang/resolve/TopDownAnalysisContext.java | 8 ++++---- .../lang/resolve/TypeHierarchyResolver.java | 18 ++++++++--------- .../ClosureExpressionsTypingVisitor.java | 2 +- .../ControlStructureTypingVisitor.java | 6 +++--- .../expressions/ExpressionTypingContext.java | 12 +++++------ .../ExpressionTypingVisitorForStatements.java | 6 +++--- .../PatternMatchingTypingVisitor.java | 2 +- .../JetDefaultModalityModifiersTest.java | 14 ++++++------- .../jetbrains/jet/types/JetOverloadTest.java | 8 ++++---- .../jet/types/JetOverridingTest.java | 8 ++++---- .../jet/types/JetTypeCheckerTest.java | 20 +++++++++---------- 17 files changed, 70 insertions(+), 70 deletions(-) rename compiler/frontend/src/org/jetbrains/jet/lang/resolve/{ClassDescriptorResolver.java => DescriptorResolver.java} (99%) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb3e2a37c80..1397a2192d0 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,7 @@ - - -fun ff(l: MyList) = l is MyList diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet b/compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet deleted file mode 100644 index 99656c2ab24..00000000000 --- a/compiler/testData/checkerWithErrorTypes/full/cast/IsTraits.jet +++ /dev/null @@ -1,4 +0,0 @@ -trait Aaa -trait Bbb - -fun f(a: Aaa) = a is Bbb diff --git a/compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet b/compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet deleted file mode 100644 index f38a4b14fbe..00000000000 --- a/compiler/testData/checkerWithErrorTypes/full/cast/WhenErasedDisallowFromAny.jet +++ /dev/null @@ -1,6 +0,0 @@ -import java.util.List; - -fun ff(l: Any) = when(l) { - is List => 1 - else 2 -} diff --git a/compiler/testData/codegen/patternMatching/is.jet b/compiler/testData/codegen/patternMatching/is.jet index 9fac50c586b..a5b5f33195f 100644 --- a/compiler/testData/codegen/patternMatching/is.jet +++ b/compiler/testData/codegen/patternMatching/is.jet @@ -1,6 +1,6 @@ fun typeName(a: Any?) : String { return when(a) { - is java.util.ArrayList<*> => "array list" + is java.util.ArrayList => "array list" else => "no idea" } } @@ -8,4 +8,4 @@ fun typeName(a: Any?) : String { fun box() : String { if(typeName(java.util.ArrayList ()) != "array list") return "array list failed" return "OK" -} +} \ No newline at end of file From aa007d415d82dfbaad3fe5d038f6e260a003d179 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 24 Nov 2011 15:31:21 +0300 Subject: [PATCH 22/22] Moved to full, since the test uses JDK --- .../{quick/regressions => full/regression}/kt588.jet | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename compiler/testData/checkerWithErrorTypes/{quick/regressions => full/regression}/kt588.jet (100%) diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt588.jet b/compiler/testData/checkerWithErrorTypes/full/regression/kt588.jet similarity index 100% rename from compiler/testData/checkerWithErrorTypes/quick/regressions/kt588.jet rename to compiler/testData/checkerWithErrorTypes/full/regression/kt588.jet