diff --git a/TeamCityBuild.xml b/TeamCityBuild.xml index bf903653b59..3adefae3f89 100644 --- a/TeamCityBuild.xml +++ b/TeamCityBuild.xml @@ -34,14 +34,6 @@ - - - - - - - - @@ -100,7 +92,7 @@ - + diff --git a/bin/kotlin b/bin/kotlin old mode 100755 new mode 100644 diff --git a/bin/run-test b/bin/run-test old mode 100755 new mode 100644 diff --git a/build-tools/Wiki.txt b/build-tools/Wiki.txt deleted file mode 100644 index e6e0577fd5b..00000000000 --- a/build-tools/Wiki.txt +++ /dev/null @@ -1,173 +0,0 @@ -{toc:style=disc|indent=20px} -h1. Ant - - -h2. Defining {{**}} task using local Kotlin setup - -One way to define Ant's {{**}} task is by using your local Kotlin setup and {{*KOTLIN_HOME*}} environment variable: - -{code:xml} - - - - - - -{code} - - -Alternatively, you can copy all jar files from Kotlin distribution to Ant's {{"lib"}} folder. - - -h2. Defining {{**}} task using Ivy - -Another way to define Ant's {{**}} task is by using Ivy: - -{{"ivyconf.xml"}}: - -{code:xml} - - - - - - - - - - - - - - - - - - - - - -{code} - -{{"ivy.xml"}}: - -{code:xml} - - - - - - - - - - - - - - - - -{code} - -{{"build.xml"}}: - -{code:xml} - - - - - - - - - - - -{code} - -h2. {{**}} attributes - - -|| {align:center}Name{align} || {align:center}Description{align} || {align:center}Required{align} || {align:center}Default Value{align} || -| {align:center}{{*src*}}{align} | Kotlin source file or directory to compile | {{"src"}} or {{"module"}} needs to be specified |   | -| {align:center}{{*module*}}{align} | Kotlin [module|http://confluence.jetbrains.net/display/Kotlin/Modules+and+Compilation] to compile | {{"src"}} or {{"module"}} needs to be specified |   | -| {align:center}{{*output*}}{align} | Destination directory | If {{"src"}} is used - {{"output"}} or {{"jar"}} needs to be specified |   | -| {align:center}{{*jar*}}{align} | Destination jar file | If {{"src"}} is used - {{"output"}} or {{"jar"}} needs to be specified -If {{"module"}} is used - only {{"jar"}} can be specified or it can be omitted | {align:center}{{"moduleName.jar"}}{align} | -| {align:center}{{*classpath*}}{align} | Compilation class path | {align:center}{{false}}{align} |   | -| {align:center}{{*classpathref*}}{align} | Compilation class path reference | {align:center}{{false}}{align} |   | -| {align:center}{{*stdlib*}}{align} | Path to {{"kotlin-runtime.jar"}} | {align:center}{{false}}{align} | {align:center}{{""}}{align} | -| {align:center}{{*includeRuntime*}}{align} | If {{"jar"}} is used - whether Kotlin runtime library is included | {align:center}{{false}}{align} | {align:center}{{true}}{align} | - - -{{}} accepts a nested {{}} element, similarly to [{{}}|http://evgeny-goldin.org/javadoc/ant/Tasks/javac.html]. - - -h2. Examples - - -{code:xml} - - - - - - - - => "smoke.jar" -{code} - -{{"Smoke.kts"}}: - -{code} -import kotlin.modules.* - -fun project() { - module("smoke") { - sources += "Smoke.kt" - } -} -{code} -{{"Smoke.kt"}}: - -{code} -package Smoke - -fun main(args: Array) { - print("${args[0]}|${args[1]}|${args[2]}") -} -{code} - - -h3. Classpath examples - - -{code:xml} - - - - - - - - - - - - - - - - - - - -{code} - - -h1. Maven - -See [{{"kotlin-maven-plugin"}}|http://evgeny-goldin.com/wiki/Kotlin-maven-plugin]. - -h1. Gradle \ No newline at end of file diff --git a/build-tools/build-tools.iml b/build-tools/build-tools.iml index d0304c4b431..fde16f7bfd8 100644 --- a/build-tools/build-tools.iml +++ b/build-tools/build-tools.iml @@ -4,13 +4,23 @@ + - + + + + + + + + + + diff --git a/build-tools/build.xml b/build-tools/build.xml deleted file mode 100644 index 50e4caf01d9..00000000000 --- a/build-tools/build.xml +++ /dev/null @@ -1,503 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [@{file}] of type [@{type}] exists - - - - - - - - - - - - - - - - - - - - [${kotlin-home}/lib] jars found, defining "kotlin.classpath" - - - - - - - [${kotlin-home}/lib] jars *not* found, creating distribution zip - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Running [@{classname}], classpath = "@{jar}" - - - - - - - - - Running [@{classname}], classpath = "${tests-dir}" - - - - - - - - - - - - - - - - - - - - ${java-out} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Running JUnit: classpath = "@{classpath}" (Jar) - - - - - - - - - - - - - Running JUnit: classpath = "@{classpath}" (Dir) - - - - - - - - - - - - - - - Running JUnit: test = "@{test}", classpath = "@{classpath}" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "ERROR:" was expected here - - - - - - - - - - - - - - - - - - "ERROR:" was expected here - - - - - - - - - - - - - - - - - - "ERROR:" was expected here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build-tools/ivy.xml b/build-tools/ivy.xml deleted file mode 100644 index 72a5931b172..00000000000 --- a/build-tools/ivy.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/build-tools/ivyconf.xml b/build-tools/ivyconf.xml deleted file mode 100644 index 2020a9e6114..00000000000 --- a/build-tools/ivyconf.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build-tools/lib/ant-contrib-1.0b3.jar b/build-tools/lib/ant-contrib-1.0b3.jar deleted file mode 100644 index 062537661a5..00000000000 Binary files a/build-tools/lib/ant-contrib-1.0b3.jar and /dev/null differ diff --git a/build-tools/test/compilation-fail/Bottles.kt b/build-tools/test/compilation-fail/Bottles.kt deleted file mode 100644 index 3224e5fc901..00000000000 --- a/build-tools/test/compilation-fail/Bottles.kt +++ /dev/null @@ -1,59 +0,0 @@ -/** - * "Bottles.kt" that doesn't compile, see line 6. - */ -package bottles - -fun main(args : Array - if (args.isEmpty) { - printBottles(99) - } - else { - try { - printBottles(Integer.parseInt(args[0])) - } - catch (e : NumberFormatException) { - System.err?.println("You have passed '${args[0]}' as a number of bottles, " + - "but it is not a valid integral number") - } - } -} - -fun printBottles(bottleCount : Int) { - if (bottleCount <= 0) { - println("No bottles - no song") - return - } - - println("The \"${bottlesOfBeer(bottleCount)}\" song\n") - - var bottles = bottleCount - while (bottles > 0) { - val bottlesOfBeer = bottlesOfBeer(bottles) - print("$bottlesOfBeer on the wall, $bottlesOfBeer.\nTake one down, pass it around, ") - bottles-- - println("${bottlesOfBeer(bottles)} on the wall.\n") - } - println("No more bottles of beer on the wall, no more bottles of beer.\n" + - "Go to the store and buy some more, ${bottlesOfBeer(bottleCount)} on the wall.") -} - -fun bottlesOfBeer(count : Int) : String = - when (count) { - 0 -> "no more bottles" - 1 -> "1 bottle" - else -> "$count bottles" - } + " of beer" - -/* - * An excerpt from the Standard Library - */ - -// From the kotlin.io package -// These are simple functions that wrap standard Java API calls -fun print(message : String) { System.out?.print(message) } -fun println(message : String) { System.out?.println(message) } - -// From the kotlin package -// This is an extension property, i.e. a property that is defined for the -// type Array, but does not sit inside the class Array -val Array.isEmpty : Boolean get() = size == 0 diff --git a/build-tools/test/compilation-fail/Smoke.kts b/build-tools/test/compilation-fail/Smoke.kts deleted file mode 100644 index fdef116a2a5..00000000000 --- a/build-tools/test/compilation-fail/Smoke.kts +++ /dev/null @@ -1,3 +0,0 @@ -import kotlin.modules.* - -fun proj \ No newline at end of file diff --git a/build-tools/test/hello/1/Hello.kt b/build-tools/test/hello/1/Hello.kt deleted file mode 100644 index 699426924dd..00000000000 --- a/build-tools/test/hello/1/Hello.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun main(args : Array) { - System.out?.println("Hello, world!") -} \ No newline at end of file diff --git a/build-tools/test/hello/2/Hello.kt b/build-tools/test/hello/2/Hello.kt deleted file mode 100644 index 83ed78ab4c4..00000000000 --- a/build-tools/test/hello/2/Hello.kt +++ /dev/null @@ -1,7 +0,0 @@ -fun main(args : Array) { - if (args.size == 0) { - System.out?.println("Please provide a name as a command-line argument") - return - } - System.out?.println("Hello, ${args[0]}!") -} diff --git a/build-tools/test/hello/3/Hello.kt b/build-tools/test/hello/3/Hello.kt deleted file mode 100644 index efc6503f75b..00000000000 --- a/build-tools/test/hello/3/Hello.kt +++ /dev/null @@ -1,4 +0,0 @@ -fun main(args : Array) { - for (name in args) - System.out?.println("Hello, $name!") -} diff --git a/build-tools/test/hello/4/Hello.kt b/build-tools/test/hello/4/Hello.kt deleted file mode 100644 index 0038a5e12c0..00000000000 --- a/build-tools/test/hello/4/Hello.kt +++ /dev/null @@ -1,9 +0,0 @@ -fun main(args : Array) { - val language = if (args.size == 0) "EN" else args[0] - System.out?.println(when (language) { - "EN" -> "Hello!" - "FR" -> "Salut!" - "IT" -> "Ciao!" - else -> "Sorry, I can't greet you in $language yet" - }) -} diff --git a/build-tools/test/hello/5/Hello.kt b/build-tools/test/hello/5/Hello.kt deleted file mode 100644 index 96a210ce6cf..00000000000 --- a/build-tools/test/hello/5/Hello.kt +++ /dev/null @@ -1,9 +0,0 @@ -class Greeter(val name : String) { - fun greet() { - System.out?.println("Hello, ${name}!"); - } -} - -fun main(args : Array) { - Greeter(args[0]).greet() -} diff --git a/build-tools/test/longer-examples/Bottles.kt b/build-tools/test/longer-examples/Bottles.kt deleted file mode 100644 index 053b8ca0731..00000000000 --- a/build-tools/test/longer-examples/Bottles.kt +++ /dev/null @@ -1,80 +0,0 @@ -/** - * This example implements the famous "99 Bottles of Beer" program - * See http://99-bottles-of-beer.net/ - * - * The point is to print out a song with the following lyrics: - * - * The "99 bottles of beer" song - * - * 99 bottles of beer on the wall, 99 bottles of beer. - * Take one down, pass it around, 98 bottles of beer on the wall. - * - * 98 bottles of beer on the wall, 98 bottles of beer. - * Take one down, pass it around, 97 bottles of beer on the wall. - * - * ... - * - * 2 bottles of beer on the wall, 2 bottles of beer. - * Take one down, pass it around, 1 bottle of beer on the wall. - * - * 1 bottle of beer on the wall, 1 bottle of beer. - * Take one down, pass it around, no more bottles of beer on the wall. - * - * No more bottles of beer on the wall, no more bottles of beer. - * Go to the store and buy some more, 99 bottles of beer on the wall. - * - * Additionally, you can pass the desired initial number of bottles to use (rather than 99) - * as a command-line argument - */ -package bottles - -fun main(args : Array) { - if (args.isEmpty) { - printBottles(99) - } - else { - try { - printBottles(Integer.parseInt(args[0])) - } - catch (e : NumberFormatException) { - System.err?.println("You have passed '${args[0]}' as a number of bottles, " + - "but it is not a valid integral number") - } - } -} - -fun printBottles(bottleCount : Int) { - if (bottleCount <= 0) { - println("No bottles - no song") - return - } - - println("The \"${bottlesOfBeer(bottleCount)}\" song\n") - - var bottles = bottleCount - while (bottles > 0) { - val bottlesOfBeer = bottlesOfBeer(bottles) - print("$bottlesOfBeer on the wall, $bottlesOfBeer.\nTake one down, pass it around, ") - bottles-- - println("${bottlesOfBeer(bottles)} on the wall.\n") - } - println("No more bottles of beer on the wall, no more bottles of beer.\n" + - "Go to the store and buy some more, ${bottlesOfBeer(bottleCount)} on the wall.") -} - -fun bottlesOfBeer(count : Int) : String = - when (count) { - 0 -> "no more bottles" - 1 -> "1 bottle" - else -> "$count bottles" - } + " of beer" - -/* - * An excerpt from the Standard Library - */ - - -// From the kotlin package -// This is an extension property, i.e. a property that is defined for the -// type Array, but does not sit inside the class Array -val Array.isEmpty : Boolean get() = size == 0 diff --git a/build-tools/test/longer-examples/HtmlBuilder.txt b/build-tools/test/longer-examples/HtmlBuilder.txt deleted file mode 100644 index dabff966180..00000000000 --- a/build-tools/test/longer-examples/HtmlBuilder.txt +++ /dev/null @@ -1,146 +0,0 @@ -/** - * This is an example of a Type-Safe Groovy-style Builder - * - * Builders are good for declaratively describing data in your code. - * In this example we show how to describe an HTML page in Kotlin. - * - * See this page for details: - * http://confluence.jetbrains.net/display/Kotlin/Type-safe+Groovy-style+builders - */ -package html - -import java.util.* - -fun main(args : Array) { - val result = - html { - head { - title {+"XML encoding with Kotlin"} - } - body { - h1 {+"XML encoding with Kotlin"} - p {+"this format can be used as an alternative markup to XML"} - - // an element with attributes and text content - a(href = "http://jetbrains.com/kotlin") {+"Kotlin"} - - // mixed content - p { - +"This is some" - b {+"mixed"} - +"text. For more see the" - a(href = "http://jetbrains.com/kotlin") {+"Kotlin"} - +"project" - } - p {+"some text"} - - // content generated from command-line arguments - p { - +"Command line arguments were:" - ul { - for (arg in args) - li {+arg} - } - } - } - } - println(result) -} - -trait Element { - fun render(builder : StringBuilder, indent : String) - - fun toString() : String? { - val builder = StringBuilder() - render(builder, "") - return builder.toString() - } -} - -class TextElement(val text : String) : Element { - override fun render(builder : StringBuilder, indent : String) { - builder.append("$indent$text\n") - } -} - -abstract class Tag(val name : String) : Element { - val children = ArrayList() - val attributes = HashMap() - - protected fun initTag(tag : T, init : T.() -> Unit) : T { - tag.init() - children.add(tag) - return tag - } - - override fun render(builder : StringBuilder, indent : String) { - builder.append("$indent<$name${renderAttributes()}>\n") - for (c in children) { - c.render(builder, indent + " ") - } - builder.append("$indent\n") - } - - private fun renderAttributes() : String? { - val builder = StringBuilder() - for (a in attributes.keySet()) { - builder.append(" $a=\"${attributes[a]}\"") - } - return builder.toString() - } -} - -abstract class TagWithText(name : String) : Tag(name) { - fun String.plus() { - children.add(TextElement(this)) - } -} - -class HTML() : TagWithText("html") { - fun head(init : Head.() -> Unit) = initTag(Head(), init) - - fun body(init : Body.() -> Unit) = initTag(Body(), init) -} - -class Head() : TagWithText("head") { - fun title(init : Title.() -> Unit) = initTag(Title(), init) -} - -class Title() : TagWithText("title") - -abstract class BodyTag(name : String) : TagWithText(name) { - fun b(init : B.() -> Unit) = initTag(B(), init) - fun p(init : P.() -> Unit) = initTag(P(), init) - fun h1(init : H1.() -> Unit) = initTag(H1(), init) - fun ul(init : UL.() -> Unit) = initTag(UL(), init) - fun a(href : String, init : A.() -> Unit) { - val a = initTag(A(), init) - a.href = href - } -} - -class Body() : BodyTag("body") -class UL() : BodyTag("ul") { - fun li(init : LI.() -> Unit) = initTag(LI(), init) -} - -class B() : BodyTag("b") -class LI() : BodyTag("li") -class P() : BodyTag("p") -class H1() : BodyTag("h1") -class A() : BodyTag("a") { - public var href : String - get() = attributes["href"] - set(value) { - attributes["href"] = value - } -} - -fun html(init : HTML.() -> Unit) : HTML { - val html = HTML() - html.init() - return html -} - -// An excerpt from the Standard Library -fun Map.set(key : K, value : V) = this.put(key, value) diff --git a/build-tools/test/longer-examples/Life.kt b/build-tools/test/longer-examples/Life.kt deleted file mode 100644 index d660385cbb6..00000000000 --- a/build-tools/test/longer-examples/Life.kt +++ /dev/null @@ -1,167 +0,0 @@ -/** - * This is a straightforward implementation of The Game of Life - * See http://en.wikipedia.org/wiki/Conway's_Game_of_Life - */ -package life - -import java.util.Collections.* -import java.util.* - -/* - * A field where cells live. Effectively immutable - */ -class Field( - val width : Int, - val height : Int, - // This function tells the constructor which cells are alive - // if init(i, j) is true, the cell (i, j) is alive - init : (Int, Int) -> Boolean -) { - private val live : Array> = Array(height) {i -> Array(width) {j -> init(i, j)}} - - private fun liveCount(i : Int, j : Int) - = if (i in 0..height-1 && - j in 0..width-1 && - live[i][j]) 1 else 0 - - // How many neighbors of (i, j) are alive? - fun liveNeighbors(i : Int, j : Int) = - liveCount(i - 1, j - 1) + - liveCount(i - 1, j) + - liveCount(i - 1, j + 1) + - liveCount(i, j - 1) + - liveCount(i, j + 1) + - liveCount(i + 1, j - 1) + - liveCount(i + 1, j) + - liveCount(i + 1, j + 1) - - // You can say field[i, j], and this function gets called - fun get(i : Int, j : Int) = live[i][j] -} - -/** - * This function takes the present state of the field - * and return a new field representing the next moment of time - */ -fun next(field : Field) : Field { - return Field(field.width, field.height) {i, j -> - val n = field.liveNeighbors(i, j) - if (field[i, j]) - // (i, j) is alive - n in 2..3 // It remains alive iff it has 2 or 3 neighbors - else - // (i, j) is dead - n == 3 // A new cell is born if there are 3 neighbors alive - } -} - -/** A few colony examples here */ -fun main(args : Array) { - // Simplistic demo - printField("***", 3) - // "Star burst" - printField(""" - __*__ - _***_ - __*__ - """, 10) - // Stable colony - printField(""" - __*__ - _*_*_ - __*__ - """, 3) - // Stable from the step 2 - printField(""" - __**__ - __**__ - __**__ - """, 3) - // Oscillating colony - printField(""" - __**__ - __**__ - __**__ - __**__ - """, 6) - // A fancier oscillating colony - printField(""" - --------------- - ---***---***--- - --------------- - -*----*-*----*- - -*----*-*----*- - -*----*-*----*- - ---***---***--- - --------------- - ---***---***--- - -*----*-*----*- - -*----*-*----*- - -*----*-*----*- - --------------- - ---***---***--- - --------------- - """, 10) -} - -// UTILITIES - -fun printField(s : String, steps : Int) { - var field = makeField(s) - for (step in 1..steps) { - println("Step: $step") - for (i in 0..field.height-1) { - for (j in 0..field.width-1) { - print(if (field[i, j]) "*" else " ") - } - println("") - } - field = next(field) - } -} - -fun makeField(s : String) : Field { - val lines = s.split("\n").sure() - val w = max(lines.toList(), comparator {o1, o2 -> - val l1 : Int = o1?.size ?: 0 - val l2 = o2?.size ?: 0 - l1 - l2 - }).sure() - val data = Array(lines.size) {Array(w.size) {false}} - - // workaround - for (i in data.indices) { - data[i] = Array(w.size) {false} - for (j in data[i].indices) - data[i][j] = false - } - - for (line in lines.indices) { - for (x in lines[line].indices) { - val c = lines[line].sure()[x] - data[line][x] = c == '*' - } - } - - return Field(w.size, lines.size) {i, j -> data[i][j]} -} - - - -// An excerpt from the Standard Library -val String?.indices : IntRange get() = IntRange(0, this.sure().size) - -fun Map.set(k : K, v : V) { put(k, v) } - -fun comparator (f : (T, T) -> Int) : Comparator = object : Comparator { - override fun compare(o1 : T, o2 : T) : Int = f(o1, o2) - override fun equals(p : Any?) : Boolean = false -} - -val Array.isEmpty : Boolean get() = size == 0 - -fun > Array.to(result: C) : C { - for (elem in this) - result.add(elem) - return result -} diff --git a/build-tools/test/longer-examples/Maze.txt b/build-tools/test/longer-examples/Maze.txt deleted file mode 100644 index 54988184680..00000000000 --- a/build-tools/test/longer-examples/Maze.txt +++ /dev/null @@ -1,226 +0,0 @@ -/** - * Let's Walk Through a Maze. - * - * Imagine there is a maze whose walls are the big 'O' letters. - * Now, I stand where a big 'I' stands and some cool prize lies - * somewhere marked with a '$' sign. Like this: - * - * OOOOOOOOOOOOOOOOO - * O O - * O$ O O - * OOOOO O - * O O - * O OOOOOOOOOOOOOO - * O O I O - * O O - * OOOOOOOOOOOOOOOOO - * - * I want to get the prize, and this program helps me do so as soon - * as I possibly can by finding a shortest path through the maze. - */ -package maze - -import java.util.Collections.* -import java.util.* - -/** - * This function looks for a path from max.start to maze.end through - * free space (a path does not go through walls). One can move only - * straightly up, down, left or right, no diagonal moves allowed. - */ -fun findPath(maze : Maze) : List<#(Int, Int)>? { - val previous = HashMap<#(Int, Int), #(Int, Int)> - - val queue = LinkedList<#(Int, Int)> - val visited = HashSet<#(Int, Int)> - - queue.offer(maze.start) - visited.add(maze.start) - while (!queue.isEmpty()) { - val cell = queue.poll() - if (cell == maze.end) break - - for (newCell in maze.neighbors(cell._1, cell._2)) { - if (newCell in visited) continue - previous[newCell] = cell - queue.offer(newCell) - visited.add(cell) - } - } - - if (previous[maze.end] == null) return null - - val path = ArrayList<#(Int, Int)>() - var current = previous[maze.end] - while (current != maze.start) { - path.add(0, current) - current = previous[current] - } - return path -} - -/** - * Find neighbors of the (i, j) cell that are not walls - */ -fun Maze.neighbors(i : Int, j : Int) : List<#(Int, Int)> { - val result = ArrayList<#(Int, Int)> - addIfFree(i - 1, j, result) - addIfFree(i, j - 1, result) - addIfFree(i + 1, j, result) - addIfFree(i, j + 1, result) - return result -} - -fun Maze.addIfFree(i : Int, j : Int, result : List<#(Int, Int)>) { - if (i !in 0..height-1) return - if (j !in 0..width-1) return - if (walls[i][j]) return - - result.add(#(i, j)) -} - -/** - * A data class that represents a maze - */ -class Maze( - // Number or columns - val width : Int, - // Number of rows - val height : Int, - // true for a wall, false for free space - val walls : Array>, - // The starting point (must not be a wall) - val start : #(Int, Int), - // The target point (must not be a wall) - val end : #(Int, Int) -) { -} - -/** A few maze examples here */ -fun main(args : Array) { - printMaze("I $") - printMaze("I O $") - printMaze(""" - O $ - O - O - O - O I - """) - printMaze(""" - OOOOOOOOOOO - O $ O - OOOOOOO OOO - O O - OOOOO OOOOO - O O - O OOOOOOOOO - O OO - OOOOOO IO - """) - printMaze(""" - OOOOOOOOOOOOOOOOO - O O - O$ O O - OOOOO O - O O - O OOOOOOOOOOOOOO - O O I O - O O - OOOOOOOOOOOOOOOOO - """) -} - -// UTILITIES - -fun printMaze(str : String) { - val maze = makeMaze(str) - - println("Maze:") - val path = findPath(maze) - for (i in 0..maze.height - 1) { - for (j in 0..maze.width - 1) { - val cell = #(i, j) - print( - if (maze.walls[i][j]) "O" - else if (cell == maze.start) "I" - else if (cell == maze.end) "$" - else if (path != null && path.contains(cell)) "~" - else " " - ) - } - println("") - } - println("Result: " + if (path == null) "No path" else "Path found") - println("") -} - - -/** - * A maze is encoded in the string s: the big 'O' letters are walls. - * I stand where a big 'I' stands and the prize is marked with - * a '$' sign. - * - * Example: - * - * OOOOOOOOOOOOOOOOO - * O O - * O$ O O - * OOOOO O - * O O - * O OOOOOOOOOOOOOO - * O O I O - * O O - * OOOOOOOOOOOOOOOOO - */ -fun makeMaze(s : String) : Maze { - val lines = s.split("\n").sure() - val w = max(lines.toList(), comparator {o1, o2 -> - val l1 : Int = o1?.size ?: 0 - val l2 = o2?.size ?: 0 - l1 - l2 - }).sure() - val data = Array>(lines.size) {Array(w.size) {false}} - - var start : #(Int, Int)? = null - var end : #(Int, Int)? = null - - for (line in lines.indices) { - for (x in lines[line].indices) { - val c = lines[line].sure()[x] - data[line][x] = c == 'O' - when (c) { - 'I' -> start = #(line, x) - '$' -> end = #(line, x) - else -> {} - } - } - } - - if (start == null) { - throw IllegalArgumentException("No starting point in the maze (should be indicated with 'I')") - } - - if (end == null) { - throw IllegalArgumentException("No goal point in the maze (should be indicated with a '$' sign)") - } - - return Maze(w.size, lines.size, data, start.sure(), end.sure()) -} - - -// An excerpt from the Standard Library -val String?.indices : IntRange get() = IntRange(0, this.sure().size) - -fun Map.set(k : K, v : V) { put(k, v) } - -fun comparator (f : (T, T) -> Int) : Comparator = object : Comparator { - override fun compare(o1 : T, o2 : T) : Int = f(o1, o2) - override fun equals(p : Any?) : Boolean = false -} - -fun > Array.to(result: C) : C { - for (elem in this) - result.add(elem) - return result -} diff --git a/build.xml b/build.xml index 4172b626402..bfba0a2c86a 100644 --- a/build.xml +++ b/build.xml @@ -1,14 +1,16 @@ + + + + + - - - @@ -20,27 +22,38 @@ - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -48,136 +61,90 @@ - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + - - - - + + + + + + + + + + + + + + + + + + - + + + + + + + + - - @@ -197,40 +164,25 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -241,93 +193,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (kotlinc.internal.com.intellij.lang.ASTNode); } + + -keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); + } + + -keepclassmembers class * { + ** toString(); + ** hashCode(); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - (kotlinc.internal.com.intellij.lang.ASTNode); - } - - # Keep the special static methods that are required in enumeration classes. - -keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); - } - - -keepclassmembers class * { - ** toString(); - ** hashCode(); - ** project(); - - ** TYPE; - ** ourInstance; - } - ]]> - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + - + + + + + - - - - diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index ed2ccb6502c..02c480dd857 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -491,6 +491,11 @@ public class JetTypeMapper { return null; final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration(); + + while(functionDescriptor.getKind()==CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + functionDescriptor = functionDescriptor.getOverriddenDescriptors().iterator().next(); + } + JvmMethodSignature descriptor = mapSignature(functionDescriptor.getOriginal(), true, kind); String owner; String ownerForDefaultImpl; diff --git a/compiler/cli/bin/kotlinc-js b/compiler/cli/bin/kotlinc-js new file mode 100644 index 00000000000..8b446640181 --- /dev/null +++ b/compiler/cli/bin/kotlinc-js @@ -0,0 +1,86 @@ +#!/bin/bash --posix +# +############################################################################## +# Copyright 2002-2011, LAMP/EPFL +# Copyright 2011, JetBrains +# +# This is free software; see the distribution for copying conditions. +# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. +############################################################################## + +cygwin=false; +case "`uname`" in + CYGWIN*) cygwin=true ;; +esac + +# Finding the root folder for this Kotlin distribution +SOURCE=$0; +SCRIPT=`basename "$SOURCE"`; +while [ -h "$SOURCE" ]; do + SCRIPT=`basename "$SOURCE"`; + LOOKUP=`ls -ld "$SOURCE"`; + TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`; + if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then + SOURCE=${TARGET:-.}; + else + SOURCE=`dirname "$SOURCE"`/${TARGET:-.}; + fi; +done; + +# see #2092 +KOTLIN_HOME=`dirname "$SOURCE"` +KOTLIN_HOME=`cd "$KOTLIN_HOME"; pwd -P` +KOTLIN_HOME=`cd "$KOTLIN_HOME"/..; pwd` + +# Remove spaces from KOTLIN_HOME on windows +if $cygwin; then + KOTLIN_HOME=`cygpath --windows --short-name "$KOTLIN_HOME"` + KOTLIN_HOME=`cygpath --unix "$KOTLIN_HOME"` +fi + +[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M" + +# break out -D and -J options and add them to JAVA_OPTS as well +# so they reach the underlying JVM in time to do some good. The +# -D options will be available as system properties. +declare -a java_args +declare -a kotlin_args + +while [ $# -gt 0 ]; do + case "$1" in + -D*) + # pass to kotlin as well: otherwise we lose it sometimes when we + # need it, e.g. communicating with a server compiler. + java_args=("${java_args[@]}" "$1") + kotlin_args=("${kotlin_args[@]}" "$1") + shift + ;; + -J*) + # as with -D, pass to kotlin even though it will almost + # never be used. + java_args=("${java_args[@]}" "${1:2}") + kotlin_args=("${kotlin_args[@]}" "$1") + shift + ;; + *) + kotlin_args=("${kotlin_args[@]}" "$1") + shift + ;; + esac +done + +# reset "$@" to the remaining args +set -- "${kotlin_args[@]}" + +if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then + JAVACMD="$JAVA_HOME/bin/java" +fi + +CPSELECT="-cp " + +"${JAVACMD:=java}" \ + $JAVA_OPTS \ + "${java_args[@]}" \ + ${CPSELECT}${KOTLIN_HOME}"/lib/kotlin-compiler.jar" \ + org.jetbrains.jet.cli.js.K2JSCompiler "$@" diff --git a/compiler/cli/bin/kotlinc.bat b/compiler/cli/bin/kotlinc-js.bat similarity index 70% rename from compiler/cli/bin/kotlinc.bat rename to compiler/cli/bin/kotlinc-js.bat index 803309766f0..f8ae5f9279e 100644 --- a/compiler/cli/bin/kotlinc.bat +++ b/compiler/cli/bin/kotlinc-js.bat @@ -21,26 +21,12 @@ if "%_JAVACMD%"=="" set _JAVACMD=java rem We use the value of the JAVA_OPTS environment variable if defined set _JAVA_OPTS=-Xmx256M -Xms32M -set _TOOL_CLASSPATH= -if "%_TOOL_CLASSPATH%"=="" ( - for %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f" - for /d %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f" -) - -"%_JAVACMD%" %_JAVA_OPTS% -cp "%_TOOL_CLASSPATH%" org.jetbrains.jet.cli.jvm.K2JVMCompiler %* +"%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" org.jetbrains.jet.cli.js.K2JSCompiler %* goto end rem ########################################################################## rem # subroutines -:add_cpath - if "%_TOOL_CLASSPATH%"=="" ( - set _TOOL_CLASSPATH=%~1 - ) else ( - set _TOOL_CLASSPATH=%_TOOL_CLASSPATH%;%~1 - ) -goto :eof - :set_home set _BIN_DIR= for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi diff --git a/compiler/cli/bin/kotlinc b/compiler/cli/bin/kotlinc-jvm similarity index 85% rename from compiler/cli/bin/kotlinc rename to compiler/cli/bin/kotlinc-jvm index 22858259c8b..dc06268ad1a 100644 --- a/compiler/cli/bin/kotlinc +++ b/compiler/cli/bin/kotlinc-jvm @@ -39,18 +39,6 @@ if $cygwin; then KOTLIN_HOME=`cygpath --unix "$KOTLIN_HOME"` fi -# Constructing the extension classpath -TOOL_CLASSPATH="" -if [ -z "$TOOL_CLASSPATH" ] ; then - for ext in "$KOTLIN_HOME"/lib/* ; do - if [ -z "$TOOL_CLASSPATH" ] ; then - TOOL_CLASSPATH="$ext" - else - TOOL_CLASSPATH="$TOOL_CLASSPATH:$ext" - fi - done -fi - [ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M" # break out -D and -J options and add them to JAVA_OPTS as well @@ -69,7 +57,7 @@ while [ $# -gt 0 ]; do shift ;; -J*) - # as with -D, pass to scala even though it will almost + # as with -D, pass to kotlin even though it will almost # never be used. java_args=("${java_args[@]}" "${1:2}") kotlin_args=("${kotlin_args[@]}" "$1") @@ -94,5 +82,5 @@ CPSELECT="-cp " "${JAVACMD:=java}" \ $JAVA_OPTS \ "${java_args[@]}" \ - ${CPSELECT}${TOOL_CLASSPATH} \ + ${CPSELECT}${KOTLIN_HOME}"/lib/kotlin-compiler.jar" \ org.jetbrains.jet.cli.jvm.K2JVMCompiler "$@" diff --git a/compiler/cli/bin/kotlinc-jvm.bat b/compiler/cli/bin/kotlinc-jvm.bat new file mode 100644 index 00000000000..0f595255e4f --- /dev/null +++ b/compiler/cli/bin/kotlinc-jvm.bat @@ -0,0 +1,37 @@ +rem based on scalac.bat from the Scala distribution +rem ########################################################################## +rem # Copyright 2002-2011, LAMP/EPFL +rem # Copyright 2011, JetBrains +rem # +rem # This is free software; see the distribution for copying conditions. +rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A +rem # PARTICULAR PURPOSE. +rem ########################################################################## +@echo off + +@setlocal +call :set_home + +if not "%JAVA_HOME%"=="" ( + if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe" +) + +if "%_JAVACMD%"=="" set _JAVACMD=java + +rem We use the value of the JAVA_OPTS environment variable if defined +set _JAVA_OPTS=-Xmx256M -Xms32M + +"%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" org.jetbrains.jet.cli.jvm.K2JVMCompiler %* +goto end + +rem ########################################################################## +rem # subroutines + +:set_home + set _BIN_DIR= + for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi + set _KOTLIN_HOME=%_BIN_DIR%.. +goto :eof + +:end +@endlocal diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java index 88dc62ee16c..313fb21f255 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java @@ -16,12 +16,13 @@ package org.jetbrains.jet.cli.common; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import com.sampullara.cli.Args; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; -import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; -import org.jetbrains.jet.cli.common.messages.MessageRenderer; +import org.jetbrains.jet.cli.common.messages.*; import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException; +import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil; import java.io.PrintStream; import java.util.List; @@ -107,20 +108,25 @@ public abstract class CLICompiler sources, @NotNull final Config config) { AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector); - final List sources = environmentForJS.getSourceFiles(); analyzerWithCompilerReport.analyzeAndReport(new Function0() { @Override public AnalyzeExhaust invoke() { BindingContext context = AnalyzerFacadeForJS - .analyzeFiles(sources, Predicates.alwaysTrue(), new Config(environmentForJS.getProject()) { - @NotNull - @Override - protected List generateLibFiles() { - return Collections.emptyList(); - } - }); + .analyzeFiles(sources, Predicates.alwaysTrue(), config); return AnalyzeExhaust.success(context, JetStandardLibrary.getInstance()); } }, sources); + return analyzerWithCompilerReport.hasErrors(); + } - stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Greeting", NO_LOCATION)); - return ExitCode.OK; + @NotNull + private static Config getConfig(@NotNull K2JSCompilerArguments arguments, @NotNull Project project) { + if (arguments.libzip == null) { + return Config.getEmptyConfig(project); + } + return new ZippedLibrarySourcesConfig(project, arguments.libzip); } } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java index 75f0855d864..aedcb0643e9 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java @@ -22,12 +22,18 @@ import org.jetbrains.jet.cli.common.CompilerArguments; /** * @author Pavel Talanov */ -public class K2JSCompilerArguments extends CompilerArguments { - @Argument(value = "output", description = "Output directory") - public String outputDir; - @Argument(value = "module", description = "Module to compile") - public String module; +/** + * NOTE: for now K2JSCompiler supports only minimal amount of parameters required to launch it from the plugin. + * You can specify only one source folder, path to the file where generated file will be stored, path to zipped library sources. + */ +public class K2JSCompilerArguments extends CompilerArguments { + @Argument(value = "output", description = "Output file path") + public String outputFile; + + //NOTE: may well be a subject to change soon + @Argument(value = "libzip", description = "Path to zipped lib sources") + public String libzip; @Argument(value = "srcdir", description = "Sources directory") public String srcdir; @@ -41,7 +47,7 @@ public class K2JSCompilerArguments extends CompilerArguments { @Argument(value = "version", description = "Display compiler version") public boolean version; - @Argument(value = "help", alias = "h", description = "show help") + @Argument(value = "help", alias = "h", description = "Show help") public boolean help; @Override @@ -58,4 +64,9 @@ public class K2JSCompilerArguments extends CompilerArguments { public boolean isVersion() { return version; } + + @Override + public boolean isVerbose() { + return verbose; + } } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java index 6cf5b743e6a..b7d2a4b8935 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.cli.jvm; import com.google.common.base.Splitter; import com.google.common.collect.Iterables; import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; import jet.modules.Module; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.cli.common.CLICompiler; @@ -53,9 +52,7 @@ public class K2JVMCompiler extends CLICompiler modules = CompileEnvironmentUtil - .loadModuleScript(arguments.module, new PrintingMessageCollector(errStream, messageRenderer, false)); + .loadModuleScript(arguments.module, messageCollector); + messageCollector.setVerbose(oldVerbose); File directory = new File(arguments.module).getParentFile(); noErrors = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules, directory, arguments.jar, arguments.outputDir, @@ -132,10 +129,6 @@ public class K2JVMCompiler extends CLICompiler loadModuleScript(String moduleScriptFile, MessageCollector messageCollector) { Disposable disposable = new Disposable() { @Override @@ -159,7 +140,6 @@ public class CompileEnvironmentUtil { }; CompilerDependencies dependencies = CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR); JetCoreEnvironment scriptEnvironment = JetCoreEnvironment.getCoreEnvironmentForJVM(disposable, dependencies); - ensureRuntime(scriptEnvironment, dependencies); scriptEnvironment.addSources(moduleScriptFile); GenerationState generationState = KotlinToJVMBytecodeCompiler diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java index fafde19fca9..e9db023eee1 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java @@ -80,7 +80,9 @@ public class JetCoreEnvironment extends JavaCoreEnvironment { CompilerSpecialMode compilerSpecialMode = compilerDependencies.getCompilerSpecialMode(); - addToClasspath(compilerDependencies.getJdkJar()); + if (compilerSpecialMode.includeJdk()) { + addToClasspath(compilerDependencies.getJdkJar()); + } if (compilerSpecialMode.includeJdkHeaders()) { for (VirtualFile root : compilerDependencies.getJdkHeaderRoots()) { diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index 2605ad66056..e21c5525b64 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -72,8 +72,6 @@ public class KotlinToJVMBytecodeCompiler { configuration.getEnvironment().addToClasspath(new File(classpathRoot)); } - CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies()); - GenerationState generationState = analyzeAndGenerate(configuration); if (generationState == null) { return null; @@ -83,9 +81,7 @@ public class KotlinToJVMBytecodeCompiler { public static boolean compileModules( K2JVMCompileEnvironmentConfiguration configuration, - @NotNull List modules, - @NotNull File directory, @Nullable String jarPath, @Nullable String outputDir, @@ -132,8 +128,6 @@ public class KotlinToJVMBytecodeCompiler { } } - CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies()); - GenerationState generationState = analyzeAndGenerate(configuration); if (generationState == null) { return false; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerDependencies.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerDependencies.java index 05075e34c10..226771fe4b5 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerDependencies.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerDependencies.java @@ -45,6 +45,11 @@ public class CompilerDependencies { this.jdkHeadersJar = jdkHeadersJar; this.runtimeJar = runtimeJar; + if (compilerSpecialMode.includeJdk()) { + if (jdkJar == null) { + throw new IllegalArgumentException("jdk must be included for mode " + compilerSpecialMode); + } + } if (compilerSpecialMode.includeJdkHeaders()) { if (jdkHeadersJar == null) { throw new IllegalArgumentException("jdkHeaders must be included for mode " + compilerSpecialMode); @@ -101,7 +106,7 @@ public class CompilerDependencies { public static CompilerDependencies compilerDependenciesForProduction(@NotNull CompilerSpecialMode compilerSpecialMode) { return new CompilerDependencies( compilerSpecialMode, - findRtJar(), + compilerSpecialMode.includeJdk() ? findRtJar() : null, compilerSpecialMode.includeJdkHeaders() ? PathUtil.getAltHeadersPath() : null, compilerSpecialMode.includeKotlinRuntime() ? PathUtil.getDefaultRuntimePath() : null); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java index 032682e5bbc..a75759cc274 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java @@ -24,17 +24,22 @@ public enum CompilerSpecialMode { BUILTINS, JDK_HEADERS, STDLIB, - JS + IDEA, + JS, ; public boolean includeJdkHeaders() { - return this == REGULAR || this == STDLIB; + return this == REGULAR || this == STDLIB || this == IDEA; } public boolean includeKotlinRuntime() { return this == REGULAR; } + public boolean includeJdk() { + return this != IDEA; + } + public boolean isStubs() { return this == BUILTINS || this == JDK_HEADERS; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java index 381a89f9594..17e5b0b94cc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java @@ -70,7 +70,7 @@ class JavaDescriptorResolverHelper { return false; } - if (!staticMembers && member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) { + if (member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) { return false; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java index b54d9e306da..28703dc5a2f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java @@ -68,7 +68,7 @@ public abstract class DeclarationDescriptorImpl extends AnnotatedImpl implements @Override public String toString() { try { - return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "]"; + return DescriptorRenderer.DEBUG_TEXT.render(this) + "[" + getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "]"; } catch (Throwable e) { // DescriptionRenderer may throw if this is not yet completely initialized // It is very inconvenient while debugging diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java index e1cd4083a61..101c4a14e06 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java @@ -33,7 +33,7 @@ import java.util.*; * @author abreslav */ public class FunctionDescriptorUtil { - private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() { + private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java index ef24b557129..bd5bf229f73 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java @@ -140,7 +140,12 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp List typeParameters = getTypeConstructor().getParameters(); Map substitutionContext = SubstitutionUtils.buildSubstitutionContext(typeParameters, typeArguments); - return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext)); + + // Unsafe substitutor is OK, because no recursion can hurt us upon a trivial substitution: + // all the types are written explicitly in the code already, they can not get infinite. + // One exception is *-projections, but they need to be handled separately anyways. + TypeSubstitutor substitutor = TypeSubstitutor.createUnsafe(substitutionContext); + return new SubstitutingScope(scopeForMemberLookup, substitutor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java index c1f1472d2c5..12b8bb0fcf1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java @@ -37,7 +37,7 @@ public interface DiagnosticHolder { if (diagnostic.getSeverity() == Severity.ERROR) { PsiFile psiFile = diagnostic.getPsiFile(); List textRanges = diagnostic.getTextRanges(); - throw new IllegalStateException(diagnostic.getFactory().getName() + DiagnosticUtils.atLocation(psiFile, textRanges.get(0))); + throw new IllegalStateException(diagnostic.getFactory().getName() + " " + psiFile.getName() + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0))); } } }; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index bde9faee6cb..5920a5bf212 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -912,7 +912,7 @@ public class DescriptorResolver { return propertyDescriptor; } - public void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) { + public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) { if (ErrorUtils.isErrorType(type)) return; JetTypeElement typeElement = typeReference.getTypeElement(); @@ -922,32 +922,32 @@ public class DescriptorResolver { List arguments = type.getArguments(); assert parameters.size() == arguments.size(); - List typeReferences = typeElement.getTypeArgumentsAsTypes(); - assert typeReferences.size() == arguments.size() : typeElement.getText(); + List jetTypeArguments = typeElement.getTypeArgumentsAsTypes(); + assert jetTypeArguments.size() == arguments.size() : typeElement.getText(); TypeSubstitutor substitutor = TypeSubstitutor.create(type); - for (int i = 0, projectionsSize = typeReferences.size(); i < projectionsSize; i++) { - JetTypeReference argumentTypeReference = typeReferences.get(i); + for (int i = 0; i < jetTypeArguments.size(); i++) { + JetTypeReference jetTypeArgument = jetTypeArguments.get(i); - if (argumentTypeReference == null) continue; + if (jetTypeArgument == null) continue; JetType typeArgument = arguments.get(i).getType(); - checkBounds(argumentTypeReference, typeArgument, trace); + checkBounds(jetTypeArgument, typeArgument, trace); TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); - checkBounds(argumentTypeReference, typeArgument, typeParameterDescriptor, substitutor, trace); + checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace); } } - public void checkBounds( - @NotNull JetTypeReference argumentTypeReference, + public static void checkBounds( + @NotNull JetTypeReference jetTypeArgument, @NotNull JetType typeArgument, @NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull TypeSubstitutor substitutor, BindingTrace trace) { for (JetType bound : typeParameterDescriptor.getUpperBounds()) { JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT); if (!JetTypeChecker.INSTANCE.isSubtypeOf(typeArgument, substitutedBound)) { - trace.report(UPPER_BOUND_VIOLATED.on(argumentTypeReference, substitutedBound, typeArgument)); + trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument)); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 5ce30d66e3f..7a4386e4d3a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -71,7 +71,7 @@ public class DescriptorUtils { typeConstructors.put(typeParameter.getTypeConstructor(), typeParameter); } //noinspection unchecked - return (Descriptor) functionDescriptor.substitute(new TypeSubstitutor(TypeSubstitutor.TypeSubstitution.EMPTY) { + return (Descriptor) functionDescriptor.substitute(new TypeSubstitutor(TypeSubstitution.EMPTY) { @Override public boolean inRange(@NotNull TypeConstructor typeConstructor) { return typeConstructors.containsKey(typeConstructor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index e27a69392b9..ab54ab52fe4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -126,7 +126,7 @@ public class TypeResolver { int expectedArgumentCount = parameters.size(); int actualArgumentCount = arguments.size(); if (ErrorUtils.isError(typeConstructor)) { - result[0] = ErrorUtils.createErrorType("??"); + result[0] = ErrorUtils.createErrorType("[Error type: " + typeConstructor + "]"); } else { if (actualArgumentCount != expectedArgumentCount) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 222d0143e38..bed5e619a86 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; @@ -407,15 +406,17 @@ public class CallResolver { return; } + Set unmappedArguments = Sets.newLinkedHashSet(); ValueArgumentsToParametersMapper.Status argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, - candidateCall); + candidateCall, unmappedArguments); if (!argumentMappingStatus.isSuccess()) { candidateCall.addStatus(OTHER_ERROR); if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR) { checkTypesWithNoCallee(context.toBasic()); return; } + checkUnknownArgumentTypes(context.toBasic(), unmappedArguments); } List jetTypeArguments = context.call.getTypeArguments(); @@ -611,6 +612,15 @@ public class CallResolver { } } + private void checkUnknownArgumentTypes(BasicResolutionContext context, Set unknownArguments) { + for (ValueArgument valueArgument : unknownArguments) { + JetExpression argumentExpression = valueArgument.getArgumentExpression(); + if (argumentExpression != null) { + expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.trace); + } + } + } + private static void replaceValueParametersWithSubstitutedOnes( ResolvedCallImpl candidateCall, @NotNull D substitutedDescriptor) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java index 769d11f2881..105ec16e5f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java @@ -71,7 +71,8 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap public static Status mapValueArgumentsToParameters( @NotNull Call call, @NotNull TracingStrategy tracing, - @NotNull ResolvedCallImpl candidateCall + @NotNull ResolvedCallImpl candidateCall, + @NotNull Set unmappedArguments ) { TemporaryBindingTrace temporaryTrace = candidateCall.getTrace(); Map varargs = Maps.newHashMap(); @@ -99,14 +100,19 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedName()); if (valueParameterDescriptor == null) { temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference)); + unmappedArguments.add(valueArgument); status = ERROR; } else { + temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); if (!usedParameters.add(valueParameterDescriptor)) { temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference)); + unmappedArguments.add(valueArgument); + status = WEAK_ERROR; + } + else { + status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs)); } - temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); - status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs)); } if (somePositioned) { temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference)); @@ -134,12 +140,14 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap } else { temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); - status = ERROR; + unmappedArguments.add(valueArgument); + status = WEAK_ERROR; } } else { temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); - status = ERROR; + unmappedArguments.add(valueArgument); + status = WEAK_ERROR; } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java index f61be7f2a29..d9104ad76b7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java @@ -49,7 +49,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { } final TypeProjection projection = new TypeProjection(type); - return TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() { + return TypeSubstitutor.create(new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { if (constructors.contains(key)) { @@ -484,7 +484,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { } public class Solution implements ConstraintSystemSolution { - private final TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() { + private final TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/CompositeTypeSubstitution.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/CompositeTypeSubstitution.java index 32b2cfd5b52..5d03af142fc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/CompositeTypeSubstitution.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/CompositeTypeSubstitution.java @@ -21,16 +21,16 @@ import org.jetbrains.annotations.NotNull; /** * @author abreslav */ -public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstitution { - private final TypeSubstitutor.TypeSubstitution[] inner; +public class CompositeTypeSubstitution implements TypeSubstitution { + private final TypeSubstitution[] inner; - public CompositeTypeSubstitution(@NotNull TypeSubstitutor.TypeSubstitution... inner) { + public CompositeTypeSubstitution(@NotNull TypeSubstitution... inner) { this.inner = inner; } @Override public TypeProjection get(TypeConstructor key) { - for (TypeSubstitutor.TypeSubstitution substitution : inner) { + for (TypeSubstitution substitution : inner) { TypeProjection value = substitution.get(key); if (value != null) return value; } @@ -39,7 +39,7 @@ public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstituti @Override public boolean isEmpty() { - for (TypeSubstitutor.TypeSubstitution substitution : inner) { + for (TypeSubstitution substitution : inner) { if (!substitution.isEmpty()) return false; } return true; @@ -48,7 +48,7 @@ public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstituti @Override public String toString() { StringBuilder builder = new StringBuilder(); - for (TypeSubstitutor.TypeSubstitution substitution : inner) { + for (TypeSubstitution substitution : inner) { builder.append(substitution).append(" * "); } return builder.toString(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java index 305739640a2..eada1237fb8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java @@ -36,7 +36,7 @@ public class DescriptorSubstitutor { @NotNull DeclarationDescriptor newContainingDeclaration, @NotNull List result) { final Map mutableSubstitution = Maps.newHashMap(); - TypeSubstitutor substitutor = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() { + TypeSubstitutor substitutor = TypeSubstitutor.create(new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java index c50f40dfb81..90f5e04380b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.util.CommonSuppliers; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -120,6 +121,21 @@ public class SubstitutionUtils { return false; } + public static Map removeTrivialSubstitutions(Map context) { + Map clean = Maps.newHashMap(context); + boolean changed = false; + for (Iterator> iterator = clean.entrySet().iterator(); iterator.hasNext(); ) { + Map.Entry entry = iterator.next(); + TypeConstructor key = entry.getKey(); + TypeProjection value = entry.getValue(); + if (key == value.getType().getConstructor() && value.getProjectionKind() == Variance.INVARIANT) { + iterator.remove(); + changed = true; + } + } + return changed ? clean : context; + } + public static void assertNotImmediatelyRecursive(Map context) { // Make sure we never replace a T with "Foo" or something similar, // because the substitution will not terminate in this case diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitution.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitution.java new file mode 100644 index 00000000000..8986c0842f4 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitution.java @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.Nullable; + +/** +* @author abreslav +*/ +public interface TypeSubstitution { + TypeSubstitution EMPTY = new TypeSubstitution() { + @Override + public TypeProjection get(TypeConstructor key) { + return null; + } + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public String toString() { + return "Empty TypeSubstitution"; + } + }; + + @Nullable + TypeProjection get(TypeConstructor key); + boolean isEmpty(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index 6e5e4e8e7e0..b92cae7e00a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -16,14 +16,16 @@ package org.jetbrains.jet.lang.types; -import com.google.common.collect.Sets; +import com.google.common.collect.Lists; import com.intellij.openapi.progress.ProcessCanceledException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; +import org.jetbrains.jet.lang.types.lang.JetStandardClasses; -import java.util.*; +import java.util.List; +import java.util.Map; /** * @author abreslav @@ -32,57 +34,6 @@ public class TypeSubstitutor { private static final int MAX_RECURSION_DEPTH = 100; - public static TypeSubstitutor makeConstantSubstitutor(Collection typeParameterDescriptors, JetType type) { - final Set constructors = Sets.newHashSet(); - for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) { - constructors.add(typeParameterDescriptor.getTypeConstructor()); - } - final TypeProjection projection = new TypeProjection(type); - - return TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() { - @Override - public TypeProjection get(TypeConstructor key) { - if (constructors.contains(key)) { - return projection; - } - return null; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public String toString() { - return "TypeConstructor.makeConstantSubstitutor(" + constructors + " -> " + projection + ")"; - } - }); - } - - public interface TypeSubstitution { - TypeSubstitution EMPTY = new TypeSubstitution() { - @Override - public TypeProjection get(TypeConstructor key) { - return null; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public String toString() { - return "Empty TypeSubstitution"; - } - }; - - @Nullable - TypeProjection get(TypeConstructor key); - boolean isEmpty(); - } - public static class MapToTypeSubstitutionAdapter implements TypeSubstitution { private final @NotNull Map substitutionContext; @@ -108,7 +59,7 @@ public class TypeSubstitutor { public static final TypeSubstitutor EMPTY = create(TypeSubstitution.EMPTY); - public static final class SubstitutionException extends Exception { + private static final class SubstitutionException extends Exception { public SubstitutionException(String message) { super(message); } @@ -122,8 +73,16 @@ public class TypeSubstitutor { return create(new CompositeTypeSubstitution(substitutions)); } + /** No assertion for immediate recursion */ + public static TypeSubstitutor createUnsafe(@NotNull Map substitutionContext) { + Map cleanContext = SubstitutionUtils.removeTrivialSubstitutions(substitutionContext); + return create(new MapToTypeSubstitutionAdapter(cleanContext)); + } + public static TypeSubstitutor create(@NotNull Map substitutionContext) { - return create(new MapToTypeSubstitutionAdapter(substitutionContext)); + Map cleanContext = SubstitutionUtils.removeTrivialSubstitutions(substitutionContext); + //SubstitutionUtils.assertNotImmediatelyRecursive(cleanContext); + return createUnsafe(cleanContext); } public static TypeSubstitutor create(@NotNull JetType context) { @@ -158,7 +117,7 @@ public class TypeSubstitutor { } try { - return unsafeSubstitute(type, howThisTypeIsUsed); + return unsafeSubstitute(new TypeProjection(howThisTypeIsUsed, type), 0).getType(); } catch (SubstitutionException e) { return ErrorUtils.createErrorType(e.getMessage()); } @@ -171,170 +130,100 @@ public class TypeSubstitutor { } try { - return unsafeSubstitute(type, howThisTypeIsUsed); + return unsafeSubstitute(new TypeProjection(howThisTypeIsUsed, type), 0).getType(); } catch (SubstitutionException e) { return null; } } @NotNull - private JetType unsafeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) throws SubstitutionException { - if (ErrorUtils.isErrorType(type)) return type; + private TypeProjection unsafeSubstitute(@NotNull TypeProjection originalProjection, int recursionDepth) throws SubstitutionException { + assertRecursionDepth(recursionDepth, originalProjection, substitution); + // The type is within the substitution range, i.e. T or T? + JetType type = originalProjection.getType(); + if (JetStandardClasses.isNothing(type) || ErrorUtils.isErrorType(type)) return originalProjection; - TypeProjection value = getValueWithCorrectNullability(substitution, type); - if (value != null) { - TypeConstructor constructor = type.getConstructor(); - assert constructor.getDeclarationDescriptor() instanceof TypeParameterDescriptor; + TypeProjection replacement = substitution.get(type.getConstructor()); - TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) constructor.getDeclarationDescriptor(); + if (replacement != null) { + // It must be a type parameter: only they can be directly substituted for + TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor(); - TypeProjection result = substitutionResult(typeParameterDescriptor, howThisTypeIsUsed, Variance.INVARIANT, value, 0); + switch (conflictType(originalProjection.getProjectionKind(), replacement.getProjectionKind())) { + case OUT_IN_IN_POSITION: + throw new SubstitutionException("Out-projection in in-position"); + case IN_IN_OUT_POSITION: + replacement = SubstitutionUtils.makeStarProjection(typeParameter); + break; + } + boolean resultingIsNullable = type.isNullable() || replacement.getType().isNullable(); + JetType substitutedType = TypeUtils.makeNullableAsSpecified(replacement.getType(), resultingIsNullable); + Variance resultingProjectionKind = combine(originalProjection.getProjectionKind(), replacement.getProjectionKind()); - return TypeUtils.makeNullableIfNeeded(result.getType(), type.isNullable()); + return new TypeProjection(resultingProjectionKind, substitutedType); } + else { + // The type is not within the substitution range, i.e. Foo, Bar etc. + List substitutedArguments = substituteTypeArguments( + type.getConstructor().getParameters(), type.getArguments(), recursionDepth); - return specializeType(type, howThisTypeIsUsed, 0); - } - - private TypeProjection getValueWithCorrectNullability(TypeSubstitution substitution, JetType type) { - TypeProjection typeProjection = substitution.get(type.getConstructor()); - if (typeProjection == null) return null; - - return type.isNullable() ? makeNullableProjection(typeProjection) : typeProjection; - } - - @NotNull - private static TypeProjection makeNullableProjection(@NotNull TypeProjection value) { - return new TypeProjection(value.getProjectionKind(), TypeUtils.makeNullable(value.getType())); - } - - private JetType specializeType(JetType subjectType, Variance callSiteVariance, int recursionDepth) throws SubstitutionException { - assertRecursionDepth(recursionDepth, subjectType, substitution); - if (ErrorUtils.isErrorType(subjectType)) return subjectType; - - List newArguments = new ArrayList(); - List arguments = subjectType.getArguments(); - for (int i = 0, argumentsSize = arguments.size(); i < argumentsSize; i++) { - TypeProjection argument = arguments.get(i); - TypeParameterDescriptor parameterDescriptor = subjectType.getConstructor().getParameters().get(i); - newArguments.add(substituteInProjection( - substitution, - argument, - parameterDescriptor, - callSiteVariance, recursionDepth + 1)); + JetType substitutedType = new JetTypeImpl(type.getAnnotations(), // Old annotations. This is questionable + type.getConstructor(), // The same constructor + type.isNullable(), // Same nullability + substitutedArguments, + new SubstitutingScope(type.getMemberScope(), this)); + return new TypeProjection(originalProjection.getProjectionKind(), substitutedType); } - return new JetTypeImpl( - subjectType.getAnnotations(), - subjectType.getConstructor(), - subjectType.isNullable(), - newArguments, - new SubstitutingScope(subjectType.getMemberScope(), this)); } - @NotNull - private TypeProjection substituteInProjection( - @NotNull TypeSubstitution substitutionContext, - @NotNull TypeProjection passedProjection, - @NotNull TypeParameterDescriptor correspondingTypeParameter, - @NotNull Variance contextCallSiteVariance, - int recursionDepth) throws SubstitutionException { - assertRecursionDepth(recursionDepth, correspondingTypeParameter, passedProjection, substitution); + private List substituteTypeArguments(List typeParameters, List typeArguments, int recursionDepth) + throws SubstitutionException { + List substitutedArguments = Lists.newArrayList(); + for (int i = 0; i < typeParameters.size(); i++) { + TypeParameterDescriptor typeParameter = typeParameters.get(i); + TypeProjection typeArgument = typeArguments.get(i); - JetType typeToSubstituteIn = passedProjection.getType(); - if (ErrorUtils.isErrorType(typeToSubstituteIn)) return passedProjection; + TypeProjection substitutedTypeArgument = unsafeSubstitute(typeArgument, recursionDepth + 1); - Variance passedProjectionKind = passedProjection.getProjectionKind(); - Variance parameterVariance = correspondingTypeParameter.getVariance(); - - Variance effectiveProjectionKind = asymmetricOr(passedProjectionKind, parameterVariance); - Variance effectiveContextVariance = contextCallSiteVariance.superpose(effectiveProjectionKind); - - TypeProjection projectionValue = getValueWithCorrectNullability(substitutionContext, typeToSubstituteIn); - if (projectionValue != null) { - assert typeToSubstituteIn.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; - - if (!allows(parameterVariance, passedProjectionKind)) { - return SubstitutionUtils.makeStarProjection(correspondingTypeParameter); + switch (conflictType(typeParameter.getVariance(), substitutedTypeArgument.getProjectionKind())) { + case OUT_IN_IN_POSITION: + substitutedTypeArgument = new TypeProjection(Variance.IN_VARIANCE, typeParameter.getLowerBoundsAsType()); + break; + case IN_IN_OUT_POSITION: + substitutedTypeArgument = SubstitutionUtils.makeStarProjection(typeParameter); + break; } - return substitutionResult(correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue, recursionDepth + 1); + substitutedArguments.add(substitutedTypeArgument); } - return new TypeProjection( - passedProjectionKind, - specializeType( - typeToSubstituteIn, - effectiveContextVariance, recursionDepth + 1)); + return substitutedArguments; } - private TypeProjection substitutionResult( - TypeParameterDescriptor correspondingTypeParameter, - Variance effectiveContextVariance, - Variance passedProjectionKind, - TypeProjection value, - int recursionDepth) throws SubstitutionException { - assertRecursionDepth(recursionDepth, correspondingTypeParameter, value, substitution); + private static Variance combine(Variance typeParameterVariance, Variance projectionKind) { + if (typeParameterVariance == Variance.INVARIANT) return projectionKind; + if (projectionKind == Variance.INVARIANT) return typeParameterVariance; + return typeParameterVariance.superpose(projectionKind); + } - Variance projectionKindValue = value.getProjectionKind(); - JetType typeValue = value.getType(); - Variance effectiveProjectionKindValue = asymmetricOr(passedProjectionKind, projectionKindValue); - JetType effectiveTypeValue; - switch (effectiveContextVariance) { - case INVARIANT: - effectiveProjectionKindValue = projectionKindValue; - effectiveTypeValue = typeValue; - break; - case IN_VARIANCE: - if (projectionKindValue == Variance.OUT_VARIANCE) { - throw new SubstitutionException(""); // TODO -// effectiveProjectionKindValue = Variance.INVARIANT; -// effectiveTypeValue = JetStandardClasses.getNothingType(); - } - else { - effectiveTypeValue = typeValue; - } - break; - case OUT_VARIANCE: - if (projectionKindValue == Variance.IN_VARIANCE) { - effectiveProjectionKindValue = Variance.INVARIANT; - effectiveTypeValue = correspondingTypeParameter.getUpperBoundsAsType(); - } - else { - effectiveTypeValue = typeValue; - } - break; - default: - throw new IllegalStateException(effectiveContextVariance.toString()); + private enum VarianceConflictType { + NO_CONFLICT, + IN_IN_OUT_POSITION, + OUT_IN_IN_POSITION; + } + + private static VarianceConflictType conflictType(Variance position, Variance argument) { + if (position == Variance.IN_VARIANCE && argument == Variance.OUT_VARIANCE) { + return VarianceConflictType.OUT_IN_IN_POSITION; } - -// if (!allows(effectiveContextVariance, projectionKindValue)) { -// throw new SubstitutionException(""); // TODO : error message -// } -// - return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, effectiveContextVariance, recursionDepth + 1)); - } - - private static Variance asymmetricOr(Variance a, Variance b) { - return a == Variance.INVARIANT ? b : a; - } - - private static boolean allows(Variance declarationSiteVariance, Variance callSiteVariance) { - switch (declarationSiteVariance) { - case INVARIANT: return true; - case IN_VARIANCE: return callSiteVariance != Variance.OUT_VARIANCE; - case OUT_VARIANCE: return callSiteVariance != Variance.IN_VARIANCE; + if (position == Variance.OUT_VARIANCE && argument == Variance.IN_VARIANCE) { + return VarianceConflictType.IN_IN_OUT_POSITION; } - throw new IllegalStateException(declarationSiteVariance.toString()); + return VarianceConflictType.NO_CONFLICT; } - private static void assertRecursionDepth(int recursionDepth, TypeParameterDescriptor parameter, TypeProjection value, TypeSubstitution substitution) { + private static void assertRecursionDepth(int recursionDepth, TypeProjection projection, TypeSubstitution substitution) { if (recursionDepth > MAX_RECURSION_DEPTH) { - throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(value) + " for " + safeToString(parameter) + "; substitution: " + safeToString(substitution)); - } - } - - private static void assertRecursionDepth(int recursionDepth, JetType type, TypeSubstitution substitution) { - if (recursionDepth > MAX_RECURSION_DEPTH) { - throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(type) + "; substitution: " + safeToString(substitution)); + throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(projection) + "; substitution: " + safeToString(substitution)); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java index e7c6b4a7434..3e2c231da4c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -369,7 +369,7 @@ public class TypeUtils { @NotNull public static JetType makeUnsubstitutedType(ClassDescriptor classDescriptor, JetScope unsubstitutedMemberScope) { if (ErrorUtils.isError(classDescriptor)) { - return ErrorUtils.createErrorType("This is very helpful diagnostics message"); + return ErrorUtils.createErrorType("Unsubstituted type for " + classDescriptor); } List arguments = getDefaultTypeProjections(classDescriptor.getTypeConstructor().getParameters()); return new JetTypeImpl( diff --git a/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java b/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java index 0e72ffe5bd1..5657df41a84 100644 --- a/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java +++ b/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java @@ -29,16 +29,11 @@ public class JetMainDetector { private JetMainDetector() { } - public static boolean hasMain(List declarations) { - for (JetDeclaration declaration : declarations) { - if (declaration instanceof JetNamedFunction) { - if (isMain((JetNamedFunction) declaration)) return true; - } - } - return false; + public static boolean hasMain(@NotNull List declarations) { + return findMainFunction(declarations) != null; } - public static boolean isMain(JetNamedFunction function) { + public static boolean isMain(@NotNull JetNamedFunction function) { if ("main".equals(function.getName())) { List parameters = function.getValueParameters(); if (parameters.size() == 1) { @@ -52,10 +47,24 @@ public class JetMainDetector { } @Nullable - public static JetFile getFileWithMain(@NotNull List files) { + public static JetNamedFunction getMainFunction(@NotNull List files) { for (JetFile file : files) { - if (hasMain(file.getDeclarations())) { - return file; + JetNamedFunction mainFunction = findMainFunction(file.getDeclarations()); + if (mainFunction != null) { + return mainFunction; + } + } + return null; + } + + @Nullable + private static JetNamedFunction findMainFunction(@NotNull List declarations) { + for (JetDeclaration declaration : declarations) { + if (declaration instanceof JetNamedFunction) { + JetNamedFunction candidateFunction = (JetNamedFunction) declaration; + if (isMain(candidateFunction)) { + return candidateFunction; + } } } return null; diff --git a/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java b/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java index 98283823254..55389a43d94 100644 --- a/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java +++ b/compiler/frontend/src/org/jetbrains/jet/resolve/DescriptorRenderer.java @@ -46,6 +46,14 @@ public class DescriptorRenderer implements Renderer { public static final DescriptorRenderer TEXT = new DescriptorRenderer(); + public static final DescriptorRenderer DEBUG_TEXT = new DescriptorRenderer() { + @Override + protected boolean hasDefaultValue(ValueParameterDescriptor descriptor) { + // hasDefaultValue() has effects + return descriptor.declaresDefaultValue(); + } + }; + public static final DescriptorRenderer HTML = new DescriptorRenderer() { @Override @@ -79,7 +87,7 @@ public class DescriptorRenderer implements Renderer { @Override public Void visitValueParameterDescriptor(ValueParameterDescriptor descriptor, StringBuilder builder) { super.visitVariableDescriptor(descriptor, builder, true); - if (descriptor.hasDefaultValue()) { + if (hasDefaultValue(descriptor)) { builder.append(" = ..."); } return null; @@ -89,6 +97,10 @@ public class DescriptorRenderer implements Renderer { private DescriptorRenderer() { } + protected boolean hasDefaultValue(ValueParameterDescriptor descriptor) { + return descriptor.hasDefaultValue(); + } + protected String renderKeyword(String keyword) { return keyword; } diff --git a/compiler/integration-tests/data/antTaskJvm/build.log.expected b/compiler/integration-tests/data/antTaskJvm/build.log.expected new file mode 100644 index 00000000000..3f171971523 --- /dev/null +++ b/compiler/integration-tests/data/antTaskJvm/build.log.expected @@ -0,0 +1,10 @@ +OUT Buildfile: build.xml +OUT +OUT build: +OUT [kotlinc] Compiling [[TestData]/hello.kt] => [[Temp]/hello.jar] +OUT [kotlinc] LOGGING: For source: [TestData]/hello.kt +OUT [kotlinc] LOGGING: Emitting: Hello/namespace.class +OUT +OUT BUILD SUCCESSFUL +OUT Total time: [time] +Return code: 0 diff --git a/compiler/integration-tests/data/antTaskJvm/build.xml b/compiler/integration-tests/data/antTaskJvm/build.xml new file mode 100644 index 00000000000..c5d0a6c090a --- /dev/null +++ b/compiler/integration-tests/data/antTaskJvm/build.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/compiler/integration-tests/data/hello.kt b/compiler/integration-tests/data/antTaskJvm/hello.kt similarity index 100% rename from compiler/integration-tests/data/hello.kt rename to compiler/integration-tests/data/antTaskJvm/hello.kt diff --git a/compiler/integration-tests/data/hello.run.expected b/compiler/integration-tests/data/antTaskJvm/hello.run.expected similarity index 100% rename from compiler/integration-tests/data/hello.run.expected rename to compiler/integration-tests/data/antTaskJvm/hello.run.expected diff --git a/compiler/integration-tests/data/compilationFailed/hello.compile.expected b/compiler/integration-tests/data/compilationFailed/hello.compile.expected new file mode 100644 index 00000000000..4b0d95cb23a --- /dev/null +++ b/compiler/integration-tests/data/compilationFailed/hello.compile.expected @@ -0,0 +1,4 @@ +OUT ERROR: [TestData]/hello.kt: (4, 5) Unresolved reference: a +OUT WARNING: [TestData]/hello.kt: (4, 5) The expression is unused +ERR exec() finished with COMPILATION_ERROR return code +Return code: 1 diff --git a/compiler/integration-tests/data/compilationFailed/hello.kt b/compiler/integration-tests/data/compilationFailed/hello.kt new file mode 100644 index 00000000000..139b0ddc047 --- /dev/null +++ b/compiler/integration-tests/data/compilationFailed/hello.kt @@ -0,0 +1,5 @@ +package Hello + +fun main(args : Array) { + a +} diff --git a/compiler/integration-tests/data/hello.compile.expected b/compiler/integration-tests/data/compileAndRunHelloApp/hello.compile.expected similarity index 100% rename from compiler/integration-tests/data/hello.compile.expected rename to compiler/integration-tests/data/compileAndRunHelloApp/hello.compile.expected diff --git a/compiler/integration-tests/data/compileAndRunHelloApp/hello.kt b/compiler/integration-tests/data/compileAndRunHelloApp/hello.kt new file mode 100644 index 00000000000..4c4a4b67c8c --- /dev/null +++ b/compiler/integration-tests/data/compileAndRunHelloApp/hello.kt @@ -0,0 +1,5 @@ +package Hello + +fun main(args : Array) { + System.out?.println("Hello!") +} diff --git a/compiler/integration-tests/data/compileAndRunHelloApp/hello.run.expected b/compiler/integration-tests/data/compileAndRunHelloApp/hello.run.expected new file mode 100644 index 00000000000..fc47ec99014 --- /dev/null +++ b/compiler/integration-tests/data/compileAndRunHelloApp/hello.run.expected @@ -0,0 +1,2 @@ +OUT Hello! +Return code: 0 diff --git a/compiler/integration-tests/data/compileAndRunModule/Smoke.compile.expected b/compiler/integration-tests/data/compileAndRunModule/Smoke.compile.expected new file mode 100644 index 00000000000..a14ac74940f --- /dev/null +++ b/compiler/integration-tests/data/compileAndRunModule/Smoke.compile.expected @@ -0,0 +1 @@ +Return code: 0 diff --git a/build-tools/test/modules/smoke/Smoke.kt b/compiler/integration-tests/data/compileAndRunModule/Smoke.kt similarity index 95% rename from build-tools/test/modules/smoke/Smoke.kt rename to compiler/integration-tests/data/compileAndRunModule/Smoke.kt index 49d0e6db899..dc2ec6c6eb9 100644 --- a/build-tools/test/modules/smoke/Smoke.kt +++ b/compiler/integration-tests/data/compileAndRunModule/Smoke.kt @@ -1,5 +1,5 @@ -package Smoke - -fun main(args: Array) { - print("${args[0]}|${args[1]}|${args[2]}") -} +package Smoke + +fun main(args: Array) { + print("${args[0]}|${args[1]}|${args[2]}") +} diff --git a/build-tools/test/modules/smoke/Smoke.kts b/compiler/integration-tests/data/compileAndRunModule/Smoke.kts similarity index 93% rename from build-tools/test/modules/smoke/Smoke.kts rename to compiler/integration-tests/data/compileAndRunModule/Smoke.kts index 179d700646e..da112ebae67 100644 --- a/build-tools/test/modules/smoke/Smoke.kts +++ b/compiler/integration-tests/data/compileAndRunModule/Smoke.kts @@ -1,7 +1,7 @@ -import kotlin.modules.* - -fun project() { - module("smoke") { - sources += "Smoke.kt" - } -} +import kotlin.modules.* + +fun project() { + module("smoke") { + sources += "Smoke.kt" + } +} diff --git a/compiler/integration-tests/data/compileAndRunModule/Smoke.run.expected b/compiler/integration-tests/data/compileAndRunModule/Smoke.run.expected new file mode 100644 index 00000000000..83e2a5a6dc9 --- /dev/null +++ b/compiler/integration-tests/data/compileAndRunModule/Smoke.run.expected @@ -0,0 +1,2 @@ +OUT 1|2|3 +Return code: 0 diff --git a/compiler/integration-tests/data/help.expected b/compiler/integration-tests/data/help/help.expected similarity index 100% rename from compiler/integration-tests/data/help.expected rename to compiler/integration-tests/data/help/help.expected diff --git a/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java b/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java new file mode 100644 index 00000000000..63d5c095d5e --- /dev/null +++ b/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin; + +import org.junit.Test; + +import java.io.File; + +import static junit.framework.Assert.assertEquals; + +public class AntTaskTest extends KotlinIntegrationTestBase { + @Test + public void antTaskJvm() throws Exception { + final String jar = tempDir.getAbsolutePath() + File.separator + "hello.jar"; + + assertEquals("compilation failed", 0, runAnt("build.log", "build.xml")); + runJava("hello.run", "-cp", jar, "Hello.namespace"); + } + + @Override + protected String normalizeOutput(String content) { + return super.normalizeOutput(content) + .replaceAll("Total time: .+\n", "Total time: [time]\n"); + } + + private int runAnt(String logName, String scriptName) throws Exception { + return runJava(logName, "-jar", getAntHome() + File.separator + "lib" + File.separator + "ant-launcher.jar", + "-Dkotlin.lib=" + getCompilerLib(), + "-Dtest.data=" + testDataDir, + "-Dtemp=" + tempDir, + "-f", scriptName); + } + + private static String getAntHome() { + return getKotlinProjectHome().getAbsolutePath() + File.separator + "dependencies" + File.separator + "ant"; + } +} diff --git a/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java b/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java index 72d912e47a7..49874136c71 100644 --- a/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java +++ b/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java @@ -35,4 +35,19 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase { assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar)); runJava("hello.run", "-cp", jar, "Hello.namespace"); } + + @Test + public void compileAndRunModule() throws Exception { + final String jar = tempDir.getAbsolutePath() + File.separator + "smoke.jar"; + + assertEquals("compilation failed", 0, runCompiler("Smoke.compile", "-module", "Smoke.kts", "-jar", jar)); + runJava("Smoke.run", "-cp", jar + File.pathSeparator + getKotlinRuntimePath(), "Smoke.namespace", "1", "2", "3"); + } + + @Test + public void compilationFailed() throws Exception { + final String jar = tempDir.getAbsolutePath() + File.separator + "smoke.jar"; + + runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar); + } } diff --git a/compiler/integration-tests/src/org/jetbrains/kotlin/KotlinIntegrationTestBase.java b/compiler/integration-tests/src/org/jetbrains/kotlin/KotlinIntegrationTestBase.java index d2656fe31b6..6bd46107cad 100644 --- a/compiler/integration-tests/src/org/jetbrains/kotlin/KotlinIntegrationTestBase.java +++ b/compiler/integration-tests/src/org/jetbrains/kotlin/KotlinIntegrationTestBase.java @@ -29,12 +29,11 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; +import org.junit.ComparisonFailure; import org.junit.Rule; import org.junit.rules.TestRule; import org.junit.rules.TestWatcher; import org.junit.runner.Description; -import sun.misc.JarFilter; import java.io.File; import java.io.IOException; @@ -47,12 +46,22 @@ import static org.junit.Assert.*; public abstract class KotlinIntegrationTestBase { protected File tempDir; + protected File testDataDir; @Rule public TestRule watchman = new TestWatcher() { @Override protected void starting(Description description) { - tempDir = Files.createTempDir(); + try { + tempDir = Files.createTempDir().getCanonicalFile(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + + final File baseTestDataDir = + new File(getKotlinProjectHome(), "compiler" + File.separator + "integration-tests" + File.separator + "data"); + testDataDir = new File(baseTestDataDir, description.getMethodName()); } @Override @@ -74,13 +83,7 @@ public abstract class KotlinIntegrationTestBase { protected int runCompiler(String logName, String... arguments) throws Exception { final File lib = getCompilerLib(); - final File[] jars = lib.listFiles(new JarFilter()); - final String classpath = StringUtil.join(jars, new Function() { - @Override - public String fun(File file) { - return file.getAbsolutePath(); - } - }, File.pathSeparator); + final String classpath = lib.getAbsolutePath() + File.separator + "kotlin-compiler.jar"; Collection javaArgs = new ArrayList(); javaArgs.add("-cp"); @@ -93,7 +96,7 @@ public abstract class KotlinIntegrationTestBase { protected int runJava(String logName, String... arguments) throws Exception { GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setWorkDirectory(getTestDataDirectory()); + commandLine.setWorkDirectory(testDataDir); commandLine.setExePath(getJavaRuntime().getAbsolutePath()); commandLine.addParameters(arguments); @@ -104,32 +107,52 @@ public abstract class KotlinIntegrationTestBase { assertEquals("Non-zero exit code", 0, exitCode); } else { - check(logName, executionLog); + check(logName, executionLog.toString()); } return exitCode; } - protected void check(String baseName, StringBuilder content) throws IOException { - final File tmpFile = new File(getTestDataDirectory(), baseName + ".tmp"); - final File expectedFile = new File(getTestDataDirectory(), baseName + ".expected"); + private static String replacePath(String content, File path, String pathId) { + final String absolutePath = path.getAbsolutePath(); + + return content + .replace(absolutePath + "/", pathId + "/") + .replace(absolutePath + "\\", pathId + "/") + .replace(absolutePath, pathId); + } + + protected String normalizeOutput(String content) { + content = replacePath(content, testDataDir, "[TestData]"); + content = replacePath(content, tempDir, "[Temp]"); + content = replacePath(content, getCompilerLib(), "[CompilerLib]"); + return content; + } + + protected void check(String baseName, String content) throws IOException { + final File actualFile = new File(testDataDir, baseName + ".actual"); + final File expectedFile = new File(testDataDir, baseName + ".expected"); + + final String normalizedContent = normalizeOutput(content); if (!expectedFile.isFile()) { - Files.write(content, tmpFile, Charsets.UTF_8); + Files.write(normalizedContent, actualFile, Charsets.UTF_8); fail("No .expected file " + expectedFile); } else { final String goldContent = Files.toString(expectedFile, UTF_8); try { - assertEquals(goldContent, content.toString()); + assertEquals(goldContent, normalizedContent); + actualFile.delete(); } - finally { - tmpFile.delete(); + catch (ComparisonFailure e) { + Files.write(normalizedContent, actualFile, Charsets.UTF_8); + throw e; } } } - protected int runProcess(final GeneralCommandLine commandLine, final StringBuilder executionLog) throws ExecutionException { + protected static int runProcess(final GeneralCommandLine commandLine, final StringBuilder executionLog) throws ExecutionException { OSProcessHandler handler = new OSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString(), commandLine.getCharset()); @@ -184,8 +207,10 @@ public abstract class KotlinIntegrationTestBase { return file; } - protected static File getTestDataDirectory() { - return new File(getKotlinProjectHome(), "compiler" + File.separator + "integration-tests" + File.separator + "data"); + protected static String getKotlinRuntimePath() { + final File file = new File(getCompilerLib(), "kotlin-runtime.jar"); + assertTrue("no kotlin runtime at " + file, file.isFile()); + return file.getAbsolutePath(); } protected static File getKotlinProjectHome() { diff --git a/compiler/testData/codegen/regressions/kt1061.kt b/compiler/testData/codegen/regressions/kt1061.kt new file mode 100644 index 00000000000..af7d1d7b6d2 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1061.kt @@ -0,0 +1,7 @@ +//KT-1061 Can't call function defined as a val + +object X { + val doit = { (i: Int) -> i } +} + +fun box() : String = if (X.doit(3) == 3) "OK" else "fail" diff --git a/compiler/testData/codegen/regressions/kt1249.kt b/compiler/testData/codegen/regressions/kt1249.kt new file mode 100644 index 00000000000..13d136fe06d --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1249.kt @@ -0,0 +1,12 @@ +//KT-1249 IllegalStateException invoking function property +class TestClass(val body : () -> Unit) : Any { + fun run() { + body() + } +} + +fun box() : String { + TestClass({}).run() + return "OK" +} + diff --git a/compiler/testData/codegen/regressions/kt1290.kt b/compiler/testData/codegen/regressions/kt1290.kt new file mode 100644 index 00000000000..da8de1b208f --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1290.kt @@ -0,0 +1,14 @@ +//KT-1290 Method property in constructor causes NPE + +class Foo(val filter: (T) -> Boolean) { + public fun bar(tee: T) : Boolean { + return filter(tee); + } +} + +fun foo() = Foo({ (i: Int) -> i < 5 }).bar(2) + +fun box() : String { + if (!foo()) return "fail" + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt1600.kt b/compiler/testData/codegen/regressions/kt1600.kt new file mode 100644 index 00000000000..e9f111a98b3 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1600.kt @@ -0,0 +1,8 @@ +abstract class Foo { + fun hello(id: T) = "O$id" +} + +class Bar: Foo() { +} + +fun box() = Bar().hello("K") diff --git a/compiler/testData/codegen/regressions/kt606.kt b/compiler/testData/codegen/regressions/kt606.kt index 83dc0b6f83d..b2012f84174 100644 --- a/compiler/testData/codegen/regressions/kt606.kt +++ b/compiler/testData/codegen/regressions/kt606.kt @@ -23,43 +23,7 @@ trait ChannelPipelineFactory { fun getPipeline() : ChannelPipeline } -fun testKt606() { - StandardPipelineFactory({ print("OK") }).getPipeline() -} - -//Tests for duplicates -//KT-1061 Can't call function defined as a val -object X { - val doit = { (i: Int) -> i } -} - -fun testKt1061() : String = if (X.doit(3) == 3) "OK" else "fail" - - -//KT-1249 IllegalStateException invoking function property -class TestClass(val body : () -> Unit) : Any { - fun run() { - body() - } -} - -fun testKt1249() { - TestClass({}).run() -} - -class Foo(val filter: (T) -> Boolean) { - public fun bar(tee: T) : Boolean { - return filter(tee); - } -} - -//KT-1290 Method property in constructor causes NPE -fun testKt1290() = Foo({ (i: Int) -> i < 5 }).bar(2) - fun box() : String { - testKt606() - testKt1061() - testKt1249() - if (!testKt1290()) return "fail" + StandardPipelineFactory({ print("OK") }).getPipeline() return "OK" -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/spreadArguments/SpreadVarargs.jet b/compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.jet similarity index 100% rename from compiler/testData/diagnostics/tests/spreadArguments/SpreadVarargs.jet rename to compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.jet diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt1897_diagnostic_part.jet b/compiler/testData/diagnostics/tests/checkArguments/kt1897_diagnostic_part.jet new file mode 100644 index 00000000000..e5d1371119a --- /dev/null +++ b/compiler/testData/diagnostics/tests/checkArguments/kt1897_diagnostic_part.jet @@ -0,0 +1,8 @@ +package a + +fun foo(i: Int, s: String) { +} + +fun test() { + foo("", 1, xx) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt1940.jet b/compiler/testData/diagnostics/tests/checkArguments/kt1940.jet new file mode 100644 index 00000000000..9253288be94 --- /dev/null +++ b/compiler/testData/diagnostics/tests/checkArguments/kt1940.jet @@ -0,0 +1,9 @@ +//KT-1940 Exception while repeating named parameters +package kt1940 + +fun foo(i: Int) {} + +fun test() { + foo(1, i = 2) //exception + foo(i = 1, i = 2) //exception +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/Projections.jet b/compiler/testData/diagnostics/tests/generics/Projections.jet new file mode 100644 index 00000000000..f2fdba24b41 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/Projections.jet @@ -0,0 +1,56 @@ +class In() { + fun f(t : T) : Unit {} + fun f(t : Int) : Int = 1 + fun f1(t : T) : Unit {} +} + +class Out() { + fun f() : T {throw IllegalStateException()} + fun f(a : Int) : Int = a +} + +class Inv() { + fun f(t : T) : T = t + fun inf(t : T) : Unit {} + fun outf() : T {throw IllegalStateException()} +} + +fun testInOut() { + In().f("1"); + (null as In).f("1") + (null as In).f("1") // Wrong Arg + (null as In<*>).f("1") // Wrong Arg + + In().f(1); + (null as In).f(1) + (null as In).f(1) + (null as In).f1(1) // !! + (null as In<*>).f(1); + + Out().f(1) + (null as Out).f(1) + (null as Out).f(1) + (null as Out<*>).f(1) + + Out().f() + (null as Out).f() + (null as Out).f() + (null as Out<*>).f() + + Inv().f(1) + (null as Inv).f(1) + (null as Inv).f(1) // !! + (null as Inv<*>).f(1) // !! + + Inv().inf(1) + (null as Inv).inf(1) + (null as Inv).inf(1) // !! + (null as Inv<*>).inf(1) // !! + + Inv().outf() + (null as Inv).outf() : Int // Type mismatch + (null as Inv).outf() + (null as Inv<*>).outf() + + Inv().outf(1) // Wrong Arg +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundCheck.jet b/compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundCheck.jet new file mode 100644 index 00000000000..33a4ca82b6f --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundCheck.jet @@ -0,0 +1,3 @@ +open class C> +class TestOK : C() +class TestFail : C<C<TestFail>>() diff --git a/compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundWithTwoArguments.jet b/compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundWithTwoArguments.jet new file mode 100644 index 00000000000..3e58ee5012a --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/RecursiveUpperBoundWithTwoArguments.jet @@ -0,0 +1 @@ +class DString>, B : D> diff --git a/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.jet b/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.jet new file mode 100644 index 00000000000..0f3bd459335 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.jet @@ -0,0 +1,16 @@ +// FILE: Aaa.java +// http://youtrack.jetbrains.com/issue/KT-1880 + +public class Aaa { + public static final int i = 1; +} + +// FILE: Bbb.java + +public class Bbb extends Aaa { + public static final String i = "s"; +} + +// FILE: b.kt + +fun foo() = Bbb.i diff --git a/compiler/testData/diagnostics/tests/regressions/kt1736.jet b/compiler/testData/diagnostics/tests/regressions/kt1736.jet new file mode 100644 index 00000000000..8214fc8e645 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt1736.jet @@ -0,0 +1,10 @@ +//KT-1736 AssertionError in CallResolver + +package kt1736 + +object Obj { + fun method() { + } +} + +val x = Obj.method{ -> } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/kt1244.jet b/compiler/testData/diagnostics/tests/scopes/kt1244.jet new file mode 100644 index 00000000000..16bc89dc4ba --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/kt1244.jet @@ -0,0 +1,13 @@ +//KT-1244 Frontend allows access to private members of other classes + +package kt1244 + +class A { + private var a = "" +} + +class B() { + { + A().a = "Hello" + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/kt1738.jet b/compiler/testData/diagnostics/tests/scopes/kt1738.jet new file mode 100644 index 00000000000..3ad2f15a121 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/kt1738.jet @@ -0,0 +1,11 @@ +//KT-1738 Make it possible to define visibility for constructor parameters which become properties + +package kt1738 + +class A(private var i: Int, var j: Int) { +} + +fun test(a: A) { + a.i++ + a.j++ +} \ No newline at end of file diff --git a/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.java b/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.java new file mode 100644 index 00000000000..6fb68424b6f --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.java @@ -0,0 +1,7 @@ +package test; + +interface Foo {} + +class MethodTypePOneUpperBound { + void bar() {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.kt b/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.kt new file mode 100644 index 00000000000..c97120384de --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.kt @@ -0,0 +1,7 @@ +package test + +trait Foo : java.lang.Object + +open class MethodTypePOneUpperBound() : java.lang.Object() { + open fun bar() = #() +} diff --git a/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.txt b/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.txt new file mode 100644 index 00000000000..9c83aa73f65 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodTypePOneUpperBound.txt @@ -0,0 +1,8 @@ +namespace test + +abstract trait test.Foo : java.lang.Object { +} +open class test.MethodTypePOneUpperBound : java.lang.Object { + final /*constructor*/ fun (): test.MethodTypePOneUpperBound + open fun bar(): jet.Tuple0 +} diff --git a/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.java b/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.java new file mode 100644 index 00000000000..ff53fa28737 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.java @@ -0,0 +1,8 @@ +package test; + +interface Foo {} +interface Bar {} + +class MethodTypePTwoUpperBounds { + void foo() {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.kt b/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.kt new file mode 100644 index 00000000000..82b931e6692 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.kt @@ -0,0 +1,10 @@ +package test + +trait Foo : java.lang.Object +trait Bar : java.lang.Object + +open class MethodTypePTwoUpperBounds() : java.lang.Object() { + open fun foo(): Unit + where T : Foo?, T : Bar? + {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.txt b/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.txt new file mode 100644 index 00000000000..8c4d02d3bcb --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodTypePTwoUpperBounds.txt @@ -0,0 +1,10 @@ +namespace test + +abstract trait test.Foo : java.lang.Object { +} +abstract trait test.Bar : java.lang.Object { +} +open class test.MethodTypePTwoUpperBounds : java.lang.Object { + final /*constructor*/ fun (): test.MethodTypePTwoUpperBounds + open fun foo(): jet.Tuple0 +} diff --git a/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt new file mode 100644 index 00000000000..cc7759ea454 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamTwoUpperBounds.kt @@ -0,0 +1,8 @@ +package test + +trait Foo +trait Bar + +fun foo() + where T : Foo, T : Bar + = #() diff --git a/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamTwoUpperBounds.txt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamTwoUpperBounds.txt new file mode 100644 index 00000000000..e09763ba27a --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamTwoUpperBounds.txt @@ -0,0 +1,7 @@ +namespace test + +abstract trait test.Foo : jet.Any { +} +abstract trait test.Bar : jet.Any { +} +final fun foo(): jet.Tuple0 diff --git a/compiler/tests/org/jetbrains/jet/CompileCompilerDependenciesTest.java b/compiler/tests/org/jetbrains/jet/CompileCompilerDependenciesTest.java index d024dfd8572..c3e084a4c68 100644 --- a/compiler/tests/org/jetbrains/jet/CompileCompilerDependenciesTest.java +++ b/compiler/tests/org/jetbrains/jet/CompileCompilerDependenciesTest.java @@ -52,7 +52,7 @@ public class CompileCompilerDependenciesTest { public static CompilerDependencies compilerDependenciesForTests(@NotNull CompilerSpecialMode compilerSpecialMode, boolean mockJdk) { return new CompilerDependencies( compilerSpecialMode, - mockJdk ? JetTestUtils.findMockJdkRtJar() : CompilerDependencies.findRtJar(), + compilerSpecialMode.includeJdk() ? (mockJdk ? JetTestUtils.findMockJdkRtJar() : CompilerDependencies.findRtJar()) : null, compilerSpecialMode.includeJdkHeaders() ? ForTestCompileJdkHeaders.jdkHeadersForTests() : null, compilerSpecialMode.includeKotlinRuntime() ? ForTestCompileRuntime.runtimeJarForTests() : null); } diff --git a/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java b/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java index 81603c5ac85..f3b85d2d459 100644 --- a/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java +++ b/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java @@ -91,12 +91,18 @@ public class ResolveDescriptorsFromExternalLibraries { hasErrors |= testLibrary("com.google.guava", "guava", "12.0-rc2"); hasErrors |= testLibrary("org.springframework", "spring-core", "3.1.1.RELEASE"); + hasErrors |= testLibrary("com.vaadin", "vaadin", "6.6.8"); + hasErrors |= testLibraryFromUrl("http://mcvaadin.googlecode.com/files/mcvaadin.jar"); return hasErrors; } + private boolean testLibraryFromUrl(@NotNull String urlJar) throws Exception { + return testLibraryFile(getLibraryFromUrl(urlJar), urlJar); + } + private boolean testLibrary(@NotNull String org, @NotNull String module, @NotNull String rev) throws Exception { LibFromMaven lib = new LibFromMaven(org, module, rev); - File jar = getLibrary(lib); + File jar = getLibraryFromMaven(lib); return testLibraryFile(jar, lib.toString()); } @@ -185,22 +191,40 @@ public class ResolveDescriptorsFromExternalLibraries { } @NotNull - private File getLibrary(@NotNull LibFromMaven lib) throws Exception { - File userHome = new File(System.getProperty("user.home")); - String fileName = lib.getModule() + "-" + lib.getRev() + ".jar"; + private File getLibraryFromUrl(@NotNull String url) throws Exception { - File dir = new File(userHome, ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule()); + String fileName = url + .replaceAll("^http://", "") + .replaceAll("/", "_") + ; + File dir = new File(userHome(), ".kotlin-project/resolve-libraries"); File file = new File(dir, fileName); + + return getFileFromUrl(url, file, url); + } + + @NotNull + private File getLibraryFromMaven(@NotNull LibFromMaven lib) throws Exception { + String fileName = lib.getModule() + "-" + lib.getRev() + ".jar"; + + File dir = new File(userHome(), ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule()); + + File file = new File(dir, fileName); + String uri = url(lib); + + return getFileFromUrl(lib.toString(), file, uri); + } + + private File getFileFromUrl(@NotNull String lib, @NotNull File file, @NotNull String uri) throws IOException { if (file.exists()) { return file; } - JetTestUtils.mkdirs(dir); + JetTestUtils.mkdirs(file.getParentFile()); - File tmp = new File(dir, fileName + "~"); + File tmp = new File(file.getPath() + "~"); - String uri = url(lib); GetMethod method = new GetMethod(uri); FileOutputStream os = null; @@ -252,6 +276,8 @@ public class ResolveDescriptorsFromExternalLibraries { } } + private static File userHome() {return new File(System.getProperty("user.home"));} + private static String url(LibFromMaven lib) { return "http://repo1.maven.org/maven2/" + lib.getOrg().replace(".", "/") + "/" + lib.getModule() + "/" + lib.getRev() + "/" + lib.getModule() + "-" + lib.getRev() + ".jar"; diff --git a/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java b/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java index 5a87c6f2b4c..268b7eeb884 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java @@ -76,8 +76,24 @@ public class ExtensionFunctionsTest extends CodegenTestCase { createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS); blackBoxFile("extensionFunctions/nested2.kt"); } + public void testKt606() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS); blackBoxFile("regressions/kt606.kt"); } + + public void testKt1061() throws Exception { + createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS); + blackBoxFile("regressions/kt1061.kt"); + } + + public void testKt1249() throws Exception { + createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS); + blackBoxFile("regressions/kt1249.kt"); + } + + public void testKt1290() throws Exception { + createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS); + blackBoxFile("regressions/kt1290.kt"); + } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java index 52f97ed5942..a051fa517e5 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java @@ -75,4 +75,8 @@ public class ObjectGenTest extends CodegenTestCase { public void testKt1186() throws Exception { blackBoxFile("regressions/kt1186.kt"); } + + public void testKt1600() throws Exception { + blackBoxFile("regressions/kt1600.kt"); + } } diff --git a/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index 8ce58931133..389371f5a8a 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -25,11 +25,13 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.CompileCompilerDependenciesTest; import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory; @@ -37,7 +39,6 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; -import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeConstructor; @@ -70,6 +71,11 @@ public abstract class ExpectedResolveData { public PsiElement getElement() { return element; } + + @Override + public String toString() { + return DiagnosticUtils.atLocation(element); + } } private final Map declarationToPosition = Maps.newHashMap(); diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 63d44934ab2..c04ae767ba5 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -91,6 +91,9 @@ + + + diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 6079753e73c..14ae9e857cf 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -34,6 +34,10 @@ specify.type.explicitly.add.return.type.action.name=Specify Return Type Explicit specify.type.explicitly.add.action.name=Specify Type Explicitly specify.type.explicitly.remove.action.name=Remove Explicitly Specified Type +goto.super.function.chooser.title=Choose super function +goto.super.property.chooser.title=Choose super property +goto.super.class.chooser.title=Choose super class or interface + livetemplate.description.main=main() function livetemplate.description.soutp=Prints function parameter names and values to System.out livetemplate.description.iter=Iterate over elements of iterable diff --git a/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java b/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java index 1449d48d69e..b64f5e5b531 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java @@ -17,12 +17,15 @@ package org.jetbrains.jet.plugin; import com.intellij.ide.IconProvider; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.PlatformIcons; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; @@ -40,24 +43,8 @@ public class JetIconProvider extends IconProvider { public Icon getIcon(@NotNull PsiElement psiElement, int flags) { if (psiElement instanceof JetFile) { JetFile file = (JetFile) psiElement; - List declarations = file.getDeclarations(); - JetClassOrObject mostImportantClass = null; - String nameWithoutExtension = StringUtil.getPackageName(file.getName()); - for (JetDeclaration declaration : declarations) { - if (mostImportantClass == null && declaration instanceof JetClassOrObject) { - mostImportantClass = (JetClassOrObject) declaration; - } - else if (declaration instanceof JetClassOrObject) { - JetClassOrObject object = (JetClassOrObject) declaration; - if (nameWithoutExtension.equals(object.getName())) { - mostImportantClass = object; - } - } - } - if (mostImportantClass != null) { - return getIcon(mostImportantClass, flags); - } - return JetIcons.FILE; + JetClassOrObject mainClass = getMainClass(file); + return mainClass != null ? getIcon(mainClass, flags) : JetIcons.FILE; } if (psiElement instanceof JetNamespaceHeader) { return (flags & Iconable.ICON_FLAG_OPEN) != 0 ? PlatformIcons.PACKAGE_OPEN_ICON : PlatformIcons.PACKAGE_ICON; @@ -101,4 +88,20 @@ public class JetIconProvider extends IconProvider { } return null; } + + @Nullable + public static JetClassOrObject getMainClass(@NotNull JetFile file) { + List classes = ContainerUtil.filter(file.getDeclarations(), new Condition() { + @Override + public boolean value(JetDeclaration jetDeclaration) { + return jetDeclaration instanceof JetClassOrObject; + } + }); + if (classes.size() == 1) { + if (StringUtil.getPackageName(file.getName()).equals(classes.get(0).getName())) { + return (JetClassOrObject) classes.get(0); + } + } + return null; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java b/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java index 44c7ca2d826..33073a31b28 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java @@ -26,6 +26,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -47,16 +48,24 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider else { ref = PsiTreeUtil.getParentOfType(originalElement, JetReferenceExpression.class); } - if (ref != null) { - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) ref.getContainingFile()) - .getBindingContext(); - DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ref); - if (declarationDescriptor != null) { - return render(declarationDescriptor, bindingContext, element, originalElement, mergeKotlinAndJava); + PsiElement declarationPsiElement = PsiTreeUtil.getParentOfType(originalElement, JetDeclaration.class); + if (ref != null || declarationPsiElement != null) { + BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( + (JetFile) originalElement.getContainingFile()).getBindingContext(); + + if (ref != null) { + DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ref); + if (declarationDescriptor != null) { + return render(declarationDescriptor, bindingContext, element, originalElement, mergeKotlinAndJava); + } + if (declarationPsiElement != null) { + declarationPsiElement = BindingContextUtils.resolveToDeclarationPsiElement(bindingContext, ref); + } } - PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(bindingContext, ref); - if (psiElement != null) { - declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement); + + if (declarationPsiElement != null) { + DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, + declarationPsiElement); if (declarationDescriptor != null) { return render(declarationDescriptor, bindingContext, element, originalElement, mergeKotlinAndJava); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java new file mode 100644 index 00000000000..b6e1d69ad01 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java @@ -0,0 +1,129 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.navigation.NavigationUtil; +import com.intellij.codeInsight.navigation.actions.GotoSuperAction; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.EditSourceUtil; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.JetStandardClasses; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; + +import java.util.Collection; +import java.util.List; + +/** + * @author Evgeny Gerashchenko + * @since 06.05.12 + */ +public class GotoSuperActionHandler implements CodeInsightActionHandler { + @Override + public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID); + + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + if (element == null) return; + @SuppressWarnings("unchecked") JetNamedDeclaration funOrClass = + PsiTreeUtil.getParentOfType(element, JetNamedFunction.class, JetClass.class, JetProperty.class); + if (funOrClass == null) return; + + final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) file).getBindingContext(); + + final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, funOrClass); + + + Collection superDescriptors; + String message; + if (descriptor instanceof ClassDescriptor) { + Collection supertypes = ((ClassDescriptor) descriptor).getTypeConstructor().getSupertypes(); + List superclasses = ContainerUtil.mapNotNull(supertypes, new Function() { + @Override + public ClassDescriptor fun(JetType type) { + ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); + if (descriptor instanceof ClassDescriptor) { + return (ClassDescriptor) descriptor; + } + return null; + } + }); + ContainerUtil.removeDuplicates(superclasses); + superDescriptors = superclasses; + message = JetBundle.message("goto.super.class.chooser.title"); + } + else if (descriptor instanceof CallableMemberDescriptor) { + superDescriptors = ((CallableMemberDescriptor) descriptor).getOverriddenDescriptors(); + if (descriptor instanceof PropertyDescriptor) { + message = JetBundle.message("goto.super.property.chooser.title"); + } + else if (descriptor instanceof SimpleFunctionDescriptor) { + message = JetBundle.message("goto.super.function.chooser.title"); + } + else + throw new IllegalStateException("Unknown member type: " + descriptor.getClass().getName()); + } + else + return; + + List superDeclarations = ContainerUtil.mapNotNull(superDescriptors, new Function() { + @Override + public PsiElement fun(DeclarationDescriptor descriptor) { + if (JetStandardClasses.getAny() == descriptor) { + return null; + } + return BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); + } + }); + if (superDeclarations.isEmpty()) return; + if (superDeclarations.size() == 1) { + Navigatable navigatable = EditSourceUtil.getDescriptor(superDeclarations.get(0)); + if (navigatable != null && navigatable.canNavigate()) { + navigatable.navigate(true); + } + } + else { + PsiElement[] superDeclarationsArray = PsiUtilCore.toPsiElementArray(superDeclarations); + JBPopup popup = descriptor instanceof ClassDescriptor + ? NavigationUtil.getPsiElementPopup(superDeclarationsArray, message) + : NavigationUtil.getPsiElementPopup(superDeclarationsArray, + new JetFunctionPsiElementCellRenderer(bindingContext), message); + popup.showInBestPositionFor(editor); + } + } + + @Override + public boolean startInWriteAction() { + return false; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/JetFunctionPsiElementCellRenderer.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/JetFunctionPsiElementCellRenderer.java new file mode 100644 index 00000000000..dc4110271dd --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/JetFunctionPsiElementCellRenderer.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight; + +import com.intellij.ide.util.DefaultPsiElementCellRenderer; +import com.intellij.psi.PsiElement; +import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +/** +* @author Evgeny Gerashchenko +* @since 06.05.12 +*/ +public class JetFunctionPsiElementCellRenderer extends DefaultPsiElementCellRenderer { + private final BindingContext bindingContext; + + public JetFunctionPsiElementCellRenderer(BindingContext bindingContext) { + this.bindingContext = bindingContext; + } + + @Override + public String getElementText(PsiElement element) { + if (element instanceof JetNamedFunction) { + JetNamedFunction function = (JetNamedFunction) element; + SimpleFunctionDescriptor fd = + bindingContext.get(BindingContext.FUNCTION, function); + assert fd != null; + return DescriptorRenderer.TEXT.render(fd); + } + return super.getElementText(element); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/JetTypeDeclarationProvider.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/JetTypeDeclarationProvider.java new file mode 100644 index 00000000000..ee4636819d1 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/JetTypeDeclarationProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight; + +import com.intellij.codeInsight.navigation.actions.TypeDeclarationProvider; +import com.intellij.psi.PsiElement; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; + +/** + * @author Evgeny Gerashchenko + * @since 07.05.12 + */ +public class JetTypeDeclarationProvider implements TypeDeclarationProvider { + @Override + public PsiElement[] getSymbolTypeDeclarations(PsiElement symbol) { + if (symbol instanceof JetElement && symbol.getContainingFile() instanceof JetFile) { + BindingContext bindingContext = + WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) symbol.getContainingFile()).getBindingContext(); + DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, symbol); + if (descriptor instanceof CallableDescriptor) { + JetType type = ((CallableDescriptor) descriptor).getReturnType(); + if (type != null) { + ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor(); + if (classifierDescriptor != null) { + PsiElement typeElement = BindingContextUtils.descriptorToDeclaration(bindingContext, classifierDescriptor); + if (typeElement != null) { + return new PsiElement[] {typeElement}; + } + } + } + } + } + return new PsiElement[0]; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtils.java b/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtils.java index b8a2d62b782..e3e5a24cea0 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtils.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.plugin.compiler; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; import com.intellij.compiler.impl.javaCompiler.OutputItemImpl; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompilerMessageCategory; @@ -57,21 +56,6 @@ public final class CompilerUtils { private CompilerUtils() { } - private static List getJarsInDirectory(File dir) { - List r = Lists.newArrayList(); - - File[] files = dir.listFiles(); - if (files != null) { - for (File jar : files) { - if (jar.isFile() && jar.getName().endsWith(".jar")) { - r.add(jar); - } - } - } - - return r; - } - public static List kompilerClasspath(File kotlinHome, CompileContext context) { File libs = new File(kotlinHome, "lib"); @@ -81,10 +65,8 @@ public final class CompilerUtils { return Collections.emptyList(); } - ArrayList answer = new ArrayList(); - answer.addAll(getJarsInDirectory(libs)); - answer.addAll(getJarsInDirectory(new File(libs, "guice"))); // TODO: flatten at artifact build + answer.add(new File(libs, "kotlin-compiler.jar")); return answer; } diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java index 72cb9695e43..5b903fc9279 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java @@ -258,8 +258,11 @@ public class JetCompiler implements TranslatingCompiler { } private static String[] commandLineArguments(VirtualFile outputDir, File scriptFile) { - return new String[]{"-module", scriptFile.getAbsolutePath(), "-output", path(outputDir), "-tags", "-verbose", "-version", "-mode", - "stdlib"}; + return new String[]{ + "-module", scriptFile.getAbsolutePath(), + "-output", path(outputDir), + "-tags", "-verbose", "-version", + "-mode", "idea"}; } private static void runOutOfProcess(final CompileContext compileContext, diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java index d85b92f8fa4..e34fd164a80 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/K2JSCompiler.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.compiler; +import com.google.common.collect.Lists; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerMessageCategory; @@ -24,13 +25,17 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; import com.intellij.util.Chunk; import jet.Function1; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.plugin.k2jsrun.K2JSRunnerUtils; import org.jetbrains.jet.plugin.project.JsModuleDetector; import java.io.PrintStream; +import java.util.ArrayList; import static org.jetbrains.jet.plugin.compiler.CompilerUtils.invokeExecMethod; import static org.jetbrains.jet.plugin.compiler.CompilerUtils.outputCompilerMessagesAndHandleExitCode; @@ -58,18 +63,22 @@ public final class K2JSCompiler implements TranslatingCompiler { return; } - if (moduleChunk.getNodes().size() != 1) { - context.addMessage(CompilerMessageCategory.ERROR, "K2JSCompiler does not support multiple modules.", null, -1, -1); + final Module module = getModule(context, moduleChunk); + if (module == null) { return; } - final Module module = moduleChunk.getNodes().iterator().next(); final CompilerEnvironment environment = CompilerEnvironment.getEnvironmentFor(context, module, /*tests = */ false); if (!environment.success()) { environment.reportErrorsTo(context); return; } + doCompile(context, sink, module, environment); + } + + private static void doCompile(@NotNull final CompileContext context, @NotNull OutputSink sink, @NotNull final Module module, + @NotNull final CompilerEnvironment environment) { CompilerUtils.OutputItemsCollectorImpl collector = new CompilerUtils.OutputItemsCollectorImpl(environment.getOutput().getPath()); outputCompilerMessagesAndHandleExitCode(context, collector, new Function1() { @Override @@ -80,25 +89,72 @@ public final class K2JSCompiler implements TranslatingCompiler { sink.add(environment.getOutput().getPath(), collector.getOutputs(), collector.getSources().toArray(VirtualFile.EMPTY_ARRAY)); } + @Nullable + private static Module getModule(@NotNull CompileContext context, @NotNull Chunk moduleChunk) { + if (moduleChunk.getNodes().size() != 1) { + context.addMessage(CompilerMessageCategory.ERROR, "K2JSCompiler does not support multiple modules.", null, -1, -1); + return null; + } + return moduleChunk.getNodes().iterator().next(); + } + @NotNull private static Integer execInProcess(@NotNull CompileContext context, @NotNull CompilerEnvironment environment, @NotNull PrintStream out, @NotNull Module module) { try { - VirtualFile[] roots = ModuleRootManager.getInstance(module).getSourceRoots(); - if (roots.length != 1) { - context.addMessage(CompilerMessageCategory.ERROR, "K2JSCompiler does not support module source roots.", null, -1, -1); - return -1; - } - String[] commandLineArgs = {"-tags", "-verbose", "-version", "-srcdir", roots[0].getPath()}; - Object rc = invokeExecMethod(environment, out, context, commandLineArgs, "org.jetbrains.jet.cli.js.K2JSCompiler"); - return CompilerUtils.getReturnCodeFromObject(rc); + return doExec(context, environment, out, module); } catch (Throwable e) { - context.addMessage(CompilerMessageCategory.ERROR, "Fail!", null, -1, -1); + context.addMessage(CompilerMessageCategory.ERROR, "Exception while executing compiler:\n" + e.getMessage(), null, -1, -1); } return -1; } + @NotNull + private static Integer doExec(@NotNull CompileContext context, @NotNull CompilerEnvironment environment, @NotNull PrintStream out, + @NotNull Module module) throws Exception { + VirtualFile[] roots = ModuleRootManager.getInstance(module).getSourceRoots(); + if (roots.length != 1) { + context.addMessage(CompilerMessageCategory.ERROR, "K2JSCompiler does not support multiple module source roots.", null, -1, -1); + return -1; + } + String[] commandLineArgs = constructArguments(context.getProject(), context.getModuleOutputDirectory(module), roots[0]); + Object rc = invokeExecMethod(environment, out, context, commandLineArgs, "org.jetbrains.jet.cli.js.K2JSCompiler"); + return CompilerUtils.getReturnCodeFromObject(rc); + } + + @NotNull + private static String[] constructArguments(@NotNull Project project, @Nullable VirtualFile outDir, @NotNull VirtualFile srcDir) { + ArrayList args = Lists.newArrayList("-tags", "-verbose", "-version"); + addPathToSourcesDir(args, srcDir); + addOutputPath(project, outDir, args); + addPathToZippedLib(project, args); + return ArrayUtil.toStringArray(args); + } + + private static void addPathToSourcesDir(@NotNull ArrayList args, @NotNull VirtualFile srcDir) { + String srcPath = srcDir.getPath(); + args.add("-srcdir"); + args.add(srcPath); + } + + private static void addOutputPath(@NotNull Project project, @Nullable VirtualFile outDir, @NotNull ArrayList args) { + if (outDir != null) { + String outPath = outDir.getPath(); + String outFile = K2JSRunnerUtils.constructPathToGeneratedFile(project, outPath); + args.add("-output"); + args.add(outFile); + } + } + + private static void addPathToZippedLib(@NotNull Project project, @NotNull ArrayList args) { + String libLocationForProject = JsModuleDetector.getLibLocationForProject(project); + if (libLocationForProject != null) { + args.add("-libzip"); + args.add(libLocationForProject); + } + } + @NotNull @Override public String getDescription() { diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java index 2767ea51553..f559f098e1c 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java @@ -23,7 +23,6 @@ import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.codeInsight.navigation.NavigationUtil; -import com.intellij.ide.util.DefaultPsiElementCellRenderer; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.IconLoader; @@ -35,12 +34,12 @@ import com.intellij.util.PsiNavigateUtil; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.Modality; -import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.plugin.codeInsight.JetFunctionPsiElementCellRenderer; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.resolve.DescriptorRenderer; @@ -128,19 +127,9 @@ public class JetLineMarkerProvider implements LineMarkerProvider { PsiNavigateUtil.navigate(list.iterator().next()); } else { - final JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilCore.toPsiElementArray(list), new DefaultPsiElementCellRenderer() { - @Override - public String getElementText(PsiElement element) { - if (element instanceof JetNamedFunction) { - JetNamedFunction function = (JetNamedFunction) element; - SimpleFunctionDescriptor fd = - bindingContext.get(BindingContext.FUNCTION, function); - assert fd != null; - return DescriptorRenderer.HTML.render(fd); - } - return super.getElementText(element); - } - }, DescriptorRenderer.HTML.render(descriptor)); + JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilCore.toPsiElementArray(list), + new JetFunctionPsiElementCellRenderer(bindingContext), + DescriptorRenderer.TEXT.render(descriptor)); if (event != null) { popup.show(new RelativePoint(event)); } diff --git a/idea/src/org/jetbrains/jet/plugin/k2jsrun/K2JSRunnerUtils.java b/idea/src/org/jetbrains/jet/plugin/k2jsrun/K2JSRunnerUtils.java index f508cc8f9c9..c356dd13732 100644 --- a/idea/src/org/jetbrains/jet/plugin/k2jsrun/K2JSRunnerUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/k2jsrun/K2JSRunnerUtils.java @@ -65,12 +65,12 @@ public final class K2JSRunnerUtils { String outputFilePath = constructPathToGeneratedFile(project, outputDirPath); K2JSTranslator.translateWithCallToMainAndSaveToFile(kotlinFiles, outputFilePath, - new IDEAConfig(project), - project); + new IDEAConfig(project) + ); notifySuccess(outputDirPath); } - private static String constructPathToGeneratedFile(Project project, String outputDirPath) { + public static String constructPathToGeneratedFile(@NotNull Project project, @NotNull String outputDirPath) { return outputDirPath + "/" + project.getName() + ".js"; } @@ -87,14 +87,14 @@ public final class K2JSRunnerUtils { @NotNull private static List getJetFiles(@NotNull Collection virtualFiles, - @NotNull Project project) { + @NotNull Project project) { List kotlinFiles = Lists.newArrayList(); PsiManager psiManager = PsiManager.getInstance(project); for (VirtualFile virtualFile : virtualFiles) { PsiFile psiFile = psiManager.findFile(virtualFile); if (psiFile instanceof JetFile) { - kotlinFiles.add((JetFile)psiFile); + kotlinFiles.add((JetFile) psiFile); } } return kotlinFiles; diff --git a/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java b/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java index 4ba93444e1f..4032da59ec2 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java +++ b/idea/src/org/jetbrains/jet/plugin/project/IDEAConfig.java @@ -16,113 +16,18 @@ package org.jetbrains.jet.plugin.project; -import com.google.common.collect.Lists; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.k2js.config.Config; -import org.jetbrains.k2js.utils.JetFileUtils; +import org.jetbrains.k2js.config.ZippedLibrarySourcesConfig; -import java.io.*; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationForProject; /** * @author Pavel Talanov */ -public final class IDEAConfig extends Config { - - @Nullable - private final String pathToLibZip; +public final class IDEAConfig extends ZippedLibrarySourcesConfig { public IDEAConfig(@NotNull Project project) { - super(project); - this.pathToLibZip = getLibLocationForProject(project); - } - - //TODO: refactor - @Nullable - private static String getLibLocationForProject(@NotNull Project project) { - VirtualFile indicationFile = JsModuleDetector.findIndicationFileInContextRoots(project); - if (indicationFile == null) { - return null; - } - try { - InputStream stream = indicationFile.getInputStream(); - String path = FileUtil.loadTextAndClose(stream); - String pathToLibFile = getFirstLine(path); - if (pathToLibFile == null) { - return null; - } - try { - URI pathToLibFileUri = new URI(pathToLibFile); - URI pathToIndicationFileUri = new URI(indicationFile.getPath()); - return pathToIndicationFileUri.resolve(pathToLibFileUri).toString(); - } - catch (URISyntaxException e) { - return null; - } - } - catch (IOException e) { - return null; - } - } - - //TODO: util - @Nullable - private static String getFirstLine(@NotNull String path) throws IOException { - BufferedReader reader = new BufferedReader(new StringReader(path)); - try { - return reader.readLine(); - } - - finally { - reader.close(); - } - } - - @NotNull - @Override - public List generateLibFiles() { - if (pathToLibZip == null) { - return Collections.emptyList(); - } - try { - File file = new File(pathToLibZip); - ZipFile zipFile = new ZipFile(file); - try { - return traverseArchive(zipFile); - } - finally { - zipFile.close(); - } - } - catch (IOException e) { - return Collections.emptyList(); - } - } - - @NotNull - private List traverseArchive(@NotNull ZipFile file) throws IOException { - List result = Lists.newArrayList(); - Enumeration zipEntries = file.entries(); - while (zipEntries.hasMoreElements()) { - ZipEntry entry = zipEntries.nextElement(); - if (!entry.isDirectory()) { - InputStream stream = file.getInputStream(entry); - String text = FileUtil.loadTextAndClose(stream); - JetFile jetFile = JetFileUtils.createPsiFile(entry.getName(), text, getProject()); - result.add(jetFile); - } - } - return result; + super(project, getLibLocationForProject(project)); } } diff --git a/idea/src/org/jetbrains/jet/plugin/project/JsModuleDetector.java b/idea/src/org/jetbrains/jet/plugin/project/JsModuleDetector.java index 9d3df9bc1e3..c8849436032 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/JsModuleDetector.java +++ b/idea/src/org/jetbrains/jet/plugin/project/JsModuleDetector.java @@ -16,17 +16,24 @@ package org.jetbrains.jet.plugin.project; -import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.URI; +import java.net.URISyntaxException; + /** * @author Pavel Talanov - * - * This class has utility functions to determine whether the project (or module) is js project. + *

