Merge branch 'master' of github.com:JetBrains/kotlin

This commit is contained in:
James Strachan
2012-05-10 21:59:29 +01:00
192 changed files with 2679 additions and 2875 deletions
+1 -9
View File
@@ -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
View File
Executable → Regular
View File
-173
View File
@@ -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 | &nbsp; |
| {align:center}{{*module*}}{align} | Kotlin [module|http://confluence.jetbrains.net/display/Kotlin/Modules+and+Compilation] to compile | {{"src"}} or {{"module"}} needs to be specified | &nbsp; |
| {align:center}{{*output*}}{align} | Destination directory | If {{"src"}} is used - {{"output"}} or {{"jar"}} needs to be specified | &nbsp; |
| {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} | &nbsp; |
| {align:center}{{*classpathref*}}{align} | Compilation class path reference | {align:center}{{false}}{align} | &nbsp; |
| {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
+11 -1
View File
@@ -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>
-503
View File
@@ -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="&lt;a href=&quot;http://jetbrains.com/kotlin&quot;&gt;"/>-->
<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="&lt;a href=&quot;http://jetbrains.com/kotlin&quot;&gt;"/>-->
</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>
-20
View File
@@ -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>
-25
View File
@@ -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
-3
View File
@@ -1,3 +0,0 @@
fun main(args : Array<String>) {
System.out?.println("Hello, world!")
}
-7
View File
@@ -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]}!")
}
-4
View File
@@ -1,4 +0,0 @@
fun main(args : Array<String>) {
for (name in args)
System.out?.println("Hello, $name!")
}
-9
View File
@@ -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"
})
}
-9
View File
@@ -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)
-167
View File
@@ -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
}
-226
View File
@@ -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
}
+324 -233
View File
@@ -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;
+86
View File
@@ -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 "$@"
+37
View File
@@ -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();
}
@@ -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;
@@ -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);
}
@@ -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;
}
@@ -70,7 +70,7 @@ class JavaDescriptorResolverHelper {
return false;
}
if (!staticMembers && member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) {
if (member.getPsiMember().getContainingClass() != psiClass.getPsiClass()) {
return false;
}
@@ -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
@@ -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) {
@@ -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) {
@@ -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;
}
}
}
@@ -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
@@ -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]}")
}
@@ -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);
}
}
@@ -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")
+2 -38
View File
@@ -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
}
@@ -0,0 +1,8 @@
package test
trait Foo
trait Bar
fun <T> foo()
where T : Foo, T : Bar
= #()
@@ -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);
}
@@ -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