diff --git a/bin/kotlin b/bin/kotlin index dac7f9ffec1..a8b911ec7be 100755 --- a/bin/kotlin +++ b/bin/kotlin @@ -18,7 +18,7 @@ done test -n "$ideaRoot" || die "Idea root not found" classpath="$root/out/production/cli" -classpath="$classpath:$root/out/production/backend:$root/out/production/frontend:$root/out/production/frontend.java" +classpath="$classpath:$root/out/production/backend:$root/out/production/frontend:$root/out/production/frontend.java:$root/out/production/jet.as.java.psi" classpath="$classpath:$root/out/production/stdlib" classpath="$classpath:$root/lib/*:$ideaRoot/lib/*:$ideaRoot/lib/rt/*" diff --git a/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/BytecodeCompilerTask.java b/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/BytecodeCompilerTask.java new file mode 100644 index 00000000000..7094b6c0ba3 --- /dev/null +++ b/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/BytecodeCompilerTask.java @@ -0,0 +1,63 @@ +package org.jetbrains.jet.buildtools.ant; + +import static org.jetbrains.jet.buildtools.core.Util.*; +import org.apache.tools.ant.Task; +import org.jetbrains.jet.buildtools.core.BytecodeCompiler; + +import java.io.File; + + +/** + * Kotlin bytecode compiler Ant task. + * + * See + * http://evgeny-goldin.org/javadoc/ant/tutorial-writing-tasks.html + * http://evgeny-goldin.org/javadoc/ant/Tasks/javac.html - attribute names should be similar to {@code }. + */ +public class BytecodeCompilerTask extends Task { + + private final BytecodeCompiler compiler = new BytecodeCompiler(); + + private File srcdir; + private File file; + private File destdir; + private File destjar; + private boolean includeRuntime = true; + private boolean excludeStdlib = false; + + public void setSrcdir ( File srcdir ) { this.srcdir = srcdir; } + public void setFile ( File file ) { this.file = file; } + public void setDestdir ( File destdir ) { this.destdir = destdir; } + public void setDestjar ( File destjar ) { this.destjar = destjar; } + + public void setIncludeRuntime ( boolean includeRuntime ) { this.includeRuntime = includeRuntime; } + public void setExcludeStdlib ( boolean excludeStdlib ) { this.excludeStdlib = excludeStdlib; } + + + @Override + public void execute() { + + if (( this.srcdir != null ) || ( this.file != null )) { + + if (( this.destdir == null ) && ( this.destjar == null )) { + throw new RuntimeException( "\"destdir\" or \"destjar\" should be specified" ); + } + + String src = getPath( this.srcdir != null ? this.srcdir : this.file ); + String dest = getPath( this.destdir != null ? this.destdir : this.destjar ); + + log( String.format( "[%s] => [%s]", src, dest )); + + if ( this.destdir != null ) { + compiler.sourcesToDir( src, dest, this.includeRuntime, this.excludeStdlib ); + } + else { + compiler.sourcesToJar( src, dest, this.includeRuntime, this.excludeStdlib ); + } + + } + else { + throw new RuntimeException( "Operation is not supported yet" ); + } + } +} diff --git a/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/JavaScriptCompilerTask.java b/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/JavaScriptCompilerTask.java new file mode 100644 index 00000000000..3435b1b1e43 --- /dev/null +++ b/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/JavaScriptCompilerTask.java @@ -0,0 +1,16 @@ +package org.jetbrains.jet.buildtools.ant; + +import org.apache.tools.ant.Task; + + +/** + * Kotlin JavaScript compiler Ant task. + * http://evgeny-goldin.org/javadoc/ant/tutorial-writing-tasks.html + */ +public class JavaScriptCompilerTask extends Task { + + @Override + public void execute() { + log( "JavaScriptCompilerTask" ); + } +} diff --git a/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/antlib.xml b/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/antlib.xml new file mode 100644 index 00000000000..59309c0326f --- /dev/null +++ b/build-tools/ant/src/org/jetbrains/jet/buildtools/ant/antlib.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/build-tools/build.xml b/build-tools/build.xml new file mode 100644 index 00000000000..1f1a16cdf87 --- /dev/null +++ b/build-tools/build.xml @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${java-out} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERROR: was expected here + + + + + + + + + + + + + + + + + + ERROR: was expected here + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java new file mode 100644 index 00000000000..6c1fb652671 --- /dev/null +++ b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java @@ -0,0 +1,71 @@ +package org.jetbrains.jet.buildtools.core; + +import org.jetbrains.jet.compiler.CompileEnvironment; + + +/** + * Wrapper class for Kotlin bytecode compiler. + */ +public class BytecodeCompiler { + + private final CompileEnvironment ENV = createCompileEnvironment(); + + + public BytecodeCompiler () { + } + + + /** + * Creates and initializes new {@link CompileEnvironment} instance. + * @return new {@link CompileEnvironment} instance + */ + private CompileEnvironment createCompileEnvironment () { + + CompileEnvironment environment = new CompileEnvironment(); + environment.setJavaRuntime( CompileEnvironment.findRtJar( true )); + + if ( ! environment.initializeKotlinRuntime()) { + throw new RuntimeException( "No Kotlin runtime library found" ); + } + + return environment; + } + + + /** + * Retrieves compilation error message. + * @param source compilation source + * @return compilation error message + */ + private String compilationError ( String source ) { + return String.format( "[%s] compilation failed, see \"ERROR:\" messages above for more details.", source ); + } + + + /** + * {@code CompileEnvironment#compileBunchOfSources} wrapper. + * + * @param source compilation source (directory or file) + * @param destination compilation destination + */ + public void sourcesToDir ( String source, String destination, boolean includeRuntime, boolean excludeStdlib ) { + boolean success = ENV.compileBunchOfSources( source, null, destination, includeRuntime, ! excludeStdlib ); + if ( ! success ) { + throw new RuntimeException( compilationError( source )); + } + } + + + /** + * {@code CompileEnvironment#compileBunchOfSources} wrapper. + * + * @param source compilation source (directory or file) + * @param jar compilation destination jar + */ + public void sourcesToJar ( String source, String jar, boolean includeRuntime, boolean excludeStdlib ) { + boolean success = ENV.compileBunchOfSources( source, jar, null, includeRuntime, ! excludeStdlib ); + if ( ! success ) { + throw new RuntimeException( compilationError( source )); + } + } +} diff --git a/build-tools/core/src/org/jetbrains/jet/buildtools/core/JavaScriptCompiler.java b/build-tools/core/src/org/jetbrains/jet/buildtools/core/JavaScriptCompiler.java new file mode 100644 index 00000000000..4d3027f4c88 --- /dev/null +++ b/build-tools/core/src/org/jetbrains/jet/buildtools/core/JavaScriptCompiler.java @@ -0,0 +1,8 @@ +package org.jetbrains.jet.buildtools.core; + + +/** + * Wrapper class for Kotlin JavaScript compiler. + */ +public class JavaScriptCompiler { +} diff --git a/build-tools/core/src/org/jetbrains/jet/buildtools/core/Util.java b/build-tools/core/src/org/jetbrains/jet/buildtools/core/Util.java new file mode 100644 index 00000000000..f1fb49b858c --- /dev/null +++ b/build-tools/core/src/org/jetbrains/jet/buildtools/core/Util.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.buildtools.core; + +import java.io.File; +import java.io.IOException; + + +/** + * General convenient utilities. + */ +public final class Util { + + private Util () { + } + + + /** + * {@code file.getCanonicalFile().getPath()} convenience wrapper. + * @param f file to get its canonical path. + * @return file's canonical path + */ + public static String getPath( File f ) { + try { + return f.getCanonicalFile().getPath(); + } + catch ( IOException e ) { + throw new RuntimeException( String.format( "Failed to resolve canonical file of [%s]: %s", f, e ), e ); + } + } + +} diff --git a/build-tools/lib/ant-contrib-1.0b3.jar b/build-tools/lib/ant-contrib-1.0b3.jar new file mode 100644 index 00000000000..062537661a5 Binary files /dev/null and b/build-tools/lib/ant-contrib-1.0b3.jar differ diff --git a/build-tools/test/compilation-fail/Bottles.kt b/build-tools/test/compilation-fail/Bottles.kt new file mode 100644 index 00000000000..7e2e0f02c99 --- /dev/null +++ b/build-tools/test/compilation-fail/Bottles.kt @@ -0,0 +1,59 @@ +/** + * "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 std.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 std 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/hello/1/Hello.kt b/build-tools/test/hello/1/Hello.kt new file mode 100644 index 00000000000..699426924dd --- /dev/null +++ b/build-tools/test/hello/1/Hello.kt @@ -0,0 +1,3 @@ +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 new file mode 100644 index 00000000000..83ed78ab4c4 --- /dev/null +++ b/build-tools/test/hello/2/Hello.kt @@ -0,0 +1,7 @@ +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 new file mode 100644 index 00000000000..efc6503f75b --- /dev/null +++ b/build-tools/test/hello/3/Hello.kt @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000000..0038a5e12c0 --- /dev/null +++ b/build-tools/test/hello/4/Hello.kt @@ -0,0 +1,9 @@ +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 new file mode 100644 index 00000000000..96a210ce6cf --- /dev/null +++ b/build-tools/test/hello/5/Hello.kt @@ -0,0 +1,9 @@ +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 new file mode 100644 index 00000000000..3e67d77779a --- /dev/null +++ b/build-tools/test/longer-examples/Bottles.kt @@ -0,0 +1,84 @@ +/** + * 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 std.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 std 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.kt b/build-tools/test/longer-examples/HtmlBuilder.kt new file mode 100644 index 00000000000..10b90890474 --- /dev/null +++ b/build-tools/test/longer-examples/HtmlBuilder.kt @@ -0,0 +1,154 @@ +/** + * 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) + +fun println(message : Any?) { + System.out?.println(message) +} + +fun print(message : Any?) { + System.out?.print(message) +} diff --git a/build-tools/test/longer-examples/Life.kt b/build-tools/test/longer-examples/Life.kt new file mode 100644 index 00000000000..5db3e652b0a --- /dev/null +++ b/build-tools/test/longer-examples/Life.kt @@ -0,0 +1,172 @@ +/** + * 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) +} + +fun println(message : Any?) { + System.out?.println(message) +} + +fun print(message : Any?) { + System.out?.print(message) +} + +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.kt b/build-tools/test/longer-examples/Maze.kt new file mode 100644 index 00000000000..091e29250c0 --- /dev/null +++ b/build-tools/test/longer-examples/Maze.kt @@ -0,0 +1,231 @@ +/** + * 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) +} + +fun println(message : Any?) { + System.out?.println(message) +} + +fun print(message : Any?) { + System.out?.print(message) +} + +fun > Array.to(result: C) : C { + for (elem in this) + result.add(elem) + return result +} diff --git a/build.xml b/build.xml index 6b9761bf26b..ec7fbbe1aa0 100644 --- a/build.xml +++ b/build.xml @@ -1,9 +1,12 @@ + + + @@ -29,7 +32,7 @@ - + @@ -55,10 +58,10 @@ - + - + @@ -75,13 +78,13 @@ - + - + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index 66273168bdc..807971b9501 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils; import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureVariance; import org.jetbrains.jet.rt.signature.JetSignatureWriter; import org.objectweb.asm.Type; import org.objectweb.asm.commons.Method; @@ -203,10 +204,20 @@ public class BothSignatureWriter { public void writeArrayEnd() { pop(); } + + private static JetSignatureVariance toJetSignatureVariance(Variance variance) { + switch (variance) { + case INVARIANT: return JetSignatureVariance.INVARIANT; + case IN_VARIANCE: return JetSignatureVariance.IN; + case OUT_VARIANCE: return JetSignatureVariance.OUT; + default: throw new IllegalStateException(); + } + } - public void writeTypeArgument(char c) { - push(signatureVisitor().visitTypeArgument(c)); - jetSignatureWriter.visitTypeArgument(c); + public void writeTypeArgument(Variance variance) { + JetSignatureVariance jsVariance = toJetSignatureVariance(variance); + push(signatureVisitor().visitTypeArgument(jsVariance.getC())); + jetSignatureWriter.visitTypeArgument(jsVariance); generic = true; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 16311b49ede..533b41acb1d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1024,7 +1024,7 @@ public class ExpressionCodegen extends JetVisitor { public void invokeFunctionNoParams(FunctionDescriptor functionDescriptor, Type type, InstructionAdapter v) { DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); - boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl; + boolean isStatic = containingDeclaration instanceof NamespaceDescriptor; functionDescriptor = functionDescriptor.getOriginal(); String owner; @@ -1092,30 +1092,32 @@ public class ExpressionCodegen extends JetVisitor { } } } - if(!(containingDeclaration instanceof JavaNamespaceDescriptor)) - getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - else - getter = null; - + getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + if (propertyDescriptor.getGetter() == null) { getter = null; } + + if (getter == null && propertyDescriptor.getReceiverParameter().exists()) { + throw new IllegalStateException(); + } + } //noinspection ConstantConditions if (isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault())) { setter = null; } else { - if(!(containingDeclaration instanceof JavaNamespaceDescriptor)) { - JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); - setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null; - } else { - setter = null; - } + JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); + setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null; if (propertyDescriptor.getSetter() == null) { setter = null; } + + if (setter == null && propertyDescriptor.isVar() && propertyDescriptor.getReceiverParameter().exists()) { + throw new IllegalStateException(); + } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 77eff97f2d8..9c7c3da8894 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -124,6 +124,9 @@ public class FunctionCodegen { av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); } av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true); + if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(0) != null) { + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(0).getKotlinSignature()); + } av.visitEnd(); } for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index ad5724d9ee8..5cd899e6ce6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -298,7 +298,7 @@ public class JetTypeMapper { signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable()); for (TypeProjection proj : jetType.getArguments()) { // TODO: +- - signatureVisitor.writeTypeArgument('='); + signatureVisitor.writeTypeArgument(proj.getProjectionKind()); mapType(proj.getType(), kind, signatureVisitor, true); signatureVisitor.writeTypeArgumentEnd(); } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java index 9b1d16180a8..2f43457dc3d 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java @@ -32,12 +32,12 @@ public class KotlinCompiler { @Argument(value = "help", alias = "h", description = "show help") public boolean help; } - + private static void usage(PrintStream target) { target.println("Usage: KotlinCompiler [-output |-jar ] [-src |-module ] [-includeRuntime] [-excludeStdlib]"); } - public static void main(String[] args) { + public static void main(String ... args) { System.setProperty("java.awt.headless", "true"); Arguments arguments = new Arguments(); try { @@ -53,7 +53,7 @@ public class KotlinCompiler { System.exit(1); return; } - + if (arguments.help) { usage(System.out); System.exit(0); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index 80c8b72a9c9..636682c0838 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -2,15 +2,26 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.intellij.psi.*; +import com.intellij.psi.HierarchicalMethodSignature; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +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.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.TypeSubstitutor; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * @author abreslav @@ -20,8 +31,6 @@ public class JavaClassMembersScope implements JetScope { private final JavaSemanticServices semanticServices; private final boolean staticMembers; private final DeclarationDescriptor containingDeclaration; - private final Map> functionGroups = Maps.newHashMap(); - private final Map> variables = Maps.newHashMap(); private final Map classifiers = Maps.newHashMap(); private Collection allDescriptors; @@ -76,7 +85,7 @@ public class JavaClassMembersScope implements JetScope { if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) { continue; } - FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, method); + FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, new PsiMethodWrapper(method)); if (functionDescriptor != null) { allDescriptors.add(functionDescriptor); } @@ -117,14 +126,7 @@ public class JavaClassMembersScope implements JetScope { @NotNull @Override public Set getProperties(@NotNull String name) { - Set variableDescriptor = variables.get(name); - if (variableDescriptor == null) { - variableDescriptor = doGetVariable(name); - if (variableDescriptor != null) { - variables.put(name, variableDescriptor); - } - } - return variableDescriptor != null ? variableDescriptor : Collections.emptySet(); + return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDeclaration, psiClass, name, staticMembers); } @Override @@ -132,32 +134,15 @@ public class JavaClassMembersScope implements JetScope { return null; } - @Nullable - private Set doGetVariable(String name) { - PsiField field = psiClass.findFieldByName(name, true); - if (field == null) return null; - if (field.hasModifierProperty(PsiModifier.STATIC) != staticMembers) { - return null; - } - - //return semanticServices.getDescriptorResolver().resolveFieldToVariableDescriptor(containingDeclaration, field); - return semanticServices.getDescriptorResolver().resolveFieldGroupByName(containingDeclaration, psiClass, name, staticMembers); - } - @NotNull @Override public Set getFunctions(@NotNull String name) { - Set functionGroup = functionGroups.get(name); - if (functionGroup == null) { - functionGroup = semanticServices.getDescriptorResolver().resolveFunctionGroup( - containingDeclaration, - psiClass, - staticMembers ? null : (ClassDescriptor) containingDeclaration, - name, - staticMembers); - functionGroups.put(name, functionGroup); - } - return functionGroup; + return semanticServices.getDescriptorResolver().resolveFunctionGroup( + containingDeclaration, + psiClass, + staticMembers ? null : (ClassDescriptor) containingDeclaration, + name, + staticMembers); } @Override diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index feb5b6896aa..1554b9732f5 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -4,23 +4,24 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.HierarchicalMethodSignature; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClassType; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiEllipsisType; -import com.intellij.psi.PsiField; import com.intellij.psi.PsiJavaFile; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiPrimitiveType; import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeParameter; import com.intellij.psi.PsiTypeParameterListOwner; +import com.intellij.psi.PsiTypeVariable; +import com.intellij.psi.impl.source.PsiClassReferenceType; import com.intellij.psi.search.DelegatingGlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope; import jet.typeinfo.TypeInfoVariance; @@ -63,6 +64,8 @@ import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -128,11 +131,12 @@ public class JavaDescriptorResolver { this.lowerBoundsForKotlin = lowerBoundsForKotlin; } } - + + private static abstract class ResolverScopeData { - @Nullable - private Set properties; protected boolean kotlin; + + private Map namedMembersMap; } private static class ResolverClassData extends ResolverScopeData { @@ -159,7 +163,6 @@ public class JavaDescriptorResolver { private final Map typeParameterDescriptorCache = Maps.newHashMap(); protected final Map methodDescriptorCache = Maps.newHashMap(); - protected final Map fieldDescriptorCache = Maps.newHashMap(); protected final JavaPsiFacade javaFacade; protected final GlobalSearchScope javaSearchScope; protected final JavaSemanticServices semanticServices; @@ -737,15 +740,6 @@ public class JavaDescriptorResolver { PsiType psiType = parameter.getPsiParameter().getType(); - JetType varargElementType; - if (psiType instanceof PsiEllipsisType) { - PsiEllipsisType psiEllipsisType = (PsiEllipsisType) psiType; - varargElementType = semanticServices.getTypeTransformer().transformToType(psiEllipsisType.getComponentType()); - } - else { - varargElementType = null; - } - boolean nullable = parameter.getJetValueParameter().nullable(); // TODO: must be very slow, make it lazy? @@ -765,6 +759,14 @@ public class JavaDescriptorResolver { } else { outType = semanticServices.getTypeTransformer().transformToType(psiType); } + + JetType varargElementType; + if (psiType instanceof PsiEllipsisType) { + varargElementType = semanticServices.getJetSemanticServices().getStandardLibrary().getArrayElementType(outType); + } else { + varargElementType = null; + } + if (receiver) { return JvmMethodParameterMeaning.receiver(outType); } else { @@ -781,252 +783,135 @@ public class JavaDescriptorResolver { } } - /* - public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) { - VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field); - if (variableDescriptor != null) { - return variableDescriptor; - } - JetType type = semanticServices.getTypeTransformer().transformToType(field.getType()); - boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL); - PropertyDescriptor propertyDescriptor = new PropertyDescriptor( - containingDeclaration, - Collections.emptyList(), - Modality.FINAL, - resolveVisibilityFromPsiModifiers(field), - !isFinal, - null, - DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), - field.getName(), - type); - semanticServices.getTrace().record(BindingContext.VARIABLE, field, propertyDescriptor); - fieldDescriptorCache.put(field, propertyDescriptor); - return propertyDescriptor; - } - */ - - private static class PropertyKey { - @NotNull - private final String name; - //@NotNull - //private final PsiType type; - //@Nullable - //private final PsiType receiverType; - - private PropertyKey(@NotNull String name /*, @NotNull PsiType type, @Nullable PsiType receiverType */) { - this.name = name; - //this.type = type; - //this.receiverType = receiverType; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - PropertyKey that = (PropertyKey) o; - - if (!name.equals(that.name)) return false; - //if (receiverType != null ? !receiverType.equals(that.receiverType) : that.receiverType != null) - // return false; - //if (!type.equals(that.type)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = name.hashCode(); - //result = 31 * result + type.hashCode(); - //result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0); - return result; - } - } - - private static class MembersForProperty { - private PsiFieldWrapper field; - private PsiMethodWrapper setter; - private PsiMethodWrapper getter; - - private PsiType type; - private PsiType receiverType; - } - - private Map getMembersForProperties(@NotNull PsiClass clazz, boolean staticMembers, boolean kotlin) { - Map membersMap = Maps.newHashMap(); - if (!kotlin) { - for (PsiField field : clazz.getFields()) { - if (field.getModifierList().hasExplicitModifier(PsiModifier.STATIC) != staticMembers) { - continue; - } - - if (field.hasModifierProperty(PsiModifier.PRIVATE)) { - continue; - } - - MembersForProperty members = new MembersForProperty(); - members.field = new PsiFieldWrapper(field); - members.type = field.getType(); - membersMap.put(new PropertyKey(field.getName() /*, field.getType(), null*/), members); - } - } - - for (PsiMethod psiMethod : clazz.getMethods()) { - PsiMethodWrapper method = new PsiMethodWrapper(psiMethod); - - if (method.isStatic() != staticMembers) { - continue; - } - - if (method.isPrivate()) { - continue; - } - - // TODO: "is" prefix - // TODO: remove getJavaClass - if (psiMethod.getName().startsWith(JvmAbi.GETTER_PREFIX)) { - - // TODO: some java properties too - if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { - - if (psiMethod.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) { - continue; - } - - int i = 0; - - PsiType receiverType; - if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) { - receiverType = method.getParameter(i).getPsiParameter().getType(); - ++i; - } else { - receiverType = null; - } - - while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) { - // TODO: store is reified - ++i; - } - - if (i != method.getParameters().size()) { - // TODO: report error properly - throw new IllegalStateException(); - } - - String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.GETTER_PREFIX.length())); - PropertyKey key = new PropertyKey(propertyName /*, psiMethod.getReturnType(), receiverType*/); - MembersForProperty members = membersMap.get(key); - if (members == null) { - members = new MembersForProperty(); - membersMap.put(key, members); - } - members.getter = new PsiMethodWrapper(psiMethod); - - // TODO: check conflicts with setter - members.type = psiMethod.getReturnType(); - members.receiverType = receiverType; - } - } else if (psiMethod.getName().startsWith(JvmAbi.SETTER_PREFIX)) { - - if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { - if (psiMethod.getParameterList().getParametersCount() == 0) { - // TODO: report error properly - throw new IllegalStateException(); - } - - int i = 0; - - PsiType receiverType = null; - PsiParameterWrapper p1 = method.getParameter(0); - if (p1.getJetValueParameter().receiver()) { - receiverType = p1.getPsiParameter().getType(); - ++i; - } - - while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) { - ++i; - } - - if (i + 1 != psiMethod.getParameterList().getParametersCount()) { - throw new IllegalStateException(); - } - - PsiType propertyType = psiMethod.getParameterList().getParameters()[i].getType(); - - String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.SETTER_PREFIX.length())); - PropertyKey key = new PropertyKey(propertyName /*, propertyType, receiverType*/); - MembersForProperty members = membersMap.get(key); - if (members == null) { - members = new MembersForProperty(); - membersMap.put(key, members); - } - members.setter = new PsiMethodWrapper(psiMethod); - - // TODO: check conflicts with getter - members.type = propertyType; - members.receiverType = receiverType; - } - } - } - - return membersMap; - } - public Set resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) { - Set r = Sets.newHashSet(); - // TODO: slow - Set variables = resolveFieldGroup(owner, psiClass, staticMembers); - for (VariableDescriptor variable : variables) { - if (variable.getName().equals(fieldName)) { - r.add(variable); - } - } - return r; - } + ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); + NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); + if (namedMembers == null) { + return Collections.emptySet(); + } + + resolveNamedGroupProperties(owner, staticMembers, namedMembers, fieldName); + + return namedMembers.propertyDescriptors; + } + @NotNull public Set resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { - - ResolverScopeData scopeData; - if (owner instanceof JavaNamespaceDescriptor) { - scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName()); - } else if (owner instanceof ClassDescriptor) { - scopeData = classDescriptorCache.get(psiClass.getQualifiedName()); - } else { - throw new IllegalStateException(); - } - if (scopeData == null) { - throw new IllegalStateException(); - } - - if (scopeData.properties != null) { - return scopeData.properties; - } + + ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); Set descriptors = Sets.newHashSet(); - Map membersForProperties = getMembersForProperties(psiClass, staticMembers, scopeData.kotlin); - for (Map.Entry entry : membersForProperties.entrySet()) { - //VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field); - //if (variableDescriptor != null) { - // return variableDescriptor; - //} - String propertyName = entry.getKey().name; - PsiType propertyType = entry.getValue().type; - PsiType receiverType = entry.getValue().receiverType; - MembersForProperty members = entry.getValue(); + Map membersForProperties = scopeData.namedMembersMap; + for (Map.Entry entry : membersForProperties.entrySet()) { + NamedMembers namedMembers = entry.getValue(); + if (namedMembers.propertyAccessors == null) { + continue; + } + + String propertyName = entry.getKey(); + resolveNamedGroupProperties(owner, staticMembers, namedMembers, propertyName); + descriptors.addAll(namedMembers.propertyDescriptors); + } + return descriptors; + } + + private Object key(TypeSource typeSource) { + if (typeSource == null) { + return ""; + } else if (typeSource.getTypeString().length() > 0) { + return typeSource.getTypeString(); + } else { + if (typeSource.getPsiType() instanceof PsiClassType) { + return ((PsiClassType) typeSource.getPsiType()).getClassName(); + } else if (typeSource.getPsiType() instanceof PsiPrimitiveType) { + return typeSource.getPsiType().getPresentableText(); + } else { + throw new IllegalStateException("" + typeSource.getPsiType().getClass()); + } + } + } + + private Object propertyKeyForGrouping(PropertyAccessorData propertyAccessor) { + Object type = key(propertyAccessor.getType()); + Object receiverType = key(propertyAccessor.getReceiverType()); + return Pair.create(type, receiverType); + } + + private void resolveNamedGroupProperties(DeclarationDescriptor owner, boolean staticMembers, NamedMembers namedMembers, String propertyName) { + if (namedMembers.propertyDescriptors != null) { + return; + } + + if (namedMembers.propertyAccessors == null) { + namedMembers.propertyDescriptors = Collections.emptySet(); + return; + } + + final List classTypeParameters; + if (!staticMembers) { + classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); + } else { + classTypeParameters = new ArrayList(0); + } + + TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); + + class GroupingValue { + PropertyAccessorData getter; + PropertyAccessorData setter; + PropertyAccessorData field; + } + + Map map = new HashMap(); + + for (PropertyAccessorData propertyAccessor : namedMembers.propertyAccessors) { + + Object key = propertyKeyForGrouping(propertyAccessor); + + GroupingValue value = map.get(key); + if (value == null) { + value = new GroupingValue(); + map.put(key, value); + } + + if (propertyAccessor.isGetter()) { + if (value.getter != null) { + throw new IllegalStateException("oops, duplicate key"); + } + value.getter = propertyAccessor; + } else if (propertyAccessor.isSetter()) { + if (value.setter != null) { + throw new IllegalStateException("oops, duplicate key"); + } + value.setter = propertyAccessor; + } else if (propertyAccessor.isField()) { + if (value.field != null) { + throw new IllegalStateException("oops, duplicate key"); + } + value.field = propertyAccessor; + } else { + throw new IllegalStateException(); + } + } + + + Set r = new HashSet(); + + for (GroupingValue members : map.values()) { boolean isFinal; if (members.setter == null && members.getter == null) { isFinal = false; } else if (members.getter != null) { - isFinal = members.getter.isFinal(); + isFinal = members.getter.getMember().isFinal(); } else if (members.setter != null) { - isFinal = members.setter.isFinal(); + isFinal = members.setter.getMember().isFinal(); } else { isFinal = false; } - PsiMemberWrapper anyMember; + PropertyAccessorData anyMember; if (members.getter != null) { anyMember = members.getter; } else if (members.field != null) { @@ -1036,10 +921,10 @@ public class JavaDescriptorResolver { } else { throw new IllegalStateException(); } - + boolean isVar; if (members.getter == null && members.setter == null) { - isVar = true; + isVar = !members.field.getMember().isFinal(); } else { isVar = members.setter != null; } @@ -1048,11 +933,11 @@ public class JavaDescriptorResolver { owner, Collections.emptyList(), isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract - resolveVisibilityFromPsiModifiers(anyMember.psiMember), + resolveVisibilityFromPsiModifiers(anyMember.getMember().psiMember), isVar, false, propertyName); - + PropertyGetterDescriptor getterDescriptor = null; PropertySetterDescriptor setterDescriptor = null; if (members.getter != null) { @@ -1061,89 +946,124 @@ public class JavaDescriptorResolver { if (members.setter != null) { setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); } - - propertyDescriptor.initialize(getterDescriptor, setterDescriptor); - final List classTypeParameters; - if (anyMember instanceof PsiMethodWrapper && !anyMember.isStatic()) { - classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); - } else { - classTypeParameters = new ArrayList(0); - } - TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); + propertyDescriptor.initialize(getterDescriptor, setterDescriptor); List typeParameters = new ArrayList(0); if (members.setter != null) { - // call ugly code with side effects - typeParameters = resolveMethodTypeParameters(members.setter, propertyDescriptor.getSetter(), typeVariableResolver); + PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember(); + + if (anyMember == members.setter) { + typeParameters = resolveMethodTypeParameters(method, setterDescriptor, typeVariableResolver); + } } if (members.getter != null) { - // call ugly code with side effects - typeParameters = resolveMethodTypeParameters(members.getter, propertyDescriptor.getGetter(), typeVariableResolver); + PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember(); + + if (anyMember == members.getter) { + typeParameters = resolveMethodTypeParameters(method, getterDescriptor, typeVariableResolver); + } } - JetType receiverJetType; - if (receiverType == null) { - receiverJetType = null; + List typeParametersForReceiver = new ArrayList(); + typeParametersForReceiver.addAll(classTypeParameters); + typeParametersForReceiver.addAll(typeParameters); + TypeVariableResolver typeVariableResolverForPropertyInternals = new TypeParameterListTypeVariableResolver(typeParametersForReceiver); + + JetType propertyType; + if (anyMember.getType().getTypeString().length() > 0) { + propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals); } else { - receiverJetType = semanticServices.getTypeTransformer().transformToType(receiverType); + propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType()); + } + + JetType receiverType; + if (anyMember.getReceiverType() == null) { + receiverType = null; + } else if (anyMember.getReceiverType().getTypeString().length() > 0) { + receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals); + } else { + receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType()); } - - JetType type = semanticServices.getTypeTransformer().transformToType(propertyType); propertyDescriptor.setType( - type, + propertyType, typeParameters, DescriptorUtils.getExpectedThisObjectIfNeeded(owner), - receiverJetType - ); + receiverType + ); if (getterDescriptor != null) { - getterDescriptor.initialize(type); + getterDescriptor.initialize(propertyType); } if (setterDescriptor != null) { // TODO: initialize } + + semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.getMember().psiMember, propertyDescriptor); - semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.psiMember, propertyDescriptor); - //fieldDescriptorCache.put(field, propertyDescriptor); - descriptors.add(propertyDescriptor); + r.add(propertyDescriptor); } - scopeData.properties = descriptors; - return descriptors; + + namedMembers.propertyDescriptors = r; + } + + private void resolveNamedGroupFunctions(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, boolean staticMembers, NamedMembers namedMembers, String functionName) { + if (namedMembers.functionDescriptors != null) { + return; + } + + if (namedMembers.methods == null) { + namedMembers.functionDescriptors = Collections.emptySet(); + return; + } + + Set functionDescriptors = new HashSet(namedMembers.methods.size()); + for (PsiMethodWrapper method : namedMembers.methods) { + functionDescriptors.add(resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutorForGenericSuperclasses, method)); + } + namedMembers.functionDescriptors = functionDescriptors; + } + + private ResolverScopeData getResolverScopeData(DeclarationDescriptor owner, PsiClassWrapper psiClass) { + ResolverScopeData scopeData; + boolean staticMembers; + if (owner instanceof JavaNamespaceDescriptor) { + scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName()); + staticMembers = true; + } else if (owner instanceof ClassDescriptor) { + scopeData = classDescriptorCache.get(psiClass.getQualifiedName()); + staticMembers = false; + } else { + throw new IllegalStateException(); + } + if (scopeData == null) { + throw new IllegalStateException(); + } + + if (scopeData.namedMembersMap == null) { + scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin); + } + + return scopeData; } @NotNull public Set resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) { - Set writableFunctionGroup = Sets.newLinkedHashSet(); - final Collection signatures = psiClass.getVisibleSignatures(); + + ResolverScopeData resolverScopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); + + Map namedMembersMap = resolverScopeData.namedMembersMap; + + NamedMembers namedMembers = namedMembersMap.get(methodName); + if (namedMembers == null || namedMembers.methods == null) { + return Collections.emptySet(); + } + TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor); - for (HierarchicalMethodSignature signature: signatures) { - if (!methodName.equals(signature.getName())) { - continue; - } - - FunctionDescriptor substitutedFunctionDescriptor = resolveHierarchicalSignatureToFunction(owner, psiClass, staticMembers, typeSubstitutor, signature); - if (substitutedFunctionDescriptor != null) { - writableFunctionGroup.add(substitutedFunctionDescriptor); - } - } - return writableFunctionGroup; - } - - @Nullable - private FunctionDescriptor resolveHierarchicalSignatureToFunction(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers, TypeSubstitutor typeSubstitutor, HierarchicalMethodSignature signature) { - PsiMethod method = signature.getMethod(); - if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) { - return null; - } - FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutor, method); -// if (functionDescriptor != null && !staticMembers) { -// for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) { -// ((FunctionDescriptorImpl) functionDescriptor).addOverriddenFunction(resolveHierarchicalSignatureToFunction(owner, superSignature.getMethod().getContainingClass(), false, typeSubstitutor, superSignature)); -// } -// } - return functionDescriptor; + resolveNamedGroupFunctions(owner, psiClass, typeSubstitutor, staticMembers, namedMembers, methodName); + + return namedMembers.functionDescriptors; } public TypeSubstitutor createSubstitutorForGenericSupertypes(ClassDescriptor classDescriptor) { @@ -1178,16 +1098,15 @@ public class JavaDescriptorResolver { } @Nullable - public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod psiMethod) { - PsiMethodWrapper method = new PsiMethodWrapper(psiMethod); + public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethodWrapper method) { - PsiType returnType = psiMethod.getReturnType(); + PsiType returnType = method.getReturnType(); if (returnType == null) { return null; } - FunctionDescriptor functionDescriptor = methodDescriptorCache.get(psiMethod); + FunctionDescriptor functionDescriptor = methodDescriptorCache.get(method.getPsiMethod()); if (functionDescriptor != null) { - if (psiMethod.getContainingClass() != psiClass) { + if (method.getPsiMethod().getContainingClass() != psiClass) { functionDescriptor = functionDescriptor.substitute(typeSubstitutorForGenericSuperclasses); } return functionDescriptor; @@ -1238,11 +1157,11 @@ public class JavaDescriptorResolver { DeclarationDescriptor classDescriptor; final List classTypeParameters; if (method.isStatic()) { - classDescriptor = resolveNamespace(psiMethod.getContainingClass()); + classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass()); classTypeParameters = Collections.emptyList(); } else { - ClassDescriptor classClassDescriptor = resolveClass(psiMethod.getContainingClass()); + ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass()); classDescriptor = classClassDescriptor; classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters(); } @@ -1252,14 +1171,14 @@ public class JavaDescriptorResolver { NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl( owner, Collections.emptyList(), // TODO - psiMethod.getName() + method.getName() ); - methodDescriptorCache.put(psiMethod, functionDescriptorImpl); + methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl); // TODO: add outer classes TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters); - final List methodTypeParameters = resolveMethodTypeParameters(new PsiMethodWrapper(psiMethod), functionDescriptorImpl, typeVariableResolverForParameters); + final List methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters); class MethodTypeVariableResolver implements TypeVariableResolver { @@ -1288,12 +1207,12 @@ public class JavaDescriptorResolver { methodTypeParameters, valueParameterDescriptors.descriptors, makeReturnType(returnType, method, new MethodTypeVariableResolver()), - Modality.convertFromFlags(psiMethod.hasModifierProperty(PsiModifier.ABSTRACT), !psiMethod.hasModifierProperty(PsiModifier.FINAL)), - resolveVisibilityFromPsiModifiers(psiMethod) + Modality.convertFromFlags(method.getPsiMethod().hasModifierProperty(PsiModifier.ABSTRACT), !method.isFinal()), + resolveVisibilityFromPsiModifiers(method.getPsiMethod()) ); - semanticServices.getTrace().record(BindingContext.FUNCTION, psiMethod, functionDescriptorImpl); + semanticServices.getTrace().record(BindingContext.FUNCTION, method.getPsiMethod(), functionDescriptorImpl); FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl; - if (psiMethod.getContainingClass() != psiClass) { + if (method.getPsiMethod().getContainingClass() != psiClass) { substitutedFunctionDescriptor = functionDescriptorImpl.substitute(typeSubstitutorForGenericSuperclasses); } return substitutedFunctionDescriptor; @@ -1301,7 +1220,7 @@ public class JavaDescriptorResolver { private List resolveMethodTypeParameters( @NotNull PsiMethodWrapper method, - @NotNull FunctionDescriptor functionDescriptor, + @NotNull DeclarationDescriptor functionDescriptor, @NotNull TypeVariableResolver classTypeVariableResolver) { if (method.getJetMethod().typeParameters().length() > 0) { List r = resolveMethodTypeParametersFromJetSignature( @@ -1319,7 +1238,7 @@ public class JavaDescriptorResolver { * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, MutableClassDescriptorLite) */ private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, - final FunctionDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver) + final DeclarationDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver) { final List r = new ArrayList(); @@ -1400,7 +1319,7 @@ public class JavaDescriptorResolver { ownerOwner = classDescriptor; substitutorForGenericSupertypes = semanticServices.getDescriptorResolver().createSubstitutorForGenericSupertypes(classDescriptor); } - FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(ownerOwner, containingClass, substitutorForGenericSupertypes, psiMethod); + FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(ownerOwner, containingClass, substitutorForGenericSupertypes, new PsiMethodWrapper(psiMethod)); return resolveTypeParameter(functionDescriptor, typeParameter); } throw new IllegalStateException("Unknown parent type: " + owner); 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 new file mode 100644 index 00000000000..fb920e33dd5 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java @@ -0,0 +1,167 @@ +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.HierarchicalMethodSignature; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Stepan Koltsov + */ +class JavaDescriptorResolverHelper { + + + private static class Builder { + private final PsiClassWrapper psiClass; + private final boolean staticMembers; + private final boolean kotlin; + + private Map namedMembersMap = new HashMap(); + + private Builder(PsiClassWrapper psiClass, boolean staticMembers, boolean kotlin) { + this.psiClass = psiClass; + this.staticMembers = staticMembers; + this.kotlin = kotlin; + } + + public void run() { + processFields(); + processMethods(); + } + + private NamedMembers getNamedMembers(String name) { + NamedMembers r = namedMembersMap.get(name); + if (r == null) { + r = new NamedMembers(); + r.name = name; + namedMembersMap.put(name, r); + } + return r; + } + + private void processFields() { + if (!kotlin) { + for (PsiFieldWrapper field : psiClass.getFields()) { + if (field.isStatic() != staticMembers) { + continue; + } + + if (field.isPrivate()) { + continue; + } + + NamedMembers namedMembers = getNamedMembers(field.getName()); + + TypeSource type = new TypeSource("", field.getType()); + namedMembers.addPropertyAccessor(new PropertyAccessorData(field, type, null)); + } + } + } + + private void processMethods() { + for (HierarchicalMethodSignature method0 : psiClass.getPsiClass().getVisibleSignatures()) { + + PsiMethodWrapper method = new PsiMethodWrapper(method0.getMethod()); + + if (method.isStatic() != staticMembers) { + continue; + } + + if (method.isPrivate()) { + continue; + } + + // TODO: "is" prefix + // TODO: remove getJavaClass + if (method.getName().startsWith(JvmAbi.GETTER_PREFIX)) { + + // TODO: some java properties too + if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { + + if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) { + continue; + } + + int i = 0; + + TypeSource receiverType; + if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) { + PsiParameterWrapper receiverParameter = method.getParameter(i); + receiverType = new TypeSource(receiverParameter.getJetValueParameter().type(), receiverParameter.getPsiParameter().getType()); + ++i; + } else { + receiverType = null; + } + + while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) { + // TODO: store is reified + ++i; + } + + if (i != method.getParameters().size()) { + // TODO: report error properly + throw new IllegalStateException(); + } + + String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.GETTER_PREFIX.length())); + NamedMembers members = getNamedMembers(propertyName); + + // TODO: what if returnType == null? + TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), method.getReturnType()); + + members.addPropertyAccessor(new PropertyAccessorData(method, true, propertyType, receiverType)); + } + } else if (method.getName().startsWith(JvmAbi.SETTER_PREFIX)) { + + if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { + if (method.getParameters().size() == 0) { + // TODO: report error properly + throw new IllegalStateException(); + } + + int i = 0; + + TypeSource receiverType = null; + PsiParameterWrapper p1 = method.getParameter(0); + if (p1.getJetValueParameter().receiver()) { + receiverType = new TypeSource(p1.getJetValueParameter().type(), p1.getPsiParameter().getType()); + ++i; + } + + while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) { + ++i; + } + + if (i + 1 != method.getParameters().size()) { + throw new IllegalStateException(); + } + + PsiParameterWrapper propertyTypeParameter = method.getParameter(i); + TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), propertyTypeParameter.getPsiParameter().getType()); + + String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.SETTER_PREFIX.length())); + NamedMembers members = getNamedMembers(propertyName); + + members.addPropertyAccessor(new PropertyAccessorData(method, false, propertyType, receiverType)); + } + } + + if (method.getJetMethod().kind() != JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { + NamedMembers namedMembers = getNamedMembers(method.getName()); + namedMembers.addMethod(method); + } + } + } + } + + + static Map getNamedMembers(@NotNull PsiClassWrapper psiClass, boolean staticMembers, boolean kotlin) { + Builder builder = new Builder(psiClass, staticMembers, kotlin); + builder.run(); + return builder.namedMembersMap; + } + + +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java index ab9b7350f29..033d1b034b3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -46,6 +47,14 @@ public class JavaSemanticServices { @Nullable public ClassDescriptor getKotlinClassDescriptor(String qualifiedName) { + if (qualifiedName.startsWith("jet.")) { + ClassDescriptor r = (ClassDescriptor) jetSemanticServices.getStandardLibrary().getLibraryScope().getClassifier(qualifiedName.substring("jet.".length())); + if (r == null) { + // TODO: better error + //throw new IllegalStateException(); + } + return r; + } return getTrace().get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, qualifiedName); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index dc5bbf755a2..a94f5217df9 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -108,11 +108,14 @@ public class JavaTypeTransformer { for (TypeParameterDescriptor parameter : parameters) { arguments.add(TypeUtils.makeStarProjection(parameter)); } - } else { + } + else { + List parameters = descriptor.getTypeConstructor().getParameters(); PsiType[] psiArguments = classType.getParameters(); - for (int i = 0, psiArgumentsLength = psiArguments.length; i < psiArgumentsLength; i++) { + for (int i = 0; i < parameters.size(); i++) { PsiType psiArgument = psiArguments[i]; - TypeParameterDescriptor typeParameterDescriptor = descriptor.getTypeConstructor().getParameters().get(i); + TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor)); } } @@ -187,7 +190,6 @@ public class JavaTypeTransformer { PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); classDescriptorMap.put(jvmPrimitiveType.getWrapper().getFqName(), standardLibrary.getPrimitiveClassDescriptor(primitiveType)); } - //classDescriptorMap.put("java.lang.Object", standardLibrary.get classDescriptorMap.put("java.lang.String", standardLibrary.getString()); } return classDescriptorMap; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index dd8e8b6b3c8..687cb47eaa0 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -12,11 +12,14 @@ import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureVariance; import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author Stepan Koltsov @@ -75,6 +78,26 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd this.classDescriptor = this.javaSemanticServices.getTypeTransformer().getPrimitiveWrappersClassDescriptorMap().get(ourName); + if (this.classDescriptor == null && ourName.equals("java.lang.Object")) { + this.classDescriptor = JetStandardClasses.getAny(); + } + + if (classDescriptor == null) { + // TODO: this is the worst code in Kotlin project + Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName); + if (matcher.matches()) { + classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1))); + } + } + + if (classDescriptor == null) { + Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName); + if (matcher.matches()) { + classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1))); + } + } + + if (this.classDescriptor == null) { this.classDescriptor = javaDescriptorResolver.resolveClass(ourName); } @@ -86,22 +109,22 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd this.typeArguments = new ArrayList(); } - private static Variance parseVariance(char wildcard) { - switch (wildcard) { - case '=': return Variance.INVARIANT; - case '+': return Variance.OUT_VARIANCE; - case '-': return Variance.IN_VARIANCE; + private static Variance parseVariance(JetSignatureVariance variance) { + switch (variance) { + case INVARIANT: return Variance.INVARIANT; + case OUT: return Variance.OUT_VARIANCE; + case IN: return Variance.IN_VARIANCE; default: throw new IllegalStateException(); } } @Override - public JetSignatureVisitor visitTypeArgument(final char wildcard) { + public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance variance) { return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { @Override protected void done(@NotNull JetType jetType) { - typeArguments.add(new TypeProjection(parseVariance(wildcard), jetType)); + typeArguments.add(new TypeProjection(parseVariance(variance), jetType)); } }; } @@ -142,7 +165,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd classDescriptor.getTypeConstructor(), nullable, typeArguments, - ErrorUtils.getErrorScope()); + classDescriptor.getMemberScope(typeArguments)); done(jetType); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/NamedMembers.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/NamedMembers.java new file mode 100644 index 00000000000..badb223ae35 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/NamedMembers.java @@ -0,0 +1,45 @@ +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** +* @author Stepan Koltsov +*/ +class NamedMembers { + String name; + List methods; + + @Nullable + PsiFieldWrapper field; + @Nullable + List propertyAccessors; + + @Nullable + private PsiClass nestedClasses; + + Set propertyDescriptors; + Set functionDescriptors; + + void addMethod(PsiMethodWrapper method) { + if (methods == null) { + methods = new ArrayList(); + } + methods.add(method); + } + + void addPropertyAccessor(PropertyAccessorData propertyAccessorData) { + if (propertyAccessors == null) { + propertyAccessors = new ArrayList(); + } + propertyAccessors.add(propertyAccessorData); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PropertyAccessorData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PropertyAccessorData.java new file mode 100644 index 00000000000..e792ddc510e --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PropertyAccessorData.java @@ -0,0 +1,63 @@ +package org.jetbrains.jet.lang.resolve.java; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; +import org.jetbrains.jet.lang.types.JetType; + +/** + * @author Stepan Koltsov + */ +class PropertyAccessorData { + + @NotNull + private final PsiMemberWrapper member; + private final boolean getter; + + @NotNull + private final TypeSource type; + @Nullable + private final TypeSource receiverType; + + + PropertyAccessorData(@NotNull PsiMethodWrapper method, boolean getter, @NotNull TypeSource type, @Nullable TypeSource receiverType) { + this.member = method; + this.type = type; + this.receiverType = receiverType; + this.getter = getter; + } + + PropertyAccessorData(@NotNull PsiFieldWrapper field, @NotNull TypeSource type, @Nullable TypeSource receiverType) { + this.member = field; + this.type = type; + this.receiverType = receiverType; + this.getter = false; + } + + @NotNull + public PsiMemberWrapper getMember() { + return member; + } + + @NotNull + public TypeSource getType() { + return type; + } + + @Nullable + public TypeSource getReceiverType() { + return receiverType; + } + + public boolean isGetter() { + return member instanceof PsiMethodWrapper && getter; + } + + public boolean isSetter() { + return member instanceof PsiMethodWrapper && !getter; + } + + public boolean isField() { + return member instanceof PsiFieldWrapper; + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassWrapper.java new file mode 100644 index 00000000000..0eb52048fa3 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassWrapper.java @@ -0,0 +1,59 @@ +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Stepan Koltsov + */ +public class PsiClassWrapper { + + @NotNull + private final PsiClass psiClass; + + public PsiClassWrapper(@NotNull PsiClass psiClass) { + this.psiClass = psiClass; + } + + private List methods; + @NotNull + public List getMethods() { + if (methods == null) { + PsiMethod[] psiMethods = psiClass.getMethods(); + List methods = new ArrayList(psiMethods.length); + for (PsiMethod psiMethod : psiMethods) { + methods.add(new PsiMethodWrapper(psiMethod)); + } + this.methods = methods; + } + return methods; + } + + private List fields; + @NotNull + public List getFields() { + if (fields == null) { + PsiField[] psiFields = psiClass.getFields(); + List fields = new ArrayList(psiFields.length); + for (PsiField psiField : psiFields) { + fields.add(new PsiFieldWrapper(psiField)); + } + this.fields = fields; + } + return fields; + } + + public String getQualifiedName() { + return psiClass.getQualifiedName(); + } + + @NotNull + public PsiClass getPsiClass() { + return psiClass; + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java index 75ad3e13860..a896d42e1c7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java @@ -1,6 +1,8 @@ package org.jetbrains.jet.lang.resolve.java; +import com.intellij.psi.PsiField; import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; /** @@ -10,4 +12,12 @@ public class PsiFieldWrapper extends PsiMemberWrapper { public PsiFieldWrapper(@NotNull PsiMember psiMember) { super(psiMember); } + + public PsiField getPsiField() { + return (PsiField) psiMember; + } + + public PsiType getType() { + return getPsiField().getType(); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java index 9e94bcd4169..7c6a2b40745 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java @@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull; /** * @author Stepan Koltsov */ -public class PsiMemberWrapper { +public abstract class PsiMemberWrapper { @NotNull protected final PsiMember psiMember; @@ -23,7 +23,11 @@ public class PsiMemberWrapper { public boolean isPrivate() { return psiMember.hasModifierProperty(PsiModifier.PRIVATE); } - + + public boolean isFinal() { + return psiMember.hasModifierProperty(PsiModifier.FINAL); + } + public String getName() { return psiMember.getName(); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java index 911b3d6119b..66b1df1f991 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java @@ -3,7 +3,9 @@ package org.jetbrains.jet.lang.resolve.java; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.java.kt.JetConstructorAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; @@ -37,10 +39,6 @@ public class PsiMethodWrapper extends PsiMemberWrapper { return getParameters().get(i); } - public boolean isFinal() { - return psiMember.hasModifierProperty(PsiModifier.FINAL); - } - private JetMethodAnnotation jetMethod; @NotNull public JetMethodAnnotation getJetMethod() { @@ -59,8 +57,17 @@ public class PsiMethodWrapper extends PsiMemberWrapper { return jetConstructor; } + public boolean isAbstract() { + return psiMember.hasModifierProperty(PsiModifier.ABSTRACT); + } + @NotNull public PsiMethod getPsiMethod() { return (PsiMethod) psiMember; } + + @Nullable + public PsiType getReturnType() { + return getPsiMethod().getReturnType(); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java new file mode 100644 index 00000000000..b7dc71e3891 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +class TypeSource { + + @NotNull + private final String typeString; + @NotNull + private final PsiType psiType; + + TypeSource(@NotNull String typeString, @NotNull PsiType psiType) { + this.typeString = typeString; + this.psiType = psiType; + } + + @NotNull + public String getTypeString() { + return typeString; + } + + @NotNull + public PsiType getPsiType() { + return psiType; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java index 6e7420483f1..b535e241b16 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java @@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; import org.jetbrains.jet.lang.types.DescriptorSubstitutor; +import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.Variance; @@ -37,6 +38,15 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab private List typeParemeters; private PropertyGetterDescriptor getter; private PropertySetterDescriptor setter; + + private PropertyDescriptor() { + super(ErrorUtils.getErrorClass(), Collections.emptyList(), "dummy"); + this.modality = null; + this.visibility = null; + this.isVar = false; + this.isObject = false; + this.original = null; + } private PropertyDescriptor( @Nullable PropertyDescriptor original, @@ -243,4 +253,8 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab propertyDescriptor.initialize(newGetter, newSetter); return propertyDescriptor; } + + public static PropertyDescriptor createDummy() { + return new PropertyDescriptor(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java index dd01df6d884..939104ff740 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java @@ -73,7 +73,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement this, annotations, false, - "&" + name, + name, Collections.emptyList(), upperBounds); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/JetVisibilityChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/JetVisibilityChecker.java new file mode 100644 index 00000000000..92ebed8e995 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/JetVisibilityChecker.java @@ -0,0 +1,19 @@ +package org.jetbrains.jet.lang.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; + +/** + * @author abreslav + */ +public class JetVisibilityChecker { + /** + * @param locationOwner owner of the call site + * @param subject the descriptor whose visibility is being checked + * @return true iff subject is visible locationOwner + */ + public boolean isVisible(@NotNull DeclarationDescriptor locationOwner, @NotNull DeclarationDescriptor subject) { + // TODO : stub implementation + return true; + } +} 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 35cd9d738a7..071b75180e3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -100,13 +100,7 @@ public class TypeResolver { int expectedArgumentCount = parameters.size(); int actualArgumentCount = arguments.size(); if (ErrorUtils.isError(typeConstructor)) { - result[0] = new JetTypeImpl( - annotations, - typeConstructor, - nullable, - arguments, // TODO : review - classDescriptor.getMemberScope(Collections.emptyList()) - ); + result[0] = ErrorUtils.createErrorType("??"); } else { if (actualArgumentCount != expectedArgumentCount) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 87c02bed6d3..a170c4ac6ed 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -15,7 +15,13 @@ import java.util.*; public class ErrorUtils { private static final ModuleDescriptor ERROR_MODULE = new ModuleDescriptor(""); - private static final JetScope ERROR_SCOPE = new JetScope() { + + + private static final JetScope ERROR_SCOPE = new ErrorScope(); + + public static class ErrorScope implements JetScope { + + private ErrorScope() {} @Override public ClassifierDescriptor getClassifier(@NotNull String name) { @@ -82,7 +88,7 @@ public class ErrorUtils { return Collections.emptyList(); } - }; + } private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), "") { @NotNull @@ -96,6 +102,12 @@ public class ErrorUtils { public Modality getModality() { return Modality.OPEN; } + + @NotNull + @Override + public ClassDescriptor substitute(TypeSubstitutor substitutor) { + return ERROR_CLASS; + } }; private static final Set ERROR_FUNCTION_GROUP = Collections.singleton(createErrorFunction(0, Collections.emptyList())); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index c79b0c9fc3f..54f781bc7fb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -78,6 +78,7 @@ public class JetStandardLibrary { private EnumMap primitiveTypeToArrayJetType; private EnumMap primitiveTypeToNullableArrayJetType; private Map primitiveJetTypeToJetArrayType; + private Map jetArrayTypeToPrimitiveJetType; private JetStandardLibrary(@NotNull Project project) { // TODO : review @@ -147,6 +148,7 @@ public class JetStandardLibrary { primitiveTypeToArrayJetType = new EnumMap(PrimitiveType.class); primitiveTypeToNullableArrayJetType = new EnumMap(PrimitiveType.class); primitiveJetTypeToJetArrayType = new HashMap(); + jetArrayTypeToPrimitiveJetType = new HashMap(); for (PrimitiveType primitive : PrimitiveType.values()) { makePrimitive(primitive); @@ -167,6 +169,7 @@ public class JetStandardLibrary { primitiveTypeToArrayJetType.put(primitiveType, arrayType); primitiveTypeToNullableArrayJetType.put(primitiveType, TypeUtils.makeNullable(arrayType)); primitiveJetTypeToJetArrayType.put(type, arrayType); + jetArrayTypeToPrimitiveJetType.put(arrayType, type); } @NotNull @@ -334,6 +337,22 @@ public class JetStandardLibrary { getArray().getMemberScope(types) ); } + + @NotNull + public JetType getArrayElementType(@NotNull JetType arrayType) { + // make non-null? + if (arrayType.getConstructor().getDeclarationDescriptor() == getArray()) { + if (arrayType.getArguments().size() != 1) { + throw new IllegalStateException(); + } + return arrayType.getArguments().get(0).getType(); + } + JetType primitiveType = jetArrayTypeToPrimitiveJetType.get(arrayType); + if (primitiveType == null) { + throw new IllegalStateException("not array: " + arrayType); + } + return primitiveType; + } @NotNull public JetType getIterableType(@NotNull JetType argument) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java index c8bc340d8bb..28e2314f8ab 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java @@ -23,6 +23,11 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType { public JetTypeImpl(List annotations, TypeConstructor constructor, boolean nullable, @NotNull List arguments, JetScope memberScope) { super(annotations); + + if (memberScope instanceof ErrorUtils.ErrorScope) { + throw new IllegalStateException(); + } + this.constructor = constructor; this.nullable = nullable; this.arguments = arguments; 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 6e6f3cfa7c9..c62b5772331 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -100,6 +100,9 @@ public class TypeUtils { if (type.isNullable() == nullable) { return type; } + if (ErrorUtils.isErrorType(type)) { + return type; + } return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), nullable, type.getArguments(), type.getMemberScope()); } @@ -285,6 +288,9 @@ 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"); + } List arguments = getDefaultTypeProjections(classDescriptor.getTypeConstructor().getParameters()); return new JetTypeImpl( Collections.emptyList(), diff --git a/compiler/testData/readJavaBinaryClass/FieldAsVar.java b/compiler/testData/readJavaBinaryClass/FieldAsVar.java new file mode 100644 index 00000000000..9c2662efce4 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/FieldAsVar.java @@ -0,0 +1,5 @@ +package test; + +final class FieldAsVar { + public int f; +} diff --git a/compiler/testData/readJavaBinaryClass/FieldAsVar.kt b/compiler/testData/readJavaBinaryClass/FieldAsVar.kt new file mode 100644 index 00000000000..358ad58ff61 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/FieldAsVar.kt @@ -0,0 +1,5 @@ +package test + +class FieldAsVar() { + var f: Int = 1 +} diff --git a/compiler/testData/readJavaBinaryClass/FinalFieldAsVal.java b/compiler/testData/readJavaBinaryClass/FinalFieldAsVal.java new file mode 100644 index 00000000000..69b7785869d --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/FinalFieldAsVal.java @@ -0,0 +1,5 @@ +package test; + +final class FinalFieldAsVal { + public final int f = 1; +} diff --git a/compiler/testData/readJavaBinaryClass/FinalFieldAsVal.kt b/compiler/testData/readJavaBinaryClass/FinalFieldAsVal.kt new file mode 100644 index 00000000000..01c67630deb --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/FinalFieldAsVal.kt @@ -0,0 +1,5 @@ +package test + +class FinalFieldAsVal() { + val f: Int = 1 +} diff --git a/compiler/testData/readJavaBinaryClass/Simple.java b/compiler/testData/readJavaBinaryClass/Simple.java new file mode 100644 index 00000000000..fd436f0c133 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/Simple.java @@ -0,0 +1,5 @@ +package test; + +public final class Simple { + public Simple() { } +} diff --git a/compiler/testData/readJavaBinaryClass/Simple.kt b/compiler/testData/readJavaBinaryClass/Simple.kt new file mode 100644 index 00000000000..8e2814732aa --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/Simple.kt @@ -0,0 +1,3 @@ +package test + +class Simple() diff --git a/compiler/testData/readJavaBinaryClass/TwoFields.java b/compiler/testData/readJavaBinaryClass/TwoFields.java new file mode 100644 index 00000000000..a969f3381c1 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/TwoFields.java @@ -0,0 +1,6 @@ +package test; + +final class TwoFields { + int a; + short b; +} diff --git a/compiler/testData/readJavaBinaryClass/TwoFields.kt b/compiler/testData/readJavaBinaryClass/TwoFields.kt new file mode 100644 index 00000000000..5699c6caaf3 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/TwoFields.kt @@ -0,0 +1,6 @@ +package test + +class TwoFields() { + var a: Int = 1 + var b: Short = 2; +} diff --git a/compiler/testData/readClass/class/Class.kt b/compiler/testData/readKotlinBinaryClass/class/Class.kt similarity index 100% rename from compiler/testData/readClass/class/Class.kt rename to compiler/testData/readKotlinBinaryClass/class/Class.kt diff --git a/compiler/testData/readClass/class/ClassInParam.kt b/compiler/testData/readKotlinBinaryClass/class/ClassInParam.kt similarity index 100% rename from compiler/testData/readClass/class/ClassInParam.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassInParam.kt diff --git a/compiler/testData/readClass/class/ClassInnerClass.kt b/compiler/testData/readKotlinBinaryClass/class/ClassInnerClass.kt similarity index 100% rename from compiler/testData/readClass/class/ClassInnerClass.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassInnerClass.kt diff --git a/compiler/testData/readClass/class/ClassOutParam.kt b/compiler/testData/readKotlinBinaryClass/class/ClassOutParam.kt similarity index 100% rename from compiler/testData/readClass/class/ClassOutParam.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassOutParam.kt diff --git a/compiler/testData/readClass/class/ClassParam.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParam.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParam.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParam.kt diff --git a/compiler/testData/readClass/class/ClassParamReferencesParam.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParamReferencesParam.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParamReferencesParam.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParamReferencesParam.kt diff --git a/compiler/testData/readClass/class/ClassParamReferencesParam2.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParamReferencesParam2.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParamReferencesParam2.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParamReferencesParam2.kt diff --git a/compiler/testData/readClass/class/ClassParamUpperClassBound.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParamUpperClassBound.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParamUpperClassBound.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParamUpperClassBound.kt diff --git a/compiler/testData/readClass/class/ClassParamUpperClassInterfaceBound.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParamUpperClassInterfaceBound.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParamUpperClassInterfaceBound.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParamUpperClassInterfaceBound.kt diff --git a/compiler/testData/readClass/class/ClassParamUpperInterfaceBound.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParamUpperInterfaceBound.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParamUpperInterfaceBound.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParamUpperInterfaceBound.kt diff --git a/compiler/testData/readClass/class/ClassParamUpperInterfaceClassBound.kt b/compiler/testData/readKotlinBinaryClass/class/ClassParamUpperInterfaceClassBound.kt similarity index 100% rename from compiler/testData/readClass/class/ClassParamUpperInterfaceClassBound.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassParamUpperInterfaceClassBound.kt diff --git a/compiler/testData/readClass/class/ClassTwoParams.kt b/compiler/testData/readKotlinBinaryClass/class/ClassTwoParams.kt similarity index 100% rename from compiler/testData/readClass/class/ClassTwoParams.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassTwoParams.kt diff --git a/compiler/testData/readClass/class/ClassTwoParams2.kt b/compiler/testData/readKotlinBinaryClass/class/ClassTwoParams2.kt similarity index 100% rename from compiler/testData/readClass/class/ClassTwoParams2.kt rename to compiler/testData/readKotlinBinaryClass/class/ClassTwoParams2.kt diff --git a/compiler/testData/readClass/class/Trait.kt b/compiler/testData/readKotlinBinaryClass/class/Trait.kt similarity index 100% rename from compiler/testData/readClass/class/Trait.kt rename to compiler/testData/readKotlinBinaryClass/class/Trait.kt diff --git a/compiler/testData/readClass/classFun/ClassInParamUsedInFun.kt b/compiler/testData/readKotlinBinaryClass/classFun/ClassInParamUsedInFun.kt similarity index 100% rename from compiler/testData/readClass/classFun/ClassInParamUsedInFun.kt rename to compiler/testData/readKotlinBinaryClass/classFun/ClassInParamUsedInFun.kt diff --git a/compiler/testData/readClass/classFun/ClassParamUsedInFun.kt b/compiler/testData/readKotlinBinaryClass/classFun/ClassParamUsedInFun.kt similarity index 100% rename from compiler/testData/readClass/classFun/ClassParamUsedInFun.kt rename to compiler/testData/readKotlinBinaryClass/classFun/ClassParamUsedInFun.kt diff --git a/compiler/testData/readClass/constructor/Constructor0.kt b/compiler/testData/readKotlinBinaryClass/constructor/Constructor0.kt similarity index 100% rename from compiler/testData/readClass/constructor/Constructor0.kt rename to compiler/testData/readKotlinBinaryClass/constructor/Constructor0.kt diff --git a/compiler/testData/readClass/constructor/Constructor1.kt b/compiler/testData/readKotlinBinaryClass/constructor/Constructor1.kt similarity index 100% rename from compiler/testData/readClass/constructor/Constructor1.kt rename to compiler/testData/readKotlinBinaryClass/constructor/Constructor1.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunGenericParam.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunGenericParam.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunGenericParam.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunGenericParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunInParam.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunInParam.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunInParam.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunInParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunOutParam.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunOutParam.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunOutParam.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunOutParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamParam.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamParam.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamParam.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamReferencesParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamReferencesParam2.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassBound.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperClassBound.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassBound.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperClassBound.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassInterfaceBound.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperClassInterfaceBound.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperClassInterfaceBound.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperClassInterfaceBound.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceBound.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperInterfaceBound.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceBound.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperInterfaceBound.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceClassBound.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperInterfaceClassBound.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamUpperInterfaceClassBound.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamUpperInterfaceClassBound.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunParamVaragParam.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamVaragParam.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunParamVaragParam.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunParamVaragParam.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunTwoTypeParams.kt diff --git a/compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithTypeVariables/FunTwoTypeParams2.kt diff --git a/compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNotNull.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/FunClassParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNotNull.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/FunClassParamNotNull.kt diff --git a/compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNullable.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/FunClassParamNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithoutTypeVariables/FunClassParamNullable.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/FunClassParamNullable.kt diff --git a/compiler/testData/readClass/fun/genericWithoutTypeVariables/FunParamNullable.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/FunParamNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithoutTypeVariables/FunParamNullable.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/FunParamNullable.kt diff --git a/compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNotNull.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNotNull.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNotNull.kt diff --git a/compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNullable.kt b/compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNullable.kt rename to compiler/testData/readKotlinBinaryClass/fun/genericWithoutTypeVariables/ReturnTypeClassParamNullable.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ClassFun.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFun.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ClassFun.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFun.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ClassFunGetFoo.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFunGetFoo.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ClassFunGetFoo.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFunGetFoo.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ClassFunGetFooSetFoo.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFunGetFooSetFoo.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ClassFunGetFooSetFoo.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFunGetFooSetFoo.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ClassFunSetFoo.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFunSetFoo.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ClassFunSetFoo.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ClassFunSetFoo.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ExtFun.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ExtFun.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ExtFun.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ExtFun.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ExtFunInClass.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ExtFunInClass.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ExtFunInClass.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ExtFunInClass.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/FunDefaultArg.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunDefaultArg.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/FunDefaultArg.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunDefaultArg.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/FunParamNotNull.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/FunParamNotNull.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunParamNotNull.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/FunVarargCharSequence.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunVarargCharSequence.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/FunVarargCharSequence.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunVarargCharSequence.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/FunVarargInt.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunVarargInt.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/FunVarargInt.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/FunVarargInt.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ModifierAbstract.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ModifierAbstract.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ModifierAbstract.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ModifierAbstract.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ModifierOpen.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ModifierOpen.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ModifierOpen.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ModifierOpen.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/NsFun.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/NsFun.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/NsFun.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/NsFun.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/NsFunGetFoo.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/NsFunGetFoo.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/NsFunGetFoo.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/NsFunGetFoo.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ReturnTypeNotNull.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ReturnTypeNotNull.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ReturnTypeNotNull.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ReturnTypeNotNull.kt diff --git a/compiler/testData/readClass/fun/nonGeneric/ReturnTypeNullable.kt b/compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ReturnTypeNullable.kt similarity index 100% rename from compiler/testData/readClass/fun/nonGeneric/ReturnTypeNullable.kt rename to compiler/testData/readKotlinBinaryClass/fun/nonGeneric/ReturnTypeNullable.kt diff --git a/compiler/testData/readClass/prop/ClassVal.kt b/compiler/testData/readKotlinBinaryClass/prop/ClassVal.kt similarity index 100% rename from compiler/testData/readClass/prop/ClassVal.kt rename to compiler/testData/readKotlinBinaryClass/prop/ClassVal.kt diff --git a/compiler/testData/readClass/prop/ClassValAbstract.kt b/compiler/testData/readKotlinBinaryClass/prop/ClassValAbstract.kt similarity index 100% rename from compiler/testData/readClass/prop/ClassValAbstract.kt rename to compiler/testData/readKotlinBinaryClass/prop/ClassValAbstract.kt diff --git a/compiler/testData/readClass/prop/ClassVar.kt b/compiler/testData/readKotlinBinaryClass/prop/ClassVar.kt similarity index 100% rename from compiler/testData/readClass/prop/ClassVar.kt rename to compiler/testData/readKotlinBinaryClass/prop/ClassVar.kt diff --git a/compiler/testData/readKotlinBinaryClass/prop/CollectionSize.kt b/compiler/testData/readKotlinBinaryClass/prop/CollectionSize.kt new file mode 100644 index 00000000000..8ab57de53f1 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/prop/CollectionSize.kt @@ -0,0 +1,6 @@ +package test + +import java.util.Collection + +val Collection<*>.anotherSize : Int + get() = size() diff --git a/compiler/testData/readClass/prop/ExtValClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValClass.kt diff --git a/compiler/testData/readClass/prop/ExtValInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValInClass.kt diff --git a/compiler/testData/readClass/prop/ExtValInt.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValInt.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValInt.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValInt.kt diff --git a/compiler/testData/readClass/prop/ExtValIntCharSequence.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValIntCharSequence.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValIntCharSequence.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValIntCharSequence.kt diff --git a/compiler/testData/readClass/prop/ExtValIntCharSequenceQ.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValIntCharSequenceQ.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValIntCharSequenceQ.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValIntCharSequenceQ.kt diff --git a/compiler/testData/readClass/prop/ExtValIntListQOfIntInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValIntListQOfIntInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValIntListQOfIntInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValIntListQOfIntInClass.kt diff --git a/compiler/testData/readClass/prop/ExtValIntTInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValIntTInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValIntTInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValIntTInClass.kt diff --git a/compiler/testData/readClass/prop/ExtValIntTQInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValIntTQInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValIntTQInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValIntTQInClass.kt diff --git a/compiler/testData/readClass/prop/ExtValTIntInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtValTIntInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtValTIntInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtValTIntInClass.kt diff --git a/compiler/testData/readClass/prop/ExtVarClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarClass.kt diff --git a/compiler/testData/readClass/prop/ExtVarInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarInClass.kt diff --git a/compiler/testData/readClass/prop/ExtVarInt.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarInt.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarInt.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarInt.kt diff --git a/compiler/testData/readClass/prop/ExtVarIntTInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarIntTInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarIntTInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarIntTInClass.kt diff --git a/compiler/testData/readClass/prop/ExtVarIntTQInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarIntTQInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarIntTQInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarIntTQInClass.kt diff --git a/compiler/testData/readClass/prop/ExtVarMapPQInt.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarMapPQInt.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarMapPQInt.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarMapPQInt.kt diff --git a/compiler/testData/readClass/prop/ExtVarTIntInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarTIntInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarTIntInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarTIntInClass.kt diff --git a/compiler/testData/readClass/prop/ExtVarTQIntInClass.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarTQIntInClass.kt similarity index 100% rename from compiler/testData/readClass/prop/ExtVarTQIntInClass.kt rename to compiler/testData/readKotlinBinaryClass/prop/ExtVarTQIntInClass.kt diff --git a/compiler/testData/readKotlinBinaryClass/prop/ExtVarl.kt b/compiler/testData/readKotlinBinaryClass/prop/ExtVarl.kt new file mode 100644 index 00000000000..d4900f45565 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/prop/ExtVarl.kt @@ -0,0 +1,8 @@ +package test + +var Int.junk: Short + get() = throw Exception() + set(p: Short) = throw Exception() + +val String.junk: Int + get() = throw Exception() diff --git a/compiler/testData/readClass/prop/NsVal.kt b/compiler/testData/readKotlinBinaryClass/prop/NsVal.kt similarity index 100% rename from compiler/testData/readClass/prop/NsVal.kt rename to compiler/testData/readKotlinBinaryClass/prop/NsVal.kt diff --git a/compiler/testData/readClass/prop/NsVar.kt b/compiler/testData/readKotlinBinaryClass/prop/NsVar.kt similarity index 100% rename from compiler/testData/readClass/prop/NsVar.kt rename to compiler/testData/readKotlinBinaryClass/prop/NsVar.kt diff --git a/compiler/testData/readKotlinBinaryClass/type/Any.kt b/compiler/testData/readKotlinBinaryClass/type/Any.kt new file mode 100644 index 00000000000..9f1e3eaa6ca --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/type/Any.kt @@ -0,0 +1,3 @@ +package test + +fun any(): Any = 1 diff --git a/compiler/testData/readKotlinBinaryClass/type/AnyQ.kt b/compiler/testData/readKotlinBinaryClass/type/AnyQ.kt new file mode 100644 index 00000000000..a59092e1372 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/type/AnyQ.kt @@ -0,0 +1,3 @@ +package test + +fun anyq(): Any? = 1 diff --git a/compiler/testData/readClass/type/ArrayOfCharSequence.kt b/compiler/testData/readKotlinBinaryClass/type/ArrayOfCharSequence.kt similarity index 100% rename from compiler/testData/readClass/type/ArrayOfCharSequence.kt rename to compiler/testData/readKotlinBinaryClass/type/ArrayOfCharSequence.kt diff --git a/compiler/testData/readClass/type/ArrayOfInt.kt b/compiler/testData/readKotlinBinaryClass/type/ArrayOfInt.kt similarity index 100% rename from compiler/testData/readClass/type/ArrayOfInt.kt rename to compiler/testData/readKotlinBinaryClass/type/ArrayOfInt.kt diff --git a/compiler/testData/readClass/type/ArrayOfString.kt b/compiler/testData/readKotlinBinaryClass/type/ArrayOfString.kt similarity index 100% rename from compiler/testData/readClass/type/ArrayOfString.kt rename to compiler/testData/readKotlinBinaryClass/type/ArrayOfString.kt diff --git a/compiler/testData/readKotlinBinaryClass/type/Function1IntString.kt b/compiler/testData/readKotlinBinaryClass/type/Function1IntString.kt new file mode 100644 index 00000000000..ce8b87d4a66 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/type/Function1IntString.kt @@ -0,0 +1,3 @@ +package test + +fun fun1(): (String) -> Int = throw Exception() diff --git a/compiler/testData/readClass/type/Int.kt b/compiler/testData/readKotlinBinaryClass/type/Int.kt similarity index 100% rename from compiler/testData/readClass/type/Int.kt rename to compiler/testData/readKotlinBinaryClass/type/Int.kt diff --git a/compiler/testData/readClass/type/IntArray.kt b/compiler/testData/readKotlinBinaryClass/type/IntArray.kt similarity index 100% rename from compiler/testData/readClass/type/IntArray.kt rename to compiler/testData/readKotlinBinaryClass/type/IntArray.kt diff --git a/compiler/testData/readClass/type/IntQ.kt b/compiler/testData/readKotlinBinaryClass/type/IntQ.kt similarity index 100% rename from compiler/testData/readClass/type/IntQ.kt rename to compiler/testData/readKotlinBinaryClass/type/IntQ.kt diff --git a/compiler/testData/readKotlinBinaryClass/type/ListOfAny.kt b/compiler/testData/readKotlinBinaryClass/type/ListOfAny.kt new file mode 100644 index 00000000000..74df70f27c7 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/type/ListOfAny.kt @@ -0,0 +1,5 @@ +package test + +import java.util.List + +fun listOfAny(): List = throw Exception() diff --git a/compiler/testData/readKotlinBinaryClass/type/ListOfAnyQ.kt b/compiler/testData/readKotlinBinaryClass/type/ListOfAnyQ.kt new file mode 100644 index 00000000000..618cb4023d6 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/type/ListOfAnyQ.kt @@ -0,0 +1,5 @@ +package test + +import java.util.List + +fun listOfAnyQ(): List = throw Exception() diff --git a/compiler/testData/readKotlinBinaryClass/type/ListOfStar.kt b/compiler/testData/readKotlinBinaryClass/type/ListOfStar.kt new file mode 100644 index 00000000000..572fa54fff4 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/type/ListOfStar.kt @@ -0,0 +1,5 @@ +package test + +import java.util.List + +fun listOfStar(): List<*> = throw Exception() diff --git a/compiler/testData/readClass/type/ListOfString.kt b/compiler/testData/readKotlinBinaryClass/type/ListOfString.kt similarity index 100% rename from compiler/testData/readClass/type/ListOfString.kt rename to compiler/testData/readKotlinBinaryClass/type/ListOfString.kt diff --git a/compiler/testData/readClass/type/String.kt b/compiler/testData/readKotlinBinaryClass/type/String.kt similarity index 100% rename from compiler/testData/readClass/type/String.kt rename to compiler/testData/readKotlinBinaryClass/type/String.kt diff --git a/compiler/testData/readClass/type/StringQ.kt b/compiler/testData/readKotlinBinaryClass/type/StringQ.kt similarity index 100% rename from compiler/testData/readClass/type/StringQ.kt rename to compiler/testData/readKotlinBinaryClass/type/StringQ.kt diff --git a/compiler/testData/writeSignature/ListOfStar.kt b/compiler/testData/writeSignature/ListOfStar.kt new file mode 100644 index 00000000000..41d0aa3c844 --- /dev/null +++ b/compiler/testData/writeSignature/ListOfStar.kt @@ -0,0 +1,8 @@ +import java.util.List + +fun listOfStar(): List<*> = throw Exception() + +// method: namespace::listOfStar +// jvm signature: ()Ljava/util/List; +// generic signature: ()Ljava/util/List<+Ljava/lang/Object;>; +// kotlin signature: ()Ljava/util/List<+?Ljava/lang/Object;>; diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/NamespaceComparator.java similarity index 77% rename from compiler/tests/org/jetbrains/jet/ReadClassDataTest.java rename to compiler/tests/org/jetbrains/jet/NamespaceComparator.java index 3740d7df4f8..a8b913c3aa6 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/NamespaceComparator.java @@ -1,20 +1,7 @@ package org.jetbrains.jet; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.psi.PsiFileFactory; -import com.intellij.psi.impl.PsiFileFactoryImpl; -import com.intellij.testFramework.LightVirtualFile; -import junit.framework.Test; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.codegen.ClassBuilderFactory; -import org.jetbrains.jet.codegen.ClassFileFactory; -import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.PropertyCodegen; -import org.jetbrains.jet.compiler.CompileEnvironment; -import org.jetbrains.jet.compiler.JetCoreEnvironment; -import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; @@ -28,24 +15,18 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.resolve.AnalyzingUtils; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; -import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; +import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.Variance; -import org.jetbrains.jet.plugin.JetLanguage; import org.junit.Assert; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; -import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; @@ -57,57 +38,19 @@ import java.util.Set; /** * @author Stepan Koltsov */ -public class ReadClassDataTest extends TestCaseWithTmpdir { +class NamespaceComparator { - private JetCoreEnvironment jetCoreEnvironment; + private final boolean includeObject; - private final File testFile; - - public ReadClassDataTest(@NotNull File testFile) { - this.testFile = testFile; - setName(testFile.getName()); + private NamespaceComparator(boolean includeObject) { + this.includeObject = includeObject; } - @Override - public void runTest() throws Exception { - jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); - - String text = FileUtil.loadFile(testFile); - - LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text); - virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); - JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); - - GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES); - AnalyzingUtils.checkForSyntacticErrors(psiFile); - BindingContext bindingContext = state.compile(psiFile); - - ClassFileFactory classFileFactory = state.getFactory(); - - CompileEnvironment.writeToOutputDirectory(classFileFactory, tmpdir.getPath()); - - NamespaceDescriptor namespaceFromSource = (NamespaceDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiFile); - - Assert.assertEquals("test", namespaceFromSource.getName()); - - Disposer.dispose(myTestRootDisposable); - - - jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); - - jetCoreEnvironment.addToClasspath(tmpdir); - jetCoreEnvironment.addToClasspath(new File("out/production/stdlib")); - - JetSemanticServices jetSemanticServices = JetSemanticServices.createSemanticServices(jetCoreEnvironment.getProject()); - JavaSemanticServices semanticServices = new JavaSemanticServices(jetCoreEnvironment.getProject(), jetSemanticServices, new BindingTraceContext()); - - JavaDescriptorResolver javaDescriptorResolver = semanticServices.getDescriptorResolver(); - NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace("test"); - - compareNamespaces(namespaceFromSource, namespaceFromClass); + public static void compareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb, boolean includeObject) { + new NamespaceComparator(includeObject).doCompareNamespaces(nsa, nsb); } - private void compareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb) { + private void doCompareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb) { Assert.assertEquals(nsa.getName(), nsb.getName()); System.out.println("namespace " + nsa.getName()); @@ -116,7 +59,7 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { Set classifierNames = new HashSet(); Set propertyNames = new HashSet(); Set functionNames = new HashSet(); - + for (DeclarationDescriptor ad : nsa.getMemberScope().getAllDescriptors()) { if (ad instanceof ClassifierDescriptor) { classifierNames.add(ad.getName()); @@ -136,7 +79,7 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { Assert.assertTrue(cb != null); compareClassifiers(ca, cb); } - + for (String name : propertyNames) { Set pa = nsa.getMemberScope().getProperties(name); Set pb = nsb.getMemberScope().getProperties(name); @@ -145,59 +88,59 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.getterName(name)).isEmpty()); Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.setterName(name)).isEmpty()); } - + for (String name : functionNames) { Set fa = nsa.getMemberScope().getFunctions(name); Set fb = nsb.getMemberScope().getFunctions(name); compareDeclarationSets(fa, fb); } } - - private void compareDeclarationSets(Set a, Set b) { + + private static void compareDeclarationSets(Set a, Set b) { String at = serializedDeclarationSets(a); String bt = serializedDeclarationSets(b); Assert.assertEquals(at, bt); System.out.print(at); } - - private String serializedDeclarationSets(Collection ds) { + + private static String serializedDeclarationSets(Collection ds) { List strings = new ArrayList(); for (DeclarationDescriptor d : ds) { StringBuilder sb = new StringBuilder(); new Serializer(sb).serialize(d); strings.add(sb.toString()); } - + Collections.sort(strings); - + StringBuilder r = new StringBuilder(); for (String string : strings) { r.append(string); r.append("\n"); } return r.toString(); - } + } private void compareClassifiers(@NotNull ClassifierDescriptor a, @NotNull ClassifierDescriptor b) { StringBuilder sba = new StringBuilder(); StringBuilder sbb = new StringBuilder(); - + new FullContentSerialier(sba).serialize((ClassDescriptor) a); new FullContentSerialier(sbb).serialize((ClassDescriptor) b); - + String as = sba.toString(); String bs = sbb.toString(); Assert.assertEquals(as, bs); System.out.println(as); } - + private void compareDescriptors(@NotNull DeclarationDescriptor a, @NotNull DeclarationDescriptor b) { StringBuilder sba = new StringBuilder(); StringBuilder sbb = new StringBuilder(); new Serializer(sba).serialize(a); new Serializer(sbb).serialize(b); - + String as = sba.toString(); String bs = sbb.toString(); @@ -275,7 +218,13 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { } else { sb.append("val "); } + if (!prop.getTypeParameters().isEmpty()) { + sb.append(" <"); + new Serializer(sb).serializeCommaSeparated(prop.getTypeParameters()); + sb.append("> "); + } if (prop.getReceiverParameter().exists()) { + // TODO: print only name for type parameter new Serializer(sb).serialize(prop.getReceiverParameter().getType()); sb.append("."); } @@ -331,6 +280,9 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { } sb.append(">"); } + if (type.isNullable()) { + sb.append("?"); + } } public void serializeCommaSeparated(List list) { @@ -347,8 +299,12 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { first = false; } } - + private Method getMethodToSerialize(Object o) { + if (o == null) { + throw new IllegalStateException("won't serialize null"); + } + // TODO: cache for (Method method : this.getClass().getMethods()) { if (!method.getName().equals("serialize")) { @@ -387,16 +343,22 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { } public void serialize(NamespaceDescriptor ns) { - if (ns.getContainingDeclaration() == null) { - // root ns + if (isRootNs(ns)) { return; } - new NamespacePrefixSerializer(sb).serialize(ns.getContainingDeclaration()); + if (ns.getContainingDeclaration() != null) { + new NamespacePrefixSerializer(sb).serialize(ns.getContainingDeclaration()); + } sb.append(ns.getName()); } public void serialize(TypeParameterDescriptor param) { - sb.append("/*").append(param.getIndex()).append("*/ "); + sb.append("/*"); + sb.append(param.getIndex()); + if (param.isReified()) { + sb.append(",r"); + } + sb.append("*/ "); serialize(param.getVariance()); sb.append(param.getName()); if (!param.getUpperBounds().isEmpty()) { @@ -414,7 +376,12 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { } } - + + private static boolean isRootNs(DeclarationDescriptor ns) { + // upyachka + return ns instanceof JavaNamespaceDescriptor && JavaDescriptorResolver.JAVA_ROOT.equals(ns.getName()); + } + private static class NamespacePrefixSerializer extends Serializer { public NamespacePrefixSerializer(StringBuilder sb) { @@ -423,11 +390,10 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { @Override public void serialize(NamespaceDescriptor ns) { - if (ns.getContainingDeclaration() == null) { - // root ns + super.serialize(ns); + if (isRootNs(ns)) { return; } - super.serialize(ns); sb.append("."); } @@ -437,7 +403,7 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { sb.append("."); } } - + private static class ValueParameterSerializer extends Serializer { public ValueParameterSerializer(StringBuilder sb) { @@ -450,7 +416,7 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { } } - private static class FullContentSerialier extends Serializer { + private class FullContentSerialier extends Serializer { private FullContentSerialier(StringBuilder sb) { super(sb); } @@ -491,6 +457,11 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { JetScope memberScope = klass.getMemberScope(typeArguments); for (DeclarationDescriptor member : memberScope.getAllDescriptors()) { + if (!includeObject) { + if (member.getName().matches("equals|hashCode|finalize|wait|notify(All)?|toString|clone|getClass")) { + continue; + } + } StringBuilder memberSb = new StringBuilder(); new FullContentSerialier(memberSb).serialize(member); memberStrings.add(memberSb.toString()); @@ -526,14 +497,5 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { } } - public static Test suite() { - return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readClass", true, new JetTestCaseBuilder.NamedTestFactory() { - @NotNull - @Override - public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { - return new ReadClassDataTest(file); - } - }); - } - + } diff --git a/compiler/tests/org/jetbrains/jet/ReadJavaBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/ReadJavaBinaryClassTest.java new file mode 100644 index 00000000000..66e4ddf1ded --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/ReadJavaBinaryClassTest.java @@ -0,0 +1,115 @@ +package org.jetbrains.jet; + +import com.google.common.base.Predicates; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.impl.PsiFileFactoryImpl; +import com.intellij.testFramework.LightVirtualFile; +import junit.framework.Test; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.codegen.ClassBuilderFactory; +import org.jetbrains.jet.codegen.GenerationState; +import org.jetbrains.jet.compiler.JetCoreEnvironment; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; +import org.jetbrains.jet.plugin.JetLanguage; +import org.junit.Assert; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import java.io.File; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +/** + * @author Stepan Koltsov + */ +public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { + + private final File ktFile; + private final File javaFile; + + public ReadJavaBinaryClassTest(File ktFile) { + this.ktFile = ktFile; + Assert.assertTrue(ktFile.getName().endsWith(".kt")); + this.javaFile = new File(ktFile.getPath().replaceFirst("\\.kt$", ".java")); + setName(javaFile.getName()); + } + + + @Override + public void runTest() throws Exception { + NamespaceDescriptor nsa = compileKotlin(); + NamespaceDescriptor nsb = compileJava(); + NamespaceComparator.compareNamespaces(nsa, nsb, false); + } + + private NamespaceDescriptor compileKotlin() throws Exception { + JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + + String text = FileUtil.loadFile(ktFile); + + LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text); + virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); + JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); + + BindingContext bindingContext = AnalyzerFacade.analyzeOneFileWithJavaIntegration(psiFile, JetControlFlowDataTraceFactory.EMPTY); + AnalyzingUtils.throwExceptionOnErrors(bindingContext); + return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, "test"); + } + + private NamespaceDescriptor compileJava() throws Exception { + JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); + + StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8")); + try { + Iterable javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(javaFile)); + List options = Arrays.asList( + "-classpath", "out/production/stdlib", + "-d", tmpdir.getPath() + ); + JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles); + + Assert.assertTrue(task.call()); + } finally { + fileManager.close(); + } + + JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + + jetCoreEnvironment.addToClasspath(tmpdir); + jetCoreEnvironment.addToClasspath(new File("out/production/stdlib")); + + JetSemanticServices jetSemanticServices = JetSemanticServices.createSemanticServices(jetCoreEnvironment.getProject()); + JavaSemanticServices semanticServices = new JavaSemanticServices(jetCoreEnvironment.getProject(), jetSemanticServices, new BindingTraceContext()); + + JavaDescriptorResolver javaDescriptorResolver = semanticServices.getDescriptorResolver(); + return javaDescriptorResolver.resolveNamespace("test"); + } + + public static Test suite() { + return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readJavaBinaryClass", true, new JetTestCaseBuilder.NamedTestFactory() { + @NotNull + @Override + public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { + return new ReadJavaBinaryClassTest(file); + } + }); + } + +} diff --git a/compiler/tests/org/jetbrains/jet/ReadKotlinBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/ReadKotlinBinaryClassTest.java new file mode 100644 index 00000000000..82fdc19e162 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/ReadKotlinBinaryClassTest.java @@ -0,0 +1,122 @@ +package org.jetbrains.jet; + +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.impl.PsiFileFactoryImpl; +import com.intellij.testFramework.LightVirtualFile; +import junit.framework.Test; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.codegen.ClassBuilderFactory; +import org.jetbrains.jet.codegen.ClassFileFactory; +import org.jetbrains.jet.codegen.GenerationState; +import org.jetbrains.jet.codegen.PropertyCodegen; +import org.jetbrains.jet.compiler.CompileEnvironment; +import org.jetbrains.jet.compiler.JetCoreEnvironment; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.Variance; +import org.jetbrains.jet.plugin.JetLanguage; +import org.junit.Assert; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.io.File; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Compile Kotlin and then parse model from .class files. + * + * @author Stepan Koltsov + */ +public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir { + + private JetCoreEnvironment jetCoreEnvironment; + + private final File testFile; + + public ReadKotlinBinaryClassTest(@NotNull File testFile) { + this.testFile = testFile; + setName(testFile.getName()); + } + + @Override + public void runTest() throws Exception { + jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + + String text = FileUtil.loadFile(testFile); + + LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text); + virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); + JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); + + GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES); + AnalyzingUtils.checkForSyntacticErrors(psiFile); + BindingContext bindingContext = state.compile(psiFile); + + ClassFileFactory classFileFactory = state.getFactory(); + + CompileEnvironment.writeToOutputDirectory(classFileFactory, tmpdir.getPath()); + + NamespaceDescriptor namespaceFromSource = (NamespaceDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiFile); + + Assert.assertEquals("test", namespaceFromSource.getName()); + + Disposer.dispose(myTestRootDisposable); + + + jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + + jetCoreEnvironment.addToClasspath(tmpdir); + jetCoreEnvironment.addToClasspath(new File("out/production/stdlib")); + + JetSemanticServices jetSemanticServices = JetSemanticServices.createSemanticServices(jetCoreEnvironment.getProject()); + JavaSemanticServices semanticServices = new JavaSemanticServices(jetCoreEnvironment.getProject(), jetSemanticServices, new BindingTraceContext()); + + JavaDescriptorResolver javaDescriptorResolver = semanticServices.getDescriptorResolver(); + NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace("test"); + + NamespaceComparator.compareNamespaces(namespaceFromSource, namespaceFromClass, false); + } + + public static Test suite() { + return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readKotlinBinaryClass", true, new JetTestCaseBuilder.NamedTestFactory() { + @NotNull + @Override + public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { + return new ReadKotlinBinaryClassTest(file); + } + }); + } + +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java index f3c8838cae5..55299ca3379 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/OverrideImplementMethodsHandler.java @@ -104,12 +104,15 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns if (!returnType.equals(stdlib.getTuple0Type())) { bodyBuilder.append(": ").append(returnType.toString()); } - bodyBuilder.append("{"); + final String initializer = defaultInitializer(returnType, stdlib); if (initializer != null) { - bodyBuilder.append("return " ).append(initializer); + bodyBuilder.append(" = ").append(initializer); } - bodyBuilder.append("}"); + else { + bodyBuilder.append("{").append("throw UnsupportedOperationException()").append("}"); + } + return JetPsiFactory.createFunction(project, bodyBuilder.toString()); } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 9be048cc95a..5f2d750ed5d 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -4,10 +4,15 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Consumer; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetQualifiedExpression; +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lang.psi.JetUserType; +import org.jetbrains.jet.lexer.JetTokens; /** * @author Nikolay Krasko @@ -30,46 +35,44 @@ public class JetCompletionContributor extends CompletionContributor { } CompletionResultSet result = _result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); - JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting( + + if (shouldRunClassNameCompletion(parameters, context)) { + JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting( parameters, result), parameters.getInvocationCount() <= 1, new Consumer() { - @Override - public void consume(LookupElement element) { - _result.addElement(element); - } - }); + + @Override + public void consume(LookupElement element) { + _result.addElement(element); + + } + }); + } } }); } -// @Override -// public void beforeCompletion(@NotNull CompletionInitializationContext context) { -// final PsiFile file = context.getFile(); -// -// if (file instanceof JetFile) { -// autoImport(file, context.getStartOffset() - 1, context.getEditor()); -// } -// } -// -// private static void autoImport(final PsiFile file, int offset, final Editor editor) { -// final CharSequence text = editor.getDocument().getCharsSequence(); -// while (offset > 0 && Character.isJavaIdentifierPart(text.charAt(offset))) offset--; -// if (offset <= 0) return; -// -// while (offset > 0 && Character.isWhitespace(text.charAt(offset))) offset--; -// if (offset <= 0 || text.charAt(offset) != '.') return; -// -// offset--; -// -// while (offset > 0 && Character.isWhitespace(text.charAt(offset))) offset--; -// if (offset <= 0) return; -// -// final JetSimpleNameExpression nameExpression = -// PsiTreeUtil.findElementOfClassAtOffset(file, offset, JetSimpleNameExpression.class, false); -// if (nameExpression == null) return; -// -// final ImportClassFix importClassFix = new ImportClassFix(nameExpression); -// if (importClassFix.isAvailable(file.getProject(), editor, file)) { -// new ImportClassFix(nameExpression).invoke(file.getProject(), editor, file); -// } -// } + private static boolean shouldRunClassNameCompletion(@NotNull CompletionParameters parameters, ProcessingContext context) { + final PsiElement element = parameters.getPosition(); + + if (parameters.getInvocationCount() > 1) { + return true; + } + + if (element.getNode().getElementType() == JetTokens.IDENTIFIER) { + if (element.getParent() instanceof JetSimpleNameExpression) { + JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) element.getParent(); + if (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) != null) { + return false; + } + + if (PsiTreeUtil.getParentOfType(nameExpression, JetUserType.class) != null) { + return true; + } + + return parameters.getInvocationCount() == 1; + } + } + + return false; + } } diff --git a/idea/testData/codeInsight/overrideImplement/genericMethod.kt.after b/idea/testData/codeInsight/overrideImplement/genericMethod.kt.after index f55e765fc4e..8ec50fce31e 100644 --- a/idea/testData/codeInsight/overrideImplement/genericMethod.kt.after +++ b/idea/testData/codeInsight/overrideImplement/genericMethod.kt.after @@ -4,7 +4,5 @@ trait G { class GC() : G { - override fun foo(t: Int): Int { - return 0 - } + override fun foo(t: Int): Int = 0 } diff --git a/idea/testData/codeInsight/overrideImplement/javaInterfaceMethod/foo/Impl.kt.after b/idea/testData/codeInsight/overrideImplement/javaInterfaceMethod/foo/Impl.kt.after index f0e3fb14e49..6554a1fc9fb 100644 --- a/idea/testData/codeInsight/overrideImplement/javaInterfaceMethod/foo/Impl.kt.after +++ b/idea/testData/codeInsight/overrideImplement/javaInterfaceMethod/foo/Impl.kt.after @@ -2,7 +2,5 @@ import foo.Intf class Impl(): Intf { - override fun getFooBar(): String? { - return null - } + override fun getFooBar(): String? = null } diff --git a/idea/testData/codeInsight/overrideImplement/javaParameters/foo/Impl.kt.after b/idea/testData/codeInsight/overrideImplement/javaParameters/foo/Impl.kt.after index a20e435f471..da4335ee7f9 100644 --- a/idea/testData/codeInsight/overrideImplement/javaParameters/foo/Impl.kt.after +++ b/idea/testData/codeInsight/overrideImplement/javaParameters/foo/Impl.kt.after @@ -3,5 +3,6 @@ import foo.Intf class Impl(): Intf { override fun fooBar(i: Int, s: Array?, foo: Any?) { + throw UnsupportedOperationException() } } diff --git a/idea/testData/codeInsight/overrideImplement/traitGenericOverride.kt b/idea/testData/codeInsight/overrideImplement/traitGenericOverride.kt new file mode 100644 index 00000000000..b2387d42ad4 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/traitGenericOverride.kt @@ -0,0 +1,7 @@ +trait G { + fun foo(t : T) : T +} + +class GC() : G { + +} \ No newline at end of file diff --git a/idea/testData/codeInsight/overrideImplement/traitGenericOverride.kt.after b/idea/testData/codeInsight/overrideImplement/traitGenericOverride.kt.after new file mode 100644 index 00000000000..4ef321e0344 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/traitGenericOverride.kt.after @@ -0,0 +1,10 @@ +trait G { + fun foo(t : T) : T +} + +class GC() : G { + + override fun foo(t: T): T { + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/overrideImplement/traitNullableFunction.kt b/idea/testData/codeInsight/overrideImplement/traitNullableFunction.kt new file mode 100644 index 00000000000..e1dcebe7663 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/traitNullableFunction.kt @@ -0,0 +1,7 @@ +trait Some { + fun foo(some : Int?) : Int +} + +class SomeOther : Some { + +} \ No newline at end of file diff --git a/idea/testData/codeInsight/overrideImplement/traitNullableFunction.kt.after b/idea/testData/codeInsight/overrideImplement/traitNullableFunction.kt.after new file mode 100644 index 00000000000..5ad1f152481 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/traitNullableFunction.kt.after @@ -0,0 +1,8 @@ +trait Some { + fun foo(some : Int?) : Int +} + +class SomeOther : Some { + + override fun foo(some: Int?): Int = 0 +} \ No newline at end of file diff --git a/idea/testData/completion/basic/JavaClassNames.kt b/idea/testData/completion/basic/JavaClassNames.kt new file mode 100644 index 00000000000..554921794bc --- /dev/null +++ b/idea/testData/completion/basic/JavaClassNames.kt @@ -0,0 +1,10 @@ +package testing + +// Should show java names by short name +class Hello() { + fun test() { + val a : S + } +} + +// EXIST: SortedMap, Short, Socket \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java index 8d528827964..42d1948e86e 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java @@ -46,6 +46,14 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase { doFileTest(); } + public void testTraitGenericOverride() { + doFileTest(); + } + + public void testTraitNullableFunction() { + doFileTest(); + } + private void doFileTest() { myFixture.configureByFile(getTestName(true) + ".kt"); doImplement(); diff --git a/stdlib/ktSrc/Standard.kt b/stdlib/ktSrc/Standard.kt index 7151a6405e8..132c3ae89e2 100644 --- a/stdlib/ktSrc/Standard.kt +++ b/stdlib/ktSrc/Standard.kt @@ -20,7 +20,7 @@ inline fun java.util.Iterator.iterator() = this /* Helper to make java.util.Enumeration usable in for */ -inline fun java.util.Enumeration.iterator() = object: Iterator { +inline fun java.util.Enumeration.iterator(): Iterator = object: Iterator { override val hasNext: Boolean get() = hasMoreElements() diff --git a/stdlib/src/jet/Iterator.java b/stdlib/src/jet/Iterator.java index f476440b7c4..8e7492f3105 100644 --- a/stdlib/src/jet/Iterator.java +++ b/stdlib/src/jet/Iterator.java @@ -1,6 +1,9 @@ package jet; +import jet.runtime.typeinfo.JetMethod; + public interface Iterator extends JetObject { + @JetMethod(kind = JetMethod.KIND_PROPERTY) boolean getHasNext(); T next (); } diff --git a/stdlib/src/jet/typeinfo/TypeInfoVariance.java b/stdlib/src/jet/typeinfo/TypeInfoVariance.java index 647bb6693a9..ed35747dc35 100644 --- a/stdlib/src/jet/typeinfo/TypeInfoVariance.java +++ b/stdlib/src/jet/typeinfo/TypeInfoVariance.java @@ -1,17 +1,21 @@ package jet.typeinfo; +import org.jetbrains.jet.rt.signature.JetSignatureVariance; + /** * @author alex.tkachman */ public enum TypeInfoVariance { - INVARIANT("") , - IN("in"), - OUT("out"); + INVARIANT("", JetSignatureVariance.INVARIANT) , + IN("in", JetSignatureVariance.IN), + OUT("out", JetSignatureVariance.OUT); private final String label; + private final JetSignatureVariance variance; - TypeInfoVariance(String label) { + TypeInfoVariance(String label, JetSignatureVariance variance) { this.label = label; + this.variance = variance; } @Override diff --git a/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java index 72003cd7b1e..b2075b7f4bc 100644 --- a/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java @@ -6,6 +6,7 @@ import jet.typeinfo.TypeInfoProjection; import jet.typeinfo.TypeInfoVariance; import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; import org.jetbrains.jet.rt.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureVariance; import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import java.lang.reflect.TypeVariable; @@ -176,17 +177,17 @@ class TypeInfoParser { this.projections = new ArrayList(); } - private static TypeInfoVariance parseVariance(char wildcard) { - switch (wildcard) { - case '=': return TypeInfoVariance.INVARIANT; - case '+': return TypeInfoVariance.OUT; - case '-': return TypeInfoVariance.IN; + private static TypeInfoVariance parseVariance(JetSignatureVariance variance) { + switch (variance) { + case INVARIANT: return TypeInfoVariance.INVARIANT; + case OUT: return TypeInfoVariance.OUT; + case IN: return TypeInfoVariance.IN; default: throw new IllegalStateException(); } } @Override - public JetSignatureVisitor visitTypeArgument(final char wildcard) { + public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance wildcard) { final TypeInfoVariance variance = parseVariance(wildcard); return new SignatureParserJetSignatureAdapter(classLoader, signature) { @Override diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java index 5d9878b3110..1f80071f63f 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java @@ -76,7 +76,7 @@ public class JetSignatureAdapter implements JetSignatureVisitor { } @Override - public JetSignatureVisitor visitTypeArgument(char wildcard) { + public JetSignatureVisitor visitTypeArgument(JetSignatureVariance wildcard) { return this; } diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java index 1d6be28930f..f65c34c6806 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java @@ -82,7 +82,7 @@ public class JetSignatureExceptionsAdapter implements JetSignatureVisitor { } @Override - public JetSignatureVisitor visitTypeArgument(char wildcard) { + public JetSignatureVisitor visitTypeArgument(JetSignatureVariance wildcard) { throw new IllegalStateException(); } diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java index 900ec35d2e0..af581935e75 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java @@ -194,12 +194,12 @@ public class JetSignatureReader { case '-': pos = parseType(signature, pos + 1, - v.visitTypeArgument(c)); + v.visitTypeArgument(JetSignatureVariance.parseVariance(c))); break; default: pos = parseType(signature, pos, - v.visitTypeArgument('=')); + v.visitTypeArgument(JetSignatureVariance.INVARIANT)); break; } } diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVariance.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVariance.java new file mode 100644 index 00000000000..2adec59f1ef --- /dev/null +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVariance.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.rt.signature; + +/** + * @author Stepan Koltsov + */ +public enum JetSignatureVariance { + INVARIANT('='), + IN('-'), + OUT('+'), + ; + + private final char c; + + private JetSignatureVariance(char c) { + this.c = c; + } + + public char getC() { + return c; + } + + public static JetSignatureVariance parseVariance(char c) { + switch (c) { + case '=': return INVARIANT; + case '+': return OUT; + case '-': return IN; + default: throw new IllegalStateException(); + } + } +} diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java index 2a16f087c1c..a3548d8ce53 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java @@ -134,7 +134,7 @@ public interface JetSignatureVisitor { * @param wildcard '+', '-' or '='. * @return a non null visitor to visit the signature of the type argument. */ - JetSignatureVisitor visitTypeArgument(char wildcard); + JetSignatureVisitor visitTypeArgument(JetSignatureVariance wildcard); /** * Ends the visit of a signature corresponding to a class or interface type. diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java index 9db334ccefb..f7c6086fac9 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java @@ -171,13 +171,13 @@ public class JetSignatureWriter implements JetSignatureVisitor { } @Override - public JetSignatureWriter visitTypeArgument(final char wildcard) { + public JetSignatureWriter visitTypeArgument(JetSignatureVariance variance) { if (argumentStack % 2 == 0) { ++argumentStack; buf.append('<'); } - if (wildcard != '=') { - buf.append(wildcard); + if (variance.getC() != '=') { + buf.append(variance.getC()); } return this; } diff --git a/testlib/test/CollectionApiCheck.kt b/testlib/test/CollectionApiCheck.kt index 8035f455fba..ba9970fa7f5 100644 --- a/testlib/test/CollectionApiCheck.kt +++ b/testlib/test/CollectionApiCheck.kt @@ -32,4 +32,4 @@ TODO try use delegation here to make sure we implement all the methods in the Tr class ListImpl(coll: ArrayList) : Traversable by coll { } -*/ \ No newline at end of file +*/ diff --git a/testlib/test/CollectionTest.kt b/testlib/test/CollectionTest.kt index d977e68595e..5d2260fbc4d 100644 --- a/testlib/test/CollectionTest.kt +++ b/testlib/test/CollectionTest.kt @@ -5,7 +5,7 @@ package test.collections import std.* import std.io.* import std.util.* -import std.test.* +import stdhack.test.* import java.util.* class CollectionTest() : TestSupport() { @@ -268,4 +268,4 @@ class CollectionTest() : TestSupport() { // assertTrue(IterableWrapper(hashSet(45, 14, 13)).contains(14)) // assertFalse(IterableWrapper(linkedList()).contains(15)) } -} \ No newline at end of file +} diff --git a/testlib/test/GenerateStandardLib.kt b/testlib/test/GenerateStandardLib.kt index 3903cf717d5..0907fd1bd77 100644 --- a/testlib/test/GenerateStandardLib.kt +++ b/testlib/test/GenerateStandardLib.kt @@ -80,4 +80,4 @@ fun main(args: Array) { generateFile(File(outDir, "StandardFromJavaCollections.kt"), "package std", File(srcDir, "JavaCollections.kt")) { it.replaceAll("java.util.Collection", "Iterable").replaceAll("(this.size)", "") } -} \ No newline at end of file +} diff --git a/testlib/test/IoTest.kt b/testlib/test/IoTest.kt index 29d3f8671a4..b910831195a 100644 --- a/testlib/test/IoTest.kt +++ b/testlib/test/IoTest.kt @@ -1,6 +1,6 @@ package test.collections -import std.test.* +import stdhack.test.* import std.io.* import std.util.* diff --git a/testlib/test/ListTest.kt b/testlib/test/ListTest.kt index 91cf6ff367d..e45177d4d91 100644 --- a/testlib/test/ListTest.kt +++ b/testlib/test/ListTest.kt @@ -1,6 +1,6 @@ package test.collections -import std.test.* +import stdhack.test.* // TODO can we avoid importing all this stuff by default I wonder? // e.g. making println and the collection builder methods public by default? @@ -27,4 +27,4 @@ class ListTest() : TestSupport() { val t = data.last assertEquals("bar", t) } -} \ No newline at end of file +} diff --git a/testlib/test/MapTest.kt b/testlib/test/MapTest.kt index 6b8e41495de..035e9e01269 100644 --- a/testlib/test/MapTest.kt +++ b/testlib/test/MapTest.kt @@ -1,6 +1,6 @@ package test.collections -import std.test.* +import stdhack.test.* // TODO can we avoid importing all this stuff by default I wonder? // e.g. making println and the collection builder methods public by default? @@ -49,4 +49,4 @@ class MapTest() : TestSupport() { assertEquals(map.size(), 1) assertEquals("James", map["name"]) } -} \ No newline at end of file +} diff --git a/testlib/test/OldStdlibTest.kt b/testlib/test/OldStdlibTest.kt index 1feb24c45f3..9ea2f7aeeae 100644 --- a/testlib/test/OldStdlibTest.kt +++ b/testlib/test/OldStdlibTest.kt @@ -3,7 +3,7 @@ package test.collections import std.* import std.io.* import std.util.* -import std.test.* +import stdhack.test.* import java.util.* import java.io.* diff --git a/testlib/test/SetTest.kt b/testlib/test/SetTest.kt index ee03be580a6..5d8eb61a4ad 100644 --- a/testlib/test/SetTest.kt +++ b/testlib/test/SetTest.kt @@ -3,7 +3,7 @@ package test.collections import std.* import std.io.* import std.util.* -import std.test.* +import stdhack.test.* import java.util.* class SetTest() : TestSupport() { @@ -67,4 +67,4 @@ class SetTest() : TestSupport() { assertEquals(arrayList(3, 3), lengths) } -} \ No newline at end of file +} diff --git a/testlib/test/StandardCollectionTest.kt b/testlib/test/StandardCollectionTest.kt index b1c554ce133..8d8631c186a 100644 --- a/testlib/test/StandardCollectionTest.kt +++ b/testlib/test/StandardCollectionTest.kt @@ -1,7 +1,7 @@ package test.collections import std.* -import std.test.* +import stdhack.test.* class StandardCollectionTest() : TestSupport() { @@ -21,4 +21,4 @@ class StandardCollectionTest() : TestSupport() { } } */ -} \ No newline at end of file +} diff --git a/testlib/test/Test.kt b/testlib/test/Test.kt index 7c433ccae60..7267920168f 100644 --- a/testlib/test/Test.kt +++ b/testlib/test/Test.kt @@ -1,4 +1,4 @@ -package std.test +package stdhack.test import std.io.* import std.util.* @@ -149,4 +149,4 @@ class KotlinTestRunner() : Runner() { // TODO no annotations yet? //@RunWith(KotlinTestRunner) abstract class TestSupport() : TestCase() { -} \ No newline at end of file +} diff --git a/testlib/test/TestDslExample.kt b/testlib/test/TestDslExample.kt index 3f8c1b59aff..1f94fe05e14 100644 --- a/testlib/test/TestDslExample.kt +++ b/testlib/test/TestDslExample.kt @@ -1,7 +1,7 @@ package testDslExample import std.io.* -import std.test.* +import stdhack.test.* import junit.framework.* import junit.textui.TestRunner