+ * This class has utility functions to determine whether the project (or module) is js project. */ public final class JsModuleDetector { @@ -36,19 +43,59 @@ public final class JsModuleDetector { } public static boolean isJsProject(@NotNull Project project) { - return findIndicationFileInContextRoots(project) != null; + return findIndicationFileInContentRoots(project) != null; } @Nullable - public static VirtualFile findIndicationFileInContextRoots(@NotNull Project project) { + public static VirtualFile findIndicationFileInContentRoots(@NotNull Project project) { VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots(); for (VirtualFile root : roots) { for (VirtualFile child : root.getChildren()) { - if (child.getFileType().equals(FileTypes.PLAIN_TEXT) && child.getName().equals(INDICATION_FILE_NAME)) { + if (child.getName().equals(INDICATION_FILE_NAME)) { return child; } } } return null; } + + //TODO: refactor + @Nullable + public static String getLibLocationForProject(@NotNull Project project) { + VirtualFile indicationFile = findIndicationFileInContentRoots(project); + if (indicationFile == null) { + return null; + } + try { + InputStream stream = indicationFile.getInputStream(); + String path = FileUtil.loadTextAndClose(stream); + String pathToLibFile = getFirstLine(path); + if (pathToLibFile == null) { + return null; + } + try { + URI pathToLibFileUri = new URI(pathToLibFile); + URI pathToIndicationFileUri = new URI(indicationFile.getPath()); + return pathToIndicationFileUri.resolve(pathToLibFileUri).toString(); + } + catch (URISyntaxException e) { + return null; + } + } + catch (IOException e) { + return null; + } + } + + @Nullable + private static String getFirstLine(@NotNull String path) throws IOException { + BufferedReader reader = new BufferedReader(new StringReader(path)); + try { + return reader.readLine(); + } + + finally { + reader.close(); + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/projectView/JetClassOrObjectTreeNode.java b/idea/src/org/jetbrains/jet/plugin/projectView/JetClassOrObjectTreeNode.java index cb4ee8b2d4f..5a896c19430 100644 --- a/idea/src/org/jetbrains/jet/plugin/projectView/JetClassOrObjectTreeNode.java +++ b/idea/src/org/jetbrains/jet/plugin/projectView/JetClassOrObjectTreeNode.java @@ -17,12 +17,15 @@ package org.jetbrains.jet.plugin.projectView; import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectView; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.AbstractPsiBasedNode; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.plugin.JetIconProvider; import java.util.Collection; @@ -48,11 +51,27 @@ public class JetClassOrObjectTreeNode extends AbstractPsiBasedNode declarations = file.getDeclarations(); - ArrayList classDeclarations = new ArrayList(); - for (JetDeclaration declaration : declarations) { - if (declaration instanceof JetClassOrObject) { - classDeclarations.add((JetClassOrObject) declaration); - } - } - VirtualFile virtualFile = file.getVirtualFile(); - String nameWithoutExtension = virtualFile != null ? virtualFile.getNameWithoutExtension() : file.getName(); - if (classDeclarations.size() == 1 && (!settings.isShowMembers() || declarations.size() == 1) && - nameWithoutExtension.equals(classDeclarations.get(0).getName())) { - result.add(new JetClassOrObjectTreeNode(file.getProject(), classDeclarations.get(0), settings)); + JetClassOrObject mainClass = JetIconProvider.getMainClass(file); + if (mainClass != null && (!settings.isShowMembers() || declarations.size() == 1)) { + result.add(new JetClassOrObjectTreeNode(file.getProject(), mainClass, settings)); } else { result.add(new JetFileTreeNode(file.getProject(), file, settings)); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java index 096a5fb9f25..ddbd49df0a3 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java @@ -215,7 +215,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific VirtualFile baseDir = myProject.getBaseDir(); if (baseDir != null) { - myPathField.setText(baseDir.getPath() + File.separatorChar + "lib"); + myPathField.setText(baseDir.getPath().replace('/', File.separatorChar) + File.separatorChar + "lib"); } return myPathField; diff --git a/js/js.tests/js.tests.iml b/js/js.tests/js.tests.iml index c6c55dda3aa..15314fd8ffb 100644 --- a/js/js.tests/js.tests.iml +++ b/js/js.tests/js.tests.iml @@ -14,6 +14,7 @@ + diff --git a/js/js.tests/test/org/jetbrains/k2js/test/MultipleFilesTranslationTest.java b/js/js.tests/test/org/jetbrains/k2js/test/MultipleFilesTranslationTest.java index 74d27737aad..70b6ba4d6a1 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/MultipleFilesTranslationTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/MultipleFilesTranslationTest.java @@ -17,6 +17,7 @@ package org.jetbrains.k2js.test; import org.jetbrains.annotations.NotNull; +import org.jetbrains.k2js.facade.MainCallParameters; import org.jetbrains.k2js.test.rhino.RhinoFunctionResultChecker; import java.util.List; @@ -36,11 +37,11 @@ public abstract class MultipleFilesTranslationTest extends BasicTest { protected void generateJsFromDir(@NotNull String dirName) throws Exception { List fullFilePaths = getAllFilesInDir(getInputFilePath(dirName)); - translateFiles(getProject(), fullFilePaths, getOutputFilePath(dirName + ".kt")); + translateFiles(getProject(), fullFilePaths, getOutputFilePath(dirName + ".kt"), MainCallParameters.noCall()); } protected void runMultiFileTest(@NotNull String dirName, @NotNull String namespaceName, - @NotNull String functionName, @NotNull Object expectedResult) throws Exception { + @NotNull String functionName, @NotNull Object expectedResult) throws Exception { generateJsFromDir(dirName); runRhinoTest(withAdditionalFiles(getOutputFilePath(dirName + ".kt")), new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult)); diff --git a/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java b/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java index 3c672cc6a01..599ef455565 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java @@ -16,13 +16,13 @@ package org.jetbrains.k2js.test; +import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; +import org.jetbrains.k2js.facade.MainCallParameters; import org.jetbrains.k2js.test.rhino.RhinoFunctionResultChecker; import org.jetbrains.k2js.test.rhino.RhinoSystemOutputChecker; import org.jetbrains.k2js.test.utils.TranslationUtils; -import java.util.Arrays; - import static org.jetbrains.k2js.test.rhino.RhinoUtils.runRhinoTest; import static org.jetbrains.k2js.test.utils.JsTestUtils.readFile; @@ -37,28 +37,32 @@ public abstract class SingleFileTranslationTest extends BasicTest { } public void runFunctionOutputTest(String filename, String namespaceName, - String functionName, Object expectedResult) throws Exception { - generateJsFromFile(filename); + String functionName, Object expectedResult) throws Exception { + generateJsFromFile(filename, MainCallParameters.noCall()); runRhinoTest(withAdditionalFiles(getOutputFilePath(filename)), new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult)); } - protected void generateJsFromFile(@NotNull String filename) throws Exception { - TranslationUtils.translateFile(getProject(), getInputFilePath(filename), getOutputFilePath(filename)); + protected void generateJsFromFile(@NotNull String filename, @NotNull MainCallParameters mainCallParameters) throws Exception { + TranslationUtils.translateFile(getProject(), getInputFilePath(filename), getOutputFilePath(filename), mainCallParameters); } public void checkFooBoxIsTrue(@NotNull String filename) throws Exception { runFunctionOutputTest(filename, "foo", "box", true); } + public void fooBoxTest() throws Exception { + checkFooBoxIsTrue(getTestName(true) + ".kt"); + } + public void checkFooBoxIsOk(@NotNull String filename) throws Exception { runFunctionOutputTest(filename, "foo", "box", "OK"); } protected void checkOutput(@NotNull String filename, @NotNull String expectedResult, @NotNull String... args) throws Exception { - generateJsFromFile(filename); + generateJsFromFile(filename, MainCallParameters.mainWithArguments(Lists.newArrayList(args))); runRhinoTest(withAdditionalFiles(getOutputFilePath(filename)), - new RhinoSystemOutputChecker(expectedResult, Arrays.asList(args))); + new RhinoSystemOutputChecker(expectedResult)); } protected void performTestWithMain(@NotNull String testName, @NotNull String testId, @NotNull String... args) throws Exception { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/TestWithEnvironment.java b/js/js.tests/test/org/jetbrains/k2js/test/TestWithEnvironment.java index b3c3759a642..d98ec899672 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/TestWithEnvironment.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/TestWithEnvironment.java @@ -20,8 +20,9 @@ import com.intellij.openapi.project.Project; import com.intellij.testFramework.UsefulTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.CompileCompilerDependenciesTest; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; /** * @author Pavel Talanov @@ -50,6 +51,9 @@ public abstract class TestWithEnvironment extends UsefulTestCase { } protected void createEnvironmentWithMockJdkAndIdeaAnnotations() { - myEnvironment = JetCoreEnvironment.getCoreEnvironmentForJS(getTestRootDisposable()); + myEnvironment = JetCoreEnvironment.getCoreEnvironmentForJVM(getTestRootDisposable(), + CompileCompilerDependenciesTest.compilerDependenciesForTests( + CompilerSpecialMode.JS, + true)); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/config/TestConfig.java b/js/js.tests/test/org/jetbrains/k2js/test/config/TestConfig.java index cb830ee2d56..66760d4ebdd 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/config/TestConfig.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/config/TestConfig.java @@ -49,7 +49,6 @@ public final class TestConfig extends Config { List libFiles = new ArrayList(); for (String libFileName : LIB_FILE_NAMES) { JetFile file = null; - //TODO: close stream? try { @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") InputStream stream = new FileInputStream(LIBRARIES_LOCATION + libFileName); @@ -70,6 +69,7 @@ public final class TestConfig extends Config { return libFiles; } + @Override @NotNull public List generateLibFiles() { if (jsLibFiles == null) { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/rhino/RhinoSystemOutputChecker.java b/js/js.tests/test/org/jetbrains/k2js/test/rhino/RhinoSystemOutputChecker.java index dabe994f36f..84352c065d9 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/rhino/RhinoSystemOutputChecker.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/rhino/RhinoSystemOutputChecker.java @@ -17,13 +17,9 @@ package org.jetbrains.k2js.test.rhino; import org.jetbrains.annotations.NotNull; -import org.jetbrains.k2js.translate.context.Namer; -import org.jetbrains.k2js.utils.GenerationUtils; import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; -import java.util.List; - import static org.junit.Assert.assertTrue; /** @@ -31,39 +27,30 @@ import static org.junit.Assert.assertTrue; */ public final class RhinoSystemOutputChecker implements RhinoResultChecker { - private final List arguments; private final String expectedResult; - public RhinoSystemOutputChecker(String expectedResult, List arguments) { + public RhinoSystemOutputChecker(@NotNull String expectedResult) { this.expectedResult = expectedResult; - this.arguments = arguments; } @Override public void runChecks(@NotNull Context context, @NotNull Scriptable scope) throws Exception { - runMain(context, scope); String result = getSystemOutput(context, scope); String trimmedExpected = trimSpace(expectedResult); String trimmedActual = trimSpace(result); - // System.out.println(trimmedActual); - // System.out.println(trimmedExpected); + assertTrue("Returned:\n" + trimmedActual + "END_OF_RETURNED\nExpected:\n" + trimmedExpected + "END_OF_EXPECTED\n", trimmedExpected.equals(trimmedActual)); } - private String getSystemOutput(@NotNull Context context, @NotNull Scriptable scope) { + private static String getSystemOutput(@NotNull Context context, @NotNull Scriptable scope) { Object output = context.evaluateString(scope, "Kotlin.System.output()", "test", 0, null); assertTrue("Output should be a string.", output instanceof String); return (String) output; } - private void runMain(Context context, Scriptable scope) { - String callToMain = GenerationUtils.generateCallToMain(Namer.getRootNamespaceName(), arguments); - context.evaluateString(scope, callToMain, "function call", 0, null); - } - - public String trimSpace(String s) { + public static String trimSpace(@NotNull String s) { String[] choppedUpString = s.trim().split("\\s"); StringBuilder sb = new StringBuilder(); for (String word : choppedUpString) { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java index 00e76b95684..4a2f0b6ff1f 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java @@ -28,32 +28,32 @@ public final class ArrayListTest extends JavaClassesTest { } public void testEmptyList() throws Exception { - checkFooBoxIsTrue("emptyList.kt"); + fooBoxTest(); } public void testAccess() throws Exception { - checkFooBoxIsTrue("access.kt"); + fooBoxTest(); } public void testIsEmpty() throws Exception { - checkFooBoxIsTrue("isEmpty.kt"); + fooBoxTest(); } public void testArrayAccess() throws Exception { - checkFooBoxIsTrue("arrayAccess.kt"); + fooBoxTest(); } public void testIterate() throws Exception { - checkFooBoxIsTrue("iterate.kt"); + fooBoxTest(); } public void testRemove() throws Exception { - checkFooBoxIsTrue("remove.kt"); + fooBoxTest(); } public void testIndexOOB() throws Exception { try { - checkFooBoxIsTrue("indexOOB.kt"); + fooBoxTest(); fail(); } catch (JavaScriptException e) { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClassInheritanceTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClassInheritanceTest.java index 7b4875bc0ad..604f74a59fc 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClassInheritanceTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClassInheritanceTest.java @@ -32,31 +32,31 @@ public final class ClassInheritanceTest extends SingleFileTranslationTest { } public void testMethodOverride() throws Exception { - checkFooBoxIsTrue("methodOverride.kt"); + fooBoxTest(); } public void testInitializationOrder() throws Exception { - checkFooBoxIsTrue("initializationOrder.kt"); + fooBoxTest(); } public void testComplexInitializationOrder() throws Exception { - checkFooBoxIsTrue("complexInitializationOrder.kt"); + fooBoxTest(); } public void testValuePassedToAncestorConstructor() throws Exception { - checkFooBoxIsTrue("valuePassedToAncestorConstructor.kt"); + fooBoxTest(); } public void testBaseClassDefinedAfterDerived() throws Exception { - checkFooBoxIsTrue("baseClassDefinedAfterDerived.kt"); + fooBoxTest(); } public void testDefinitionOrder() throws Exception { - checkFooBoxIsTrue("definitionOrder.kt"); + fooBoxTest(); } public void testAbstractVarOverride() throws Exception { - checkFooBoxIsTrue("abstractVarOverride.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java index 0beb3836ac0..e3380fc94c4 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java @@ -28,6 +28,6 @@ public final class ClosureTest extends SingleFileTranslationTest { } public void testIteratingCallbacks() throws Exception { - checkFooBoxIsTrue("iteratingCallbacks.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/DangerousTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/DangerousTest.java index 9867eb335aa..861be8c5348 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/DangerousTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/DangerousTest.java @@ -28,30 +28,30 @@ public final class DangerousTest extends SingleFileTranslationTest { } public void testIfAsFunArgument() throws Exception { - checkFooBoxIsTrue("ifAsFunArgument.kt"); + fooBoxTest(); } public void testIfAsPlusArgument() throws Exception { - checkFooBoxIsTrue("ifAsPlusArgument.kt"); + fooBoxTest(); } public void testWhenAsMinusArgument() throws Exception { - checkFooBoxIsTrue("whenAsMinusArgument.kt"); + fooBoxTest(); } public void testEvaluationOrder() throws Exception { - checkFooBoxIsTrue("evaluationOrder.kt"); + fooBoxTest(); } public void testDangerousInsideDangerous() throws Exception { - checkFooBoxIsTrue("dangerousInsideDangerous.kt"); + fooBoxTest(); } public void test2dangerousInExpression() throws Exception { - checkFooBoxIsTrue("2dangerousInExpression.kt"); + fooBoxTest(); } public void testDangerousInline() throws Exception { - checkFooBoxIsTrue("dangerousInline.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java index 72058f94a29..4108553cf48 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java @@ -28,35 +28,35 @@ public final class ExtensionFunctionTest extends SingleFileTranslationTest { } public void testIntExtension() throws Exception { - checkFooBoxIsTrue("intExtension.kt"); + fooBoxTest(); } public void testExtensionWithImplicitReceiver() throws Exception { - checkFooBoxIsTrue("extensionWithImplicitReceiver.kt"); + fooBoxTest(); } public void testExtensionFunctionOnExpression() throws Exception { - checkFooBoxIsTrue("extensionFunctionOnExpression.kt"); + fooBoxTest(); } public void testExtensionUsedInsideClass() throws Exception { - checkFooBoxIsTrue("extensionUsedInsideClass.kt"); + fooBoxTest(); } public void testVirtualExtension() throws Exception { - checkFooBoxIsTrue("virtualExtension.kt"); + fooBoxTest(); } public void testVirtualExtensionOverride() throws Exception { - checkFooBoxIsTrue("virtualExtensionOverride.kt"); + fooBoxTest(); } public void testExtensionLiteralPassedToFunction() throws Exception { - checkFooBoxIsTrue("extensionLiteralPassedToFunction.kt"); + fooBoxTest(); } public void testExtensionInsideFunctionLiteral() throws Exception { - checkFooBoxIsTrue("extensionInsideFunctionLiteral.kt"); + fooBoxTest(); } public void testGenericExtension() throws Exception { @@ -64,6 +64,6 @@ public final class ExtensionFunctionTest extends SingleFileTranslationTest { } public void testExtensionFunctionCalledFromExtensionFunction() throws Exception { - checkFooBoxIsTrue("extensionFunctionCalledFromExtensionFunction.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionPropertyTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionPropertyTest.java index b3e1d3b1589..29588d3eea5 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionPropertyTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionPropertyTest.java @@ -28,14 +28,14 @@ public final class ExtensionPropertyTest extends SingleFileTranslationTest { } public void testSimplePropertyWithGetter() throws Exception { - checkFooBoxIsTrue("simplePropertyWithGetter.kt"); + fooBoxTest(); } public void testPropertyWithGetterAndSetter() throws Exception { - checkFooBoxIsTrue("propertyWithGetterAndSetter.kt"); + fooBoxTest(); } public void testAbsExtension() throws Exception { - checkFooBoxIsTrue("absExtension.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ForeachTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ForeachTest.java index 3a8f2572a06..0d8fe7247ff 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ForeachTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ForeachTest.java @@ -26,10 +26,10 @@ public final class ForeachTest extends AbstractExpressionTest { } public void testForIteratesOverArray() throws Exception { - checkFooBoxIsTrue("forIteratesOverArray.kt"); + fooBoxTest(); } public void testForOnEmptyArray() throws Exception { - checkFooBoxIsTrue("forOnEmptyArray.kt"); + fooBoxTest(); } } \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java index 20eeae619cc..3042bbe287f 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java @@ -28,27 +28,27 @@ public class FunctionTest extends AbstractExpressionTest { } public void testFunctionUsedBeforeDeclaration() throws Exception { - checkFooBoxIsTrue("functionUsedBeforeDeclaration.kt"); + fooBoxTest(); } public void testFunctionWithTwoParametersCall() throws Exception { - checkFooBoxIsTrue("functionWithTwoParametersCall.kt"); + fooBoxTest(); } public void testFunctionLiteral() throws Exception { - checkFooBoxIsTrue("functionLiteral.kt"); + fooBoxTest(); } public void testAdderClosure() throws Exception { - checkFooBoxIsTrue("adderClosure.kt"); + fooBoxTest(); } public void testLoopClosure() throws Exception { - checkFooBoxIsTrue("loopClosure.kt"); + fooBoxTest(); } public void testFunctionLiteralAsParameter() throws Exception { - checkFooBoxIsTrue("functionLiteralAsParameter.kt"); + fooBoxTest(); } public void testClosureWithParameter() throws Exception { @@ -65,44 +65,48 @@ public class FunctionTest extends AbstractExpressionTest { public void testImplicitItParameter() throws Exception { - checkFooBoxIsTrue("implicitItParameter.kt"); + fooBoxTest(); } public void testDefaultParameters() throws Exception { - checkFooBoxIsTrue("defaultParameters.kt"); + fooBoxTest(); } public void testFunctionLiteralAsLastParameter() throws Exception { - checkFooBoxIsTrue("functionLiteralAsLastParameter.kt"); + fooBoxTest(); } public void testNamedArguments() throws Exception { - checkFooBoxIsTrue("namedArguments.kt"); + fooBoxTest(); } public void testExpressionAsFunction() throws Exception { - checkFooBoxIsTrue("expressionAsFunction.kt"); + fooBoxTest(); } public void testVararg() throws Exception { - checkFooBoxIsTrue("vararg.kt"); + fooBoxTest(); } - //TODO: disabled. Probable cause : vars in closures. -// -// public void testKT921() throws Exception { -// -// checkOutput("KT-921.kt", "1,\n" + -// "1, 2,\n" + -// "2, "); -// } + public void testKT921() throws Exception { + + checkOutput("KT-921.kt", "1, end\n" + + "1, 2, end\n" + + "1, 2, 3, end\n" + + "2, 3, end\n" + + "!\n" + + "3, end\n" + + "!\n" + + "end\n" + + "!"); + } public void testFunctionInsideFunction() throws Exception { - checkFooBoxIsTrue("functionInsideFunction.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/InlineTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/InlineTest.java index 852a41e5288..7f808428247 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/InlineTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/InlineTest.java @@ -67,7 +67,7 @@ public final class InlineTest extends SingleFileTranslationTest { } private void checkFooBoxIsTrueAndFunctionNameIsNotReferenced(@NotNull String filename, String funName) throws Exception { - checkFooBoxIsTrue(filename); + fooBoxTest(); String generatedJSFilePath = getOutputFilePath(filename); String outputFileText = FileUtil.loadFile(new File(generatedJSFilePath)); assertTrue(countOccurrences(outputFileText, funName) == 1); diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/MiscTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/MiscTest.java index e6b3a42c8d5..1fa25a13f89 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/MiscTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/MiscTest.java @@ -27,7 +27,6 @@ import org.mozilla.javascript.JavaScriptException; */ public final class MiscTest extends AbstractExpressionTest { - public MiscTest() { super("misc/"); } @@ -37,12 +36,12 @@ public final class MiscTest extends AbstractExpressionTest { } public void testIntRange() throws Exception { - checkFooBoxIsTrue("intRange.kt"); + fooBoxTest(); } public void testSafecallComputesExpressionOnlyOnce() throws Exception { - checkFooBoxIsTrue("safecallComputesExpressionOnlyOnce.kt"); + fooBoxTest(); } public void testClassWithoutNamespace() throws Exception { @@ -51,7 +50,7 @@ public final class MiscTest extends AbstractExpressionTest { public void testIfElseAsExpressionWithThrow() throws Exception { try { - checkFooBoxIsTrue("ifAsExpressionWithThrow.kt"); + fooBoxTest(); fail(); } catch (JavaScriptException e) { @@ -92,34 +91,51 @@ public final class MiscTest extends AbstractExpressionTest { } public void testFunInConstructor() throws Exception { - checkFooBoxIsTrue("funInConstructor.kt"); + fooBoxTest(); } public void testFunInConstructorBlock() throws Exception { - checkFooBoxIsTrue("funInConstructorBlock.kt"); + fooBoxTest(); } public void testPropertyAsFunCalledOnConstructor() throws Exception { - checkFooBoxIsTrue("propertyAsFunCalledOnConstructor.kt"); + fooBoxTest(); } public void testNamespacePropertyCalledAsFun() throws Exception { - checkFooBoxIsTrue("namespacePropertyCalledAsFun.kt"); + fooBoxTest(); } public void testExtensionLiteralCreatedAtNamespaceLevel() throws Exception { - checkFooBoxIsTrue("extensionLiteralCreatedAtNamespaceLevel.kt"); + fooBoxTest(); } public void testTemporaryVariableCreatedInNamespaceInitializer() throws Exception { - checkFooBoxIsTrue("temporaryVariableCreatedInNamespaceInitializer.kt"); + fooBoxTest(); } public void testWhenReturnedWithoutBlock() throws Exception { - checkFooBoxIsTrue("whenReturnedWithoutBlock.kt"); + fooBoxTest(); } public void testElvis() throws Exception { - checkFooBoxIsTrue("elvis.kt"); + fooBoxTest(); + } + + public void testExtensionLiteralCalledInsideExtensionFunction() throws Exception { + fooBoxTest(); + } + + public void testKt1865() throws Exception { + checkFooBoxIsTrue("KT-1865.kt"); + } + + public void testMainFunInNestedNamespace() throws Exception { + checkOutput("mainFunInNestedNamespace.kt", "ayee"); + } + + + public void testPropertiesWithExplicitlyDefinedAccessorsWithoutBodies() throws Exception { + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NameClashesTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NameClashesTest.java index 421e8a072f0..ad7aeb03dd6 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NameClashesTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NameClashesTest.java @@ -29,6 +29,6 @@ public final class NameClashesTest extends SingleFileTranslationTest { } public void testMethodOverload() throws Exception { - checkFooBoxIsTrue("methodOverload.kt"); + fooBoxTest(); } } \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java index 852d4c67f73..c85eae2ed83 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java @@ -43,19 +43,19 @@ public final class NativeInteropTest extends SingleFileTranslationTest { } public void testSimple() throws Exception { - checkFooBoxIsTrue("simple.kt"); + fooBoxTest(); } public void testClass() throws Exception { - checkFooBoxIsTrue("class.kt"); + fooBoxTest(); } public void testVararg() throws Exception { - checkFooBoxIsTrue("vararg.kt"); + fooBoxTest(); } public void testUndefined() throws Exception { - checkFooBoxIsTrue("undefined.kt"); + fooBoxTest(); } public void testKt1519() throws Exception { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java index d4aea34083d..51eed910ebd 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java @@ -28,22 +28,22 @@ public final class ObjectTest extends SingleFileTranslationTest { } public void testObjectWithMethods() throws Exception { - checkFooBoxIsTrue("objectWithMethods.kt"); + fooBoxTest(); } public void testObjectDeclaration() throws Exception { - checkFooBoxIsTrue("objectDeclaration.kt"); + fooBoxTest(); } public void testObjectInMethod() throws Exception { - checkFooBoxIsTrue("objectInMethod.kt"); + fooBoxTest(); } public void testObjectInheritingFromATrait() throws Exception { - checkFooBoxIsTrue("objectInheritingFromATrait.kt"); + fooBoxTest(); } } \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/OperatorOverloadingTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/OperatorOverloadingTest.java index 908f241f070..9b2a0c962b0 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/OperatorOverloadingTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/OperatorOverloadingTest.java @@ -28,76 +28,76 @@ public final class OperatorOverloadingTest extends SingleFileTranslationTest { } public void testPlusOverload() throws Exception { - checkFooBoxIsTrue("plusOverload.kt"); + fooBoxTest(); } public void testPostfixInc() throws Exception { - checkFooBoxIsTrue("postfixIncOverload.kt"); + fooBoxTest(); } public void testPrefixDecOverload() throws Exception { - checkFooBoxIsTrue("prefixDecOverload.kt"); + fooBoxTest(); } public void testPrefixIncReturnsCorrectValue() throws Exception { - checkFooBoxIsTrue("prefixIncReturnsCorrectValue.kt"); + fooBoxTest(); } public void testOverloadedCallOnProperty() throws Exception { - checkFooBoxIsTrue("overloadedCallOnProperty.kt"); + fooBoxTest(); } public void testPostfixOnProperty() throws Exception { - checkFooBoxIsTrue("postfixOnProperty.kt"); + fooBoxTest(); } public void testOperatorOverloadOnPropertyCallGetterAndSetterOnlyOnce() throws Exception { - checkFooBoxIsTrue("operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt"); + fooBoxTest(); } public void testUnaryOnIntProperty() throws Exception { - checkFooBoxIsTrue("unaryOnIntProperty.kt"); + fooBoxTest(); } public void testUnaryOnIntPropertyAsStatement() throws Exception { - checkFooBoxIsTrue("unaryOnIntProperty2.kt"); + fooBoxTest(); } public void testBinaryDivOverload() throws Exception { - checkFooBoxIsTrue("binaryDivOverload.kt"); + fooBoxTest(); } public void testPlusAssignNoReassign() throws Exception { - checkFooBoxIsTrue("plusAssignNoReassign.kt"); + fooBoxTest(); } public void testNotOverload() throws Exception { - checkFooBoxIsTrue("notOverload.kt"); + fooBoxTest(); } public void testCompareTo() throws Exception { - checkFooBoxIsTrue("compareTo.kt"); + fooBoxTest(); } public void testPlusAndMinusAsAnExpression() throws Exception { - checkFooBoxIsTrue("plusAndMinusAsAnExpression.kt"); + fooBoxTest(); } public void testUsingModInCaseModAssignNotAvailable() throws Exception { - checkFooBoxIsTrue("usingModInCaseModAssignNotAvailable.kt"); + fooBoxTest(); } public void testOverloadPlusAssignArrayList() throws Exception { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java index 6a6759331c3..2cfd988f3f6 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java @@ -29,31 +29,31 @@ public final class PatternMatchingTest extends SingleFileTranslationTest { } public void testWhenType() throws Exception { - checkFooBoxIsTrue("whenType.kt"); + fooBoxTest(); } public void testWhenNotType() throws Exception { - checkFooBoxIsTrue("whenNotType.kt"); + fooBoxTest(); } public void testWhenExecutesOnlyOnce() throws Exception { - checkFooBoxIsTrue("whenExecutesOnlyOnce.kt"); + fooBoxTest(); } public void testWhenValue() throws Exception { - checkFooBoxIsTrue("whenValue.kt"); + fooBoxTest(); } public void testWhenNotValue() throws Exception { - checkFooBoxIsTrue("whenNotValue.kt"); + fooBoxTest(); } public void testWhenValueOrType() throws Exception { - checkFooBoxIsTrue("whenValueOrType.kt"); + fooBoxTest(); } public void testWhenWithIf() throws Exception { - checkFooBoxIsTrue("whenWithIf.kt"); + fooBoxTest(); } public void testMultipleCases() throws Exception { @@ -61,16 +61,16 @@ public final class PatternMatchingTest extends SingleFileTranslationTest { } public void testMatchNullableType() throws Exception { - checkFooBoxIsTrue("matchNullableType.kt"); + fooBoxTest(); } public void testWhenAsExpression() throws Exception { - checkFooBoxIsTrue("whenAsExpression.kt"); + fooBoxTest(); } public void testWhenAsExpressionWithThrow() throws Exception { try { - checkFooBoxIsTrue("whenAsExpressionWithThrow.kt"); + fooBoxTest(); fail(); } catch (JavaScriptException e) { @@ -82,6 +82,6 @@ public final class PatternMatchingTest extends SingleFileTranslationTest { } public void testWhenWithoutExpression() throws Exception { - checkFooBoxIsTrue("whenWithoutExpression.kt"); + fooBoxTest(); } } \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PropertyAccessTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PropertyAccessTest.java index b0337104eaa..7bad8bd9f53 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PropertyAccessTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PropertyAccessTest.java @@ -28,12 +28,12 @@ public final class PropertyAccessTest extends SingleFileTranslationTest { } public void testAccessToInstanceProperty() throws Exception { - checkFooBoxIsTrue("accessToInstanceProperty.kt"); + fooBoxTest(); } public void testTwoClassesWithProperties() throws Exception { - checkFooBoxIsTrue("twoClassesWithProperties.kt"); + fooBoxTest(); } @@ -43,34 +43,34 @@ public final class PropertyAccessTest extends SingleFileTranslationTest { public void testCustomGetter() throws Exception { - checkFooBoxIsTrue("customGetter.kt"); + fooBoxTest(); } public void testCustomSetter() throws Exception { - checkFooBoxIsTrue("customSetter.kt"); + fooBoxTest(); } public void testNamespacePropertyInitializer() throws Exception { - checkFooBoxIsTrue("namespacePropertyInitializer.kt"); + fooBoxTest(); } public void testNamespacePropertySet() throws Exception { - checkFooBoxIsTrue("namespacePropertySet.kt"); + fooBoxTest(); } public void testNamespaceCustomAccessors() throws Exception { - checkFooBoxIsTrue("namespaceCustomAccessors.kt"); + fooBoxTest(); } public void testClassUsesNamespaceProperties() throws Exception { - checkFooBoxIsTrue("classUsesNamespaceProperties.kt"); + fooBoxTest(); } public void testExtensionLiteralSafeCall() throws Exception { - checkFooBoxIsTrue("extensionLiteralSafeCall.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java index 5b4d3c39a5f..878ee527ae9 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java @@ -28,10 +28,10 @@ public class RTTITest extends SingleFileTranslationTest { } public void testIsSameClass() throws Exception { - checkFooBoxIsTrue("isSameClass.kt"); + fooBoxTest(); } public void testNotIsOtherClass() throws Exception { - checkFooBoxIsTrue("notIsOtherClass.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RangeTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RangeTest.java index 6aff22c38b3..10a497e40a9 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RangeTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RangeTest.java @@ -28,20 +28,20 @@ public final class RangeTest extends SingleFileTranslationTest { } public void testExplicitRange() throws Exception { - checkFooBoxIsTrue("explicitRange.kt"); + fooBoxTest(); } public void testRangeSugarSyntax() throws Exception { - checkFooBoxIsTrue("rangeSugarSyntax.kt"); + fooBoxTest(); } public void testIntInRange() throws Exception { - checkFooBoxIsTrue("intInRange.kt"); + fooBoxTest(); } public void testIteratingOverRanges() throws Exception { - checkFooBoxIsTrue("iteratingOverRanges.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/SafeCallTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/SafeCallTest.java index a07341c8f1b..223fe940d79 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/SafeCallTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/SafeCallTest.java @@ -28,7 +28,7 @@ public final class SafeCallTest extends SingleFileTranslationTest { } public void testSafeAccess() throws Exception { - checkFooBoxIsTrue("safeAccess.kt"); + fooBoxTest(); } public void testSafeExtensionFunctionCall() throws Exception { @@ -36,10 +36,10 @@ public final class SafeCallTest extends SingleFileTranslationTest { } public void testSafeCall() throws Exception { - checkFooBoxIsTrue("safeCall.kt"); + fooBoxTest(); } public void testSafeCallReturnsNullIfFails() throws Exception { - checkFooBoxIsTrue("safeCallReturnsNullIfFails.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/StandardClassesTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StandardClassesTest.java index 55632d8c93b..8a02744a4ac 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/StandardClassesTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StandardClassesTest.java @@ -28,38 +28,38 @@ public final class StandardClassesTest extends SingleFileTranslationTest { } public void testArray() throws Exception { - checkFooBoxIsTrue("array.kt"); + fooBoxTest(); } public void testArrayAccess() throws Exception { - checkFooBoxIsTrue("arrayAccess.kt"); + fooBoxTest(); } public void testArrayIsFilledWithNulls() throws Exception { - checkFooBoxIsTrue("arrayIsFilledWithNulls.kt"); + fooBoxTest(); } public void testArrayFunctionConstructor() throws Exception { - checkFooBoxIsTrue("arrayFunctionConstructor.kt"); + fooBoxTest(); } public void testArraySize() throws Exception { - checkFooBoxIsTrue("arraySize.kt"); + fooBoxTest(); } //TODO: this feature in not supported for some time //TODO: support it. Probably configurable. // (expected = JavaScriptException.class) // public void arrayThrowsExceptionOnOOBaccess() throws Exception { -// checkFooBoxIsTrue("arrayThrowsExceptionOnOOBaccess.kt"); +// fooBoxTest(); // } public void testArraysIterator() throws Exception { - checkFooBoxIsTrue("arraysIterator.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/StringTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StringTest.java index 3773a7b1a44..b7d2d4525e8 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/StringTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StringTest.java @@ -26,11 +26,11 @@ public final class StringTest extends AbstractExpressionTest { } public void testStringConstant() throws Exception { - checkFooBoxIsTrue("stringConstant.kt"); + fooBoxTest(); } public void testStringAssignment() throws Exception { - checkFooBoxIsTrue("stringAssignment.kt"); + fooBoxTest(); } public void testIntInTemplate() throws Exception { @@ -45,7 +45,7 @@ public final class StringTest extends AbstractExpressionTest { runFunctionOutputTest("multipleExpressionsInTemplate.kt", "foo", "box", "left = 3\nright = 2\nsum = 5\n"); } - public void testToStringMethod() throws Exception { - checkFooBoxIsTrue("objectToStringCallInTemplate.kt"); + public void testObjectToStringCallInTemplate() throws Exception { + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/TraitTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/TraitTest.java index b391b6920cf..9c7a9fee62f 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/TraitTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/TraitTest.java @@ -28,32 +28,32 @@ public final class TraitTest extends SingleFileTranslationTest { } public void testTraitAddsFunctionsToClass() throws Exception { - checkFooBoxIsTrue("traitAddsFunctionsToClass.kt"); + fooBoxTest(); } public void testClassDerivesFromClassAndTrait() throws Exception { - checkFooBoxIsTrue("classDerivesFromClassAndTrait.kt"); + fooBoxTest(); } public void testClassDerivesFromTraitAndClass() throws Exception { - checkFooBoxIsTrue("classDerivesFromTraitAndClass.kt"); + fooBoxTest(); } public void testExample() throws Exception { - checkFooBoxIsTrue("example.kt"); + fooBoxTest(); } public void testTraitExtendsTrait() throws Exception { - checkFooBoxIsTrue("traitExtendsTrait.kt"); + fooBoxTest(); } public void testTraitExtendsTwoTraits() throws Exception { - checkFooBoxIsTrue("traitExtendsTwoTraits.kt"); + fooBoxTest(); } @@ -63,6 +63,6 @@ public final class TraitTest extends SingleFileTranslationTest { public void testDefinitionOrder() throws Exception { - checkFooBoxIsTrue("definitionOrder.kt"); + fooBoxTest(); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/TupleTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/TupleTest.java index c1ba39cb37c..b1506a2cbd3 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/TupleTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/TupleTest.java @@ -29,11 +29,11 @@ public final class TupleTest extends SingleFileTranslationTest { } public void testTwoElements() throws Exception { - checkFooBoxIsTrue("twoElements.kt"); + fooBoxTest(); } public void testMultipleMembers() throws Exception { - checkFooBoxIsTrue("multipleMembers.kt"); + fooBoxTest(); } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/utils/TranslationUtils.java b/js/js.tests/test/org/jetbrains/k2js/test/utils/TranslationUtils.java index d2e07e4e538..13a2ecfc5fb 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/utils/TranslationUtils.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/utils/TranslationUtils.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.k2js.facade.K2JSTranslator; +import org.jetbrains.k2js.facade.MainCallParameters; import org.jetbrains.k2js.generate.CodeGenerator; import org.jetbrains.k2js.test.config.TestConfig; @@ -44,19 +45,21 @@ public final class TranslationUtils { private static /*var*/ K2JSTranslator translator = null; public static void translateFile(@NotNull Project project, @NotNull String inputFile, - @NotNull String outputFile) throws Exception { - translateFiles(project, Collections.singletonList(inputFile), outputFile); + @NotNull String outputFile, @NotNull MainCallParameters mainCallParameters) throws Exception { + translateFiles(project, Collections.singletonList(inputFile), outputFile, mainCallParameters); } public static void translateFiles(@NotNull Project project, @NotNull List inputFiles, - @NotNull String outputFile) throws Exception { + @NotNull String outputFile, @NotNull MainCallParameters mainCallParameters) throws Exception { + List psiFiles = createPsiFileList(inputFiles, project); - JsProgram program = getTranslator(project).generateProgram(psiFiles); + JsProgram program = getTranslator(project).generateProgram(psiFiles, mainCallParameters); FileWriter writer = new FileWriter(new File(outputFile)); try { writer.write("\"use strict\";\n"); writer.write(CodeGenerator.toString(program)); - } finally { + } + finally { writer.close(); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java index 922995b6095..7886c6818a0 100644 --- a/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java +++ b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java @@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.k2js.config.Config; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Set; @@ -67,7 +66,7 @@ public final class AnalyzerFacadeForJS { final ModuleDescriptor owner = new ModuleDescriptor(""); - Predicate completely = Predicates.and(notLibFiles(config.getLibFiles()), filesToAnalyzeCompletely); + Predicate completely = Predicates.and(notLibFiles(config.getLibFiles()), filesToAnalyzeCompletely); TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(completely, false, false); @@ -115,25 +114,6 @@ public final class AnalyzerFacadeForJS { return result; } - //TODO: exclude? - @NotNull - public static BindingContext analyzeNamespace(@NotNull JetFile file) { - BindingTraceContext bindingTraceContext = new BindingTraceContext(); - Project project = file.getProject(); - - final ModuleDescriptor owner = new ModuleDescriptor(""); - - TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters( - Predicates.alwaysTrue(), false, false); - - InjectorForTopDownAnalyzerForJs injector = new InjectorForTopDownAnalyzerForJs( - project, topDownAnalysisParameters, new ObservableBindingTrace(bindingTraceContext), owner, - JetControlFlowDataTraceFactory.EMPTY, JsConfiguration.jsLibConfiguration(project)); - - injector.getTopDownAnalyzer().analyzeFiles(Collections.singletonList(file)); - return bindingTraceContext.getBindingContext(); - } - private static final class JsConfiguration implements ModuleConfiguration { @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/config/Config.java b/js/js.translator/src/org/jetbrains/k2js/config/Config.java index 1d182c5d729..ae3b12449be 100644 --- a/js/js.translator/src/org/jetbrains/k2js/config/Config.java +++ b/js/js.translator/src/org/jetbrains/k2js/config/Config.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -31,6 +32,17 @@ import java.util.List; */ public abstract class Config { + @NotNull + public static Config getEmptyConfig(@NotNull Project project) { + return new Config(project) { + @NotNull + @Override + protected List generateLibFiles() { + return Collections.emptyList(); + } + }; + } + @NotNull protected static final List LIB_FILE_NAMES = Arrays.asList( "/core/annotations.kt", diff --git a/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java b/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java new file mode 100644 index 00000000000..dec84239cac --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.k2js.config; + +import com.google.common.collect.Lists; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.k2js.utils.JetFileUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * @author Pavel Talanov + */ +public class ZippedLibrarySourcesConfig extends Config { + @Nullable + protected final String pathToLibZip; + + public ZippedLibrarySourcesConfig(@NotNull Project project, @Nullable String pathToZip) { + super(project); + pathToLibZip = pathToZip; + } + + @NotNull + @Override + public List generateLibFiles() { + if (pathToLibZip == null) { + return Collections.emptyList(); + } + try { + File file = new File(pathToLibZip); + ZipFile zipFile = new ZipFile(file); + try { + return traverseArchive(zipFile); + } + finally { + zipFile.close(); + } + } + catch (IOException e) { + return Collections.emptyList(); + } + } + + @NotNull + private List traverseArchive(@NotNull ZipFile file) throws IOException { + List result = Lists.newArrayList(); + Enumeration zipEntries = file.entries(); + while (zipEntries.hasMoreElements()) { + ZipEntry entry = zipEntries.nextElement(); + if (!entry.isDirectory()) { + InputStream stream = file.getInputStream(entry); + String text = FileUtil.loadTextAndClose(stream); + JetFile jetFile = JetFileUtils.createPsiFile(entry.getName(), text, getProject()); + result.add(jetFile); + } + } + return result; + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java b/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java index f137660accc..99a0c17ee32 100644 --- a/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java @@ -24,22 +24,18 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; -import org.jetbrains.jet.plugin.JetMainDetector; import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS; import org.jetbrains.k2js.config.Config; +import org.jetbrains.k2js.facade.exceptions.TranslationException; import org.jetbrains.k2js.generate.CodeGenerator; import org.jetbrains.k2js.translate.general.Translation; -import org.jetbrains.k2js.utils.GenerationUtils; import org.jetbrains.k2js.utils.JetFileUtils; import java.io.File; import java.io.FileWriter; +import java.io.IOException; import java.util.*; -import static org.jetbrains.k2js.translate.utils.PsiUtils.getNamespaceName; - -//TODO: clean up the code - /** * @author Pavel Talanov *

@@ -48,21 +44,19 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getNamespaceName; public final class K2JSTranslator { public static void translateWithCallToMainAndSaveToFile(@NotNull List files, - @NotNull String outputPath, - @NotNull Config config, - @NotNull Project project) throws Exception { + @NotNull String outputPath, + @NotNull Config config) throws Exception { K2JSTranslator translator = new K2JSTranslator(config); - String programCode = translator.generateProgramCode(files) + "\n"; - JetFile fileWithMain = JetMainDetector.getFileWithMain(files); - if (fileWithMain == null) { - throw new RuntimeException("No file with main detected."); - } - String callToMain = generateCallToMain(fileWithMain, ""); + String programCode = translator.generateProgramCode(files, MainCallParameters.mainWithoutArguments()) + "\n"; + writeCodeToFile(outputPath, programCode); + } + + private static void writeCodeToFile(@NotNull String outputPath, @NotNull String programCode) throws IOException { File file = new File(outputPath); FileUtil.createParentDirs(file); FileWriter writer = new FileWriter(file); try { - writer.write(programCode + callToMain); + writer.write(programCode); } finally { writer.close(); @@ -77,46 +71,39 @@ public final class K2JSTranslator { this.config = config; } - //TODO: refactor //TODO: web demo related method @SuppressWarnings("UnusedDeclaration") @NotNull - public String translateStringWithCallToMain(@NotNull String programText, @NotNull String argumentsString) { + public String translateStringWithCallToMain(@NotNull String programText, @NotNull String argumentsString) throws TranslationException { JetFile file = JetFileUtils.createPsiFile("test", programText, getProject()); - String programCode = generateProgramCode(file) + "\n"; + String programCode = generateProgramCode(file, MainCallParameters.mainWithArguments(parseString(argumentsString))) + "\n"; String flushOutput = "Kotlin.System.flush();\n"; - String callToMain = generateCallToMain(file, argumentsString); String programOutput = "Kotlin.System.output();\n"; - return programCode + flushOutput + callToMain + programOutput; + return flushOutput + programCode + programOutput; } @NotNull - public String generateProgramCode(@NotNull JetFile psiFile) { - JsProgram program = generateProgram(Arrays.asList(psiFile)); + public String generateProgramCode(@NotNull JetFile file, @NotNull MainCallParameters mainCallParameters) throws TranslationException { + JsProgram program = generateProgram(Arrays.asList(file), mainCallParameters); CodeGenerator generator = new CodeGenerator(); return generator.generateToString(program); } @NotNull - public String generateProgramCode(@NotNull List files) { - JsProgram program = generateProgram(files); + public String generateProgramCode(@NotNull List files, @NotNull MainCallParameters mainCallParameters) + throws TranslationException { + JsProgram program = generateProgram(files, mainCallParameters); CodeGenerator generator = new CodeGenerator(); return generator.generateToString(program); } @NotNull - public JsProgram generateProgram(@NotNull List filesToTranslate) { + public JsProgram generateProgram(@NotNull List filesToTranslate, @NotNull MainCallParameters mainCallParameters) + throws TranslationException { JetStandardLibrary.initialize(config.getProject()); BindingContext bindingContext = AnalyzerFacadeForJS.analyzeFilesAndCheckErrors(filesToTranslate, config); Collection files = AnalyzerFacadeForJS.withJsLibAdded(filesToTranslate, config); - return Translation.generateAst(bindingContext, Lists.newArrayList(files)); - } - - @NotNull - public static String generateCallToMain(@NotNull JetFile file, @NotNull String argumentString) { - String namespaceName = getNamespaceName(file); - List arguments = parseString(argumentString); - return GenerationUtils.generateCallToMain(namespaceName, arguments); + return Translation.generateAst(bindingContext, Lists.newArrayList(files), mainCallParameters); } //TODO: util diff --git a/js/js.translator/src/org/jetbrains/k2js/facade/MainCallParameters.java b/js/js.translator/src/org/jetbrains/k2js/facade/MainCallParameters.java new file mode 100644 index 00000000000..d7c5bc8cf73 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/facade/MainCallParameters.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.k2js.facade; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +/** + * @author Pavel Talanov + */ +public abstract class MainCallParameters { + + @NotNull + public static MainCallParameters noCall() { + return new MainCallParameters() { + + @NotNull + @Override + public List arguments() { + throw new UnsupportedOperationException("#arguments"); + } + + @Override + public boolean shouldBeGenerated() { + return false; + } + }; + } + + + @NotNull + public static MainCallParameters mainWithoutArguments() { + return new MainCallParameters() { + + @NotNull + @Override + public List arguments() { + return Collections.emptyList(); + } + + @Override + public boolean shouldBeGenerated() { + return true; + } + }; + } + + @NotNull + public static MainCallParameters mainWithArguments(@NotNull final List parameters) { + return new MainCallParameters() { + + @NotNull + @Override + public List arguments() { + return parameters; + } + + @Override + public boolean shouldBeGenerated() { + return true; + } + }; + } + + public abstract boolean shouldBeGenerated(); + + @NotNull + public abstract List arguments(); +} diff --git a/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/MainFunctionNotFoundException.java b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/MainFunctionNotFoundException.java new file mode 100644 index 00000000000..fdbe4e5f640 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/MainFunctionNotFoundException.java @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.k2js.facade.exceptions; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Pavel Talanov + */ +public class MainFunctionNotFoundException extends TranslationException { + public MainFunctionNotFoundException(@NotNull String message) { + super(message); + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/utils/GenerationUtils.java b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/TranslationException.java similarity index 52% rename from js/js.translator/src/org/jetbrains/k2js/utils/GenerationUtils.java rename to js/js.translator/src/org/jetbrains/k2js/facade/exceptions/TranslationException.java index 84e4fa5a0a7..82cf86b4911 100644 --- a/js/js.translator/src/org/jetbrains/k2js/utils/GenerationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/TranslationException.java @@ -14,33 +14,24 @@ * limitations under the License. */ -package org.jetbrains.k2js.utils; +package org.jetbrains.k2js.facade.exceptions; import org.jetbrains.annotations.NotNull; -import java.util.List; - -//TODO: very thin class - /** * @author Pavel Talanov */ -public final class GenerationUtils { +public class TranslationException extends Exception { - private GenerationUtils() { + public TranslationException(@NotNull String message) { + super(message); } - @NotNull - public static String generateCallToMain(@NotNull String namespaceName, @NotNull List arguments) { - String constructArguments = "var args = [];\n"; - int index = 0; - for (String argument : arguments) { - constructArguments = constructArguments + "args[" + index + "]= \"" + argument + "\";\n"; - index++; - } - String callMain = namespaceName + ".main(args);\n"; - return constructArguments + callMain; + public TranslationException(@NotNull Throwable cause) { + super(cause); } - + public TranslationException(@NotNull String message, @NotNull Exception cause) { + super(message, cause); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/TranslationInternalException.java b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/TranslationInternalException.java new file mode 100644 index 00000000000..c2cf42247cd --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/TranslationInternalException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.k2js.facade.exceptions; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Pavel Talanov + */ +public class TranslationInternalException extends TranslationException { + + public TranslationInternalException(@NotNull Throwable cause) { + super(cause); + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/UnsupportedFeatureException.java b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/UnsupportedFeatureException.java new file mode 100644 index 00000000000..3806043ba5a --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/facade/exceptions/UnsupportedFeatureException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.k2js.facade.exceptions; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Pavel Talanov + */ +public class UnsupportedFeatureException extends TranslationException { + + public UnsupportedFeatureException(@NotNull String message, @NotNull Exception cause) { + super(message, cause); + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java index aef94dd94e1..0488084bc17 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java @@ -27,12 +27,13 @@ import org.jetbrains.jet.lang.psi.JetPropertyAccessor; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.Translation; -import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.ArrayList; import java.util.List; -import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; +import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyForDescriptor; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.newNamedMethod; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters; import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField; import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference; @@ -51,7 +52,7 @@ public final class PropertyTranslator extends AbstractTranslator { private final JetProperty declaration; static public List translateAccessors(@NotNull PropertyDescriptor descriptor, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { PropertyTranslator propertyTranslator = new PropertyTranslator(descriptor, context); return propertyTranslator.translate(); } @@ -59,7 +60,7 @@ public final class PropertyTranslator extends AbstractTranslator { private PropertyTranslator(@NotNull PropertyDescriptor property, @NotNull TranslationContext context) { super(context); this.property = property; - this.declaration = BindingUtils.getPropertyForDescriptor(bindingContext(), property); + this.declaration = getPropertyForDescriptor(bindingContext(), property); } @NotNull @@ -90,11 +91,11 @@ public final class PropertyTranslator extends AbstractTranslator { } private boolean hasCustomGetter() { - return ((declaration != null) && (declaration.getGetter() != null)); + return ((declaration != null) && (declaration.getGetter() != null) && getCustomGetterDeclaration().getBodyExpression() != null); } private boolean hasCustomSetter() { - return ((declaration != null) && (declaration.getSetter() != null)); + return ((declaration != null) && (declaration.getSetter() != null) && getCustomSetterDeclaration().getBodyExpression() != null); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java index b78bd8127c5..a73256bc3bc 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -20,10 +20,16 @@ import com.google.dart.compiler.backend.js.JsNamer; import com.google.dart.compiler.backend.js.JsPrettyNamer; import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; +import org.jetbrains.k2js.facade.MainCallParameters; +import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException; +import org.jetbrains.k2js.facade.exceptions.TranslationInternalException; +import org.jetbrains.k2js.facade.exceptions.TranslationException; +import org.jetbrains.k2js.facade.exceptions.UnsupportedFeatureException; import org.jetbrains.k2js.translate.context.StaticContext; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.declaration.ClassTranslator; @@ -34,14 +40,18 @@ import org.jetbrains.k2js.translate.expression.PatternTranslator; import org.jetbrains.k2js.translate.expression.WhenTranslator; import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator; import org.jetbrains.k2js.translate.initializer.NamespaceInitializerTranslator; +import org.jetbrains.k2js.translate.reference.CallBuilder; +import org.jetbrains.k2js.translate.utils.JsAstUtils; import org.jetbrains.k2js.translate.utils.dangerous.DangerousData; import org.jetbrains.k2js.translate.utils.dangerous.DangerousTranslator; +import java.util.Collections; import java.util.List; import java.util.Map; -import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToExpression; -import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement; +import static org.jetbrains.jet.plugin.JetMainDetector.getMainFunction; +import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.dangerous.DangerousData.collect; /** @@ -57,7 +67,7 @@ public final class Translation { @NotNull public static FunctionTranslator functionTranslator(@NotNull JetDeclarationWithBody function, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return FunctionTranslator.newInstance(function, context); } @@ -68,8 +78,8 @@ public final class Translation { @NotNull public static JsInvocation translateClassDeclaration(@NotNull JetClass classDeclaration, - @NotNull Map aliasingMap, - @NotNull TranslationContext context) { + @NotNull Map aliasingMap, + @NotNull TranslationContext context) { return ClassTranslator.generateClassCreationExpression(classDeclaration, aliasingMap, context); } @@ -99,48 +109,92 @@ public final class Translation { @NotNull public static JsExpression translateAsExpression(@NotNull JetExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return convertToExpression(translateExpression(expression, context)); } @NotNull public static JsStatement translateAsStatement(@NotNull JetExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return convertToStatement(translateExpression(expression, context)); } @NotNull public static JsNode translateWhenExpression(@NotNull JetWhenExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return WhenTranslator.translateWhenExpression(expression, context); } //TODO: see if generate*Initializer methods fit somewhere else @NotNull public static JsPropertyInitializer generateClassInitializerMethod(@NotNull JetClassOrObject classDeclaration, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { final ClassInitializerTranslator classInitializerTranslator = new ClassInitializerTranslator(classDeclaration, context); return classInitializerTranslator.generateInitializeMethod(); } @NotNull public static JsPropertyInitializer generateNamespaceInitializerMethod(@NotNull NamespaceDescriptor namespace, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { final NamespaceInitializerTranslator namespaceInitializerTranslator = new NamespaceInitializerTranslator(namespace, context); return namespaceInitializerTranslator.generateInitializeMethod(); } @NotNull public static JsProgram generateAst(@NotNull BindingContext bindingContext, - @NotNull List files) { + @NotNull List files, @NotNull MainCallParameters mainCallParameters) throws TranslationException { + try { + return doGenerateAst(bindingContext, files, mainCallParameters); + } + catch (UnsupportedOperationException e) { + throw new UnsupportedFeatureException("Unsupported feature used.", e); + } + catch (Throwable e) { + throw new TranslationInternalException(e); + } + } + + @NotNull + private static JsProgram doGenerateAst(@NotNull BindingContext bindingContext, @NotNull List files, + @NotNull MainCallParameters mainCallParameters) throws MainFunctionNotFoundException { //TODO: move some of the code somewhere JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance(); StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext); JsBlock block = staticContext.getProgram().getFragmentBlock(0); TranslationContext context = TranslationContext.rootContext(staticContext); block.getStatements().addAll(translateFiles(files, context)); + if (mainCallParameters.shouldBeGenerated()) { + block.getStatements().add(generateCallToMain(context, files, mainCallParameters.arguments())); + } JsNamer namer = new JsPrettyNamer(); namer.exec(context.program()); return context.program(); } + + @NotNull + private static JsStatement generateCallToMain(@NotNull TranslationContext context, @NotNull List files, + @NotNull List arguments) throws MainFunctionNotFoundException { + JetNamedFunction mainFunction = getMainFunction(files); + if (mainFunction == null) { + throw new MainFunctionNotFoundException("Main function was not found. Please check compiler arguments"); + } + JsInvocation translatedCall = generateInvocation(context, mainFunction); + setArguments(context, arguments, translatedCall); + return translatedCall.makeStmt(); + } + + @NotNull + private static JsInvocation generateInvocation(@NotNull TranslationContext context, @NotNull JetNamedFunction mainFunction) { + FunctionDescriptor functionDescriptor = getFunctionDescriptor(context.bindingContext(), mainFunction); + JsExpression translatedCall = CallBuilder.build(context).descriptor(functionDescriptor).translate(); + assert translatedCall instanceof JsInvocation; + return (JsInvocation) translatedCall; + } + + private static void setArguments(@NotNull TranslationContext context, @NotNull List arguments, + @NotNull JsInvocation translatedCall) { + JsArrayLiteral arrayLiteral = new JsArrayLiteral(); + arrayLiteral.getExpressions().addAll(toStringLiteralList(arguments, context.program())); + JsAstUtils.setArguments(translatedCall, Collections.singletonList(arrayLiteral)); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java index 3db146a9563..f1438688fbd 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java @@ -58,7 +58,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator { @NotNull public JsPropertyInitializer generateInitializeMethod() { - //TODO: it's inconsistent that we scope for class and function for constructor, currently have problems implementing better way + //TODO: it's inconsistent that we have scope for class and function for constructor, currently have problems implementing better way ConstructorDescriptor primaryConstructor = getConstructor(bindingContext(), classDeclaration); JsFunction result = context().getFunctionObject(primaryConstructor); //NOTE: while we translate constructor parameters we also add property initializer statements diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java index 02bf303717d..b19818a5ef1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java @@ -51,20 +51,20 @@ public abstract class AbstractCallExpressionTranslator extends AbstractTranslato protected final CallType callType; protected AbstractCallExpressionTranslator(@NotNull JetCallExpression expression, - @Nullable JsExpression receiver, - @NotNull CallType type, @NotNull TranslationContext context) { + @Nullable JsExpression receiver, + @NotNull CallType type, @NotNull TranslationContext context) { super(context); this.expression = expression; this.resolvedCall = getResolvedCallForCallExpression(bindingContext(), expression); this.receiver = receiver; - callType = type; + this.callType = type; } abstract public boolean shouldWrapVarargInArray(); @NotNull protected List translateSingleArgument(@NotNull ResolvedValueArgument actualArgument, - @NotNull ValueParameterDescriptor parameterDescriptor) { + @NotNull ValueParameterDescriptor parameterDescriptor) { List valueArguments = actualArgument.getArguments(); if (actualArgument instanceof VarargValueArgument) { return translateVarargArgument(valueArguments); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParameters.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParameters.java index 14c09db8dde..880a99ec32c 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParameters.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParameters.java @@ -56,4 +56,13 @@ public final class CallParameters { public JsExpression getReceiver() { return receiver; } + + @Nullable + public JsExpression getThisOrReceiverOrNull() { + if (thisObject == null) { + return receiver; + } + assert receiver == null; + return thisObject; + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java index e49a9d82435..c107c3bdf77 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java @@ -19,14 +19,16 @@ package org.jetbrains.k2js.translate.reference; import com.google.dart.compiler.backend.js.ast.JsExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.utils.TranslationUtils; -import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*; +import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor; /** * @author Pavel Talanov @@ -34,10 +36,10 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*; public final class CallParametersResolver { public static CallParameters resolveCallParameters(@Nullable JsExpression qualifier, - @Nullable JsExpression callee, - @NotNull CallableDescriptor descriptor, - @NotNull ResolvedCall call, - @NotNull TranslationContext context) { + @Nullable JsExpression callee, + @NotNull CallableDescriptor descriptor, + @NotNull ResolvedCall call, + @NotNull TranslationContext context) { return (new CallParametersResolver(qualifier, callee, descriptor, call, context)).resolve(); } @@ -55,10 +57,10 @@ public final class CallParametersResolver { private final boolean isExtensionCall; public CallParametersResolver(@Nullable JsExpression qualifier, - @Nullable JsExpression callee, - @NotNull CallableDescriptor descriptor, - @NotNull ResolvedCall call, - @NotNull TranslationContext context) { + @Nullable JsExpression callee, + @NotNull CallableDescriptor descriptor, + @NotNull ResolvedCall call, + @NotNull TranslationContext context) { this.qualifier = qualifier; this.callee = callee; this.descriptor = descriptor; @@ -104,7 +106,7 @@ public final class CallParametersResolver { if (qualifier != null) { return qualifier; } - DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor); + DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(resolvedCall.getResultingDescriptor()); assert expectedReceiverDescriptor != null; return TranslationUtils.getThisObject(context, expectedReceiverDescriptor); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index 40261414321..e3adc795fd5 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -130,7 +130,7 @@ public final class CallTranslator extends AbstractTranslator { private JsExpression intrinsicInvocation() { assert descriptor instanceof FunctionDescriptor; Intrinsic intrinsic = context().intrinsics().getFunctionIntrinsic((FunctionDescriptor) descriptor); - return intrinsic.apply(callParameters.getThisObject(), arguments, context()); + return intrinsic.apply(callParameters.getThisOrReceiverOrNull(), arguments, context()); } private boolean isConstructor() { @@ -244,7 +244,7 @@ public final class CallTranslator extends AbstractTranslator { } @Nullable - JsExpression getThisObjectOrQualifier() { + private JsExpression getThisObjectOrQualifier() { JsExpression thisObject = callParameters.getThisObject(); if (thisObject != null) { return thisObject; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index a6fcbf75dbb..11090c851b7 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -55,41 +55,41 @@ public final class BindingUtils { DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); assert descriptor != null; assert descriptorClass.isInstance(descriptor) - : expression.toString() + " expected to have of type" + descriptorClass.toString(); + : expression.toString() + " expected to have of type" + descriptorClass.toString(); //noinspection unchecked - return (D)descriptor; + return (D) descriptor; } @NotNull public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context, - @NotNull JetClassOrObject declaration) { + @NotNull JetClassOrObject declaration) { return getDescriptorForExpression(context, declaration, ClassDescriptor.class); } @NotNull public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context, - @NotNull JetFile declaration) { + @NotNull JetFile declaration) { NamespaceDescriptor namespaceDescriptor = - context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration)); + context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration)); assert namespaceDescriptor != null : "File should have a namespace descriptor."; return namespaceDescriptor; } @NotNull public static FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context, - @NotNull JetDeclarationWithBody declaration) { + @NotNull JetDeclarationWithBody declaration) { return getDescriptorForExpression(context, declaration, FunctionDescriptor.class); } @NotNull public static PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context, - @NotNull JetProperty declaration) { + @NotNull JetProperty declaration) { return getDescriptorForExpression(context, declaration, PropertyDescriptor.class); } @NotNull public static JetClass getClassForDescriptor(@NotNull BindingContext context, - @NotNull ClassDescriptor descriptor) { + @NotNull ClassDescriptor descriptor) { JetClass result = (JetClass) BindingContextUtils.classDescriptorToDeclaration(context, descriptor); if (result == null) { throw new IllegalStateException("JetClass not found for " + descriptor); @@ -99,15 +99,15 @@ public final class BindingUtils { @NotNull public static JetFunction getFunctionForDescriptor(@NotNull BindingContext context, - @NotNull SimpleFunctionDescriptor descriptor) { + @NotNull SimpleFunctionDescriptor descriptor) { PsiElement result = BindingContextUtils.callableDescriptorToDeclaration(context, descriptor); assert result instanceof JetFunction : "SimpleFunctionDescriptor should have declaration of type JetFunction"; - return (JetFunction)result; + return (JetFunction) result; } @NotNull public static List getDeclarationsForNamespace(@NotNull BindingContext bindingContext, - @NotNull NamespaceDescriptor namespace) { + @NotNull NamespaceDescriptor namespace) { List declarations = new ArrayList(); for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespace)) { if (descriptor instanceof NamespaceDescriptor) { @@ -123,22 +123,22 @@ public final class BindingUtils { @Nullable private static JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context, - @NotNull DeclarationDescriptor descriptor) { + @NotNull DeclarationDescriptor descriptor) { PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor); if (result == null) { //TODO: never get there return null; } assert result instanceof JetDeclaration : "Descriptor should correspond to an element."; - return (JetDeclaration)result; + return (JetDeclaration) result; } @NotNull private static JetParameter getParameterForDescriptor(@NotNull BindingContext context, - @NotNull ValueParameterDescriptor descriptor) { + @NotNull ValueParameterDescriptor descriptor) { PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor); assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter."; - return (JetParameter)result; + return (JetParameter) result; } public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) { @@ -155,7 +155,7 @@ public final class BindingUtils { @NotNull public static JetType getTypeByReference(@NotNull BindingContext context, - @NotNull JetTypeReference typeReference) { + @NotNull JetTypeReference typeReference) { JetType result = context.get(BindingContext.TYPE, typeReference); assert result != null : "TypeReference should reference a type"; return result; @@ -163,29 +163,29 @@ public final class BindingUtils { @NotNull public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context, - @NotNull JetTypeReference typeReference) { + @NotNull JetTypeReference typeReference) { return getClassDescriptorForType(getTypeByReference(context, typeReference)); } @Nullable public static PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context, - @NotNull JetParameter parameter) { + @NotNull JetParameter parameter) { return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); } @Nullable public static JetProperty getPropertyForDescriptor(@NotNull BindingContext context, - @NotNull PropertyDescriptor property) { + @NotNull PropertyDescriptor property) { PsiElement result = BindingContextUtils.descriptorToDeclaration(context, property); if (!(result instanceof JetProperty)) { return null; } - return (JetProperty)result; + return (JetProperty) result; } @NotNull public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context, - @NotNull JetReferenceExpression reference) { + @NotNull JetReferenceExpression reference) { DeclarationDescriptor referencedDescriptor = getNullableDescriptorForReferenceExpression(context, reference); assert referencedDescriptor != null : "Reference expression must reference a descriptor."; return referencedDescriptor; @@ -194,7 +194,7 @@ public final class BindingUtils { //TODO: remove? @Nullable public static DeclarationDescriptor getNullableDescriptorForReferenceExpression(@NotNull BindingContext context, - @NotNull JetReferenceExpression reference) { + @NotNull JetReferenceExpression reference) { return context.get(BindingContext.REFERENCE_TARGET, reference); } @@ -204,7 +204,7 @@ public final class BindingUtils { @NotNull public static ResolvedCall getResolvedCall(@NotNull BindingContext context, - @NotNull JetExpression expression) { + @NotNull JetExpression expression) { ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression); assert resolvedCall != null : "Must resolve to a call."; return resolvedCall; @@ -212,18 +212,18 @@ public final class BindingUtils { @NotNull public static ResolvedCall getResolvedCallForProperty(@NotNull BindingContext context, - @NotNull JetExpression expression) { + @NotNull JetExpression expression) { ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression); assert resolvedCall != null : "Must resolve to a call."; if (resolvedCall instanceof VariableAsFunctionResolvedCall) { - return ((VariableAsFunctionResolvedCall)resolvedCall).getVariableCall(); + return ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall(); } return resolvedCall; } @NotNull public static ResolvedCall getResolvedCallForCallExpression(@NotNull BindingContext context, - @NotNull JetCallExpression expression) { + @NotNull JetCallExpression expression) { JetExpression calleeExpression = PsiUtils.getCallee(expression); return getResolvedCall(context, calleeExpression); } @@ -237,20 +237,20 @@ public final class BindingUtils { @Nullable public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context, - @NotNull JetOperationExpression expression) { + @NotNull JetOperationExpression expression) { DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression - (context, expression.getOperationReference()); + (context, expression.getOperationReference()); if (descriptorForReferenceExpression == null) return null; assert descriptorForReferenceExpression instanceof FunctionDescriptor - : "Operation should resolve to function descriptor."; - return (FunctionDescriptor)descriptorForReferenceExpression; + : "Operation should resolve to function descriptor."; + return (FunctionDescriptor) descriptorForReferenceExpression; } @NotNull public static DeclarationDescriptor getDescriptorForElement(@NotNull BindingContext context, - @NotNull PsiElement element) { + @NotNull PsiElement element) { DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); assert descriptor != null : element + " doesn't have a descriptor."; return descriptor; @@ -267,17 +267,27 @@ public final class BindingUtils { @NotNull public static JetExpression getDefaultArgument(@NotNull BindingContext context, - @NotNull ValueParameterDescriptor parameterDescriptor) { - assert parameterDescriptor.hasDefaultValue() : "Unsupplied parameter must have default value."; - JetParameter psiParameter = getParameterForDescriptor(context, parameterDescriptor); + @NotNull ValueParameterDescriptor parameterDescriptor) { + ValueParameterDescriptor descriptorWhichDeclaresDefaultValue = getOriginalDescriptorWhichDeclaresDefaultValue(parameterDescriptor); + JetParameter psiParameter = getParameterForDescriptor(context, descriptorWhichDeclaresDefaultValue); JetExpression defaultValue = psiParameter.getDefaultValue(); assert defaultValue != null : "No default value found in PSI."; return defaultValue; } + private static ValueParameterDescriptor getOriginalDescriptorWhichDeclaresDefaultValue( + @NotNull ValueParameterDescriptor parameterDescriptor) { + ValueParameterDescriptor result = parameterDescriptor; + assert result.hasDefaultValue() : "Unsupplied parameter must have default value."; + while (!result.declaresDefaultValue()) { + result = result.getOverriddenDescriptors().iterator().next(); + } + return result; + } + @NotNull public static FunctionDescriptor getIteratorFunction(@NotNull BindingContext context, - @NotNull JetExpression rangeExpression) { + @NotNull JetExpression rangeExpression) { FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_ITERATOR, rangeExpression); assert functionDescriptor != null : "Range expression must have a descriptor for iterator function."; return functionDescriptor; @@ -285,7 +295,7 @@ public final class BindingUtils { @NotNull public static FunctionDescriptor getNextFunction(@NotNull BindingContext context, - @NotNull JetExpression rangeExpression) { + @NotNull JetExpression rangeExpression) { FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_NEXT, rangeExpression); assert functionDescriptor != null : "Range expression must have a descriptor for next function."; return functionDescriptor; @@ -293,7 +303,7 @@ public final class BindingUtils { @NotNull public static CallableDescriptor getHasNextCallable(@NotNull BindingContext context, - @NotNull JetExpression rangeExpression) { + @NotNull JetExpression rangeExpression) { CallableDescriptor hasNextDescriptor = context.get(BindingContext.LOOP_RANGE_HAS_NEXT, rangeExpression); assert hasNextDescriptor != null : "Range expression must have a descriptor for hasNext function or property."; return hasNextDescriptor; @@ -301,7 +311,7 @@ public final class BindingUtils { @NotNull public static PropertyDescriptor getPropertyDescriptorForObjectDeclaration(@NotNull BindingContext context, - @NotNull JetObjectDeclarationName name) { + @NotNull JetObjectDeclarationName name) { PropertyDescriptor propertyDescriptor = context.get(BindingContext.OBJECT_DECLARATION, name); assert propertyDescriptor != null; return propertyDescriptor; @@ -309,7 +319,7 @@ public final class BindingUtils { @NotNull public static Set getAllNonNativeNamespaceDescriptors(@NotNull BindingContext context, - @NotNull List files) { + @NotNull List files) { Set descriptorSet = Sets.newHashSet(); for (JetFile file : files) { //TODO: can't be @@ -323,7 +333,7 @@ public final class BindingUtils { @NotNull public static JetType getTypeForExpression(@NotNull BindingContext context, - @NotNull JetExpression expression) { + @NotNull JetExpression expression) { JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); assert type != null; return type; @@ -331,8 +341,8 @@ public final class BindingUtils { @NotNull public static ResolvedCall getResolvedCallForArrayAccess(@NotNull BindingContext context, - @NotNull JetArrayAccessExpression arrayAccessExpression, - boolean isGet) { + @NotNull JetArrayAccessExpression arrayAccessExpression, + boolean isGet) { ResolvedCall resolvedCall = context.get(isGet ? INDEXED_LVALUE_GET : INDEXED_LVALUE_SET, arrayAccessExpression); @@ -341,9 +351,9 @@ public final class BindingUtils { } public static ConstructorDescriptor getConstructor(@NotNull BindingContext bindingContext, - @NotNull JetClassOrObject declaration) { + @NotNull JetClassOrObject declaration) { ConstructorDescriptor primaryConstructor = - getClassDescriptor(bindingContext, declaration).getUnsubstitutedPrimaryConstructor(); + getClassDescriptor(bindingContext, declaration).getUnsubstitutedPrimaryConstructor(); assert primaryConstructor != null : "Traits do not have initialize methods."; return primaryConstructor; } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java index f2b19b49f23..cd27a872d82 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java @@ -21,10 +21,7 @@ import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.util.*; /** * @author Pavel Talanov @@ -83,11 +80,6 @@ public final class JsAstUtils { return new JsPrefixOperation(JsUnaryOperator.NOT, expression); } - @NotNull - public static JsStatement newAssignmentStatement(@NotNull JsNameRef nameRef, @NotNull JsExpression expr) { - return convertToStatement(new JsBinaryOperation(JsBinaryOperator.ASG, nameRef, expr)); - } - @NotNull public static JsBinaryOperation and(@NotNull JsExpression op1, @NotNull JsExpression op2) { return new JsBinaryOperation(JsBinaryOperator.AND, op1, op2); @@ -165,9 +157,9 @@ public final class JsAstUtils { @NotNull public static JsFor generateForExpression(@NotNull JsVars initExpression, - @NotNull JsExpression condition, - @NotNull JsExpression incrExpression, - @NotNull JsStatement body) { + @NotNull JsExpression condition, + @NotNull JsExpression incrExpression, + @NotNull JsStatement body) { JsFor result = new JsFor(); result.setInitVars(initExpression); result.setCondition(condition); @@ -271,4 +263,13 @@ public final class JsAstUtils { correspondingFunction.setBody(new JsBlock()); return correspondingFunction; } + + @NotNull + public static List toStringLiteralList(@NotNull List strings, @NotNull JsProgram program) { + ArrayList result = Lists.newArrayList(); + for (String str : strings) { + result.add(program.getStringLiteral(str)); + } + return result; + } } diff --git a/js/js.translator/testFiles/expression/misc/cases/KT-1865.kt b/js/js.translator/testFiles/expression/misc/cases/KT-1865.kt new file mode 100644 index 00000000000..9f87cb1ea1b --- /dev/null +++ b/js/js.translator/testFiles/expression/misc/cases/KT-1865.kt @@ -0,0 +1,11 @@ +package foo + +open class A { + open fun foo(a : Int = 1) = a +} + +class B : A() { + override fun foo(a : Int) = a + 1 +} + +fun box() = (B().foo() == 2) \ No newline at end of file diff --git a/js/js.translator/testFiles/expression/misc/cases/extensionLiteralCalledInsideExtensionFunction.kt b/js/js.translator/testFiles/expression/misc/cases/extensionLiteralCalledInsideExtensionFunction.kt new file mode 100644 index 00000000000..fe46faf30df --- /dev/null +++ b/js/js.translator/testFiles/expression/misc/cases/extensionLiteralCalledInsideExtensionFunction.kt @@ -0,0 +1,18 @@ +package foo + +fun A.create(init : A.() -> Unit) : A { + init() + return this +} + +fun box() : Boolean { + val a = A().create { + c = 1 + t + } + return a.c == 4 +} + +class A() { + val t = 3 + var c = 2 +} \ No newline at end of file diff --git a/js/js.translator/testFiles/expression/misc/cases/ifAsExpressionWithThrow.kt b/js/js.translator/testFiles/expression/misc/cases/ifElseAsExpressionWithThrow.kt similarity index 100% rename from js/js.translator/testFiles/expression/misc/cases/ifAsExpressionWithThrow.kt rename to js/js.translator/testFiles/expression/misc/cases/ifElseAsExpressionWithThrow.kt diff --git a/js/js.translator/testFiles/expression/misc/cases/mainFunInNestedNamespace.kt b/js/js.translator/testFiles/expression/misc/cases/mainFunInNestedNamespace.kt new file mode 100644 index 00000000000..68f27fdb447 --- /dev/null +++ b/js/js.translator/testFiles/expression/misc/cases/mainFunInNestedNamespace.kt @@ -0,0 +1,7 @@ +package a.b.c + +import js.* + +fun main(args : Array) { + println("ayee") +} \ No newline at end of file diff --git a/js/js.translator/testFiles/expression/misc/cases/propertiesWithExplicitlyDefinedAccessorsWithoutBodies.kt b/js/js.translator/testFiles/expression/misc/cases/propertiesWithExplicitlyDefinedAccessorsWithoutBodies.kt new file mode 100644 index 00000000000..29a23fa27ad --- /dev/null +++ b/js/js.translator/testFiles/expression/misc/cases/propertiesWithExplicitlyDefinedAccessorsWithoutBodies.kt @@ -0,0 +1,14 @@ +package foo + + +class A() { + private var c : Int = 3 + private get + private set + + fun f() = c + 1 +} + +fun box() : Boolean { + return A().f() == 4 +} \ No newline at end of file diff --git a/js/js.translator/testFiles/operatorOverloading/cases/postfixIncOverload.kt b/js/js.translator/testFiles/operatorOverloading/cases/postfixInc.kt similarity index 100% rename from js/js.translator/testFiles/operatorOverloading/cases/postfixIncOverload.kt rename to js/js.translator/testFiles/operatorOverloading/cases/postfixInc.kt diff --git a/js/js.translator/testFiles/operatorOverloading/cases/unaryOnIntProperty2.kt b/js/js.translator/testFiles/operatorOverloading/cases/unaryOnIntPropertyAsStatement.kt similarity index 100% rename from js/js.translator/testFiles/operatorOverloading/cases/unaryOnIntProperty2.kt rename to js/js.translator/testFiles/operatorOverloading/cases/unaryOnIntPropertyAsStatement.kt diff --git a/libraries/maven-settings.xml b/libraries/maven-settings.xml index 468a0d21d71..3a5040305c7 100644 --- a/libraries/maven-settings.xml +++ b/libraries/maven-settings.xml @@ -14,7 +14,7 @@ - jetbrains-kotlin-snapshots + jetbrains-kotlin tc-kotlin ${tc-kotlin.password} diff --git a/libraries/pom.xml b/libraries/pom.xml index 03a07f15814..4d46e650692 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -19,7 +19,8 @@ 11.0.2 4.10 0.2.3.8 - ${project-root}/dist/kotlinc + ${project-root}/dist + ${kotlin-dist}/kotlinc 1.6 1.6 2.4 @@ -31,16 +32,16 @@ false - jetbrains-kotlin-release - jetbrains-kotlin-release - http://repository.jetbrains.com/kotlin-release + jetbrains-kotlin + jetbrains-kotlin + http://repository.jetbrains.com/kotlin default false - jetbrains-kotlin-snapshots - jetbrains-kotlin-snapshots - http://repository.jetbrains.com/kotlin-snapshots + jetbrains-kotlin + jetbrains-kotlin + http://repository.jetbrains.com/kotlin default diff --git a/libraries/tools/kdoc-maven-plugin/pom.xml b/libraries/tools/kdoc-maven-plugin/pom.xml index e5022802935..14b98fd1d00 100644 --- a/libraries/tools/kdoc-maven-plugin/pom.xml +++ b/libraries/tools/kdoc-maven-plugin/pom.xml @@ -22,12 +22,12 @@ org.jetbrains.kotlin - kotlin-maven-plugin + kdoc ${project.version} org.jetbrains.kotlin - kdoc + kotlin-maven-plugin ${project.version} @@ -35,8 +35,8 @@ pegdown ${pegdown.version} - + src/main/java src/test/java diff --git a/libraries/tools/kdoc/pom.xml b/libraries/tools/kdoc/pom.xml index 451cad9c400..53cb667da0c 100644 --- a/libraries/tools/kdoc/pom.xml +++ b/libraries/tools/kdoc/pom.xml @@ -23,7 +23,7 @@ org.jetbrains.kotlin - kotlin-maven-plugin + kotlin-compiler ${project.version} diff --git a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt index ad2e696fc1b..28306f6a68c 100644 --- a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt +++ b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt @@ -12,7 +12,7 @@ import java.util.List import java.util.HashSet import java.util.* -import com.intellij.psi.PsiElement +import org.jetbrains.jet.internal.com.intellij.psi.PsiElement import org.jetbrains.jet.lang.resolve.BindingContext import org.jetbrains.jet.lang.resolve.BindingContext.* import org.jetbrains.jet.cli.common.CompilerPlugin diff --git a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt index afdd10c5f1a..2bd2ecf4c53 100644 --- a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt +++ b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/KDoc.kt @@ -12,7 +12,7 @@ import java.util.List import java.util.HashSet import java.util.Collection -import com.intellij.psi.PsiElement +import org.jetbrains.jet.internal.com.intellij.psi.PsiElement import org.jetbrains.jet.lang.resolve.BindingContext import org.jetbrains.jet.lang.resolve.BindingContext.* import org.jetbrains.jet.cli.common.CompilerPlugin diff --git a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/HtmlKotlinVisitor.kt b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/HtmlKotlinVisitor.kt index bf48c688db9..8a13b2eab09 100644 --- a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/HtmlKotlinVisitor.kt +++ b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/HtmlKotlinVisitor.kt @@ -1,10 +1,10 @@ package org.jetbrains.kotlin.doc.highlighter -import com.intellij.psi.PsiFile +import org.jetbrains.jet.internal.com.intellij.psi.PsiFile import org.jetbrains.jet.lang.psi.* -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiWhiteSpace -import com.intellij.psi.PsiComment +import org.jetbrains.jet.internal.com.intellij.psi.PsiElement +import org.jetbrains.jet.internal.com.intellij.psi.PsiWhiteSpace +import org.jetbrains.jet.internal.com.intellij.psi.PsiComment class HtmlKotlinVisitor: JetTreeVisitor() { diff --git a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/SyntaxHighlighter.kt b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/SyntaxHighlighter.kt index 955d339d670..e334f62bf66 100644 --- a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/SyntaxHighlighter.kt +++ b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/highlighter/SyntaxHighlighter.kt @@ -1,8 +1,8 @@ package org.jetbrains.kotlin.doc.highlighter -import com.intellij.psi.* -import com.intellij.psi.tree.IElementType -import com.intellij.psi.tree.TokenSet +import org.jetbrains.jet.internal.com.intellij.psi.* +import org.jetbrains.jet.internal.com.intellij.psi.tree.IElementType +import org.jetbrains.jet.internal.com.intellij.psi.tree.TokenSet import java.util.HashMap import java.util.Map import kotlin.template.HtmlFormatter diff --git a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt index 6e195ef9dbc..3186ed6f4cb 100644 --- a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt +++ b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt @@ -35,14 +35,15 @@ import org.jetbrains.kotlin.doc.templates.KDocTemplate import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl import org.jetbrains.jet.lang.descriptors.Visibility import org.jetbrains.jet.lang.descriptors.ClassKind -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiDirectory +import org.jetbrains.jet.internal.com.intellij.psi.PsiElement +import org.jetbrains.jet.internal.com.intellij.psi.PsiFile +import org.jetbrains.jet.internal.com.intellij.psi.PsiDirectory import org.jetbrains.jet.lang.descriptors.Visibilities import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils.LineAndColumn -import com.intellij.psi.PsiFileSystemItem +import org.jetbrains.jet.internal.com.intellij.psi.PsiFileSystemItem import java.io.File +import org.jetbrains.jet.internal.com.intellij.psi.PsiElement /** diff --git a/libraries/tools/kotlin-install/pom.xml b/libraries/tools/kotlin-install/pom.xml index 2d276556326..7388d8a7318 100644 --- a/libraries/tools/kotlin-install/pom.xml +++ b/libraries/tools/kotlin-install/pom.xml @@ -19,16 +19,16 @@ kotlin-install pom - Installs the Kotlin runtime dependencies into the local maven repo + Installs and deploys the Kotlin compiler org.apache.maven.plugins maven-install-plugin + 2.3.1 - org.jetbrains.kotlin:kotlin-compiler verify install-file @@ -39,104 +39,36 @@ ${project.version} jar ${kotlin-sdk}/lib/kotlin-compiler.jar + ${kotlin-dist}/kotlin-compiler-sources.jar + ${kotlin-dist}/kotlin-compiler-javadoc.jar true true + + + + + maven-deploy-plugin + 2.7 + - org.jetbrains.kotlin:kotlin-build-tools - verify + deploy - install-file + deploy-file org.jetbrains.kotlin - kotlin-build-tools + kotlin-compiler ${project.version} jar - ${kotlin-sdk}/lib/kotlin-build-tools.jar - true - true - - - - org.jetbrains.kotlin:intellij-core - verify - - install-file - - - org.jetbrains.kotlin - intellij-core - ${project.version} - jar - ${kotlin-sdk}/lib/intellij-core.jar - true - true - - - - org.jetbrains.kotlin:intellij-annotations - verify - - install-file - - - org.jetbrains.kotlin - intellij-annotations - ${project.version} - jar - ${kotlin-sdk}/lib/annotations.jar - true - true - - - - org.jetbrains.kotlin:trove4j - verify - - install-file - - - org.jetbrains.kotlin - trove4j - ${project.version} - jar - ${kotlin-sdk}/lib/trove4j.jar - true - true - - - - org.jetbrains.kotlin:picocontainer - verify - - install-file - - - org.jetbrains.kotlin - picocontainer - ${project.version} - jar - ${kotlin-sdk}/lib/picocontainer.jar - true - true - - - - org.jetbrains.kotlin:dartc - verify - - install-file - - - org.jetbrains.kotlin - dartc - ${project.version} - jar - ${kotlin-sdk}/lib/js/${dart.name}.jar - true + ${kotlin-sdk}/lib/kotlin-compiler.jar + ${kotlin-dist}/kotlin-compiler-sources.jar + ${kotlin-dist}/kotlin-compiler-javadoc.jar true + jetbrains-kotlin + http://repository.jetbrains.com/kotlin + false diff --git a/libraries/tools/kotlin-maven-plugin/pom.xml b/libraries/tools/kotlin-maven-plugin/pom.xml index 69f0b072965..f7170466c65 100644 --- a/libraries/tools/kotlin-maven-plugin/pom.xml +++ b/libraries/tools/kotlin-maven-plugin/pom.xml @@ -25,102 +25,13 @@ maven-plugin-api ${maven.version} - - - org.jetbrains.kotlin kotlin-compiler ${project.version} - - org.jetbrains.kotlin - kotlin-runtime - ${project.version} - - - org.jetbrains.kotlin - intellij-core - ${project.version} - - - org.jetbrains.kotlin - intellij-annotations - ${project.version} - - - - - org.jetbrains.kotlin - kotlin-build-tools - ${project.version} - - - - - com.google.guava - guava - ${guava.version} - - - asm - asm - ${asm.version} - - - asm - asm-tree - ${asm.version} - - - asm - asm-commons - ${asm.version} - - - asm - asm-util - ${asm.version} - - - org.jetbrains.kotlin - trove4j - ${project.version} - - - - org.jetbrains.kotlin - picocontainer - ${project.version} - - - - - - - org.jetbrains.kotlin - dartc - ${project.version} - + src/main/java src/test/java @@ -145,30 +56,33 @@ 2.9 - + diff --git a/libraries/tools/kotlin-maven-plugin/src/it/settings.xml b/libraries/tools/kotlin-maven-plugin/src/it/settings.xml new file mode 100644 index 00000000000..4d6edd35ac6 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/it/settings.xml @@ -0,0 +1,35 @@ + + + + + it-repo + + true + + + + local.central + @localRepositoryUrl@ + + true + + + true + + + + + + local.central + @localRepositoryUrl@ + + true + + + true + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/pom.xml b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/pom.xml new file mode 100644 index 00000000000..cb69d9c1f65 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.jetbrains.kotlin.it + test-helloworld + 1.0 + Test Hello World project + + + Test the kotlin-maven-plugin:compile goal on HelloWorld project. + + + + 0.1-SNAPSHOT + + + + + junit + junit + 4.9 + + + + + + ${project.basedir}/src/main/kotlin + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + compile + process-sources + + compile + + + + test-compile + process-test-sources + + test-compile + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/src/main/kotlin/org/jetbrains/HelloWorld.kt b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/src/main/kotlin/org/jetbrains/HelloWorld.kt new file mode 100644 index 00000000000..c3a8fa7ca3a --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/src/main/kotlin/org/jetbrains/HelloWorld.kt @@ -0,0 +1,14 @@ +package org.jetbrains +/** + * User: danielpenkin + * Date: 06.05.12 + * Time: 22:53 + */ + +fun main(args : Array) { + System.out?.println(getGreeting()) +} + +fun getGreeting() : String { + return "Hello, World!" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/src/test/java/org/jetbrains/HelloWorldJavaTest.java b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/src/test/java/org/jetbrains/HelloWorldJavaTest.java new file mode 100644 index 00000000000..5a60556b1b2 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/src/test/java/org/jetbrains/HelloWorldJavaTest.java @@ -0,0 +1,18 @@ +package org.jetbrains; + +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +/** + * User: danielpenkin + * Date: 06.05.12 + * Time: 23:35 + */ +public class HelloWorldJavaTest { + + @Test + public void greeting() { + assertEquals("Hello, World!", org.jetbrains.namespace.getGreeting()); + } +} diff --git a/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/verify.bsh b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/verify.bsh new file mode 100644 index 00000000000..760db7e13d0 --- /dev/null +++ b/libraries/tools/kotlin-maven-plugin/src/it/test-helloworld/verify.bsh @@ -0,0 +1,7 @@ +import java.io.*; + +File file = new File( basedir, "target/test-helloworld-1.0.jar" ); +if (!file.exists() || !file.isFile()) +{ + throw new FileNotFoundException( "Could not find generated JAR: " + file ); +} \ No newline at end of file diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JSCompilerPlugin.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JSCompilerPlugin.java index 0ecd68f0e9f..9f5d7b4dfec 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JSCompilerPlugin.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JSCompilerPlugin.java @@ -17,18 +17,17 @@ package org.jetbrains.kotlin.maven; import com.google.common.io.Files; -import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.cli.common.CompilerPlugin; import org.jetbrains.jet.cli.common.CompilerPluginContext; +import org.jetbrains.jet.internal.com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.k2js.config.Config; import org.jetbrains.k2js.facade.K2JSTranslator; +import org.jetbrains.k2js.facade.MainCallParameters; import java.io.File; -import java.io.IOException; -import java.lang.Override; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @@ -54,15 +53,17 @@ public class K2JSCompilerPlugin implements CompilerPlugin { } }; - K2JSTranslator translator = new K2JSTranslator(config); - final String code = translator.generateProgramCode(sources); - - File file = new File(outFile); - try { + + K2JSTranslator translator = new K2JSTranslator(config); + + final String code = translator.generateProgramCode(sources, MainCallParameters.noCall()); + + File file = new File(outFile); Files.createParentDirs(file); Files.write(code, file, Charset.forName("UTF-8")); - } catch (IOException e) { + } + catch (Exception e) { throw new RuntimeException(e); } } diff --git a/update_dependencies.xml b/update_dependencies.xml index e7e9c20c8ca..6f93ceffbb6 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -24,6 +24,17 @@ + + + + + + + + + + + @@ -32,6 +43,22 @@ + + + + + + + + + + + + + + +