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