Merge branch 'master' of github.com:JetBrains/kotlin
This commit is contained in:
+1
-9
@@ -34,14 +34,6 @@
|
||||
<echoprop prop="user.home"/>
|
||||
<echoprop prop="user.dir"/>
|
||||
|
||||
<target name="unzipDependencies">
|
||||
<unzip dest="ideaSDK">
|
||||
<fileset dir="ideaSDK" includes="ideaIC*.zip"/>
|
||||
</unzip>
|
||||
|
||||
<delete dir="ideaSDK" includes="ideaIC*.zip"/>
|
||||
</target>
|
||||
|
||||
<target name="cleanupArtifacts">
|
||||
<delete dir="${artifact.output.path}" includes="*"/>
|
||||
</target>
|
||||
@@ -100,7 +92,7 @@
|
||||
<delete file="${compiler.version.java.bk}" quiet="true"/>
|
||||
</target>
|
||||
|
||||
<target name="pre_build" depends="writeVersionToTemplateFiles, cleanupArtifacts, unzipDependencies, dist, generateInjectors">
|
||||
<target name="pre_build" depends="writeVersionToTemplateFiles, cleanupArtifacts, dist, generateInjectors">
|
||||
</target>
|
||||
|
||||
<target name="zipArtifact">
|
||||
|
||||
Executable → Regular
Executable → Regular
@@ -1,173 +0,0 @@
|
||||
{toc:style=disc|indent=20px}
|
||||
h1. Ant
|
||||
|
||||
|
||||
h2. Defining {{*<kotlinc>*}} task using local Kotlin setup
|
||||
|
||||
One way to define Ant's {{*<kotlinc>*}} task is by using your local Kotlin setup and {{*KOTLIN_HOME*}} environment variable:
|
||||
|
||||
{code:xml}
|
||||
<property environment="env"/>
|
||||
<taskdef resource = "org/jetbrains/jet/buildtools/ant/antlib.xml">
|
||||
<classpath>
|
||||
<fileset dir = "${env.KOTLIN_HOME}/lib" includes = "*.jar"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
{code}
|
||||
|
||||
|
||||
Alternatively, you can copy all jar files from Kotlin distribution to Ant's {{"lib"}} folder.
|
||||
|
||||
|
||||
h2. Defining {{*<kotlinc>*}} task using Ivy
|
||||
|
||||
Another way to define Ant's {{*<kotlinc>*}} task is by using Ivy:
|
||||
|
||||
{{"ivyconf.xml"}}:
|
||||
|
||||
{code:xml}
|
||||
<ivysettings>
|
||||
<property name='ivy.checksums' value=''/>
|
||||
<caches defaultCache="${user.home}/.ivy/cache"/>
|
||||
<settings defaultResolver="sonatype-repo"/>
|
||||
<statuses>
|
||||
<status name='integration' integration='true'/>
|
||||
</statuses>
|
||||
<resolvers>
|
||||
<url name="sonatype-repo" m2compatible="true">
|
||||
<artifact pattern="https://oss.sonatype.org/content/repositories/central/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
|
||||
</url>
|
||||
<url name='jetbrains-repo' alwaysCheckExactRevision='yes' checkmodified='true'>
|
||||
<ivy pattern='http://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/teamcity-ivy.xml'/>
|
||||
<artifact pattern='http://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/[artifact](.[ext])'/>
|
||||
</url>
|
||||
</resolvers>
|
||||
<modules>
|
||||
<module organisation='org' name='bt343' matcher='regexp' resolver='jetbrains-repo'/>
|
||||
<module organisation='org' name='bt344' matcher='regexp' resolver='jetbrains-repo'/>
|
||||
</modules>
|
||||
</ivysettings>
|
||||
{code}
|
||||
|
||||
{{"ivy.xml"}}:
|
||||
|
||||
{code:xml}
|
||||
<ivy-module version="1.3">
|
||||
<info organisation="com.jetbrains" module="kotlin"/>
|
||||
<dependencies>
|
||||
<!-- Kotlin build: http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt344 -->
|
||||
<!-- http://teamcity.jetbrains.com/guestAuth/repository/download/bt344/latest.lastSuccessful/teamcity-ivy.xml -->
|
||||
<dependency org="org" name="bt344" rev="latest.lastSuccessful">
|
||||
<include ext="jar" matcher="exactOrRegexp"/>
|
||||
</dependency>
|
||||
<!-- IDEA build: http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt343 -->
|
||||
<!-- http://teamcity.jetbrains.com/guestAuth/repository/download/bt343/latest.lastSuccessful/teamcity-ivy.xml -->
|
||||
<dependency org="org" name="bt343" rev="latest.lastSuccessful">
|
||||
<include name="core/.*" ext="jar" matcher="exactOrRegexp"/>
|
||||
</dependency>
|
||||
<dependency org="asm" name="asm-util" rev="3.3.1"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
{code}
|
||||
|
||||
{{"build.xml"}}:
|
||||
|
||||
{code:xml}
|
||||
<!-- Copy Ivy jar and all its dependencies to Ant's "lib": http://www.apache.org/dist/ant/ivy/2.2.0/apache-ivy-2.2.0-bin-with-deps.zip -->
|
||||
<taskdef uri="antlib:org.apache.ivy.ant" resource="org/apache/ivy/ant/antlib.xml"/>
|
||||
<ivy:configure file="${basedir}/ivyconf.xml"/>
|
||||
<ivy:resolve file="${basedir}/ivy.xml"/>
|
||||
<ivy:cachepath pathid="kotlin.classpath" organisation="org" revision="latest.lastSuccessful"/>
|
||||
|
||||
<taskdef resource = "org/jetbrains/jet/buildtools/ant/antlib.xml">
|
||||
<classpath>
|
||||
<path refid="kotlin.classpath"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
{code}
|
||||
|
||||
h2. {{*<kotlinc>*}} attributes
|
||||
|
||||
|
||||
|| {align:center}Name{align} || {align:center}Description{align} || {align:center}Required{align} || {align:center}Default Value{align} ||
|
||||
| {align:center}{{*src*}}{align} | Kotlin source file or directory to compile | {{"src"}} or {{"module"}} needs to be specified | |
|
||||
| {align:center}{{*module*}}{align} | Kotlin [module|http://confluence.jetbrains.net/display/Kotlin/Modules+and+Compilation] to compile | {{"src"}} or {{"module"}} needs to be specified | |
|
||||
| {align:center}{{*output*}}{align} | Destination directory | If {{"src"}} is used - {{"output"}} or {{"jar"}} needs to be specified | |
|
||||
| {align:center}{{*jar*}}{align} | Destination jar file | If {{"src"}} is used - {{"output"}} or {{"jar"}} needs to be specified
|
||||
If {{"module"}} is used - only {{"jar"}} can be specified or it can be omitted | {align:center}{{"moduleName.jar"}}{align} |
|
||||
| {align:center}{{*classpath*}}{align} | Compilation class path | {align:center}{{false}}{align} | |
|
||||
| {align:center}{{*classpathref*}}{align} | Compilation class path reference | {align:center}{{false}}{align} | |
|
||||
| {align:center}{{*stdlib*}}{align} | Path to {{"kotlin-runtime.jar"}} | {align:center}{{false}}{align} | {align:center}{{""}}{align} |
|
||||
| {align:center}{{*includeRuntime*}}{align} | If {{"jar"}} is used - whether Kotlin runtime library is included | {align:center}{{false}}{align} | {align:center}{{true}}{align} |
|
||||
|
||||
|
||||
{{<kotlinc>}} accepts a nested {{<classpath>}} element, similarly to [{{<javac>}}|http://evgeny-goldin.org/javadoc/ant/Tasks/javac.html].
|
||||
|
||||
|
||||
h2. Examples
|
||||
|
||||
|
||||
{code:xml}
|
||||
<kotlinc src = "test/longer-examples/Bottles.kt" output = "dist"/>
|
||||
<kotlinc src = "test/longer-examples" output = "dist"/>
|
||||
|
||||
<kotlinc src = "test/longer-examples/Bottles.kt" jar = "dist.jar"/>
|
||||
<kotlinc src = "test/longer-examples" jar = "dist.jar"/>
|
||||
|
||||
<kotlinc module = "test/modules/smoke/Smoke.kts" jar = "dist.jar"/>
|
||||
<kotlinc module = "test/modules/smoke/Smoke.kts"/> => "smoke.jar"
|
||||
{code}
|
||||
|
||||
{{"Smoke.kts"}}:
|
||||
|
||||
{code}
|
||||
import kotlin.modules.*
|
||||
|
||||
fun project() {
|
||||
module("smoke") {
|
||||
sources += "Smoke.kt"
|
||||
}
|
||||
}
|
||||
{code}
|
||||
{{"Smoke.kt"}}:
|
||||
|
||||
{code}
|
||||
package Smoke
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
print("${args[0]}|${args[1]}|${args[2]}")
|
||||
}
|
||||
{code}
|
||||
|
||||
|
||||
h3. Classpath examples
|
||||
|
||||
|
||||
{code:xml}
|
||||
<path id="junit-jar">
|
||||
<fileset file="lib/junit.jar"/>
|
||||
</path>
|
||||
|
||||
<kotlinc src = "src/unit-tests" jar = "tests.jar" classpath = "lib/junit.jar"/>
|
||||
|
||||
<kotlinc src = "src/unit-tests" jar = "tests.jar" classpathref = "junit-jar"/>
|
||||
|
||||
<kotlinc src = "src/unit-tests" jar = "tests.jar">
|
||||
<classpath>
|
||||
<path refid="junit-jar"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
|
||||
<kotlinc src = "src/unit-tests" jar = "tests.jar">
|
||||
<classpath>
|
||||
<fileset file="lib/junit.jar"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
{code}
|
||||
|
||||
|
||||
h1. Maven
|
||||
|
||||
See [{{"kotlin-maven-plugin"}}|http://evgeny-goldin.com/wiki/Kotlin-maven-plugin].
|
||||
|
||||
h1. Gradle
|
||||
@@ -4,13 +4,23 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/core/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/ant/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="cli" />
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="runtime" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../dependencies/ant.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="idea-full" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -1,503 +0,0 @@
|
||||
<project name="build-tools" default="buildToolsJar" xmlns:ivy="antlib:org.apache.ivy.ant">
|
||||
|
||||
<property name="tests-dir" location="${output}/ant-test/build-tools-test"/>
|
||||
<property name="tests-jar" location="${tests-dir}/out.jar"/>
|
||||
<property name="junit-jar" location="${basedir}/libraries/lib/junit-4.9.jar"/>
|
||||
<property name="failonerror" value="true"/> <!-- Whether invoking compiled classes should file on error -->
|
||||
<property name="use-ivy" value="false"/> <!-- Whether Ivy should be used to define "kotlin.classpath" and <kotlinc> task -->
|
||||
<!-- Override with "-Duse-ivy=true" -->
|
||||
|
||||
|
||||
<!-- http://ant-contrib.sourceforge.net/tasks/tasks/index.html -->
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml">
|
||||
<classpath>
|
||||
<pathelement location="${basedir}/build-tools/lib/ant-contrib-1.0b3.jar"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
|
||||
|
||||
<path id="junit-jar">
|
||||
<fileset file="${junit-jar}"/>
|
||||
</path>
|
||||
|
||||
|
||||
<!-- Verifies file or directory specified exists -->
|
||||
<macrodef name="verify-exists">
|
||||
<attribute name="file"/>
|
||||
<attribute name="type" default="dir"/>
|
||||
<sequential>
|
||||
<if>
|
||||
<available file="@{file}" type="@{type}"/>
|
||||
<then>
|
||||
<echo>[@{file}] of type [@{type}] exists</echo>
|
||||
</then>
|
||||
<else>
|
||||
<fail message="[@{file}] of type [@{type}] is not found!"/>
|
||||
</else>
|
||||
</if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Defines "kotlin.classpath" using ${kotlin-home} -->
|
||||
<macrodef name="kotlin-home-setup">
|
||||
<sequential>
|
||||
<if>
|
||||
<and>
|
||||
<available file="${kotlin-home}/lib/kotlin-build-tools.jar" type="file"/>
|
||||
<available file="${kotlin-home}/lib/kotlin-compiler.jar" type="file"/>
|
||||
<available file="${kotlin-home}/lib/kotlin-runtime.jar" type="file"/>
|
||||
</and>
|
||||
<then>
|
||||
<echo>[${kotlin-home}/lib] jars found, defining "kotlin.classpath"</echo>
|
||||
<path id="kotlin.classpath">
|
||||
<fileset dir = "${kotlin-home}/lib" includes = "*.jar"/>
|
||||
</path>
|
||||
</then>
|
||||
<else>
|
||||
<!-- Creating and unpacking the distribution archive to make sure it's Ok -->
|
||||
<echo>[${kotlin-home}/lib] jars *not* found, creating distribution zip</echo>
|
||||
|
||||
<antcall target = "zip"/>
|
||||
<verify-exists file="${output}/${output.name}.zip" type="file"/>
|
||||
|
||||
<!-- Sometimes deleting "dist/kotlinc/lib/alt/kotlin-jdk-headers.jar" fails -->
|
||||
<delete dir = "${kotlin-home}" failonerror="false"/>
|
||||
<mkdir dir = "${kotlin-home}"/>
|
||||
<unzip src = "${output}/${output.name}.zip" dest="${output}"/>
|
||||
|
||||
<verify-exists file="${kotlin-home}/lib"/>
|
||||
<verify-exists file="${kotlin-home}/lib/kotlin-build-tools.jar" type="file"/>
|
||||
<verify-exists file="${kotlin-home}/lib/kotlin-compiler.jar" type="file"/>
|
||||
<verify-exists file="${kotlin-home}/lib/kotlin-runtime.jar" type="file"/>
|
||||
|
||||
<kotlin-home-setup/>
|
||||
</else>
|
||||
</if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Defines "kotlin.classpath" and <kotlinc> task -->
|
||||
<macrodef name="define-kotlinc">
|
||||
<sequential>
|
||||
<if>
|
||||
<istrue value="${use-ivy}"/>
|
||||
<then>
|
||||
<!-- Defining "kotlin.classpath" with Ivy -->
|
||||
<taskdef uri="antlib:org.apache.ivy.ant" resource="org/apache/ivy/ant/antlib.xml"/>
|
||||
<ivy:configure file="${basedir}/build-tools/ivyconf.xml"/>
|
||||
<ivy:resolve file="${basedir}/build-tools/ivy.xml"/>
|
||||
<ivy:cachepath pathid="kotlin.classpath" organisation="org" revision="latest.lastSuccessful"/>
|
||||
</then>
|
||||
<else>
|
||||
<!-- Defining "kotlin.classpath" with ${kotlin-home} -->
|
||||
<kotlin-home-setup/>
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<taskdef resource = "org/jetbrains/jet/buildtools/ant/antlib.xml">
|
||||
<classpath>
|
||||
<path refid="kotlin.classpath"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<!-- Deletes all previously compiled files -->
|
||||
<macrodef name="cleanup">
|
||||
<sequential>
|
||||
<delete dir = "${tests-dir}" failonerror="true"/>
|
||||
<delete file = "${tests-jar}" failonerror="true"/>
|
||||
<mkdir dir = "${tests-dir}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Runs <kotlinc> create a *.class files in directory -->
|
||||
<macrodef name="kotlinc-dir">
|
||||
<attribute name="src"/>
|
||||
<attribute name="stdlib" default=""/>
|
||||
|
||||
<sequential>
|
||||
<cleanup/>
|
||||
<kotlinc src = "@{src}" output = "${tests-dir}" stdlib = "@{stdlib}" classpathref="junit-jar"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Runs <kotlinc> to create a *.class files in a jar -->
|
||||
<macrodef name="kotlinc-jar">
|
||||
<attribute name="src" default=""/>
|
||||
<attribute name="module" default=""/>
|
||||
<attribute name="includeRuntime" default="true"/>
|
||||
<attribute name="stdlib" default=""/>
|
||||
<attribute name="jar" default="${tests-jar}"/>
|
||||
<sequential>
|
||||
|
||||
<cleanup/>
|
||||
|
||||
<if>
|
||||
<equals arg1="@{module}" arg2=""/>
|
||||
<then>
|
||||
<kotlinc src = "@{src}" jar = "@{jar}" includeRuntime = "@{includeRuntime}" stdlib = "@{stdlib}">
|
||||
<classpath>
|
||||
<path refid="junit-jar"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
</then>
|
||||
<elseif>
|
||||
<equals arg1="@{jar}" arg2=""/>
|
||||
<then>
|
||||
<kotlinc module = "@{module}" includeRuntime = "@{includeRuntime}" stdlib = "@{stdlib}">
|
||||
<classpath>
|
||||
<fileset file="${junit-jar}"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
</then>
|
||||
</elseif>
|
||||
<else>
|
||||
<kotlinc module = "@{module}" jar = "@{jar}" includeRuntime = "@{includeRuntime}" stdlib = "@{stdlib}" classpath="${junit-jar}"/>
|
||||
</else>
|
||||
</if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Runs <java> for compiled classes and verifies the output correctness -->
|
||||
<macrodef name="run-java">
|
||||
<attribute name="out"/>
|
||||
<attribute name="classname" default="namespace"/>
|
||||
<attribute name="args" default=""/>
|
||||
<attribute name="equals" default="true"/> <!-- Whether strict equality of output to @{out} required -->
|
||||
<attribute name="run-jar" default="false"/> <!-- Whether to run compiled classes or a jar file -->
|
||||
<attribute name="jar" default="${tests-jar}"/> <!-- Jar to use for classpath if "run-jar" is "true" -->
|
||||
<sequential>
|
||||
<var name = "java-out" unset = "true"/>
|
||||
|
||||
<if>
|
||||
<istrue value="@{run-jar}"/>
|
||||
<then>
|
||||
<echo>Running [@{classname}], classpath = "@{jar}"</echo>
|
||||
<java outputproperty = "java-out"
|
||||
classname = "@{classname}"
|
||||
failonerror = "${failonerror}">
|
||||
<classpath>
|
||||
<pathelement path = "@{jar}"/>
|
||||
</classpath>
|
||||
<arg line = "@{args}"/>
|
||||
</java>
|
||||
</then>
|
||||
<else>
|
||||
<echo>Running [@{classname}], classpath = "${tests-dir}"</echo>
|
||||
<java outputproperty = "java-out"
|
||||
classname = "@{classname}"
|
||||
failonerror = "${failonerror}">
|
||||
<classpath>
|
||||
<pathelement path = "${tests-dir}"/>
|
||||
<path refid = "kotlin.classpath"/>
|
||||
</classpath>
|
||||
<arg line = "@{args}"/>
|
||||
</java>
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<or>
|
||||
<equals arg1="${java-out}" arg2="@{out}"/>
|
||||
<and>
|
||||
<isfalse value="@{equals}"/>
|
||||
<contains string="${java-out}" substring="@{out}"/>
|
||||
</and>
|
||||
</or>
|
||||
<then>
|
||||
<echo>${java-out}</echo>
|
||||
</then>
|
||||
<elseif>
|
||||
<istrue value="${failonerror}"/>
|
||||
<then>
|
||||
<fail message="Test failed: '${java-out}' (received) != '@{out}' (expected), equals = [@{equals}]"/>
|
||||
</then>
|
||||
</elseif>
|
||||
</if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Compiles "Hello.kt" as a single file and a folder, runs <java> and verifies the output -->
|
||||
<macrodef name="hello-test">
|
||||
<attribute name="root"/>
|
||||
<attribute name="args" default=""/>
|
||||
<attribute name="out"/>
|
||||
<sequential>
|
||||
<kotlinc-dir src = "@{root}/Hello.kt"/>
|
||||
<run-java args = "@{args}" out = "@{out}"/>
|
||||
|
||||
<kotlinc-dir src = "@{root}"/>
|
||||
<run-java args = "@{args}" out = "@{out}"/>
|
||||
|
||||
<kotlinc-jar src = "@{root}/Hello.kt"/>
|
||||
<run-java args = "@{args}" out = "@{out}" run-jar="true"/>
|
||||
|
||||
<kotlinc-jar src = "@{root}"/>
|
||||
<run-java args = "@{args}" out = "@{out}" run-jar="true"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Runs all Hello tests -->
|
||||
<macrodef name="hello-tests">
|
||||
<sequential>
|
||||
<hello-test root="${basedir}/build-tools/test/hello/1" out="Hello, world!"/>
|
||||
<hello-test root="${basedir}/build-tools/test/hello/2" args="Kotlin-Developer" out="Hello, Kotlin-Developer!"/>
|
||||
<hello-test root="${basedir}/build-tools/test/hello/3" args="Mickey-Mouse" out="Hello, Mickey-Mouse!"/>
|
||||
<hello-test root="${basedir}/build-tools/test/hello/4" args="IT" out="Ciao!"/>
|
||||
<hello-test root="${basedir}/build-tools/test/hello/4" args="FR" out="Salut!"/>
|
||||
<hello-test root="${basedir}/build-tools/test/hello/5" args="Donald-Duck" out="Hello, Donald-Duck!"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Compiles, runs and verifies the output of web demo longer examples -->
|
||||
<macrodef name="longer-examples-tests">
|
||||
<sequential>
|
||||
<kotlinc-dir src = "${basedir}/build-tools/test/longer-examples"/>
|
||||
|
||||
<run-java classname = "bottles.namespace" equals="false" out="12 bottles of beer on the wall, 12 bottles of beer."/>
|
||||
<run-java classname = "life.namespace" equals="false" out="*** ** ** ***"/>
|
||||
<!--<run-java classname = "maze.namespace" equals="false" out="O ~OOOOOOOOOOOOOO"/>-->
|
||||
<!--<run-java classname = "html.namespace" equals="false" out="<a href="http://jetbrains.com/kotlin">"/>-->
|
||||
|
||||
<kotlinc-jar src = "${basedir}/build-tools/test/longer-examples"/>
|
||||
|
||||
<run-java classname = "bottles.namespace" equals="false" run-jar="true" out="12 bottles of beer on the wall, 12 bottles of beer."/>
|
||||
<run-java classname = "life.namespace" equals="false" run-jar="true" out="*** ** ** ***"/>
|
||||
<!--<run-java classname = "maze.namespace" equals="false" run-jar="true" out="O ~OOOOOOOOOOOOOO"/>-->
|
||||
<!--<run-java classname = "html.namespace" equals="false" run-jar="true" out="<a href="http://jetbrains.com/kotlin">"/>-->
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Compiles and runs a Kotlin module -->
|
||||
<macrodef name="module-tests">
|
||||
<sequential>
|
||||
<!-- Module => Explicit Jar -->
|
||||
<kotlinc-jar module="${basedir}/build-tools/test/modules/smoke/Smoke.kts"/>
|
||||
<run-java classname = "Smoke.namespace" run-jar = "true" args = "1 2 3" out = "1|2|3"/>
|
||||
|
||||
<!-- Module => Default Jar -->
|
||||
<kotlinc-jar module="${basedir}/build-tools/test/modules/smoke/Smoke.kts" jar=""/>
|
||||
<move file="${basedir}/build-tools/test/modules/smoke/smoke.jar" todir="${tests-dir}"/>
|
||||
<run-java classname = "Smoke.namespace" run-jar = "true" args = "1 2 3" out = "1|2|3" jar="${tests-dir}/smoke.jar"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Runs JUnit single test or batch tests -->
|
||||
<macrodef name="run-junit">
|
||||
<attribute name="classpath"/>
|
||||
<attribute name="test" default=""/>
|
||||
<sequential>
|
||||
|
||||
<path id="junit-classpath">
|
||||
<path refid="junit-jar"/>
|
||||
<path refid="kotlin.classpath"/>
|
||||
<pathelement location="@{classpath}"/>
|
||||
</path>
|
||||
|
||||
<if>
|
||||
<equals arg1="@{test}" arg2=""/>
|
||||
<then>
|
||||
<!-- Batch tests -->
|
||||
<if>
|
||||
<matches string="@{classpath}" pattern="\.jar$"/>
|
||||
<then>
|
||||
<!-- Batch tests from a jar -->
|
||||
<echo>Running JUnit: classpath = "@{classpath}" (Jar)</echo>
|
||||
<junit haltonfailure="true">
|
||||
<classpath>
|
||||
<path refid="junit-classpath"/>
|
||||
</classpath>
|
||||
<formatter type="plain" usefile="false"/>
|
||||
<batchtest>
|
||||
<zipfileset src="@{classpath}" includes="**/*Test.class" excludes="**/BuiltTest.class"/>
|
||||
</batchtest>
|
||||
</junit>
|
||||
</then>
|
||||
<else>
|
||||
<!-- Batch tests from a dir -->
|
||||
<echo>Running JUnit: classpath = "@{classpath}" (Dir)</echo>
|
||||
<junit haltonfailure="true">
|
||||
<classpath>
|
||||
<path refid="junit-classpath"/>
|
||||
</classpath>
|
||||
<formatter type="plain" usefile="false"/>
|
||||
<batchtest>
|
||||
<fileset dir="@{classpath}" includes="**/*Test.class" excludes="**/BuiltTest.class"/>
|
||||
</batchtest>
|
||||
</junit>
|
||||
</else>
|
||||
</if>
|
||||
</then>
|
||||
<else>
|
||||
<!-- Single test -->
|
||||
<echo>Running JUnit: test = "@{test}", classpath = "@{classpath}"</echo>
|
||||
<junit haltonfailure="true">
|
||||
<classpath>
|
||||
<path refid="junit-classpath"/>
|
||||
</classpath>
|
||||
<formatter type="plain" usefile="false"/>
|
||||
<test name="@{test}"/>
|
||||
</junit>
|
||||
</else>
|
||||
</if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Runs all JUnit tests, first each test separately and then all of them in a batch mode -->
|
||||
<macrodef name="testlib-junit-tests">
|
||||
<attribute name="classpath"/>
|
||||
<sequential>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.CollectionTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.IoTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.ListTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.MapTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.OldStdlibTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.SetTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.collections.StandardCollectionTest"/>
|
||||
<run-junit classpath="@{classpath}" test="test.stdlib.issues.StdLibIssuesTest"/>
|
||||
<run-junit classpath="@{classpath}" test="testString.StringTest"/>
|
||||
|
||||
<run-junit classpath="@{classpath}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Compiles "testlib" Kotlin tests (dir/module => dir/jar) and runs all JUnit tests resulted -->
|
||||
<macrodef name="testlib-tests">
|
||||
<sequential>
|
||||
<!-- Dir => Dir -->
|
||||
<kotlinc-dir src = "${basedir}/libraries/stdlib/test"/>
|
||||
<testlib-junit-tests classpath = "${tests-dir}"/>
|
||||
|
||||
<!-- Dir => Jar -->
|
||||
<kotlinc-jar src = "${basedir}/libraries/stdlib/test"/>
|
||||
<testlib-junit-tests classpath = "${tests-jar}"/>
|
||||
|
||||
<!-- Module => Explicit Jar -->
|
||||
<kotlinc-jar module = "${basedir}/libraries/stdlib/testModule.kt"/>
|
||||
<testlib-junit-tests classpath = "${tests-jar}"/>
|
||||
|
||||
<!-- Module => Default Jar -->
|
||||
<kotlinc-jar module = "${basedir}/libraries/stdlib/testModule.kt" jar=""/>
|
||||
<move file="${basedir}/libraries/testlib/testlib.jar" todir="${tests-dir}"/>
|
||||
<testlib-junit-tests classpath = "${tests-dir}/testlib.jar"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Verifies build fails if <kotlinc> fails -->
|
||||
<macrodef name="compilation-fail-test">
|
||||
<sequential>
|
||||
<var name="failed" value="false"/>
|
||||
<trycatch property="error-message" reference="bar">
|
||||
<try>
|
||||
<!-- Should fail -->
|
||||
<kotlinc-dir src = "${basedir}/build-tools/test/compilation-fail"/>
|
||||
</try>
|
||||
<catch>
|
||||
<var name="failed" value="true"/>
|
||||
<echo>"ERROR:" was expected here</echo>
|
||||
</catch>
|
||||
</trycatch>
|
||||
<if>
|
||||
<isfalse value="${failed}"/>
|
||||
<then>
|
||||
<fail message="kotlinc-dir: compilation should have failed!"/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<var name="failed" value="false"/>
|
||||
<trycatch property="error-message" reference="bar">
|
||||
<try>
|
||||
<!-- Should fail -->
|
||||
<kotlinc-jar src = "${basedir}/build-tools/test/compilation-fail"/>
|
||||
</try>
|
||||
<catch>
|
||||
<var name="failed" value="true"/>
|
||||
<echo>"ERROR:" was expected here</echo>
|
||||
</catch>
|
||||
</trycatch>
|
||||
<if>
|
||||
<isfalse value="${failed}"/>
|
||||
<then>
|
||||
<fail message="kotlinc-jar: compilation should have failed!"/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<var name="failed" value="false"/>
|
||||
<trycatch property="error-message" reference="bar">
|
||||
<try>
|
||||
<!-- Should fail -->
|
||||
<kotlinc-jar module = "${basedir}/build-tools/test/compilation-fail/Smoke.kts"/>
|
||||
</try>
|
||||
<catch>
|
||||
<var name="failed" value="true"/>
|
||||
<echo>"ERROR:" was expected here</echo>
|
||||
</catch>
|
||||
</trycatch>
|
||||
<if>
|
||||
<isfalse value="${failed}"/>
|
||||
<then>
|
||||
<fail message="kotlinc-jar: compilation should have failed!"/>
|
||||
</then>
|
||||
</if>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
||||
<!-- Creates build tools distribution jar -->
|
||||
<target name="buildToolsJar" depends="compile">
|
||||
<mkdir dir ="${output}/classes/buildTools"/>
|
||||
<javac destdir="${output}/classes/buildTools" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src>
|
||||
<dirset dir="${basedir}/build-tools">
|
||||
<include name="core/src"/>
|
||||
<include name="ant/src"/>
|
||||
<include name="maven/src"/>
|
||||
<include name="gradle/src"/>
|
||||
</dirset>
|
||||
<dirset dir="${basedir}/js">
|
||||
<include name="js.translator/src"/>
|
||||
</dirset>
|
||||
<!--
|
||||
<dirset dir="${basedir}/j2k">
|
||||
<include name="src"/>
|
||||
</dirset>
|
||||
-->
|
||||
</src>
|
||||
<compilerarg value="-Xlint:all"/>
|
||||
<classpath>
|
||||
<path refid = "classpath.kotlin"/>
|
||||
<fileset dir = "${ant.home}/lib" includes="*.jar"/>
|
||||
<fileset dir = "${basedir}/js/js.translator/lib" includes="*.jar"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-build-tools.jar">
|
||||
<fileset dir = "${output}/classes/buildTools"/>
|
||||
<fileset dir = "${basedir}/build-tools/ant/src" includes="**/*.xml"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- Tests build tools distribution jar -->
|
||||
<target name="buildToolsTest">
|
||||
<define-kotlinc/>
|
||||
<hello-tests/>
|
||||
<longer-examples-tests/>
|
||||
<module-tests/>
|
||||
<!--<testlib-tests/>-->
|
||||
<compilation-fail-test/>
|
||||
</target>
|
||||
</project>
|
||||
@@ -1,20 +0,0 @@
|
||||
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||
<!-- Configuring Ant to work with TeamCity Ivy repo: http://goo.gl/foaTg -->
|
||||
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||
|
||||
<ivy-module version="1.3">
|
||||
<info organisation="com.jetbrains" module="kotlin"/>
|
||||
<dependencies>
|
||||
<!-- Kotlin build: http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt344 -->
|
||||
<!-- http://teamcity.jetbrains.com/guestAuth/repository/download/bt344/latest.lastSuccessful/teamcity-ivy.xml -->
|
||||
<dependency org="org" name="bt344" rev="latest.lastSuccessful">
|
||||
<include ext="jar" matcher="exactOrRegexp"/>
|
||||
</dependency>
|
||||
<!-- IDEA build: http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt343 -->
|
||||
<!-- http://teamcity.jetbrains.com/guestAuth/repository/download/bt343/latest.lastSuccessful/teamcity-ivy.xml -->
|
||||
<dependency org="org" name="bt343" rev="latest.lastSuccessful">
|
||||
<include name="core/.*" ext="jar" matcher="exactOrRegexp"/>
|
||||
</dependency>
|
||||
<dependency org="asm" name="asm-util" rev="3.3.1"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
@@ -1,25 +0,0 @@
|
||||
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||
<!-- Configuring Ant to work with TeamCity Ivy repo: http://goo.gl/foaTg -->
|
||||
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||
|
||||
<ivysettings>
|
||||
<property name='ivy.checksums' value=''/>
|
||||
<caches defaultCache="${user.home}/.ivy/cache"/>
|
||||
<settings defaultResolver="sonatype-repo"/>
|
||||
<statuses>
|
||||
<status name='integration' integration='true'/>
|
||||
</statuses>
|
||||
<resolvers>
|
||||
<url name="sonatype-repo" m2compatible="true">
|
||||
<artifact pattern="https://oss.sonatype.org/content/repositories/central/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
|
||||
</url>
|
||||
<url name='jetbrains-repo' alwaysCheckExactRevision='yes' checkmodified='true'>
|
||||
<ivy pattern='http://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/teamcity-ivy.xml'/>
|
||||
<artifact pattern='http://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/[artifact](.[ext])'/>
|
||||
</url>
|
||||
</resolvers>
|
||||
<modules>
|
||||
<module organisation='org' name='bt343' matcher='regexp' resolver='jetbrains-repo'/>
|
||||
<module organisation='org' name='bt344' matcher='regexp' resolver='jetbrains-repo'/>
|
||||
</modules>
|
||||
</ivysettings>
|
||||
Binary file not shown.
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* "Bottles.kt" that doesn't compile, see line 6.
|
||||
*/
|
||||
package bottles
|
||||
|
||||
fun main(args : Array<String>
|
||||
if (args.isEmpty) {
|
||||
printBottles(99)
|
||||
}
|
||||
else {
|
||||
try {
|
||||
printBottles(Integer.parseInt(args[0]))
|
||||
}
|
||||
catch (e : NumberFormatException) {
|
||||
System.err?.println("You have passed '${args[0]}' as a number of bottles, " +
|
||||
"but it is not a valid integral number")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun printBottles(bottleCount : Int) {
|
||||
if (bottleCount <= 0) {
|
||||
println("No bottles - no song")
|
||||
return
|
||||
}
|
||||
|
||||
println("The \"${bottlesOfBeer(bottleCount)}\" song\n")
|
||||
|
||||
var bottles = bottleCount
|
||||
while (bottles > 0) {
|
||||
val bottlesOfBeer = bottlesOfBeer(bottles)
|
||||
print("$bottlesOfBeer on the wall, $bottlesOfBeer.\nTake one down, pass it around, ")
|
||||
bottles--
|
||||
println("${bottlesOfBeer(bottles)} on the wall.\n")
|
||||
}
|
||||
println("No more bottles of beer on the wall, no more bottles of beer.\n" +
|
||||
"Go to the store and buy some more, ${bottlesOfBeer(bottleCount)} on the wall.")
|
||||
}
|
||||
|
||||
fun bottlesOfBeer(count : Int) : String =
|
||||
when (count) {
|
||||
0 -> "no more bottles"
|
||||
1 -> "1 bottle"
|
||||
else -> "$count bottles"
|
||||
} + " of beer"
|
||||
|
||||
/*
|
||||
* An excerpt from the Standard Library
|
||||
*/
|
||||
|
||||
// From the kotlin.io package
|
||||
// These are simple functions that wrap standard Java API calls
|
||||
fun print(message : String) { System.out?.print(message) }
|
||||
fun println(message : String) { System.out?.println(message) }
|
||||
|
||||
// From the kotlin package
|
||||
// This is an extension property, i.e. a property that is defined for the
|
||||
// type Array<T>, but does not sit inside the class Array
|
||||
val <T> Array<T>.isEmpty : Boolean get() = size == 0
|
||||
@@ -1,3 +0,0 @@
|
||||
import kotlin.modules.*
|
||||
|
||||
fun proj
|
||||
@@ -1,3 +0,0 @@
|
||||
fun main(args : Array<String>) {
|
||||
System.out?.println("Hello, world!")
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
fun main(args : Array<String>) {
|
||||
if (args.size == 0) {
|
||||
System.out?.println("Please provide a name as a command-line argument")
|
||||
return
|
||||
}
|
||||
System.out?.println("Hello, ${args[0]}!")
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
fun main(args : Array<String>) {
|
||||
for (name in args)
|
||||
System.out?.println("Hello, $name!")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
fun main(args : Array<String>) {
|
||||
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"
|
||||
})
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
class Greeter(val name : String) {
|
||||
fun greet() {
|
||||
System.out?.println("Hello, ${name}!");
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
Greeter(args[0]).greet()
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* This example implements the famous "99 Bottles of Beer" program
|
||||
* See http://99-bottles-of-beer.net/
|
||||
*
|
||||
* The point is to print out a song with the following lyrics:
|
||||
*
|
||||
* The "99 bottles of beer" song
|
||||
*
|
||||
* 99 bottles of beer on the wall, 99 bottles of beer.
|
||||
* Take one down, pass it around, 98 bottles of beer on the wall.
|
||||
*
|
||||
* 98 bottles of beer on the wall, 98 bottles of beer.
|
||||
* Take one down, pass it around, 97 bottles of beer on the wall.
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* 2 bottles of beer on the wall, 2 bottles of beer.
|
||||
* Take one down, pass it around, 1 bottle of beer on the wall.
|
||||
*
|
||||
* 1 bottle of beer on the wall, 1 bottle of beer.
|
||||
* Take one down, pass it around, no more bottles of beer on the wall.
|
||||
*
|
||||
* No more bottles of beer on the wall, no more bottles of beer.
|
||||
* Go to the store and buy some more, 99 bottles of beer on the wall.
|
||||
*
|
||||
* Additionally, you can pass the desired initial number of bottles to use (rather than 99)
|
||||
* as a command-line argument
|
||||
*/
|
||||
package bottles
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
if (args.isEmpty) {
|
||||
printBottles(99)
|
||||
}
|
||||
else {
|
||||
try {
|
||||
printBottles(Integer.parseInt(args[0]))
|
||||
}
|
||||
catch (e : NumberFormatException) {
|
||||
System.err?.println("You have passed '${args[0]}' as a number of bottles, " +
|
||||
"but it is not a valid integral number")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun printBottles(bottleCount : Int) {
|
||||
if (bottleCount <= 0) {
|
||||
println("No bottles - no song")
|
||||
return
|
||||
}
|
||||
|
||||
println("The \"${bottlesOfBeer(bottleCount)}\" song\n")
|
||||
|
||||
var bottles = bottleCount
|
||||
while (bottles > 0) {
|
||||
val bottlesOfBeer = bottlesOfBeer(bottles)
|
||||
print("$bottlesOfBeer on the wall, $bottlesOfBeer.\nTake one down, pass it around, ")
|
||||
bottles--
|
||||
println("${bottlesOfBeer(bottles)} on the wall.\n")
|
||||
}
|
||||
println("No more bottles of beer on the wall, no more bottles of beer.\n" +
|
||||
"Go to the store and buy some more, ${bottlesOfBeer(bottleCount)} on the wall.")
|
||||
}
|
||||
|
||||
fun bottlesOfBeer(count : Int) : String =
|
||||
when (count) {
|
||||
0 -> "no more bottles"
|
||||
1 -> "1 bottle"
|
||||
else -> "$count bottles"
|
||||
} + " of beer"
|
||||
|
||||
/*
|
||||
* An excerpt from the Standard Library
|
||||
*/
|
||||
|
||||
|
||||
// From the kotlin package
|
||||
// This is an extension property, i.e. a property that is defined for the
|
||||
// type Array<T>, but does not sit inside the class Array
|
||||
val <T> Array<T>.isEmpty : Boolean get() = size == 0
|
||||
@@ -1,146 +0,0 @@
|
||||
/**
|
||||
* This is an example of a Type-Safe Groovy-style Builder
|
||||
*
|
||||
* Builders are good for declaratively describing data in your code.
|
||||
* In this example we show how to describe an HTML page in Kotlin.
|
||||
*
|
||||
* See this page for details:
|
||||
* http://confluence.jetbrains.net/display/Kotlin/Type-safe+Groovy-style+builders
|
||||
*/
|
||||
package html
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
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<Element>()
|
||||
val attributes = HashMap<String, String>()
|
||||
|
||||
protected fun initTag<T : Element>(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</$name>\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 <K, V> Map<K, V>.set(key : K, value : V) = this.put(key, value)
|
||||
@@ -1,167 +0,0 @@
|
||||
/**
|
||||
* This is a straightforward implementation of The Game of Life
|
||||
* See http://en.wikipedia.org/wiki/Conway's_Game_of_Life
|
||||
*/
|
||||
package life
|
||||
|
||||
import java.util.Collections.*
|
||||
import java.util.*
|
||||
|
||||
/*
|
||||
* A field where cells live. Effectively immutable
|
||||
*/
|
||||
class Field(
|
||||
val width : Int,
|
||||
val height : Int,
|
||||
// This function tells the constructor which cells are alive
|
||||
// if init(i, j) is true, the cell (i, j) is alive
|
||||
init : (Int, Int) -> Boolean
|
||||
) {
|
||||
private val live : Array<Array<Boolean>> = 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<String>) {
|
||||
// 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<String?>(lines.toList(), comparator<String?> {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 <K, V> Map<K, V>.set(k : K, v : V) { put(k, v) }
|
||||
|
||||
fun comparator<T> (f : (T, T) -> Int) : Comparator<T> = object : Comparator<T> {
|
||||
override fun compare(o1 : T, o2 : T) : Int = f(o1, o2)
|
||||
override fun equals(p : Any?) : Boolean = false
|
||||
}
|
||||
|
||||
val <T> Array<T>.isEmpty : Boolean get() = size == 0
|
||||
|
||||
fun <T, C: Collection<T>> Array<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
/**
|
||||
* Let's Walk Through a Maze.
|
||||
*
|
||||
* Imagine there is a maze whose walls are the big 'O' letters.
|
||||
* Now, I stand where a big 'I' stands and some cool prize lies
|
||||
* somewhere marked with a '$' sign. Like this:
|
||||
*
|
||||
* OOOOOOOOOOOOOOOOO
|
||||
* O O
|
||||
* O$ O O
|
||||
* OOOOO O
|
||||
* O O
|
||||
* O OOOOOOOOOOOOOO
|
||||
* O O I O
|
||||
* O O
|
||||
* OOOOOOOOOOOOOOOOO
|
||||
*
|
||||
* I want to get the prize, and this program helps me do so as soon
|
||||
* as I possibly can by finding a shortest path through the maze.
|
||||
*/
|
||||
package maze
|
||||
|
||||
import java.util.Collections.*
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* This function looks for a path from max.start to maze.end through
|
||||
* free space (a path does not go through walls). One can move only
|
||||
* straightly up, down, left or right, no diagonal moves allowed.
|
||||
*/
|
||||
fun findPath(maze : Maze) : List<#(Int, Int)>? {
|
||||
val previous = HashMap<#(Int, Int), #(Int, Int)>
|
||||
|
||||
val queue = LinkedList<#(Int, Int)>
|
||||
val visited = HashSet<#(Int, Int)>
|
||||
|
||||
queue.offer(maze.start)
|
||||
visited.add(maze.start)
|
||||
while (!queue.isEmpty()) {
|
||||
val cell = queue.poll()
|
||||
if (cell == maze.end) break
|
||||
|
||||
for (newCell in maze.neighbors(cell._1, cell._2)) {
|
||||
if (newCell in visited) continue
|
||||
previous[newCell] = cell
|
||||
queue.offer(newCell)
|
||||
visited.add(cell)
|
||||
}
|
||||
}
|
||||
|
||||
if (previous[maze.end] == null) return null
|
||||
|
||||
val path = ArrayList<#(Int, Int)>()
|
||||
var current = previous[maze.end]
|
||||
while (current != maze.start) {
|
||||
path.add(0, current)
|
||||
current = previous[current]
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
/**
|
||||
* Find neighbors of the (i, j) cell that are not walls
|
||||
*/
|
||||
fun Maze.neighbors(i : Int, j : Int) : List<#(Int, Int)> {
|
||||
val result = ArrayList<#(Int, Int)>
|
||||
addIfFree(i - 1, j, result)
|
||||
addIfFree(i, j - 1, result)
|
||||
addIfFree(i + 1, j, result)
|
||||
addIfFree(i, j + 1, result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun Maze.addIfFree(i : Int, j : Int, result : List<#(Int, Int)>) {
|
||||
if (i !in 0..height-1) return
|
||||
if (j !in 0..width-1) return
|
||||
if (walls[i][j]) return
|
||||
|
||||
result.add(#(i, j))
|
||||
}
|
||||
|
||||
/**
|
||||
* A data class that represents a maze
|
||||
*/
|
||||
class Maze(
|
||||
// Number or columns
|
||||
val width : Int,
|
||||
// Number of rows
|
||||
val height : Int,
|
||||
// true for a wall, false for free space
|
||||
val walls : Array<out Array<out Boolean>>,
|
||||
// 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<String>) {
|
||||
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<String?>(lines.toList(), comparator<String?> {o1, o2 ->
|
||||
val l1 : Int = o1?.size ?: 0
|
||||
val l2 = o2?.size ?: 0
|
||||
l1 - l2
|
||||
}).sure()
|
||||
val data = Array<Array<Boolean>>(lines.size) {Array<Boolean>(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 <K, V> Map<K, V>.set(k : K, v : V) { put(k, v) }
|
||||
|
||||
fun comparator<T> (f : (T, T) -> Int) : Comparator<T> = object : Comparator<T> {
|
||||
override fun compare(o1 : T, o2 : T) : Int = f(o1, o2)
|
||||
override fun equals(p : Any?) : Boolean = false
|
||||
}
|
||||
|
||||
fun <T, C: Collection<T>> Array<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
<project name="Kotlin" default="dist">
|
||||
|
||||
<!-- Set to false to disable proguard run on kotlin-compiler.jar. Speeds up the build -->
|
||||
<property name="shrink" value="true"/>
|
||||
<!-- Set to false to disable compiler's javadoc generation. Speeds up the build -->
|
||||
<property name="generate.javadoc" value="true"/>
|
||||
|
||||
<property name="output" value="${basedir}/dist"/>
|
||||
<property name="kotlin-home" value="${output}/kotlinc"/>
|
||||
<property name="build.number" value="snapshot"/>
|
||||
<property name="output.name" value="kotlin-${build.number}"/>
|
||||
<property name="idea.sdk" value="${basedir}/ideaSDK"/>
|
||||
|
||||
<import file="build-tools/build.xml" optional="false"/>
|
||||
|
||||
|
||||
<path id="classpath">
|
||||
<fileset dir="${idea.sdk}" includes="core/*.jar"/>
|
||||
|
||||
@@ -20,27 +22,38 @@
|
||||
|
||||
<fileset dir="${basedir}/lib" includes="**/*.jar"/>
|
||||
<fileset dir="${basedir}/js/js.translator/lib" includes="*.jar"/>
|
||||
<pathelement path="${output}/classes/runtime"/>
|
||||
</path>
|
||||
|
||||
<path id="classpath.kotlin">
|
||||
<path refid="classpath"/>
|
||||
<pathelement path="${output}/classes/compiler"/>
|
||||
<dirset id="compilerSources.dirset" dir="${basedir}/">
|
||||
<include name="compiler/frontend/src"/>
|
||||
<include name="compiler/frontend.java/src"/>
|
||||
<include name="compiler/backend/src"/>
|
||||
<include name="compiler/cli/src"/>
|
||||
<include name="compiler/util/src"/>
|
||||
<include name="compiler/jet.as.java.psi/src"/>
|
||||
|
||||
<include name="runtime/src"/>
|
||||
|
||||
<include name="js/js.translator/src"/>
|
||||
</dirset>
|
||||
|
||||
<path id="compilerSources.path">
|
||||
<dirset refid="compilerSources.dirset"/>
|
||||
</path>
|
||||
|
||||
<path id="sourcepath">
|
||||
<dirset dir="${basedir}/compiler">
|
||||
<include name="frontend/src"/>
|
||||
<include name="frontend.java/src"/>
|
||||
<include name="backend/src"/>
|
||||
<include name="cli/src"/>
|
||||
<include name="util/src"/>
|
||||
<include name="jet.as.java.psi/src"/>
|
||||
</dirset>
|
||||
<dirset dir="${basedir}/js/js.translator">
|
||||
<include name="src"/>
|
||||
</dirset>
|
||||
</path>
|
||||
<macrodef name="cleandir">
|
||||
<attribute name="dir"/>
|
||||
|
||||
<sequential>
|
||||
<echo message="Cleaning @{dir}"/>
|
||||
<delete dir="@{dir}" failonerror="false"/>
|
||||
<mkdir dir="@{dir}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${output}"/>
|
||||
</target>
|
||||
|
||||
<target name="init" depends="clean">
|
||||
<mkdir dir="${kotlin-home}"/>
|
||||
@@ -48,136 +61,90 @@
|
||||
<mkdir dir="${kotlin-home}/lib/alt"/>
|
||||
</target>
|
||||
|
||||
<target name="compileRT" depends="init">
|
||||
<mkdir dir="${output}/classes/runtime"/>
|
||||
<javac destdir="${output}/classes/runtime" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src path="${basedir}/runtime/src"/>
|
||||
<classpath refid="classpath"/>
|
||||
</javac>
|
||||
<target name="prepareDist">
|
||||
<copy todir="${kotlin-home}/bin">
|
||||
<fileset dir="${basedir}/compiler/cli/bin"/>
|
||||
</copy>
|
||||
|
||||
<copy todir="${kotlin-home}/license">
|
||||
<fileset dir="${basedir}/license"/>
|
||||
</copy>
|
||||
|
||||
<echo file="${kotlin-home}/build.txt" message="${build.number}"/>
|
||||
|
||||
<chmod dir="${kotlin-home}/bin" includes="*" perm="755"/>
|
||||
</target>
|
||||
|
||||
<target name="compileStdlib" depends="jar,jarLang,compileRT">
|
||||
<mkdir dir="${output}/classes/stdlib"/>
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true" fork="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
<arg value="-src"/>
|
||||
<arg value="${basedir}/libraries/stdlib/src"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="${output}/classes/stdlib"/>
|
||||
<arg value="-mode"/>
|
||||
<arg value="stdlib"/>
|
||||
<arg value="-classpath"/>
|
||||
<arg value="${output}/classes/runtime"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="compileJDKHeaders" depends="jar,jarLang">
|
||||
<mkdir dir="${output}/classes/stdlib"/>
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
<arg value="-src"/>
|
||||
<arg value="${basedir}/jdk-headers/src"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="${output}/classes/jdk-headers"/>
|
||||
<arg value="-mode"/>
|
||||
<arg value="jdkHeaders"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="compileLang" depends="jar">
|
||||
<mkdir dir="${output}/classes/lang"/>
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
<arg value="-src"/>
|
||||
<arg value="${basedir}/compiler/frontend/src"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="${output}/classes/lang"/>
|
||||
<arg value="-mode"/>
|
||||
<arg value="builtins"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="jarRT" depends="compile,copyKotlinJars,compileStdlib">
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-runtime.jar">
|
||||
<fileset dir="${output}/classes/runtime"/>
|
||||
<fileset dir="${output}/classes/stdlib"/>
|
||||
<fileset dir="${basedir}/runtime" includes="src/**/*"/>
|
||||
<fileset dir="${basedir}/libraries/stdlib" includes="src/**/*"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jarJDKHeaders" depends="compile,compileJDKHeaders">
|
||||
<jar destfile="${kotlin-home}/lib/alt/kotlin-jdk-headers.jar">
|
||||
<fileset dir="${output}/classes/jdk-headers"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jarLang" depends="compile,compileLang">
|
||||
<jar destfile="${kotlin-home}/lib/lang.jar">
|
||||
<fileset dir="${output}/classes/lang"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="compileInjectorsGenerator">
|
||||
<mkdir dir="${output}/classes/injectorsGenerator"/>
|
||||
<target name="injectorsGenerator">
|
||||
<cleandir dir="${output}/classes/injectorsGenerator"/>
|
||||
<javac destdir="${output}/classes/injectorsGenerator" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src path="injector-generator/src"/>
|
||||
<src refid="sourcepath"/>
|
||||
<src refid="compilerSources.path"/>
|
||||
<classpath refid="classpath"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="generateInjectors" depends="compileInjectorsGenerator">
|
||||
<target name="generateInjectors" depends="injectorsGenerator">
|
||||
<java classname="org.jetbrains.jet.di.AllInjectorsGenerator" failonerror="true">
|
||||
<classpath refid="classpath"/>
|
||||
<classpath path="${output}/classes/injectorsGenerator"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="compileRT,generateInjectors">
|
||||
<mkdir dir="${output}/classes/compiler"/>
|
||||
<javac destdir="${output}/classes/compiler" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src refid="sourcepath"/>
|
||||
<classpath refid="classpath"/>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="compilerSources" if="generate.javadoc">
|
||||
<jar jarfile="${output}/kotlin-compiler-sources.jar">
|
||||
<!-- TODO How to convert it from pathset or dirset ? -->
|
||||
<fileset dir="compiler/frontend/src"/>
|
||||
<fileset dir="compiler/frontend.java/src"/>
|
||||
<fileset dir="compiler/backend/src"/>
|
||||
<fileset dir="compiler/cli/src"/>
|
||||
<fileset dir="compiler/util/src"/>
|
||||
<fileset dir="compiler/jet.as.java.psi/src"/>
|
||||
<fileset dir="runtime/src"/>
|
||||
<fileset dir="js/js.translator/src"/>
|
||||
|
||||
<target name="compileTests" depends="dist">
|
||||
<mkdir dir="${output}/classes/tests"/>
|
||||
<javac destdir="${output}/classes/tests" debug="true" includeAntRuntime="false">
|
||||
<src path="compiler/tests"/>
|
||||
<classpath refid="classpath"/>
|
||||
<classpath location="${output}/classes/compiler"/>
|
||||
<classpath location="ideaSDK/lib/junit-4.10.jar"/>
|
||||
<classpath location="ideaSDK/lib/idea.jar"/>
|
||||
</javac>
|
||||
</target>
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="JetBrains"/>
|
||||
|
||||
<target name="jar" depends="compile">
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-compiler.jar">
|
||||
<fileset dir="${output}/classes/compiler"/>
|
||||
<fileset dir="${basedir}/compiler/frontend/src" includes="jet/**"/>
|
||||
<attribute name="Implementation-Vendor" value="JetBrains"/>
|
||||
<attribute name="Implementation-Title" value="Kotlin Compiler Sources"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
<delete dir="${output}/kotlin-compiler-javadoc" failonerror="false" />
|
||||
<javadoc destdir="${output}/kotlin-compiler-javadoc"
|
||||
sourcepathref="compilerSources.path"
|
||||
classpathref="classpath"
|
||||
linksource="yes"
|
||||
windowtitle="Kotlin Compiler"/>
|
||||
<jar jarfile="${output}/kotlin-compiler-javadoc.jar">
|
||||
<fileset dir="${output}/kotlin-compiler-javadoc"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="JetBrains"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="JetBrains"/>
|
||||
<attribute name="Implementation-Title" value="Kotlin Compiler Javadoc"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jarjar">
|
||||
<target name="compiler">
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="${basedir}/dependencies/jarjar.jar"/>
|
||||
<taskdef resource="proguard/ant/task.properties" classpath="${basedir}/dependencies/proguard.jar"/>
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${basedir}/dependencies/ant-contrib.jar"/>
|
||||
|
||||
<cleandir dir="${output}/classes/compiler"/>
|
||||
<javac destdir="${output}/classes/compiler" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src refid="compilerSources.path"/>
|
||||
<classpath refid="classpath"/>
|
||||
</javac>
|
||||
|
||||
<!-- JarJar Kotlin compiler & dependencies -->
|
||||
<delete file="${output}/kotlin-compiler-jarjar.jar" failonerror="false"/>
|
||||
<jarjar jarfile="${output}/kotlin-compiler-jarjar.jar">
|
||||
<fileset dir="${output}/classes/compiler"/>
|
||||
<fileset dir="${output}/classes/runtime"/>
|
||||
<fileset dir="${basedir}/compiler/frontend/src" includes="jet/**"/>
|
||||
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
@@ -197,40 +164,25 @@
|
||||
|
||||
<zap pattern="org.jdom.xpath.Jaxen*"/>
|
||||
|
||||
<zap pattern="org.mozilla.javascript.xml.impl.xmlbeans.**" />
|
||||
<zap pattern="org.mozilla.javascript.xml.impl.xmlbeans.**"/>
|
||||
|
||||
<rule pattern="com.intellij.**" result="kotlinc.internal.com.intellij.@1"/>
|
||||
<rule pattern="com.sun.jna.**" result="kotlinc.internal.com.sun.jna.@1"/>
|
||||
<rule pattern="org.apache.log4j.**" result="kotlinc.internal.org.apache.log4j.@1"/>
|
||||
<rule pattern="org.jdom.**" result="kotlinc.internal.org.jdom.@1"/>
|
||||
<rule pattern="JDOMAbout**" result="kotlinc.internal.org.jdom.JDOMAbout@1"/>
|
||||
<rule pattern="org.intellij.lang.annotations.**" result="kotlinc.internal.org.intellij.lang.annotations.@1"/>
|
||||
<rule pattern="org.jetbrains.annotations.**" result="kotlinc.internal.org.jetbrains.annotations.@1"/>
|
||||
<rule pattern="com.google.**" result="kotlinc.internal.com.google.@1"/>
|
||||
<rule pattern="org.objectweb.asm.**" result="kotlinc.internal.org.objectweb.asm.@1"/>
|
||||
<rule pattern="com.sampullara.cli.**" result="kotlinc.internal.com.sampullara.cli.@1"/>
|
||||
<rule pattern="org.picocontainer.**" result="kotlinc.internal.org.picocontainer.@1"/>
|
||||
<rule pattern="gnu.trove.**" result="kotlinc.internal.gnu.trove.@1"/>
|
||||
<rule pattern="javax.inject.**" result="kotlinc.internal.javax.inject.@1"/>
|
||||
</jarjar>
|
||||
|
||||
<delete failonerror="false" dir="${output}/kotlin-compiler.exploded"/>
|
||||
<mkdir dir="${output}/kotlin-compiler.exploded"/>
|
||||
<unzip src="${output}/kotlin-compiler-jarjar.jar" dest="${output}/kotlin-compiler.exploded"/>
|
||||
|
||||
<delete file="${output}/kotlin-compiler-jarjar.jar"/>
|
||||
|
||||
<!-- Clean JarJar result -->
|
||||
<delete file="${output}/kotlin-compiler-clean.jar" failonerror="false"/>
|
||||
<jar jarfile="${output}/kotlin-compiler-clean.jar">
|
||||
<fileset dir="${output}/kotlin-compiler.exploded">
|
||||
<include name="**/*.class"/>
|
||||
<include name="**/*.jet"/>
|
||||
<include name="**/*.jet.src"/>
|
||||
<include name="**/*.kt"/>
|
||||
<include name="/META-INF/services/**"/>
|
||||
<include name="/messages/**"/>
|
||||
</fileset>
|
||||
<rule pattern="com.intellij.**" result="org.jetbrains.jet.internal.com.intellij.@1"/>
|
||||
<rule pattern="com.sun.jna.**" result="org.jetbrains.jet.internal.com.sun.jna.@1"/>
|
||||
<rule pattern="org.apache.log4j.**" result="org.jetbrains.jet.internal.org.apache.log4j.@1"/>
|
||||
<rule pattern="org.jdom.**" result="org.jetbrains.jet.internal.org.jdom.@1"/>
|
||||
<rule pattern="JDOMAbout**" result="org.jetbrains.jet.internal.org.jdom.JDOMAbout@1"/>
|
||||
<rule pattern="org.intellij.lang.annotations.**" result="org.jetbrains.jet.internal.org.intellij.lang.annotations.@1"/>
|
||||
<rule pattern="com.google.**" result="org.jetbrains.jet.internal.com.google.@1"/>
|
||||
<rule pattern="org.objectweb.asm.**" result="org.jetbrains.jet.internal.org.objectweb.asm.@1"/>
|
||||
<rule pattern="com.sampullara.cli.**" result="org.jetbrains.jet.internal.com.sampullara.cli.@1"/>
|
||||
<rule pattern="org.picocontainer.**" result="org.jetbrains.jet.internal.org.picocontainer.@1"/>
|
||||
<rule pattern="gnu.trove.**" result="org.jetbrains.jet.internal.gnu.trove.@1"/>
|
||||
<rule pattern="javax.inject.**" result="org.jetbrains.jet.internal.javax.inject.@1"/>
|
||||
<rule pattern="com.thoughtworks.xstream.**" result="org.jetbrains.jet.internal.com.thoughtworks.xstream.@1"/>
|
||||
<rule pattern="org.json.**" result="org.jetbrains.jet.internal.org.json.@1"/>
|
||||
<rule pattern="org.mozilla.**" result="org.jetbrains.jet.internal.org.mozilla.@1"/>
|
||||
<rule pattern="org.xmlpull.**" result="org.jetbrains.jet.internal.org.xmlpull.@1"/>
|
||||
<rule pattern="org.kohsuke.args4j.**" result="org.jetbrains.jet.internal.org.kohsuke.args4j.@1"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="JetBrains"/>
|
||||
@@ -241,93 +193,232 @@
|
||||
|
||||
<attribute name="Main-Class" value="org.jetbrains.jet.cli.jvm.K2JVMCompiler"/>
|
||||
</manifest>
|
||||
</jarjar>
|
||||
|
||||
<delete file="${kotlin-home}/lib/kotlin-compiler.jar" failonerror="false"/>
|
||||
|
||||
<if>
|
||||
<isfalse value="${shrink}"/>
|
||||
|
||||
<then>
|
||||
<copy file="${output}/kotlin-compiler-jarjar.jar"
|
||||
tofile="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</then>
|
||||
|
||||
<else>
|
||||
<cleandir dir="${output}/kotlin-compiler.exploded"/>
|
||||
<unzip src="${output}/kotlin-compiler-jarjar.jar" dest="${output}/kotlin-compiler.exploded"/>
|
||||
|
||||
<!-- Clean JarJar result -->
|
||||
<jar jarfile="${output}/kotlin-compiler-before-proguard.jar"
|
||||
manifest="${output}/kotlin-compiler.exploded/META-INF/MANIFEST.MF">
|
||||
|
||||
<fileset dir="${output}/kotlin-compiler.exploded">
|
||||
<include name="**/*.class"/>
|
||||
<include name="**/*.jet"/>
|
||||
<include name="**/*.jet.src"/>
|
||||
<include name="**/*.kt"/>
|
||||
<include name="META-INF/services/**"/>
|
||||
<include name="messages/**"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
<delete dir="${output}/kotlin-compiler.exploded"/>
|
||||
|
||||
<available property="rtjar" value="${java.home}/lib/rt.jar" file="${java.home}/lib/rt.jar"/>
|
||||
<available property="rtjar" value="${java.home}/../Classes/classes.jar" file="${java.home}/../Classes/classes.jar"/>
|
||||
|
||||
<proguard><![CDATA[
|
||||
-injars '${output}/kotlin-compiler-before-proguard.jar'
|
||||
-outjars '${kotlin-home}/lib/kotlin-compiler.jar'
|
||||
|
||||
-libraryjars '${rtjar}'
|
||||
|
||||
-target 1.6
|
||||
-dontoptimize
|
||||
-dontobfuscate
|
||||
|
||||
-keepclasseswithmembers public class * {
|
||||
public static void main(java.lang.String[]);
|
||||
}
|
||||
|
||||
-keep class org.jetbrains.annotations.** {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep class org.jetbrains.k2js.** {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep class org.jetbrains.jet.** {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keep class jet.** {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * { void start(); }
|
||||
|
||||
-keepclasseswithmembers class * { void stop(); }
|
||||
-keepclasseswithmembers class * { void dispose(); }
|
||||
|
||||
-keepclasseswithmembers class * { ** getFileSystem(); }
|
||||
-keepclasseswithmembers class * { ** isVarArgs(); }
|
||||
-keepclasseswithmembers class * { ** getApplication(); }
|
||||
-keepclasseswithmembers class * { ** finalizeReferent(); }
|
||||
-keepclasseswithmembers class * { ** newBuilder(); }
|
||||
-keepclasseswithmembers class * { ** startFinalizer(java.lang.Class,java.lang.Object); }
|
||||
-keepclasseswithmembers class * { ** executeOnPooledThread(java.lang.Runnable); }
|
||||
-keepclasseswithmembers class * { ** getUserData(java.lang.String); }
|
||||
-keepclasseswithmembers class * { int getBooleanAttributes(java.io.File); }
|
||||
|
||||
-keepclasseswithmembers class * { ** project(); }
|
||||
|
||||
-keepclasseswithmembers class * { ** TYPE; }
|
||||
-keepclasseswithmembers class * { ** ourInstance; }
|
||||
|
||||
-keepclasseswithmembers class * { <init>(kotlinc.internal.com.intellij.lang.ASTNode); }
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keepclassmembers class * {
|
||||
** toString();
|
||||
** hashCode();
|
||||
}
|
||||
]]></proguard>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<target name="antTools">
|
||||
<cleandir dir="${output}/classes/buildTools"/>
|
||||
<javac destdir="${output}/classes/buildTools" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src>
|
||||
<dirset dir="${basedir}/build-tools">
|
||||
<include name="core/src"/>
|
||||
<include name="ant/src"/>
|
||||
</dirset>
|
||||
</src>
|
||||
<compilerarg value="-Xlint:all"/>
|
||||
<classpath>
|
||||
<fileset dir="${kotlin-home}/lib" includes="kotlin-compiler.jar"/>
|
||||
<fileset dir="${basedir}/dependencies" includes="ant.jar"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-ant.jar">
|
||||
<fileset dir="${output}/classes/buildTools"/>
|
||||
<fileset dir="${basedir}/build-tools/ant/src" includes="**/*.xml"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="JetBrains"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="JetBrains"/>
|
||||
<attribute name="Implementation-Title" value="Kotlin Compiler Ant Tasks"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
|
||||
<attribute name="Class-Path" value="kotlin-compiler.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
<delete dir="${output}/kotlin-compiler.exploded" />
|
||||
|
||||
<available property="rtjar" value="${java.home}/lib/rt.jar" file="${java.home}/lib/rt.jar" />
|
||||
<available property="rtjar" value="${java.home}/../Classes/classes.jar" file="${java.home}/../Classes/classes.jar" />
|
||||
|
||||
<delete file="${output}/kotlin-compiler.jar" failonerror="false"/>
|
||||
<proguard><![CDATA[
|
||||
-injars '${output}/kotlin-compiler-clean.jar'
|
||||
-outjars '${output}/kotlin-compiler.jar'
|
||||
|
||||
-libraryjars '${rtjar}'
|
||||
|
||||
-target 1.6
|
||||
-dontoptimize
|
||||
-dontobfuscate
|
||||
|
||||
# Keep application classes, along with their 'main' methods.
|
||||
-keepclasseswithmembers public class * {
|
||||
public static void main(java.lang.String[]);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
# Various dynamically called methods
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void dispose();
|
||||
** getFileSystem();
|
||||
** isVarArgs();
|
||||
** getApplication();
|
||||
** finalizeReferent();
|
||||
** newBuilder();
|
||||
** startFinalizer(java.lang.Class,java.lang.Object);
|
||||
** executeOnPooledThread(java.lang.Runnable);
|
||||
** getUserData(java.lang.String);
|
||||
int getBooleanAttributes(java.io.File);
|
||||
<init>(kotlinc.internal.com.intellij.lang.ASTNode);
|
||||
}
|
||||
|
||||
# Keep the special static methods that are required in enumeration classes.
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keepclassmembers class * {
|
||||
** toString();
|
||||
** hashCode();
|
||||
** project();
|
||||
|
||||
** TYPE;
|
||||
** ourInstance;
|
||||
}
|
||||
]]></proguard>
|
||||
<delete file="${output}/kotlin-compiler-clean.jar" />
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${output}"/>
|
||||
<target name="jdkHeaders">
|
||||
<cleandir dir="${output}/classes/stdlib"/>
|
||||
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
<arg value="-src"/>
|
||||
<arg value="${basedir}/jdk-headers/src"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="${output}/classes/jdk-headers"/>
|
||||
<arg value="-mode"/>
|
||||
<arg value="jdkHeaders"/>
|
||||
</java>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/alt/kotlin-jdk-headers.jar">
|
||||
<fileset dir="${output}/classes/jdk-headers"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="JetBrains"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="JetBrains"/>
|
||||
<attribute name="Implementation-Title" value="Kotlin Compiler JDK Headers"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="copyKotlinJars">
|
||||
<copy todir="${kotlin-home}/lib">
|
||||
<fileset dir="${idea.sdk}/core" includes="*.jar"/>
|
||||
<fileset dir="${basedir}/lib" includes="**/*.jar"/>
|
||||
</copy>
|
||||
<copy todir="${kotlin-home}/lib/js">
|
||||
<fileset dir="${basedir}/js/js.translator/lib" includes="**/*.jar"/>
|
||||
</copy>
|
||||
<copy todir="${kotlin-home}/bin">
|
||||
<fileset dir="${basedir}/compiler/cli/bin"/>
|
||||
</copy>
|
||||
<chmod dir="${kotlin-home}/bin" includes="*" perm="755"/>
|
||||
<target name="runtime">
|
||||
<cleandir dir="${output}/classes/runtime"/>
|
||||
<javac destdir="${output}/classes/runtime" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<src path="${basedir}/runtime/src"/>
|
||||
</javac>
|
||||
|
||||
<cleandir dir="${output}/classes/stdlib"/>
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true" fork="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
<arg value="-src"/>
|
||||
<arg value="${basedir}/libraries/stdlib/src"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="${output}/classes/stdlib"/>
|
||||
<arg value="-mode"/>
|
||||
<arg value="stdlib"/>
|
||||
<arg value="-classpath"/>
|
||||
<arg value="${output}/classes/runtime"/>
|
||||
</java>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-runtime.jar">
|
||||
<fileset dir="${output}/classes/runtime"/>
|
||||
<fileset dir="${output}/classes/stdlib"/>
|
||||
<fileset dir="${basedir}/runtime" includes="src/**/*"/>
|
||||
<fileset dir="${basedir}/libraries/stdlib" includes="src/**/*"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="JetBrains"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="JetBrains"/>
|
||||
<attribute name="Implementation-Title" value="Kotlin Compiler Runtime + StdLib"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="init,copyKotlinJars,jar,buildToolsJar,jarJDKHeaders,jarRT,jarLang,jarjar"/>
|
||||
<target name="lang">
|
||||
<cleandir dir="${output}/classes/lang"/>
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
<arg value="-src"/>
|
||||
<arg value="${basedir}/compiler/frontend/src"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="${output}/classes/lang"/>
|
||||
<arg value="-mode"/>
|
||||
<arg value="builtins"/>
|
||||
</java>
|
||||
|
||||
<target name="doc" depends="dist"/>
|
||||
<!-- Not used yet -->
|
||||
<!--
|
||||
<jar destfile="${kotlin-home}/lib/lang.jar">
|
||||
<fileset dir="${output}/classes/lang"/>
|
||||
</jar>
|
||||
-->
|
||||
</target>
|
||||
|
||||
<target name="dist"
|
||||
depends="init,prepareDist,injectorsGenerator,generateInjectors,compiler,compilerSources,antTools,jdkHeaders,runtime,lang"/>
|
||||
|
||||
<target name="zip" depends="dist">
|
||||
<echo file="${kotlin-home}/build.txt" message="${build.number}"/>
|
||||
<zip destfile="${output}/${output.name}.zip">
|
||||
<zipfileset prefix="kotlinc" dir="${kotlin-home}"/>
|
||||
<zipfileset prefix="kotlinc" file="${output}/build.txt"/>
|
||||
<zipfileset prefix="kotlinc/license" dir="${basedir}/license"/>
|
||||
<zipfileset prefix="kotlinc/bin" filemode="755" dir="${basedir}/compiler/cli/bin"/>
|
||||
</zip>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -491,6 +491,11 @@ public class JetTypeMapper {
|
||||
return null;
|
||||
|
||||
final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration();
|
||||
|
||||
while(functionDescriptor.getKind()==CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
functionDescriptor = functionDescriptor.getOverriddenDescriptors().iterator().next();
|
||||
}
|
||||
|
||||
JvmMethodSignature descriptor = mapSignature(functionDescriptor.getOriginal(), true, kind);
|
||||
String owner;
|
||||
String ownerForDefaultImpl;
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash --posix
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2002-2011, LAMP/EPFL
|
||||
# Copyright 2011, JetBrains
|
||||
#
|
||||
# This is free software; see the distribution for copying conditions.
|
||||
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
##############################################################################
|
||||
|
||||
cygwin=false;
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
esac
|
||||
|
||||
# Finding the root folder for this Kotlin distribution
|
||||
SOURCE=$0;
|
||||
SCRIPT=`basename "$SOURCE"`;
|
||||
while [ -h "$SOURCE" ]; do
|
||||
SCRIPT=`basename "$SOURCE"`;
|
||||
LOOKUP=`ls -ld "$SOURCE"`;
|
||||
TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`;
|
||||
if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then
|
||||
SOURCE=${TARGET:-.};
|
||||
else
|
||||
SOURCE=`dirname "$SOURCE"`/${TARGET:-.};
|
||||
fi;
|
||||
done;
|
||||
|
||||
# see #2092
|
||||
KOTLIN_HOME=`dirname "$SOURCE"`
|
||||
KOTLIN_HOME=`cd "$KOTLIN_HOME"; pwd -P`
|
||||
KOTLIN_HOME=`cd "$KOTLIN_HOME"/..; pwd`
|
||||
|
||||
# Remove spaces from KOTLIN_HOME on windows
|
||||
if $cygwin; then
|
||||
KOTLIN_HOME=`cygpath --windows --short-name "$KOTLIN_HOME"`
|
||||
KOTLIN_HOME=`cygpath --unix "$KOTLIN_HOME"`
|
||||
fi
|
||||
|
||||
[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M"
|
||||
|
||||
# break out -D and -J options and add them to JAVA_OPTS as well
|
||||
# so they reach the underlying JVM in time to do some good. The
|
||||
# -D options will be available as system properties.
|
||||
declare -a java_args
|
||||
declare -a kotlin_args
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-D*)
|
||||
# pass to kotlin as well: otherwise we lose it sometimes when we
|
||||
# need it, e.g. communicating with a server compiler.
|
||||
java_args=("${java_args[@]}" "$1")
|
||||
kotlin_args=("${kotlin_args[@]}" "$1")
|
||||
shift
|
||||
;;
|
||||
-J*)
|
||||
# as with -D, pass to kotlin even though it will almost
|
||||
# never be used.
|
||||
java_args=("${java_args[@]}" "${1:2}")
|
||||
kotlin_args=("${kotlin_args[@]}" "$1")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
kotlin_args=("${kotlin_args[@]}" "$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# reset "$@" to the remaining args
|
||||
set -- "${kotlin_args[@]}"
|
||||
|
||||
if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
|
||||
CPSELECT="-cp "
|
||||
|
||||
"${JAVACMD:=java}" \
|
||||
$JAVA_OPTS \
|
||||
"${java_args[@]}" \
|
||||
${CPSELECT}${KOTLIN_HOME}"/lib/kotlin-compiler.jar" \
|
||||
org.jetbrains.jet.cli.js.K2JSCompiler "$@"
|
||||
@@ -21,26 +21,12 @@ if "%_JAVACMD%"=="" set _JAVACMD=java
|
||||
rem We use the value of the JAVA_OPTS environment variable if defined
|
||||
set _JAVA_OPTS=-Xmx256M -Xms32M
|
||||
|
||||
set _TOOL_CLASSPATH=
|
||||
if "%_TOOL_CLASSPATH%"=="" (
|
||||
for %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f"
|
||||
for /d %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f"
|
||||
)
|
||||
|
||||
"%_JAVACMD%" %_JAVA_OPTS% -cp "%_TOOL_CLASSPATH%" org.jetbrains.jet.cli.jvm.K2JVMCompiler %*
|
||||
"%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" org.jetbrains.jet.cli.js.K2JSCompiler %*
|
||||
goto end
|
||||
|
||||
rem ##########################################################################
|
||||
rem # subroutines
|
||||
|
||||
:add_cpath
|
||||
if "%_TOOL_CLASSPATH%"=="" (
|
||||
set _TOOL_CLASSPATH=%~1
|
||||
) else (
|
||||
set _TOOL_CLASSPATH=%_TOOL_CLASSPATH%;%~1
|
||||
)
|
||||
goto :eof
|
||||
|
||||
:set_home
|
||||
set _BIN_DIR=
|
||||
for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi
|
||||
@@ -39,18 +39,6 @@ if $cygwin; then
|
||||
KOTLIN_HOME=`cygpath --unix "$KOTLIN_HOME"`
|
||||
fi
|
||||
|
||||
# Constructing the extension classpath
|
||||
TOOL_CLASSPATH=""
|
||||
if [ -z "$TOOL_CLASSPATH" ] ; then
|
||||
for ext in "$KOTLIN_HOME"/lib/* ; do
|
||||
if [ -z "$TOOL_CLASSPATH" ] ; then
|
||||
TOOL_CLASSPATH="$ext"
|
||||
else
|
||||
TOOL_CLASSPATH="$TOOL_CLASSPATH:$ext"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M"
|
||||
|
||||
# break out -D and -J options and add them to JAVA_OPTS as well
|
||||
@@ -69,7 +57,7 @@ while [ $# -gt 0 ]; do
|
||||
shift
|
||||
;;
|
||||
-J*)
|
||||
# as with -D, pass to scala even though it will almost
|
||||
# as with -D, pass to kotlin even though it will almost
|
||||
# never be used.
|
||||
java_args=("${java_args[@]}" "${1:2}")
|
||||
kotlin_args=("${kotlin_args[@]}" "$1")
|
||||
@@ -94,5 +82,5 @@ CPSELECT="-cp "
|
||||
"${JAVACMD:=java}" \
|
||||
$JAVA_OPTS \
|
||||
"${java_args[@]}" \
|
||||
${CPSELECT}${TOOL_CLASSPATH} \
|
||||
${CPSELECT}${KOTLIN_HOME}"/lib/kotlin-compiler.jar" \
|
||||
org.jetbrains.jet.cli.jvm.K2JVMCompiler "$@"
|
||||
@@ -0,0 +1,37 @@
|
||||
rem based on scalac.bat from the Scala distribution
|
||||
rem ##########################################################################
|
||||
rem # Copyright 2002-2011, LAMP/EPFL
|
||||
rem # Copyright 2011, JetBrains
|
||||
rem #
|
||||
rem # This is free software; see the distribution for copying conditions.
|
||||
rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
rem # PARTICULAR PURPOSE.
|
||||
rem ##########################################################################
|
||||
@echo off
|
||||
|
||||
@setlocal
|
||||
call :set_home
|
||||
|
||||
if not "%JAVA_HOME%"=="" (
|
||||
if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe"
|
||||
)
|
||||
|
||||
if "%_JAVACMD%"=="" set _JAVACMD=java
|
||||
|
||||
rem We use the value of the JAVA_OPTS environment variable if defined
|
||||
set _JAVA_OPTS=-Xmx256M -Xms32M
|
||||
|
||||
"%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" org.jetbrains.jet.cli.jvm.K2JVMCompiler %*
|
||||
goto end
|
||||
|
||||
rem ##########################################################################
|
||||
rem # subroutines
|
||||
|
||||
:set_home
|
||||
set _BIN_DIR=
|
||||
for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi
|
||||
set _KOTLIN_HOME=%_BIN_DIR%..
|
||||
goto :eof
|
||||
|
||||
:end
|
||||
@endlocal
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
package org.jetbrains.jet.cli.common;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.sampullara.cli.Args;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
|
||||
import org.jetbrains.jet.cli.common.messages.MessageRenderer;
|
||||
import org.jetbrains.jet.cli.common.messages.*;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.List;
|
||||
@@ -107,20 +108,25 @@ public abstract class CLICompiler<A extends CompilerArguments, C extends Compile
|
||||
final MessageRenderer messageRenderer = getMessageRenderer(arguments);
|
||||
errStream.print(messageRenderer.renderPreamble());
|
||||
printVersionIfNeeded(errStream, arguments, messageRenderer);
|
||||
PrintingMessageCollector messageCollector = new PrintingMessageCollector(errStream, messageRenderer, arguments.isVerbose());
|
||||
Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||
try {
|
||||
return doExecute(errStream, arguments, messageRenderer);
|
||||
return doExecute(arguments, messageCollector, rootDisposable);
|
||||
}
|
||||
finally {
|
||||
messageCollector.printToErrStream();
|
||||
errStream.print(messageRenderer.renderConclusion());
|
||||
Disposer.dispose(rootDisposable);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: can't declare parameters as not null due to KT-1863
|
||||
@NotNull
|
||||
protected abstract ExitCode doExecute(PrintStream stream, A arguments, MessageRenderer renderer);
|
||||
protected abstract ExitCode doExecute(A arguments, PrintingMessageCollector messageCollector, Disposable rootDisposable);
|
||||
|
||||
//TODO: can we make it private?
|
||||
@NotNull
|
||||
private MessageRenderer getMessageRenderer(@NotNull A arguments) {
|
||||
protected MessageRenderer getMessageRenderer(@NotNull A arguments) {
|
||||
return arguments.isTags() ? MessageRenderer.TAGS : MessageRenderer.PLAIN;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,4 +44,5 @@ public abstract class CompilerArguments {
|
||||
public abstract boolean isHelp();
|
||||
public abstract boolean isTags();
|
||||
public abstract boolean isVersion();
|
||||
public abstract boolean isVerbose();
|
||||
}
|
||||
|
||||
+10
-1
@@ -31,7 +31,8 @@ import java.util.Collection;
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public class PrintingMessageCollector implements MessageCollector {
|
||||
private final boolean verbose;
|
||||
|
||||
private boolean verbose;
|
||||
private final PrintStream errStream;
|
||||
private final MessageRenderer messageRenderer;
|
||||
|
||||
@@ -70,4 +71,12 @@ public class PrintingMessageCollector implements MessageCollector {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
public void setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.cli.js;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import jet.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -25,19 +26,18 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.cli.common.CLICompiler;
|
||||
import org.jetbrains.jet.cli.common.ExitCode;
|
||||
import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
|
||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
|
||||
import org.jetbrains.jet.cli.common.messages.MessageRenderer;
|
||||
import org.jetbrains.jet.cli.common.messages.PrintingMessageCollector;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
|
||||
import org.jetbrains.k2js.config.Config;
|
||||
import org.jetbrains.k2js.config.ZippedLibrarySourcesConfig;
|
||||
import org.jetbrains.k2js.facade.K2JSTranslator;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
|
||||
@@ -60,39 +60,69 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments, K2JSCompile
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ExitCode doExecute(PrintStream stream, K2JSCompilerArguments arguments, MessageRenderer renderer) {
|
||||
PrintingMessageCollector messageCollector = new PrintingMessageCollector(stream, renderer, true);
|
||||
if (arguments.module != null) {
|
||||
stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Module arg is not supported", NO_LOCATION));
|
||||
return ExitCode.INTERNAL_ERROR;
|
||||
}
|
||||
protected ExitCode doExecute(K2JSCompilerArguments arguments, PrintingMessageCollector messageCollector, Disposable rootDisposable) {
|
||||
|
||||
if (arguments.srcdir == null) {
|
||||
stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Specify sources location via -srcdir", NO_LOCATION));
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Specify sources location via -srcdir", NO_LOCATION);
|
||||
return ExitCode.INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||
JetCoreEnvironment environmentForJS = getEnvironment(arguments, rootDisposable);
|
||||
Config config = getConfig(arguments, environmentForJS.getProject());
|
||||
if (analyzeAndReportErrors(messageCollector, environmentForJS.getSourceFiles(), config)) {
|
||||
return ExitCode.COMPILATION_ERROR;
|
||||
}
|
||||
|
||||
String outputFile = arguments.outputFile;
|
||||
if (outputFile == null) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Specify output file via -output", CompilerMessageLocation.NO_LOCATION);
|
||||
return ExitCode.INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return translateAndGenerateOutputFile(messageCollector, environmentForJS, config, outputFile);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetCoreEnvironment getEnvironment(K2JSCompilerArguments arguments, Disposable rootDisposable) {
|
||||
final JetCoreEnvironment environmentForJS = JetCoreEnvironment.getCoreEnvironmentForJS(rootDisposable);
|
||||
environmentForJS.addSources(arguments.srcdir);
|
||||
return environmentForJS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ExitCode translateAndGenerateOutputFile(@NotNull PrintingMessageCollector messageCollector,
|
||||
@NotNull JetCoreEnvironment environmentForJS, @NotNull Config config, @NotNull String outputFile) {
|
||||
try {
|
||||
K2JSTranslator.translateWithCallToMainAndSaveToFile(environmentForJS.getSourceFiles(), outputFile, config
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Exception while translating:\n" + e.getMessage(),
|
||||
CompilerMessageLocation.NO_LOCATION);
|
||||
return ExitCode.INTERNAL_ERROR;
|
||||
}
|
||||
return ExitCode.OK;
|
||||
}
|
||||
|
||||
private static boolean analyzeAndReportErrors(@NotNull PrintingMessageCollector messageCollector,
|
||||
@NotNull final List<JetFile> sources, @NotNull final Config config) {
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector);
|
||||
final List<JetFile> sources = environmentForJS.getSourceFiles();
|
||||
analyzerWithCompilerReport.analyzeAndReport(new Function0<AnalyzeExhaust>() {
|
||||
@Override
|
||||
public AnalyzeExhaust invoke() {
|
||||
BindingContext context = AnalyzerFacadeForJS
|
||||
.analyzeFiles(sources, Predicates.<PsiFile>alwaysTrue(), new Config(environmentForJS.getProject()) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<JetFile> generateLibFiles() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
});
|
||||
.analyzeFiles(sources, Predicates.<PsiFile>alwaysTrue(), config);
|
||||
return AnalyzeExhaust.success(context, JetStandardLibrary.getInstance());
|
||||
}
|
||||
}, sources);
|
||||
return analyzerWithCompilerReport.hasErrors();
|
||||
}
|
||||
|
||||
stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Greeting", NO_LOCATION));
|
||||
return ExitCode.OK;
|
||||
@NotNull
|
||||
private static Config getConfig(@NotNull K2JSCompilerArguments arguments, @NotNull Project project) {
|
||||
if (arguments.libzip == null) {
|
||||
return Config.getEmptyConfig(project);
|
||||
}
|
||||
return new ZippedLibrarySourcesConfig(project, arguments.libzip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,18 @@ import org.jetbrains.jet.cli.common.CompilerArguments;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "output", description = "Output directory")
|
||||
public String outputDir;
|
||||
|
||||
@Argument(value = "module", description = "Module to compile")
|
||||
public String module;
|
||||
/**
|
||||
* NOTE: for now K2JSCompiler supports only minimal amount of parameters required to launch it from the plugin.
|
||||
* You can specify only one source folder, path to the file where generated file will be stored, path to zipped library sources.
|
||||
*/
|
||||
public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "output", description = "Output file path")
|
||||
public String outputFile;
|
||||
|
||||
//NOTE: may well be a subject to change soon
|
||||
@Argument(value = "libzip", description = "Path to zipped lib sources")
|
||||
public String libzip;
|
||||
|
||||
@Argument(value = "srcdir", description = "Sources directory")
|
||||
public String srcdir;
|
||||
@@ -41,7 +47,7 @@ public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "version", description = "Display compiler version")
|
||||
public boolean version;
|
||||
|
||||
@Argument(value = "help", alias = "h", description = "show help")
|
||||
@Argument(value = "help", alias = "h", description = "Show help")
|
||||
public boolean help;
|
||||
|
||||
@Override
|
||||
@@ -58,4 +64,9 @@ public class K2JSCompilerArguments extends CompilerArguments {
|
||||
public boolean isVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.cli.jvm;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.cli.common.CLICompiler;
|
||||
@@ -53,9 +52,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments, K2JVMComp
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected ExitCode doExecute(PrintStream errStream,
|
||||
K2JVMCompilerArguments arguments,
|
||||
MessageRenderer messageRenderer) {
|
||||
protected ExitCode doExecute(K2JVMCompilerArguments arguments, PrintingMessageCollector messageCollector, Disposable rootDisposable) {
|
||||
|
||||
CompilerSpecialMode mode = parseCompilerSpecialMode(arguments);
|
||||
File jdkHeadersJar;
|
||||
@@ -85,9 +82,6 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments, K2JVMComp
|
||||
}
|
||||
|
||||
CompilerDependencies dependencies = new CompilerDependencies(mode, CompilerDependencies.findRtJar(), jdkHeadersJar, runtimeJar);
|
||||
PrintingMessageCollector messageCollector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
|
||||
Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||
|
||||
JetCoreEnvironment environment = JetCoreEnvironment.getCoreEnvironmentForJVM(rootDisposable, dependencies);
|
||||
K2JVMCompileEnvironmentConfiguration configuration =
|
||||
new K2JVMCompileEnvironmentConfiguration(environment, messageCollector);
|
||||
@@ -99,8 +93,11 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments, K2JVMComp
|
||||
|
||||
boolean noErrors;
|
||||
if (arguments.module != null) {
|
||||
boolean oldVerbose = messageCollector.isVerbose();
|
||||
messageCollector.setVerbose(false);
|
||||
List<Module> modules = CompileEnvironmentUtil
|
||||
.loadModuleScript(arguments.module, new PrintingMessageCollector(errStream, messageRenderer, false));
|
||||
.loadModuleScript(arguments.module, messageCollector);
|
||||
messageCollector.setVerbose(oldVerbose);
|
||||
File directory = new File(arguments.module).getParentFile();
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules,
|
||||
directory, arguments.jar, arguments.outputDir,
|
||||
@@ -132,10 +129,6 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments, K2JVMComp
|
||||
CompilerMessageLocation.NO_LOCATION);
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
finally {
|
||||
Disposer.dispose(rootDisposable);
|
||||
messageCollector.printToErrStream();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -153,6 +153,11 @@ public class K2JVMCompilerArguments extends CompilerArguments {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
public void setTags(boolean tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@@ -131,25 +131,6 @@ public class CompileEnvironmentUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ensureRuntime(JetCoreEnvironment environment, CompilerDependencies compilerDependencies) {
|
||||
if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.REGULAR) {
|
||||
ensureJdkRuntime(environment);
|
||||
ensureKotlinRuntime(environment);
|
||||
}
|
||||
else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.JDK_HEADERS) {
|
||||
ensureJdkRuntime(environment);
|
||||
}
|
||||
else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.STDLIB) {
|
||||
ensureJdkRuntime(environment);
|
||||
}
|
||||
else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.BUILTINS) {
|
||||
// nop
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("unknown mode: " + compilerDependencies.getCompilerSpecialMode());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Module> loadModuleScript(String moduleScriptFile, MessageCollector messageCollector) {
|
||||
Disposable disposable = new Disposable() {
|
||||
@Override
|
||||
@@ -159,7 +140,6 @@ public class CompileEnvironmentUtil {
|
||||
};
|
||||
CompilerDependencies dependencies = CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR);
|
||||
JetCoreEnvironment scriptEnvironment = JetCoreEnvironment.getCoreEnvironmentForJVM(disposable, dependencies);
|
||||
ensureRuntime(scriptEnvironment, dependencies);
|
||||
scriptEnvironment.addSources(moduleScriptFile);
|
||||
|
||||
GenerationState generationState = KotlinToJVMBytecodeCompiler
|
||||
|
||||
@@ -80,7 +80,9 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
|
||||
|
||||
CompilerSpecialMode compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
|
||||
|
||||
addToClasspath(compilerDependencies.getJdkJar());
|
||||
if (compilerSpecialMode.includeJdk()) {
|
||||
addToClasspath(compilerDependencies.getJdkJar());
|
||||
}
|
||||
|
||||
if (compilerSpecialMode.includeJdkHeaders()) {
|
||||
for (VirtualFile root : compilerDependencies.getJdkHeaderRoots()) {
|
||||
|
||||
@@ -72,8 +72,6 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
configuration.getEnvironment().addToClasspath(new File(classpathRoot));
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies());
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
@@ -83,9 +81,7 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
|
||||
public static boolean compileModules(
|
||||
K2JVMCompileEnvironmentConfiguration configuration,
|
||||
|
||||
@NotNull List<Module> modules,
|
||||
|
||||
@NotNull File directory,
|
||||
@Nullable String jarPath,
|
||||
@Nullable String outputDir,
|
||||
@@ -132,8 +128,6 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies());
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return false;
|
||||
|
||||
+6
-1
@@ -45,6 +45,11 @@ public class CompilerDependencies {
|
||||
this.jdkHeadersJar = jdkHeadersJar;
|
||||
this.runtimeJar = runtimeJar;
|
||||
|
||||
if (compilerSpecialMode.includeJdk()) {
|
||||
if (jdkJar == null) {
|
||||
throw new IllegalArgumentException("jdk must be included for mode " + compilerSpecialMode);
|
||||
}
|
||||
}
|
||||
if (compilerSpecialMode.includeJdkHeaders()) {
|
||||
if (jdkHeadersJar == null) {
|
||||
throw new IllegalArgumentException("jdkHeaders must be included for mode " + compilerSpecialMode);
|
||||
@@ -101,7 +106,7 @@ public class CompilerDependencies {
|
||||
public static CompilerDependencies compilerDependenciesForProduction(@NotNull CompilerSpecialMode compilerSpecialMode) {
|
||||
return new CompilerDependencies(
|
||||
compilerSpecialMode,
|
||||
findRtJar(),
|
||||
compilerSpecialMode.includeJdk() ? findRtJar() : null,
|
||||
compilerSpecialMode.includeJdkHeaders() ? PathUtil.getAltHeadersPath() : null,
|
||||
compilerSpecialMode.includeKotlinRuntime() ? PathUtil.getDefaultRuntimePath() : null);
|
||||
}
|
||||
|
||||
+7
-2
@@ -24,17 +24,22 @@ public enum CompilerSpecialMode {
|
||||
BUILTINS,
|
||||
JDK_HEADERS,
|
||||
STDLIB,
|
||||
JS
|
||||
IDEA,
|
||||
JS,
|
||||
;
|
||||
|
||||
public boolean includeJdkHeaders() {
|
||||
return this == REGULAR || this == STDLIB;
|
||||
return this == REGULAR || this == STDLIB || this == IDEA;
|
||||
}
|
||||
|
||||
public boolean includeKotlinRuntime() {
|
||||
return this == REGULAR;
|
||||
}
|
||||
|
||||
public boolean includeJdk() {
|
||||
return this != IDEA;
|
||||
}
|
||||
|
||||
public boolean isStubs() {
|
||||
return this == BUILTINS || this == JDK_HEADERS;
|
||||
}
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ class JavaDescriptorResolverHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!staticMembers && member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) {
|
||||
if (member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public abstract class DeclarationDescriptorImpl extends AnnotatedImpl implements
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "]";
|
||||
return DescriptorRenderer.DEBUG_TEXT.render(this) + "[" + getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "]";
|
||||
} catch (Throwable e) {
|
||||
// DescriptionRenderer may throw if this is not yet completely initialized
|
||||
// It is very inconvenient while debugging
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import java.util.*;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class FunctionDescriptorUtil {
|
||||
private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() {
|
||||
private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitution() {
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
|
||||
+6
-1
@@ -140,7 +140,12 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = getTypeConstructor().getParameters();
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = SubstitutionUtils.buildSubstitutionContext(typeParameters, typeArguments);
|
||||
return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext));
|
||||
|
||||
// Unsafe substitutor is OK, because no recursion can hurt us upon a trivial substitution:
|
||||
// all the types are written explicitly in the code already, they can not get infinite.
|
||||
// One exception is *-projections, but they need to be handled separately anyways.
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.createUnsafe(substitutionContext);
|
||||
return new SubstitutingScope(scopeForMemberLookup, substitutor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public interface DiagnosticHolder {
|
||||
if (diagnostic.getSeverity() == Severity.ERROR) {
|
||||
PsiFile psiFile = diagnostic.getPsiFile();
|
||||
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||
throw new IllegalStateException(diagnostic.getFactory().getName() + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
|
||||
throw new IllegalStateException(diagnostic.getFactory().getName() + " " + psiFile.getName() + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -912,7 +912,7 @@ public class DescriptorResolver {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
public void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) {
|
||||
public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) {
|
||||
if (ErrorUtils.isErrorType(type)) return;
|
||||
|
||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||
@@ -922,32 +922,32 @@ public class DescriptorResolver {
|
||||
List<TypeProjection> arguments = type.getArguments();
|
||||
assert parameters.size() == arguments.size();
|
||||
|
||||
List<JetTypeReference> typeReferences = typeElement.getTypeArgumentsAsTypes();
|
||||
assert typeReferences.size() == arguments.size() : typeElement.getText();
|
||||
List<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
|
||||
assert jetTypeArguments.size() == arguments.size() : typeElement.getText();
|
||||
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(type);
|
||||
for (int i = 0, projectionsSize = typeReferences.size(); i < projectionsSize; i++) {
|
||||
JetTypeReference argumentTypeReference = typeReferences.get(i);
|
||||
for (int i = 0; i < jetTypeArguments.size(); i++) {
|
||||
JetTypeReference jetTypeArgument = jetTypeArguments.get(i);
|
||||
|
||||
if (argumentTypeReference == null) continue;
|
||||
if (jetTypeArgument == null) continue;
|
||||
|
||||
JetType typeArgument = arguments.get(i).getType();
|
||||
checkBounds(argumentTypeReference, typeArgument, trace);
|
||||
checkBounds(jetTypeArgument, typeArgument, trace);
|
||||
|
||||
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
||||
checkBounds(argumentTypeReference, typeArgument, typeParameterDescriptor, substitutor, trace);
|
||||
checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkBounds(
|
||||
@NotNull JetTypeReference argumentTypeReference,
|
||||
public static void checkBounds(
|
||||
@NotNull JetTypeReference jetTypeArgument,
|
||||
@NotNull JetType typeArgument,
|
||||
@NotNull TypeParameterDescriptor typeParameterDescriptor,
|
||||
@NotNull TypeSubstitutor substitutor, BindingTrace trace) {
|
||||
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
|
||||
JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
|
||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(typeArgument, substitutedBound)) {
|
||||
trace.report(UPPER_BOUND_VIOLATED.on(argumentTypeReference, substitutedBound, typeArgument));
|
||||
trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class DescriptorUtils {
|
||||
typeConstructors.put(typeParameter.getTypeConstructor(), typeParameter);
|
||||
}
|
||||
//noinspection unchecked
|
||||
return (Descriptor) functionDescriptor.substitute(new TypeSubstitutor(TypeSubstitutor.TypeSubstitution.EMPTY) {
|
||||
return (Descriptor) functionDescriptor.substitute(new TypeSubstitutor(TypeSubstitution.EMPTY) {
|
||||
@Override
|
||||
public boolean inRange(@NotNull TypeConstructor typeConstructor) {
|
||||
return typeConstructors.containsKey(typeConstructor);
|
||||
|
||||
@@ -126,7 +126,7 @@ public class TypeResolver {
|
||||
int expectedArgumentCount = parameters.size();
|
||||
int actualArgumentCount = arguments.size();
|
||||
if (ErrorUtils.isError(typeConstructor)) {
|
||||
result[0] = ErrorUtils.createErrorType("??");
|
||||
result[0] = ErrorUtils.createErrorType("[Error type: " + typeConstructor + "]");
|
||||
}
|
||||
else {
|
||||
if (actualArgumentCount != expectedArgumentCount) {
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -407,15 +406,17 @@ public class CallResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
|
||||
ValueArgumentsToParametersMapper.Status
|
||||
argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing,
|
||||
candidateCall);
|
||||
candidateCall, unmappedArguments);
|
||||
if (!argumentMappingStatus.isSuccess()) {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR) {
|
||||
checkTypesWithNoCallee(context.toBasic());
|
||||
return;
|
||||
}
|
||||
checkUnknownArgumentTypes(context.toBasic(), unmappedArguments);
|
||||
}
|
||||
|
||||
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
|
||||
@@ -611,6 +612,15 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUnknownArgumentTypes(BasicResolutionContext context, Set<ValueArgument> unknownArguments) {
|
||||
for (ValueArgument valueArgument : unknownArguments) {
|
||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||
if (argumentExpression != null) {
|
||||
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(
|
||||
ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||
|
||||
|
||||
+13
-5
@@ -71,7 +71,8 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
|
||||
public static <D extends CallableDescriptor> Status mapValueArgumentsToParameters(
|
||||
@NotNull Call call,
|
||||
@NotNull TracingStrategy tracing,
|
||||
@NotNull ResolvedCallImpl<D> candidateCall
|
||||
@NotNull ResolvedCallImpl<D> candidateCall,
|
||||
@NotNull Set<ValueArgument> unmappedArguments
|
||||
) {
|
||||
TemporaryBindingTrace temporaryTrace = candidateCall.getTrace();
|
||||
Map<ValueParameterDescriptor, VarargValueArgument> varargs = Maps.newHashMap();
|
||||
@@ -99,14 +100,19 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
|
||||
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedName());
|
||||
if (valueParameterDescriptor == null) {
|
||||
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
|
||||
unmappedArguments.add(valueArgument);
|
||||
status = ERROR;
|
||||
}
|
||||
else {
|
||||
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
||||
unmappedArguments.add(valueArgument);
|
||||
status = WEAK_ERROR;
|
||||
}
|
||||
else {
|
||||
status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs));
|
||||
}
|
||||
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
||||
status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs));
|
||||
}
|
||||
if (somePositioned) {
|
||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
|
||||
@@ -134,12 +140,14 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
|
||||
}
|
||||
else {
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||
status = ERROR;
|
||||
unmappedArguments.add(valueArgument);
|
||||
status = WEAK_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||
status = ERROR;
|
||||
unmappedArguments.add(valueArgument);
|
||||
status = WEAK_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -49,7 +49,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
|
||||
}
|
||||
final TypeProjection projection = new TypeProjection(type);
|
||||
|
||||
return TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() {
|
||||
return TypeSubstitutor.create(new TypeSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
if (constructors.contains(key)) {
|
||||
@@ -484,7 +484,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
|
||||
}
|
||||
|
||||
public class Solution implements ConstraintSystemSolution {
|
||||
private final TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() {
|
||||
private final TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
|
||||
|
||||
@@ -21,16 +21,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstitution {
|
||||
private final TypeSubstitutor.TypeSubstitution[] inner;
|
||||
public class CompositeTypeSubstitution implements TypeSubstitution {
|
||||
private final TypeSubstitution[] inner;
|
||||
|
||||
public CompositeTypeSubstitution(@NotNull TypeSubstitutor.TypeSubstitution... inner) {
|
||||
public CompositeTypeSubstitution(@NotNull TypeSubstitution... inner) {
|
||||
this.inner = inner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
for (TypeSubstitutor.TypeSubstitution substitution : inner) {
|
||||
for (TypeSubstitution substitution : inner) {
|
||||
TypeProjection value = substitution.get(key);
|
||||
if (value != null) return value;
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstituti
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (TypeSubstitutor.TypeSubstitution substitution : inner) {
|
||||
for (TypeSubstitution substitution : inner) {
|
||||
if (!substitution.isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
@@ -48,7 +48,7 @@ public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstituti
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (TypeSubstitutor.TypeSubstitution substitution : inner) {
|
||||
for (TypeSubstitution substitution : inner) {
|
||||
builder.append(substitution).append(" * ");
|
||||
}
|
||||
return builder.toString();
|
||||
|
||||
@@ -36,7 +36,7 @@ public class DescriptorSubstitutor {
|
||||
@NotNull DeclarationDescriptor newContainingDeclaration,
|
||||
@NotNull List<TypeParameterDescriptor> result) {
|
||||
final Map<TypeConstructor, TypeProjection> mutableSubstitution = Maps.newHashMap();
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() {
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.util.CommonSuppliers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -120,6 +121,21 @@ public class SubstitutionUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Map<TypeConstructor, TypeProjection> removeTrivialSubstitutions(Map<TypeConstructor, TypeProjection> context) {
|
||||
Map<TypeConstructor, TypeProjection> clean = Maps.newHashMap(context);
|
||||
boolean changed = false;
|
||||
for (Iterator<Map.Entry<TypeConstructor, TypeProjection>> iterator = clean.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<TypeConstructor, TypeProjection> entry = iterator.next();
|
||||
TypeConstructor key = entry.getKey();
|
||||
TypeProjection value = entry.getValue();
|
||||
if (key == value.getType().getConstructor() && value.getProjectionKind() == Variance.INVARIANT) {
|
||||
iterator.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed ? clean : context;
|
||||
}
|
||||
|
||||
public static void assertNotImmediatelyRecursive(Map<TypeConstructor, TypeProjection> context) {
|
||||
// Make sure we never replace a T with "Foo<T>" or something similar,
|
||||
// because the substitution will not terminate in this case
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface TypeSubstitution {
|
||||
TypeSubstitution EMPTY = new TypeSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Empty TypeSubstitution";
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
TypeProjection get(TypeConstructor key);
|
||||
boolean isEmpty();
|
||||
}
|
||||
@@ -16,14 +16,16 @@
|
||||
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -32,57 +34,6 @@ public class TypeSubstitutor {
|
||||
|
||||
private static final int MAX_RECURSION_DEPTH = 100;
|
||||
|
||||
public static TypeSubstitutor makeConstantSubstitutor(Collection<TypeParameterDescriptor> typeParameterDescriptors, JetType type) {
|
||||
final Set<TypeConstructor> constructors = Sets.newHashSet();
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
|
||||
constructors.add(typeParameterDescriptor.getTypeConstructor());
|
||||
}
|
||||
final TypeProjection projection = new TypeProjection(type);
|
||||
|
||||
return TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
if (constructors.contains(key)) {
|
||||
return projection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TypeConstructor.makeConstantSubstitutor(" + constructors + " -> " + projection + ")";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface TypeSubstitution {
|
||||
TypeSubstitution EMPTY = new TypeSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Empty TypeSubstitution";
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
TypeProjection get(TypeConstructor key);
|
||||
boolean isEmpty();
|
||||
}
|
||||
|
||||
public static class MapToTypeSubstitutionAdapter implements TypeSubstitution {
|
||||
private final @NotNull Map<TypeConstructor, TypeProjection> substitutionContext;
|
||||
|
||||
@@ -108,7 +59,7 @@ public class TypeSubstitutor {
|
||||
|
||||
public static final TypeSubstitutor EMPTY = create(TypeSubstitution.EMPTY);
|
||||
|
||||
public static final class SubstitutionException extends Exception {
|
||||
private static final class SubstitutionException extends Exception {
|
||||
public SubstitutionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
@@ -122,8 +73,16 @@ public class TypeSubstitutor {
|
||||
return create(new CompositeTypeSubstitution(substitutions));
|
||||
}
|
||||
|
||||
/** No assertion for immediate recursion */
|
||||
public static TypeSubstitutor createUnsafe(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
Map<TypeConstructor, TypeProjection> cleanContext = SubstitutionUtils.removeTrivialSubstitutions(substitutionContext);
|
||||
return create(new MapToTypeSubstitutionAdapter(cleanContext));
|
||||
}
|
||||
|
||||
public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
return create(new MapToTypeSubstitutionAdapter(substitutionContext));
|
||||
Map<TypeConstructor, TypeProjection> cleanContext = SubstitutionUtils.removeTrivialSubstitutions(substitutionContext);
|
||||
//SubstitutionUtils.assertNotImmediatelyRecursive(cleanContext);
|
||||
return createUnsafe(cleanContext);
|
||||
}
|
||||
|
||||
public static TypeSubstitutor create(@NotNull JetType context) {
|
||||
@@ -158,7 +117,7 @@ public class TypeSubstitutor {
|
||||
}
|
||||
|
||||
try {
|
||||
return unsafeSubstitute(type, howThisTypeIsUsed);
|
||||
return unsafeSubstitute(new TypeProjection(howThisTypeIsUsed, type), 0).getType();
|
||||
} catch (SubstitutionException e) {
|
||||
return ErrorUtils.createErrorType(e.getMessage());
|
||||
}
|
||||
@@ -171,170 +130,100 @@ public class TypeSubstitutor {
|
||||
}
|
||||
|
||||
try {
|
||||
return unsafeSubstitute(type, howThisTypeIsUsed);
|
||||
return unsafeSubstitute(new TypeProjection(howThisTypeIsUsed, type), 0).getType();
|
||||
} catch (SubstitutionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetType unsafeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) throws SubstitutionException {
|
||||
if (ErrorUtils.isErrorType(type)) return type;
|
||||
private TypeProjection unsafeSubstitute(@NotNull TypeProjection originalProjection, int recursionDepth) throws SubstitutionException {
|
||||
assertRecursionDepth(recursionDepth, originalProjection, substitution);
|
||||
// The type is within the substitution range, i.e. T or T?
|
||||
JetType type = originalProjection.getType();
|
||||
if (JetStandardClasses.isNothing(type) || ErrorUtils.isErrorType(type)) return originalProjection;
|
||||
|
||||
TypeProjection value = getValueWithCorrectNullability(substitution, type);
|
||||
if (value != null) {
|
||||
TypeConstructor constructor = type.getConstructor();
|
||||
assert constructor.getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||
TypeProjection replacement = substitution.get(type.getConstructor());
|
||||
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) constructor.getDeclarationDescriptor();
|
||||
if (replacement != null) {
|
||||
// It must be a type parameter: only they can be directly substituted for
|
||||
TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
TypeProjection result = substitutionResult(typeParameterDescriptor, howThisTypeIsUsed, Variance.INVARIANT, value, 0);
|
||||
switch (conflictType(originalProjection.getProjectionKind(), replacement.getProjectionKind())) {
|
||||
case OUT_IN_IN_POSITION:
|
||||
throw new SubstitutionException("Out-projection in in-position");
|
||||
case IN_IN_OUT_POSITION:
|
||||
replacement = SubstitutionUtils.makeStarProjection(typeParameter);
|
||||
break;
|
||||
}
|
||||
boolean resultingIsNullable = type.isNullable() || replacement.getType().isNullable();
|
||||
JetType substitutedType = TypeUtils.makeNullableAsSpecified(replacement.getType(), resultingIsNullable);
|
||||
Variance resultingProjectionKind = combine(originalProjection.getProjectionKind(), replacement.getProjectionKind());
|
||||
|
||||
return TypeUtils.makeNullableIfNeeded(result.getType(), type.isNullable());
|
||||
return new TypeProjection(resultingProjectionKind, substitutedType);
|
||||
}
|
||||
else {
|
||||
// The type is not within the substitution range, i.e. Foo, Bar<T> etc.
|
||||
List<TypeProjection> substitutedArguments = substituteTypeArguments(
|
||||
type.getConstructor().getParameters(), type.getArguments(), recursionDepth);
|
||||
|
||||
return specializeType(type, howThisTypeIsUsed, 0);
|
||||
}
|
||||
|
||||
private TypeProjection getValueWithCorrectNullability(TypeSubstitution substitution, JetType type) {
|
||||
TypeProjection typeProjection = substitution.get(type.getConstructor());
|
||||
if (typeProjection == null) return null;
|
||||
|
||||
return type.isNullable() ? makeNullableProjection(typeProjection) : typeProjection;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TypeProjection makeNullableProjection(@NotNull TypeProjection value) {
|
||||
return new TypeProjection(value.getProjectionKind(), TypeUtils.makeNullable(value.getType()));
|
||||
}
|
||||
|
||||
private JetType specializeType(JetType subjectType, Variance callSiteVariance, int recursionDepth) throws SubstitutionException {
|
||||
assertRecursionDepth(recursionDepth, subjectType, substitution);
|
||||
if (ErrorUtils.isErrorType(subjectType)) return subjectType;
|
||||
|
||||
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
|
||||
List<TypeProjection> arguments = subjectType.getArguments();
|
||||
for (int i = 0, argumentsSize = arguments.size(); i < argumentsSize; i++) {
|
||||
TypeProjection argument = arguments.get(i);
|
||||
TypeParameterDescriptor parameterDescriptor = subjectType.getConstructor().getParameters().get(i);
|
||||
newArguments.add(substituteInProjection(
|
||||
substitution,
|
||||
argument,
|
||||
parameterDescriptor,
|
||||
callSiteVariance, recursionDepth + 1));
|
||||
JetType substitutedType = new JetTypeImpl(type.getAnnotations(), // Old annotations. This is questionable
|
||||
type.getConstructor(), // The same constructor
|
||||
type.isNullable(), // Same nullability
|
||||
substitutedArguments,
|
||||
new SubstitutingScope(type.getMemberScope(), this));
|
||||
return new TypeProjection(originalProjection.getProjectionKind(), substitutedType);
|
||||
}
|
||||
return new JetTypeImpl(
|
||||
subjectType.getAnnotations(),
|
||||
subjectType.getConstructor(),
|
||||
subjectType.isNullable(),
|
||||
newArguments,
|
||||
new SubstitutingScope(subjectType.getMemberScope(), this));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TypeProjection substituteInProjection(
|
||||
@NotNull TypeSubstitution substitutionContext,
|
||||
@NotNull TypeProjection passedProjection,
|
||||
@NotNull TypeParameterDescriptor correspondingTypeParameter,
|
||||
@NotNull Variance contextCallSiteVariance,
|
||||
int recursionDepth) throws SubstitutionException {
|
||||
assertRecursionDepth(recursionDepth, correspondingTypeParameter, passedProjection, substitution);
|
||||
private List<TypeProjection> substituteTypeArguments(List<TypeParameterDescriptor> typeParameters, List<TypeProjection> typeArguments, int recursionDepth)
|
||||
throws SubstitutionException {
|
||||
List<TypeProjection> substitutedArguments = Lists.newArrayList();
|
||||
for (int i = 0; i < typeParameters.size(); i++) {
|
||||
TypeParameterDescriptor typeParameter = typeParameters.get(i);
|
||||
TypeProjection typeArgument = typeArguments.get(i);
|
||||
|
||||
JetType typeToSubstituteIn = passedProjection.getType();
|
||||
if (ErrorUtils.isErrorType(typeToSubstituteIn)) return passedProjection;
|
||||
TypeProjection substitutedTypeArgument = unsafeSubstitute(typeArgument, recursionDepth + 1);
|
||||
|
||||
Variance passedProjectionKind = passedProjection.getProjectionKind();
|
||||
Variance parameterVariance = correspondingTypeParameter.getVariance();
|
||||
|
||||
Variance effectiveProjectionKind = asymmetricOr(passedProjectionKind, parameterVariance);
|
||||
Variance effectiveContextVariance = contextCallSiteVariance.superpose(effectiveProjectionKind);
|
||||
|
||||
TypeProjection projectionValue = getValueWithCorrectNullability(substitutionContext, typeToSubstituteIn);
|
||||
if (projectionValue != null) {
|
||||
assert typeToSubstituteIn.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||
|
||||
if (!allows(parameterVariance, passedProjectionKind)) {
|
||||
return SubstitutionUtils.makeStarProjection(correspondingTypeParameter);
|
||||
switch (conflictType(typeParameter.getVariance(), substitutedTypeArgument.getProjectionKind())) {
|
||||
case OUT_IN_IN_POSITION:
|
||||
substitutedTypeArgument = new TypeProjection(Variance.IN_VARIANCE, typeParameter.getLowerBoundsAsType());
|
||||
break;
|
||||
case IN_IN_OUT_POSITION:
|
||||
substitutedTypeArgument = SubstitutionUtils.makeStarProjection(typeParameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return substitutionResult(correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue, recursionDepth + 1);
|
||||
substitutedArguments.add(substitutedTypeArgument);
|
||||
}
|
||||
return new TypeProjection(
|
||||
passedProjectionKind,
|
||||
specializeType(
|
||||
typeToSubstituteIn,
|
||||
effectiveContextVariance, recursionDepth + 1));
|
||||
return substitutedArguments;
|
||||
}
|
||||
|
||||
private TypeProjection substitutionResult(
|
||||
TypeParameterDescriptor correspondingTypeParameter,
|
||||
Variance effectiveContextVariance,
|
||||
Variance passedProjectionKind,
|
||||
TypeProjection value,
|
||||
int recursionDepth) throws SubstitutionException {
|
||||
assertRecursionDepth(recursionDepth, correspondingTypeParameter, value, substitution);
|
||||
private static Variance combine(Variance typeParameterVariance, Variance projectionKind) {
|
||||
if (typeParameterVariance == Variance.INVARIANT) return projectionKind;
|
||||
if (projectionKind == Variance.INVARIANT) return typeParameterVariance;
|
||||
return typeParameterVariance.superpose(projectionKind);
|
||||
}
|
||||
|
||||
Variance projectionKindValue = value.getProjectionKind();
|
||||
JetType typeValue = value.getType();
|
||||
Variance effectiveProjectionKindValue = asymmetricOr(passedProjectionKind, projectionKindValue);
|
||||
JetType effectiveTypeValue;
|
||||
switch (effectiveContextVariance) {
|
||||
case INVARIANT:
|
||||
effectiveProjectionKindValue = projectionKindValue;
|
||||
effectiveTypeValue = typeValue;
|
||||
break;
|
||||
case IN_VARIANCE:
|
||||
if (projectionKindValue == Variance.OUT_VARIANCE) {
|
||||
throw new SubstitutionException(""); // TODO
|
||||
// effectiveProjectionKindValue = Variance.INVARIANT;
|
||||
// effectiveTypeValue = JetStandardClasses.getNothingType();
|
||||
}
|
||||
else {
|
||||
effectiveTypeValue = typeValue;
|
||||
}
|
||||
break;
|
||||
case OUT_VARIANCE:
|
||||
if (projectionKindValue == Variance.IN_VARIANCE) {
|
||||
effectiveProjectionKindValue = Variance.INVARIANT;
|
||||
effectiveTypeValue = correspondingTypeParameter.getUpperBoundsAsType();
|
||||
}
|
||||
else {
|
||||
effectiveTypeValue = typeValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException(effectiveContextVariance.toString());
|
||||
private enum VarianceConflictType {
|
||||
NO_CONFLICT,
|
||||
IN_IN_OUT_POSITION,
|
||||
OUT_IN_IN_POSITION;
|
||||
}
|
||||
|
||||
private static VarianceConflictType conflictType(Variance position, Variance argument) {
|
||||
if (position == Variance.IN_VARIANCE && argument == Variance.OUT_VARIANCE) {
|
||||
return VarianceConflictType.OUT_IN_IN_POSITION;
|
||||
}
|
||||
|
||||
// if (!allows(effectiveContextVariance, projectionKindValue)) {
|
||||
// throw new SubstitutionException(""); // TODO : error message
|
||||
// }
|
||||
//
|
||||
return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, effectiveContextVariance, recursionDepth + 1));
|
||||
}
|
||||
|
||||
private static Variance asymmetricOr(Variance a, Variance b) {
|
||||
return a == Variance.INVARIANT ? b : a;
|
||||
}
|
||||
|
||||
private static boolean allows(Variance declarationSiteVariance, Variance callSiteVariance) {
|
||||
switch (declarationSiteVariance) {
|
||||
case INVARIANT: return true;
|
||||
case IN_VARIANCE: return callSiteVariance != Variance.OUT_VARIANCE;
|
||||
case OUT_VARIANCE: return callSiteVariance != Variance.IN_VARIANCE;
|
||||
if (position == Variance.OUT_VARIANCE && argument == Variance.IN_VARIANCE) {
|
||||
return VarianceConflictType.IN_IN_OUT_POSITION;
|
||||
}
|
||||
throw new IllegalStateException(declarationSiteVariance.toString());
|
||||
return VarianceConflictType.NO_CONFLICT;
|
||||
}
|
||||
|
||||
private static void assertRecursionDepth(int recursionDepth, TypeParameterDescriptor parameter, TypeProjection value, TypeSubstitution substitution) {
|
||||
private static void assertRecursionDepth(int recursionDepth, TypeProjection projection, TypeSubstitution substitution) {
|
||||
if (recursionDepth > MAX_RECURSION_DEPTH) {
|
||||
throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(value) + " for " + safeToString(parameter) + "; substitution: " + safeToString(substitution));
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertRecursionDepth(int recursionDepth, JetType type, TypeSubstitution substitution) {
|
||||
if (recursionDepth > MAX_RECURSION_DEPTH) {
|
||||
throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(type) + "; substitution: " + safeToString(substitution));
|
||||
throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(projection) + "; substitution: " + safeToString(substitution));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ public class TypeUtils {
|
||||
@NotNull
|
||||
public static JetType makeUnsubstitutedType(ClassDescriptor classDescriptor, JetScope unsubstitutedMemberScope) {
|
||||
if (ErrorUtils.isError(classDescriptor)) {
|
||||
return ErrorUtils.createErrorType("This is very helpful diagnostics message");
|
||||
return ErrorUtils.createErrorType("Unsubstituted type for " + classDescriptor);
|
||||
}
|
||||
List<TypeProjection> arguments = getDefaultTypeProjections(classDescriptor.getTypeConstructor().getParameters());
|
||||
return new JetTypeImpl(
|
||||
|
||||
@@ -29,16 +29,11 @@ public class JetMainDetector {
|
||||
private JetMainDetector() {
|
||||
}
|
||||
|
||||
public static boolean hasMain(List<JetDeclaration> declarations) {
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
if (isMain((JetNamedFunction) declaration)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public static boolean hasMain(@NotNull List<JetDeclaration> declarations) {
|
||||
return findMainFunction(declarations) != null;
|
||||
}
|
||||
|
||||
public static boolean isMain(JetNamedFunction function) {
|
||||
public static boolean isMain(@NotNull JetNamedFunction function) {
|
||||
if ("main".equals(function.getName())) {
|
||||
List<JetParameter> parameters = function.getValueParameters();
|
||||
if (parameters.size() == 1) {
|
||||
@@ -52,10 +47,24 @@ public class JetMainDetector {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JetFile getFileWithMain(@NotNull List<JetFile> files) {
|
||||
public static JetNamedFunction getMainFunction(@NotNull List<JetFile> files) {
|
||||
for (JetFile file : files) {
|
||||
if (hasMain(file.getDeclarations())) {
|
||||
return file;
|
||||
JetNamedFunction mainFunction = findMainFunction(file.getDeclarations());
|
||||
if (mainFunction != null) {
|
||||
return mainFunction;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetNamedFunction findMainFunction(@NotNull List<JetDeclaration> declarations) {
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
JetNamedFunction candidateFunction = (JetNamedFunction) declaration;
|
||||
if (isMain(candidateFunction)) {
|
||||
return candidateFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -46,6 +46,14 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
||||
|
||||
public static final DescriptorRenderer TEXT = new DescriptorRenderer();
|
||||
|
||||
public static final DescriptorRenderer DEBUG_TEXT = new DescriptorRenderer() {
|
||||
@Override
|
||||
protected boolean hasDefaultValue(ValueParameterDescriptor descriptor) {
|
||||
// hasDefaultValue() has effects
|
||||
return descriptor.declaresDefaultValue();
|
||||
}
|
||||
};
|
||||
|
||||
public static final DescriptorRenderer HTML = new DescriptorRenderer() {
|
||||
|
||||
@Override
|
||||
@@ -79,7 +87,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
||||
@Override
|
||||
public Void visitValueParameterDescriptor(ValueParameterDescriptor descriptor, StringBuilder builder) {
|
||||
super.visitVariableDescriptor(descriptor, builder, true);
|
||||
if (descriptor.hasDefaultValue()) {
|
||||
if (hasDefaultValue(descriptor)) {
|
||||
builder.append(" = ...");
|
||||
}
|
||||
return null;
|
||||
@@ -89,6 +97,10 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
||||
private DescriptorRenderer() {
|
||||
}
|
||||
|
||||
protected boolean hasDefaultValue(ValueParameterDescriptor descriptor) {
|
||||
return descriptor.hasDefaultValue();
|
||||
}
|
||||
|
||||
protected String renderKeyword(String keyword) {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
OUT Buildfile: build.xml
|
||||
OUT
|
||||
OUT build:
|
||||
OUT [kotlinc] Compiling [[TestData]/hello.kt] => [[Temp]/hello.jar]
|
||||
OUT [kotlinc] LOGGING: For source: [TestData]/hello.kt
|
||||
OUT [kotlinc] LOGGING: Emitting: Hello/namespace.class
|
||||
OUT
|
||||
OUT BUILD SUCCESSFUL
|
||||
OUT Total time: [time]
|
||||
Return code: 0
|
||||
@@ -0,0 +1,7 @@
|
||||
<project name="Ant Task Test" default="build">
|
||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||
|
||||
<target name="build">
|
||||
<kotlinc src="${test.data}/hello.kt" output="${temp}/hello.jar"/>
|
||||
</target>
|
||||
</project>
|
||||
@@ -0,0 +1,4 @@
|
||||
OUT ERROR: [TestData]/hello.kt: (4, 5) Unresolved reference: a
|
||||
OUT WARNING: [TestData]/hello.kt: (4, 5) The expression is unused
|
||||
ERR exec() finished with COMPILATION_ERROR return code
|
||||
Return code: 1
|
||||
@@ -0,0 +1,5 @@
|
||||
package Hello
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
a
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package Hello
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
System.out?.println("Hello!")
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
OUT Hello!
|
||||
Return code: 0
|
||||
@@ -0,0 +1 @@
|
||||
Return code: 0
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
package Smoke
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
print("${args[0]}|${args[1]}|${args[2]}")
|
||||
}
|
||||
package Smoke
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
print("${args[0]}|${args[1]}|${args[2]}")
|
||||
}
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
import kotlin.modules.*
|
||||
|
||||
fun project() {
|
||||
module("smoke") {
|
||||
sources += "Smoke.kt"
|
||||
}
|
||||
}
|
||||
import kotlin.modules.*
|
||||
|
||||
fun project() {
|
||||
module("smoke") {
|
||||
sources += "Smoke.kt"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
OUT 1|2|3
|
||||
Return code: 0
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
public class AntTaskTest extends KotlinIntegrationTestBase {
|
||||
@Test
|
||||
public void antTaskJvm() throws Exception {
|
||||
final String jar = tempDir.getAbsolutePath() + File.separator + "hello.jar";
|
||||
|
||||
assertEquals("compilation failed", 0, runAnt("build.log", "build.xml"));
|
||||
runJava("hello.run", "-cp", jar, "Hello.namespace");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String normalizeOutput(String content) {
|
||||
return super.normalizeOutput(content)
|
||||
.replaceAll("Total time: .+\n", "Total time: [time]\n");
|
||||
}
|
||||
|
||||
private int runAnt(String logName, String scriptName) throws Exception {
|
||||
return runJava(logName, "-jar", getAntHome() + File.separator + "lib" + File.separator + "ant-launcher.jar",
|
||||
"-Dkotlin.lib=" + getCompilerLib(),
|
||||
"-Dtest.data=" + testDataDir,
|
||||
"-Dtemp=" + tempDir,
|
||||
"-f", scriptName);
|
||||
}
|
||||
|
||||
private static String getAntHome() {
|
||||
return getKotlinProjectHome().getAbsolutePath() + File.separator + "dependencies" + File.separator + "ant";
|
||||
}
|
||||
}
|
||||
@@ -35,4 +35,19 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase {
|
||||
assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar));
|
||||
runJava("hello.run", "-cp", jar, "Hello.namespace");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compileAndRunModule() throws Exception {
|
||||
final String jar = tempDir.getAbsolutePath() + File.separator + "smoke.jar";
|
||||
|
||||
assertEquals("compilation failed", 0, runCompiler("Smoke.compile", "-module", "Smoke.kts", "-jar", jar));
|
||||
runJava("Smoke.run", "-cp", jar + File.pathSeparator + getKotlinRuntimePath(), "Smoke.namespace", "1", "2", "3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compilationFailed() throws Exception {
|
||||
final String jar = tempDir.getAbsolutePath() + File.separator + "smoke.jar";
|
||||
|
||||
runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar);
|
||||
}
|
||||
}
|
||||
|
||||
+47
-22
@@ -29,12 +29,11 @@ import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.junit.ComparisonFailure;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import sun.misc.JarFilter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -47,12 +46,22 @@ import static org.junit.Assert.*;
|
||||
|
||||
public abstract class KotlinIntegrationTestBase {
|
||||
protected File tempDir;
|
||||
protected File testDataDir;
|
||||
|
||||
@Rule
|
||||
public TestRule watchman = new TestWatcher() {
|
||||
@Override
|
||||
protected void starting(Description description) {
|
||||
tempDir = Files.createTempDir();
|
||||
try {
|
||||
tempDir = Files.createTempDir().getCanonicalFile();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
final File baseTestDataDir =
|
||||
new File(getKotlinProjectHome(), "compiler" + File.separator + "integration-tests" + File.separator + "data");
|
||||
testDataDir = new File(baseTestDataDir, description.getMethodName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,13 +83,7 @@ public abstract class KotlinIntegrationTestBase {
|
||||
protected int runCompiler(String logName, String... arguments) throws Exception {
|
||||
final File lib = getCompilerLib();
|
||||
|
||||
final File[] jars = lib.listFiles(new JarFilter());
|
||||
final String classpath = StringUtil.join(jars, new Function<File, String>() {
|
||||
@Override
|
||||
public String fun(File file) {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}, File.pathSeparator);
|
||||
final String classpath = lib.getAbsolutePath() + File.separator + "kotlin-compiler.jar";
|
||||
|
||||
Collection<String> javaArgs = new ArrayList<String>();
|
||||
javaArgs.add("-cp");
|
||||
@@ -93,7 +96,7 @@ public abstract class KotlinIntegrationTestBase {
|
||||
|
||||
protected int runJava(String logName, String... arguments) throws Exception {
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setWorkDirectory(getTestDataDirectory());
|
||||
commandLine.setWorkDirectory(testDataDir);
|
||||
commandLine.setExePath(getJavaRuntime().getAbsolutePath());
|
||||
commandLine.addParameters(arguments);
|
||||
|
||||
@@ -104,32 +107,52 @@ public abstract class KotlinIntegrationTestBase {
|
||||
assertEquals("Non-zero exit code", 0, exitCode);
|
||||
}
|
||||
else {
|
||||
check(logName, executionLog);
|
||||
check(logName, executionLog.toString());
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
protected void check(String baseName, StringBuilder content) throws IOException {
|
||||
final File tmpFile = new File(getTestDataDirectory(), baseName + ".tmp");
|
||||
final File expectedFile = new File(getTestDataDirectory(), baseName + ".expected");
|
||||
private static String replacePath(String content, File path, String pathId) {
|
||||
final String absolutePath = path.getAbsolutePath();
|
||||
|
||||
return content
|
||||
.replace(absolutePath + "/", pathId + "/")
|
||||
.replace(absolutePath + "\\", pathId + "/")
|
||||
.replace(absolutePath, pathId);
|
||||
}
|
||||
|
||||
protected String normalizeOutput(String content) {
|
||||
content = replacePath(content, testDataDir, "[TestData]");
|
||||
content = replacePath(content, tempDir, "[Temp]");
|
||||
content = replacePath(content, getCompilerLib(), "[CompilerLib]");
|
||||
return content;
|
||||
}
|
||||
|
||||
protected void check(String baseName, String content) throws IOException {
|
||||
final File actualFile = new File(testDataDir, baseName + ".actual");
|
||||
final File expectedFile = new File(testDataDir, baseName + ".expected");
|
||||
|
||||
final String normalizedContent = normalizeOutput(content);
|
||||
|
||||
if (!expectedFile.isFile()) {
|
||||
Files.write(content, tmpFile, Charsets.UTF_8);
|
||||
Files.write(normalizedContent, actualFile, Charsets.UTF_8);
|
||||
fail("No .expected file " + expectedFile);
|
||||
}
|
||||
else {
|
||||
final String goldContent = Files.toString(expectedFile, UTF_8);
|
||||
try {
|
||||
assertEquals(goldContent, content.toString());
|
||||
assertEquals(goldContent, normalizedContent);
|
||||
actualFile.delete();
|
||||
}
|
||||
finally {
|
||||
tmpFile.delete();
|
||||
catch (ComparisonFailure e) {
|
||||
Files.write(normalizedContent, actualFile, Charsets.UTF_8);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int runProcess(final GeneralCommandLine commandLine, final StringBuilder executionLog) throws ExecutionException {
|
||||
protected static int runProcess(final GeneralCommandLine commandLine, final StringBuilder executionLog) throws ExecutionException {
|
||||
OSProcessHandler handler =
|
||||
new OSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString(), commandLine.getCharset());
|
||||
|
||||
@@ -184,8 +207,10 @@ public abstract class KotlinIntegrationTestBase {
|
||||
return file;
|
||||
}
|
||||
|
||||
protected static File getTestDataDirectory() {
|
||||
return new File(getKotlinProjectHome(), "compiler" + File.separator + "integration-tests" + File.separator + "data");
|
||||
protected static String getKotlinRuntimePath() {
|
||||
final File file = new File(getCompilerLib(), "kotlin-runtime.jar");
|
||||
assertTrue("no kotlin runtime at " + file, file.isFile());
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
protected static File getKotlinProjectHome() {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
//KT-1061 Can't call function defined as a val
|
||||
|
||||
object X {
|
||||
val doit = { (i: Int) -> i }
|
||||
}
|
||||
|
||||
fun box() : String = if (X.doit(3) == 3) "OK" else "fail"
|
||||
@@ -0,0 +1,12 @@
|
||||
//KT-1249 IllegalStateException invoking function property
|
||||
class TestClass(val body : () -> Unit) : Any {
|
||||
fun run() {
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
TestClass({}).run()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//KT-1290 Method property in constructor causes NPE
|
||||
|
||||
class Foo<T>(val filter: (T) -> Boolean) {
|
||||
public fun bar(tee: T) : Boolean {
|
||||
return filter(tee);
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() = Foo({ (i: Int) -> i < 5 }).bar(2)
|
||||
|
||||
fun box() : String {
|
||||
if (!foo()) return "fail"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
abstract class Foo<T> {
|
||||
fun hello(id: T) = "O$id"
|
||||
}
|
||||
|
||||
class Bar: Foo<String>() {
|
||||
}
|
||||
|
||||
fun box() = Bar().hello("K")
|
||||
@@ -23,43 +23,7 @@ trait ChannelPipelineFactory {
|
||||
fun getPipeline() : ChannelPipeline
|
||||
}
|
||||
|
||||
fun testKt606() {
|
||||
StandardPipelineFactory({ print("OK") }).getPipeline()
|
||||
}
|
||||
|
||||
//Tests for duplicates
|
||||
//KT-1061 Can't call function defined as a val
|
||||
object X {
|
||||
val doit = { (i: Int) -> i }
|
||||
}
|
||||
|
||||
fun testKt1061() : String = if (X.doit(3) == 3) "OK" else "fail"
|
||||
|
||||
|
||||
//KT-1249 IllegalStateException invoking function property
|
||||
class TestClass(val body : () -> Unit) : Any {
|
||||
fun run() {
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
fun testKt1249() {
|
||||
TestClass({}).run()
|
||||
}
|
||||
|
||||
class Foo<T>(val filter: (T) -> Boolean) {
|
||||
public fun bar(tee: T) : Boolean {
|
||||
return filter(tee);
|
||||
}
|
||||
}
|
||||
|
||||
//KT-1290 Method property in constructor causes NPE
|
||||
fun testKt1290() = Foo({ (i: Int) -> i < 5 }).bar(2)
|
||||
|
||||
fun box() : String {
|
||||
testKt606()
|
||||
testKt1061()
|
||||
testKt1249()
|
||||
if (!testKt1290()) return "fail"
|
||||
StandardPipelineFactory({ print("OK") }).getPipeline()
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package a
|
||||
|
||||
fun foo(<!UNUSED_PARAMETER!>i<!>: Int, <!UNUSED_PARAMETER!>s<!>: String) {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(<!TYPE_MISMATCH!>""<!>, <!ERROR_COMPILE_TIME_VALUE!>1<!>, <!TOO_MANY_ARGUMENTS, UNRESOLVED_REFERENCE!>xx<!>)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//KT-1940 Exception while repeating named parameters
|
||||
package kt1940
|
||||
|
||||
fun foo(<!UNUSED_PARAMETER!>i<!>: Int) {}
|
||||
|
||||
fun test() {
|
||||
foo(1, <!ARGUMENT_PASSED_TWICE, MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>i<!> = 2) //exception
|
||||
foo(i = 1, <!ARGUMENT_PASSED_TWICE!>i<!> = 2) //exception
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
class In<in T>() {
|
||||
fun f(<!UNUSED_PARAMETER!>t<!> : T) : Unit {}
|
||||
fun f(<!UNUSED_PARAMETER!>t<!> : Int) : Int = 1
|
||||
fun f1(<!UNUSED_PARAMETER!>t<!> : T) : Unit {}
|
||||
}
|
||||
|
||||
class Out<out T>() {
|
||||
fun f() : T {throw IllegalStateException()}
|
||||
fun f(a : Int) : Int = a
|
||||
}
|
||||
|
||||
class Inv<T>() {
|
||||
fun f(t : T) : T = t
|
||||
fun inf(<!UNUSED_PARAMETER!>t<!> : T) : Unit {}
|
||||
fun outf() : T {throw IllegalStateException()}
|
||||
}
|
||||
|
||||
fun testInOut() {
|
||||
In<String>().f("1");
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<in String>).f("1")
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<out String>).f(<!TYPE_MISMATCH!>"1"<!>) // Wrong Arg
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<*>).f(<!TYPE_MISMATCH!>"1"<!>) // Wrong Arg
|
||||
|
||||
In<String>().f(1);
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<in String>).f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<out String>).f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<out String>).<!UNRESOLVED_REFERENCE!>f1<!>(1) // !!
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<*>).f(1);
|
||||
|
||||
Out<Int>().f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<out Int>).f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<in Int>).f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<*>).f(1)
|
||||
|
||||
Out<Int>().f()
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<out Int>).f()
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<in Int>).f()
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<*>).f()
|
||||
|
||||
Inv<Int>().f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).f(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).<!UNRESOLVED_REFERENCE!>f<!>(1) // !!
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).<!UNRESOLVED_REFERENCE!>f<!>(1) // !!
|
||||
|
||||
Inv<Int>().inf(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).inf(1)
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).<!UNRESOLVED_REFERENCE!>inf<!>(1) // !!
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).<!UNRESOLVED_REFERENCE!>inf<!>(1) // !!
|
||||
|
||||
Inv<Int>().outf()
|
||||
<!TYPE_MISMATCH!>(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).outf()<!> : Int // Type mismatch
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).outf()
|
||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).outf()
|
||||
|
||||
Inv<Int>().outf(<!TOO_MANY_ARGUMENTS!>1<!>) // Wrong Arg
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
open class C<T : C<T>>
|
||||
class TestOK : C<TestOK>()
|
||||
class TestFail : C<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>C<<!UPPER_BOUND_VIOLATED!>TestFail<!>><!>>()
|
||||
@@ -0,0 +1 @@
|
||||
class D<A : D<A, <!UPPER_BOUND_VIOLATED!>String<!>>, B : D<A, B>>
|
||||
@@ -0,0 +1,16 @@
|
||||
// FILE: Aaa.java
|
||||
// http://youtrack.jetbrains.com/issue/KT-1880
|
||||
|
||||
public class Aaa {
|
||||
public static final int i = 1;
|
||||
}
|
||||
|
||||
// FILE: Bbb.java
|
||||
|
||||
public class Bbb extends Aaa {
|
||||
public static final String i = "s";
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
fun foo() = Bbb.i
|
||||
@@ -0,0 +1,10 @@
|
||||
//KT-1736 AssertionError in CallResolver
|
||||
|
||||
package kt1736
|
||||
|
||||
object Obj {
|
||||
fun method() {
|
||||
}
|
||||
}
|
||||
|
||||
val x = Obj.method<!TOO_MANY_ARGUMENTS, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{ -> }<!>
|
||||
@@ -0,0 +1,13 @@
|
||||
//KT-1244 Frontend allows access to private members of other classes
|
||||
|
||||
package kt1244
|
||||
|
||||
class A {
|
||||
private var a = ""
|
||||
}
|
||||
|
||||
class B() {
|
||||
{
|
||||
A().<!INVISIBLE_MEMBER!>a<!> = "Hello"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
//KT-1738 Make it possible to define visibility for constructor parameters which become properties
|
||||
|
||||
package kt1738
|
||||
|
||||
class A(private var i: Int, var j: Int) {
|
||||
}
|
||||
|
||||
fun test(a: A) {
|
||||
a.<!INVISIBLE_MEMBER!>i<!>++
|
||||
a.j++
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test;
|
||||
|
||||
interface Foo {}
|
||||
|
||||
class MethodTypePOneUpperBound {
|
||||
<T extends Foo> void bar() {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
trait Foo : java.lang.Object
|
||||
|
||||
open class MethodTypePOneUpperBound() : java.lang.Object() {
|
||||
open fun <erased T : Foo?> bar() = #()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.Foo : java.lang.Object {
|
||||
}
|
||||
open class test.MethodTypePOneUpperBound : java.lang.Object {
|
||||
final /*constructor*/ fun <init>(): test.MethodTypePOneUpperBound
|
||||
open fun </*0*/ T : test.Foo?>bar(): jet.Tuple0
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test;
|
||||
|
||||
interface Foo {}
|
||||
interface Bar {}
|
||||
|
||||
class MethodTypePTwoUpperBounds {
|
||||
<T extends Foo & Bar> void foo() {}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package test
|
||||
|
||||
trait Foo : java.lang.Object
|
||||
trait Bar : java.lang.Object
|
||||
|
||||
open class MethodTypePTwoUpperBounds() : java.lang.Object() {
|
||||
open fun <erased T> foo(): Unit
|
||||
where T : Foo?, T : Bar?
|
||||
{}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.Foo : java.lang.Object {
|
||||
}
|
||||
abstract trait test.Bar : java.lang.Object {
|
||||
}
|
||||
open class test.MethodTypePTwoUpperBounds : java.lang.Object {
|
||||
final /*constructor*/ fun <init>(): test.MethodTypePTwoUpperBounds
|
||||
open fun </*0*/ T : test.Bar? & test.Foo?>foo(): jet.Tuple0
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
trait Foo
|
||||
trait Bar
|
||||
|
||||
fun <T> foo()
|
||||
where T : Foo, T : Bar
|
||||
= #()
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.Foo : jet.Any {
|
||||
}
|
||||
abstract trait test.Bar : jet.Any {
|
||||
}
|
||||
final fun </*0,r*/ T : test.Bar & test.Foo>foo(): jet.Tuple0
|
||||
@@ -52,7 +52,7 @@ public class CompileCompilerDependenciesTest {
|
||||
public static CompilerDependencies compilerDependenciesForTests(@NotNull CompilerSpecialMode compilerSpecialMode, boolean mockJdk) {
|
||||
return new CompilerDependencies(
|
||||
compilerSpecialMode,
|
||||
mockJdk ? JetTestUtils.findMockJdkRtJar() : CompilerDependencies.findRtJar(),
|
||||
compilerSpecialMode.includeJdk() ? (mockJdk ? JetTestUtils.findMockJdkRtJar() : CompilerDependencies.findRtJar()) : null,
|
||||
compilerSpecialMode.includeJdkHeaders() ? ForTestCompileJdkHeaders.jdkHeadersForTests() : null,
|
||||
compilerSpecialMode.includeKotlinRuntime() ? ForTestCompileRuntime.runtimeJarForTests() : null);
|
||||
}
|
||||
|
||||
+34
-8
@@ -91,12 +91,18 @@ public class ResolveDescriptorsFromExternalLibraries {
|
||||
|
||||
hasErrors |= testLibrary("com.google.guava", "guava", "12.0-rc2");
|
||||
hasErrors |= testLibrary("org.springframework", "spring-core", "3.1.1.RELEASE");
|
||||
hasErrors |= testLibrary("com.vaadin", "vaadin", "6.6.8");
|
||||
hasErrors |= testLibraryFromUrl("http://mcvaadin.googlecode.com/files/mcvaadin.jar");
|
||||
return hasErrors;
|
||||
}
|
||||
|
||||
private boolean testLibraryFromUrl(@NotNull String urlJar) throws Exception {
|
||||
return testLibraryFile(getLibraryFromUrl(urlJar), urlJar);
|
||||
}
|
||||
|
||||
private boolean testLibrary(@NotNull String org, @NotNull String module, @NotNull String rev) throws Exception {
|
||||
LibFromMaven lib = new LibFromMaven(org, module, rev);
|
||||
File jar = getLibrary(lib);
|
||||
File jar = getLibraryFromMaven(lib);
|
||||
|
||||
return testLibraryFile(jar, lib.toString());
|
||||
}
|
||||
@@ -185,22 +191,40 @@ public class ResolveDescriptorsFromExternalLibraries {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File getLibrary(@NotNull LibFromMaven lib) throws Exception {
|
||||
File userHome = new File(System.getProperty("user.home"));
|
||||
String fileName = lib.getModule() + "-" + lib.getRev() + ".jar";
|
||||
private File getLibraryFromUrl(@NotNull String url) throws Exception {
|
||||
|
||||
File dir = new File(userHome, ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule());
|
||||
String fileName = url
|
||||
.replaceAll("^http://", "")
|
||||
.replaceAll("/", "_")
|
||||
;
|
||||
File dir = new File(userHome(), ".kotlin-project/resolve-libraries");
|
||||
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
return getFileFromUrl(url, file, url);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File getLibraryFromMaven(@NotNull LibFromMaven lib) throws Exception {
|
||||
String fileName = lib.getModule() + "-" + lib.getRev() + ".jar";
|
||||
|
||||
File dir = new File(userHome(), ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule());
|
||||
|
||||
File file = new File(dir, fileName);
|
||||
String uri = url(lib);
|
||||
|
||||
return getFileFromUrl(lib.toString(), file, uri);
|
||||
}
|
||||
|
||||
private File getFileFromUrl(@NotNull String lib, @NotNull File file, @NotNull String uri) throws IOException {
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
|
||||
JetTestUtils.mkdirs(dir);
|
||||
JetTestUtils.mkdirs(file.getParentFile());
|
||||
|
||||
File tmp = new File(dir, fileName + "~");
|
||||
File tmp = new File(file.getPath() + "~");
|
||||
|
||||
String uri = url(lib);
|
||||
GetMethod method = new GetMethod(uri);
|
||||
|
||||
FileOutputStream os = null;
|
||||
@@ -252,6 +276,8 @@ public class ResolveDescriptorsFromExternalLibraries {
|
||||
}
|
||||
}
|
||||
|
||||
private static File userHome() {return new File(System.getProperty("user.home"));}
|
||||
|
||||
private static String url(LibFromMaven lib) {
|
||||
return "http://repo1.maven.org/maven2/" + lib.getOrg().replace(".", "/") + "/" + lib.getModule() + "/" + lib.getRev()
|
||||
+ "/" + lib.getModule() + "-" + lib.getRev() + ".jar";
|
||||
|
||||
@@ -76,8 +76,24 @@ public class ExtensionFunctionsTest extends CodegenTestCase {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS);
|
||||
blackBoxFile("extensionFunctions/nested2.kt");
|
||||
}
|
||||
|
||||
public void testKt606() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS);
|
||||
blackBoxFile("regressions/kt606.kt");
|
||||
}
|
||||
|
||||
public void testKt1061() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS);
|
||||
blackBoxFile("regressions/kt1061.kt");
|
||||
}
|
||||
|
||||
public void testKt1249() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS);
|
||||
blackBoxFile("regressions/kt1249.kt");
|
||||
}
|
||||
|
||||
public void testKt1290() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.BUILTINS);
|
||||
blackBoxFile("regressions/kt1290.kt");
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user