mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-27 00:21:29 +00:00
Compare commits
180 Commits
get-script
...
build-docs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31060c3352 | ||
|
|
0b5c285eff | ||
|
|
6541e58902 | ||
|
|
aac0cd68f1 | ||
|
|
006268b4a5 | ||
|
|
53bb95c032 | ||
|
|
c0e9cfbf34 | ||
|
|
a61d8c0fbb | ||
|
|
72dd2e4b64 | ||
|
|
56a9086248 | ||
|
|
fffe2e812a | ||
|
|
341e9543c3 | ||
|
|
2e15fe7e19 | ||
|
|
58444eb769 | ||
|
|
3a57737379 | ||
|
|
608e17ca16 | ||
|
|
e4167473e9 | ||
|
|
776faec1e2 | ||
|
|
1b7f57c84e | ||
|
|
8878843a16 | ||
|
|
777d81c351 | ||
|
|
48e75bf869 | ||
|
|
a203e7e129 | ||
|
|
c63562e956 | ||
|
|
c35d7905a0 | ||
|
|
ed04194185 | ||
|
|
7f8c57a2e5 | ||
|
|
7e26cc23aa | ||
|
|
3451bc250c | ||
|
|
c9ab1f7521 | ||
|
|
53e9f2caef | ||
|
|
2ff7e27634 | ||
|
|
8c8ed411c6 | ||
|
|
e6e7f334bd | ||
|
|
1775856d8e | ||
|
|
df423cfb61 | ||
|
|
85033abc7c | ||
|
|
2ebfe809b3 | ||
|
|
a682d35edd | ||
|
|
81f6ea621e | ||
|
|
1b55bbc5da | ||
|
|
0b7576f246 | ||
|
|
30fb24911c | ||
|
|
6f69a9c96e | ||
|
|
90db318cc7 | ||
|
|
4d2e9dd070 | ||
|
|
9ab9fb45fb | ||
|
|
22514a132e | ||
|
|
6dbe3ae123 | ||
|
|
d28497987d | ||
|
|
9ebdd5ebaf | ||
|
|
cae95e5247 | ||
|
|
e56ea84084 | ||
|
|
8fa55ccbde | ||
|
|
6f2ab29889 | ||
|
|
708b813ef2 | ||
|
|
15cd5411de | ||
|
|
093c2bfeda | ||
|
|
8746113e08 | ||
|
|
8e2d24341f | ||
|
|
79c52eeaa0 | ||
|
|
4221fc8813 | ||
|
|
97b66cdeb6 | ||
|
|
478caf27e1 | ||
|
|
4f6edbaf69 | ||
|
|
b7e1cd95a6 | ||
|
|
05fb47531a | ||
|
|
59caeff3db | ||
|
|
adc74268f4 | ||
|
|
63e109b061 | ||
|
|
e73f70d323 | ||
|
|
591b972bfd | ||
|
|
f113624180 | ||
|
|
0ca1481fd6 | ||
|
|
84ca3735ff | ||
|
|
99f9b5e4a9 | ||
|
|
6a4e7c8c3e | ||
|
|
716efa9ba2 | ||
|
|
4fe07270e6 | ||
|
|
ecd828e479 | ||
|
|
98d842841a | ||
|
|
ab82ab0a9b | ||
|
|
b4af84f44e | ||
|
|
5412f0ca00 | ||
|
|
03508e309a | ||
|
|
194ea17413 | ||
|
|
5219033917 | ||
|
|
ce267dca54 | ||
|
|
f6d652a5d4 | ||
|
|
5a73faf09c | ||
|
|
1a4cbb4687 | ||
|
|
baa7fe71b8 | ||
|
|
b39bb3d10d | ||
|
|
41bb820083 | ||
|
|
a9d66e30a2 | ||
|
|
15539122c9 | ||
|
|
24376fd857 | ||
|
|
6c9fe38ff7 | ||
|
|
80432d7b71 | ||
|
|
056d631a65 | ||
|
|
27d389f9e5 | ||
|
|
917da3d445 | ||
|
|
441148fa9e | ||
|
|
62510f6ead | ||
|
|
41c8efc688 | ||
|
|
1f31aa82f3 | ||
|
|
6e506fccde | ||
|
|
5317abb00d | ||
|
|
5595bea2ea | ||
|
|
36a6288dee | ||
|
|
411962ee57 | ||
|
|
6532442701 | ||
|
|
53cfd2095d | ||
|
|
6b47229cf8 | ||
|
|
6991eadcf5 | ||
|
|
25ed1553d1 | ||
|
|
279bbb4732 | ||
|
|
d6f86b7c05 | ||
|
|
61664c02cd | ||
|
|
52a33cc494 | ||
|
|
f80e78ac57 | ||
|
|
d3587bb028 | ||
|
|
2aff73b432 | ||
|
|
f08fd888a8 | ||
|
|
08abb61e12 | ||
|
|
ef6669e865 | ||
|
|
e7f7673123 | ||
|
|
e85ca8de52 | ||
|
|
c6385f9309 | ||
|
|
c2417ac243 | ||
|
|
9e236c4a23 | ||
|
|
dd32987eb2 | ||
|
|
b141f3754a | ||
|
|
2fc74d2819 | ||
|
|
6c6e163881 | ||
|
|
0ee4ddfda9 | ||
|
|
01c92992c9 | ||
|
|
4154bba5a3 | ||
|
|
cf6cef71e2 | ||
|
|
ce5a104eb2 | ||
|
|
94b5148d5b | ||
|
|
5c0831d5ad | ||
|
|
894f85d822 | ||
|
|
9e1a4992d8 | ||
|
|
1b7198cb03 | ||
|
|
24182e39d8 | ||
|
|
b6e32cc03d | ||
|
|
4518c5bac6 | ||
|
|
58ad4b1386 | ||
|
|
1f62636400 | ||
|
|
b10adf2de0 | ||
|
|
5befeb4ccf | ||
|
|
614a4fec22 | ||
|
|
bd45c70083 | ||
|
|
2961301297 | ||
|
|
bdde75a6a3 | ||
|
|
e325523034 | ||
|
|
84f17ba1a1 | ||
|
|
c649752e8e | ||
|
|
9cace66246 | ||
|
|
6375fb773d | ||
|
|
b6f1cf8107 | ||
|
|
86ced88e0d | ||
|
|
06e909acad | ||
|
|
95d774697c | ||
|
|
7bc246f614 | ||
|
|
a2bb0ace05 | ||
|
|
3594294d0a | ||
|
|
fca79f9bf9 | ||
|
|
fd5bb25349 | ||
|
|
5fbd738f24 | ||
|
|
63e4beab76 | ||
|
|
89caa70987 | ||
|
|
ea8b082355 | ||
|
|
ae0218431c | ||
|
|
77dff7b7f5 | ||
|
|
15502b4153 | ||
|
|
b9891c36e2 | ||
|
|
d3a9008bd3 | ||
|
|
249a3a0ec9 |
2
.idea/libraries/asm.xml
generated
2
.idea/libraries/asm.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm-src.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/idea_full.xml
generated
2
.idea/libraries/idea_full.xml
generated
@@ -10,8 +10,8 @@
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm-src.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/lib" recursive="false" />
|
||||
</library>
|
||||
|
||||
2
.idea/libraries/intellij_core.xml
generated
2
.idea/libraries/intellij_core.xml
generated
@@ -10,8 +10,8 @@
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm-src.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/core" recursive="false" />
|
||||
</library>
|
||||
|
||||
17
.idea/libraries/intellij_core_analysis.xml
generated
17
.idea/libraries/intellij_core_analysis.xml
generated
@@ -1,17 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="intellij-core-analysis">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core-analysis/intellij-core-analysis.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2632
ChangeLog.md
2632
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
private val NORMAL_VERSION = 8
|
||||
private val EXPERIMENTAL_VERSION = 4
|
||||
@@ -40,8 +41,16 @@ class CacheVersion(
|
||||
) {
|
||||
private val isEnabled by lazy(isEnabled)
|
||||
|
||||
private val actualVersion: Int
|
||||
get() = versionFile.readText().toInt()
|
||||
private val actualVersion: Int?
|
||||
get() = try {
|
||||
versionFile.readText().toInt()
|
||||
}
|
||||
catch (e: NumberFormatException) {
|
||||
null
|
||||
}
|
||||
catch (e: IOException) {
|
||||
null
|
||||
}
|
||||
|
||||
private val expectedVersion: Int
|
||||
get() {
|
||||
|
||||
@@ -9743,6 +9743,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -9756,6 +9757,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -10463,6 +10465,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -10478,6 +10481,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -11822,6 +11826,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -11837,6 +11842,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -11852,6 +11858,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -11870,6 +11877,7 @@ public final class DebugProtoBuf {
|
||||
*ClassKind
|
||||
*isInner
|
||||
*isData
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
@@ -17725,6 +17733,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -17741,6 +17751,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -18084,6 +18096,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -18102,6 +18116,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -18913,6 +18929,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -18931,6 +18949,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -18949,6 +18969,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -18970,6 +18992,8 @@ public final class DebugProtoBuf {
|
||||
*isInline
|
||||
*isTailrec
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
@@ -20015,6 +20039,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -20034,6 +20059,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -20391,6 +20417,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -20412,6 +20439,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -21211,6 +21239,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -21232,6 +21261,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -21253,6 +21283,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -21277,6 +21308,7 @@ public final class DebugProtoBuf {
|
||||
*hasConstant
|
||||
*isExternal
|
||||
*isDelegated
|
||||
*isHeader
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
|
||||
62
build.xml
62
build.xml
@@ -5,7 +5,7 @@
|
||||
<!-- 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="generate.javadoc" value="false"/>
|
||||
|
||||
<!-- Set to false to prevent jarjar and metadata stripping on kotlin-reflect.jar and reflection sources. Use to debug reflection -->
|
||||
<property name="obfuscate.reflect" value="true"/>
|
||||
@@ -584,7 +584,18 @@
|
||||
</fileset>
|
||||
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/annotations.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/asm-all.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/guava-19.0.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/intellij-core.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/jdom.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/jna.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/log4j.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/picocontainer.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/snappy-in-java-0.5.1.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/trove4j.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/xpp3-1.1.4-min.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/xstream-1.4.8.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-platform.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/oromatcher.jar"/>
|
||||
<zipfileset src="${idea.sdk}/jps/jps-model.jar"/>
|
||||
@@ -770,41 +781,40 @@
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
<jar jarfile="${output}/kotlin-daemon-client-sources.jar">
|
||||
<fileset dir="compiler/daemon/daemon-common/src"/>
|
||||
<fileset dir="compiler/daemon/daemon-client/src"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.daemon.client.sources}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="compiler-client-embeddable">
|
||||
<cleandir dir="${output}/classes/compiler-client-embeddable"/>
|
||||
<javac2 destdir="${output}/classes/compiler-client-embeddable" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<withKotlin modulename="compiler-deps">
|
||||
<compilerarg value="-version"/>
|
||||
</withKotlin>
|
||||
<src>
|
||||
<pathelement path="compiler/daemon/daemon-common/src"/>
|
||||
<pathelement path="compiler/cli/cli-common/"/>
|
||||
</src>
|
||||
<classpath>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
|
||||
</classpath>
|
||||
</javac2>
|
||||
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
|
||||
|
||||
<jarjar jarfile="${output}/kotlin-compiler-client-embeddable-before-shrink.jar">
|
||||
<jarjar jarfile="${kotlin-home}/lib/kotlin-compiler-client-embeddable.jar">
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
<zipfileset src="${kotlin-home}/lib/kotlin-daemon-client.jar"/>
|
||||
<fileset dir="${output}/classes/compiler"
|
||||
includes="org/jetbrains/kotlin/daemon/common/** org/jetbrains/kotlin/cli/common/messages/CompilerMessage* org/jetbrains/kotlin/cli/common/messages/Message* org/jetbrains/kotlin/cli/common/repl/**"/>
|
||||
<zipfileset src="${kotlin-home}/lib/kotlin-daemon-client.jar" excludes="net/rubygrapefruit/platform/** net/ net/rubygrapefruit/"/>
|
||||
<fileset dir="${output}/classes/compiler-client-embeddable"
|
||||
includes="META-INF/** org/jetbrains/kotlin/daemon/common/** org/jetbrains/kotlin/cli/common/messages/CompilerMessage* org/jetbrains/kotlin/cli/common/messages/Message* org/jetbrains/kotlin/cli/common/repl/**"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.client,embeddable}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.client.embeddable}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
<attribute name="Class-Path" value="kotlin-stdlib.jar"/>
|
||||
</manifest>
|
||||
</jarjar>
|
||||
|
||||
<shrink configuration="${basedir}/compiler/compiler-client.pro"/>
|
||||
</target>
|
||||
|
||||
<target name="android-extensions-compiler">
|
||||
@@ -1021,6 +1031,8 @@
|
||||
<element name="class-path"/>
|
||||
|
||||
<sequential>
|
||||
<property environment="env"/>
|
||||
|
||||
<cleandir dir="@{output}"/>
|
||||
|
||||
<dirset dir="${basedir}" id="src.dirset">
|
||||
@@ -1053,6 +1065,8 @@
|
||||
<arg line="@{additionalOptions}"/>
|
||||
<arg value="-classpath"/>
|
||||
<arg value="${toString:classpath.path}"/>
|
||||
<arg value="-jdk-home" />
|
||||
<arg value="${env.JDK_16}" />
|
||||
<arg value="-module-name"/>
|
||||
<arg value="@{moduleName}"/>
|
||||
<arg value="-Xallow-kotlin-package"/>
|
||||
@@ -1384,7 +1398,7 @@
|
||||
depends="builtins,stdlib,kotlin-test,core,reflection,pack-runtime,pack-runtime-sources,script-runtime,mock-runtime-for-test"/>
|
||||
|
||||
<target name="dist"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,sam-with-receiver-compiler-plugin,source-sections-compiler-plugin,annotation-processing-under-jdk8,daemon-client,kotlin-build-common-test"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,sam-with-receiver-compiler-plugin,source-sections-compiler-plugin,annotation-processing-under-jdk8,daemon-client,compiler-client-embeddable,kotlin-build-common-test"
|
||||
description="Builds redistributables from sources"/>
|
||||
|
||||
<target name="dist-quick"
|
||||
|
||||
@@ -65,7 +65,17 @@ public abstract class AnnotationCodegen {
|
||||
new JvmFlagAnnotation("kotlin.jvm.Synchronized", Opcodes.ACC_SYNCHRONIZED)
|
||||
);
|
||||
|
||||
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {};
|
||||
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String name, @NotNull String desc) {
|
||||
return safe(super.visitAnnotation(name, desc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return safe(super.visitArray(name));
|
||||
}
|
||||
};
|
||||
|
||||
private final InnerClassConsumer innerClassConsumer;
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
|
||||
@@ -85,6 +85,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
|
||||
import static org.jetbrains.kotlin.types.Variance.INVARIANT;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -367,6 +368,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (context.closure != null)
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
|
||||
|
||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||
extension.generateClassSyntheticParts(this);
|
||||
}
|
||||
@@ -1306,14 +1309,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
CodegenUtilKt.reportTarget6InheritanceErrorIfNeeded(descriptor, myClass.getPsiOrParent(), restrictedInheritance, state);
|
||||
}
|
||||
|
||||
private void generateDelegationToDefaultImpl(@NotNull final FunctionDescriptor traitFun, @NotNull final FunctionDescriptor inheritedFun) {
|
||||
private void generateDelegationToDefaultImpl(@NotNull final FunctionDescriptor interfaceFun, @NotNull final FunctionDescriptor inheritedFun) {
|
||||
functionCodegen.generateMethod(
|
||||
JvmDeclarationOriginKt.DelegationToDefaultImpls(descriptorToDeclaration(traitFun), traitFun),
|
||||
new JvmDeclarationOrigin(CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun),
|
||||
inheritedFun,
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
DeclarationDescriptor containingDeclaration = traitFun.getContainingDeclaration();
|
||||
DeclarationDescriptor containingDeclaration = interfaceFun.getContainingDeclaration();
|
||||
if (!DescriptorUtils.isInterface(containingDeclaration)) return;
|
||||
|
||||
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
|
||||
@@ -1325,12 +1328,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
||||
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
|
||||
|
||||
Method traitMethod = typeMapper.mapAsmMethod(traitFun.getOriginal(), OwnerKind.DEFAULT_IMPLS);
|
||||
Method traitMethod = typeMapper.mapAsmMethod(interfaceFun.getOriginal(), OwnerKind.DEFAULT_IMPLS);
|
||||
|
||||
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
|
||||
Type[] originalArgTypes = traitMethod.getArgumentTypes();
|
||||
assert originalArgTypes.length == argTypes.length + 1 :
|
||||
"Invalid trait implementation signature: " + signature + " vs " + traitMethod + " for " + traitFun;
|
||||
"Invalid trait implementation signature: " + signature + " vs " + traitMethod + " for " + interfaceFun;
|
||||
|
||||
InstructionAdapter iv = codegen.v;
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
|
||||
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DelegationToDefaultImpls
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
@@ -48,8 +48,10 @@ class InterfaceImplBodyCodegen(
|
||||
get() = (v as InterfaceImplClassBuilder).isAnythingGenerated
|
||||
|
||||
override fun generateDeclaration() {
|
||||
val codegenFlags = ACC_PUBLIC or ACC_FINAL or ACC_SUPER
|
||||
val flags = if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) codegenFlags or ACC_STATIC else codegenFlags
|
||||
v.defineClass(
|
||||
myClass.psiOrParent, state.classFileVersion, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
|
||||
myClass.psiOrParent, state.classFileVersion, flags,
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
@@ -113,7 +115,10 @@ class InterfaceImplBodyCodegen(
|
||||
if (delegateTo is JavaMethodDescriptor) return
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
DelegationToDefaultImpls(DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor),
|
||||
JvmDeclarationOrigin(
|
||||
JvmDeclarationOriginKind.DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL,
|
||||
DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor
|
||||
),
|
||||
descriptor,
|
||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
abstract class SignatureCollectingClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
delegate: ClassBuilderFactory, val shouldGenerate: (JvmDeclarationOrigin) -> Boolean
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
|
||||
protected abstract fun handleClashingSignatures(data: ConflictingJvmDeclarationsData)
|
||||
@@ -57,11 +57,17 @@ abstract class SignatureCollectingClassBuilderFactory(
|
||||
|
||||
override fun newField(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor {
|
||||
signatures.putValue(RawSignature(name, desc, MemberKind.FIELD), origin)
|
||||
if (!shouldGenerate(origin)) {
|
||||
return AbstractClassBuilder.EMPTY_FIELD_VISITOR
|
||||
}
|
||||
return super.newField(origin, access, name, desc, signature, value)
|
||||
}
|
||||
|
||||
override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor {
|
||||
signatures.putValue(RawSignature(name, desc, MemberKind.METHOD), origin)
|
||||
if (!shouldGenerate(origin)) {
|
||||
return AbstractClassBuilder.EMPTY_METHOD_VISITOR
|
||||
}
|
||||
return super.newMethod(origin, access, name, desc, signature, exceptions)
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class OptimizationMethodVisitor extends TransformationMethodVisitor {
|
||||
private static final MethodTransformer MANDATORY_METHOD_TRANSFORMER = new FixStackWithLabelNormalizationMethodTransformer();
|
||||
|
||||
private static final MethodTransformer[] OPTIMIZATION_TRANSFORMERS = new MethodTransformer[] {
|
||||
new CapturedVarsOptimizationMethodTransformer(),
|
||||
//new CapturedVarsOptimizationMethodTransformer(),
|
||||
new RedundantNullCheckV2MethodTransformer(),
|
||||
new RedundantCheckCastEliminationMethodTransformer(),
|
||||
new RedundantBoxingMethodTransformer(),
|
||||
|
||||
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.codegen.optimization
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.nullCheck.popReferenceValueBefore
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -44,6 +41,10 @@ class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
|
||||
val insnType = Type.getObjectType(insn.desc)
|
||||
if (!isTrivialSubtype(insnType, valueType)) continue
|
||||
|
||||
//Keep casts to multiarray types cause dex doesn't recognize ANEWARRAY [Ljava/lang/Object; as Object [][], but Object [] type
|
||||
//It's not clear is it bug in dex or not and maybe best to distinguish such types from MULTINEWARRRAY ones in method analyzer
|
||||
if (isMultiArrayType(insnType)) continue
|
||||
|
||||
if (insn.opcode == Opcodes.CHECKCAST) {
|
||||
redundantCheckCasts.add(insn)
|
||||
}
|
||||
@@ -57,4 +58,6 @@ class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
|
||||
|
||||
private fun isTrivialSubtype(superType: Type, subType: Type) =
|
||||
superType == subType
|
||||
|
||||
private fun isMultiArrayType(type: Type) = type.sort == Type.ARRAY && type.dimensions != 1
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.optimization.captured
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.removeEmptyCatchBlocks
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
|
||||
@@ -63,6 +64,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
val stackInsns: MutableCollection<AbstractInsnNode> = LinkedHashSet()
|
||||
val getFieldInsns: MutableCollection<FieldInsnNode> = LinkedHashSet()
|
||||
val putFieldInsns: MutableCollection<FieldInsnNode> = LinkedHashSet()
|
||||
var cleanVarInstruction: VarInsnNode? = null
|
||||
|
||||
fun canRewrite(): Boolean =
|
||||
!hazard &&
|
||||
@@ -198,6 +200,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
for (refValue in refValues) {
|
||||
if (refValue.hazard) continue
|
||||
val localVar = refValue.localVar ?: continue
|
||||
val oldVarIndex = localVar.index
|
||||
|
||||
if (refValue.valueType.size != 1) {
|
||||
refValue.localVarIndex = methodNode.maxLocals
|
||||
@@ -214,9 +217,30 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
refValue.hazard = true
|
||||
continue
|
||||
}
|
||||
|
||||
val cleanInstructions = findCleanInstructions(refValue, oldVarIndex, methodNode.instructions)
|
||||
if (cleanInstructions.size > 1 ) {
|
||||
refValue.hazard = true
|
||||
continue
|
||||
}
|
||||
refValue.cleanVarInstruction = cleanInstructions.firstOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
private fun findCleanInstructions(refValue: CapturedVarDescriptor, oldVarIndex: Int, instructions: InsnList): List<VarInsnNode> {
|
||||
val cleanInstructions =
|
||||
InsnSequence(instructions).filterIsInstance<VarInsnNode>().filter {
|
||||
it.`var` == oldVarIndex
|
||||
}.filter {
|
||||
it.previous?.opcode == Opcodes.ACONST_NULL
|
||||
}.filter {
|
||||
val operationIndex = instructions.indexOf(it)
|
||||
val localVariableNode = refValue.localVar!!
|
||||
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(localVariableNode.end)
|
||||
}.toList()
|
||||
return cleanInstructions
|
||||
}
|
||||
|
||||
private fun rewrite() {
|
||||
for (refValue in refValues) {
|
||||
if (!refValue.canRewrite()) continue
|
||||
@@ -248,6 +272,13 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
capturedVar.putFieldInsns.forEach {
|
||||
set(it, VarInsnNode(capturedVar.valueType.getOpcode(Opcodes.ISTORE), capturedVar.localVarIndex))
|
||||
}
|
||||
|
||||
//after visiting block codegen tries to delete all allocated references:
|
||||
// see ExpressionCodegen.addLeaveTaskToRemoveLocalVariableFromFrameMap
|
||||
capturedVar.cleanVarInstruction?.let {
|
||||
remove(it.previous)
|
||||
remove(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
private val EXTERNAL_SOURCES_KINDS = arrayOf(
|
||||
JvmDeclarationOriginKind.DELEGATION_TO_DEFAULT_IMPLS,
|
||||
JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL,
|
||||
JvmDeclarationOriginKind.DELEGATION,
|
||||
JvmDeclarationOriginKind.BRIDGE
|
||||
)
|
||||
@@ -58,8 +58,9 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
bindingContext: BindingContext,
|
||||
private val diagnostics: DiagnosticSink,
|
||||
fileClassesProvider: JvmFileClassesProvider,
|
||||
moduleName: String
|
||||
) : SignatureCollectingClassBuilderFactory(builderFactory) {
|
||||
moduleName: String,
|
||||
shouldGenerate: (JvmDeclarationOrigin) -> Boolean
|
||||
) : SignatureCollectingClassBuilderFactory(builderFactory, shouldGenerate) {
|
||||
|
||||
// Avoid errors when some classes are not loaded for some reason
|
||||
private val typeMapper = KotlinTypeMapper(
|
||||
|
||||
@@ -44,6 +44,8 @@ import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||
import java.io.File
|
||||
|
||||
@@ -177,8 +179,10 @@ class GenerationState @JvmOverloads constructor(
|
||||
{ OptimizationClassBuilderFactory(it, configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false)) },
|
||||
::CoroutineTransformerClassBuilderFactory,
|
||||
{ BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
it, this.bindingContext, diagnostics, fileClassesProvider, this.moduleName
|
||||
).apply { duplicateSignatureFactory = this } },
|
||||
it, this.bindingContext, diagnostics,
|
||||
fileClassesProvider, this.moduleName,
|
||||
shouldGenerate = { !shouldOnlyCollectSignatures(it) }
|
||||
).apply { duplicateSignatureFactory = this } },
|
||||
{ BuilderFactoryForDuplicateClassNameDiagnostics(it, diagnostics) },
|
||||
{ configuration.get(JVMConfigurationKeys.DECLARATIONS_JSON_PATH)
|
||||
?.let { destination -> SignatureDumpingBuilderFactory(it, File(destination)) } ?: it }
|
||||
@@ -209,6 +213,9 @@ class GenerationState @JvmOverloads constructor(
|
||||
fun destroy() {
|
||||
interceptedBuilderFactory.close()
|
||||
}
|
||||
|
||||
private fun shouldOnlyCollectSignatures(origin: JvmDeclarationOrigin)
|
||||
= classBuilderMode == ClassBuilderMode.LIGHT_CLASSES && origin.originKind == CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
|
||||
}
|
||||
|
||||
private class LazyJvmDiagnostics(compute: () -> Diagnostics): Diagnostics {
|
||||
|
||||
@@ -71,6 +71,10 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
|
||||
@ValueDescription("<path>")
|
||||
public String outputPostfix;
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@Argument(value = "Xtypedarrays", description = "Translate primitive arrays to JS typed arrays")
|
||||
public boolean typedArrays;
|
||||
|
||||
@NotNull
|
||||
public static K2JSCompilerArguments createDefaultInstance() {
|
||||
K2JSCompilerArguments arguments = new K2JSCompilerArguments();
|
||||
|
||||
@@ -111,6 +111,10 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
@Argument(value = "Xload-builtins-from-dependencies", description = "Load definitions of built-in declarations from module dependencies, instead of from the compiler")
|
||||
public boolean loadBuiltInsFromDependencies;
|
||||
|
||||
@Argument(value = "Xscript-resolver-environment", description = "Script resolver environment in key-value pairs (the value could be quoted and escaped)")
|
||||
@ValueDescription("<key=value[,]>")
|
||||
public String[] scriptResolverEnvironment;
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
public String[] friendPaths;
|
||||
|
||||
|
||||
@@ -22,5 +22,6 @@
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="annotation-collector" />
|
||||
<orderEntry type="module" module-name="builtins-serializer" />
|
||||
<orderEntry type="module" module-name="script.runtime" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -286,6 +286,10 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
ContainerUtil.addAllNotNull(libraries, arguments.libraries.split(File.pathSeparator));
|
||||
}
|
||||
|
||||
if (arguments.typedArrays) {
|
||||
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, true);
|
||||
}
|
||||
|
||||
configuration.put(JSConfigurationKeys.LIBRARIES, libraries);
|
||||
|
||||
String moduleKindName = arguments.moduleKind;
|
||||
|
||||
@@ -215,13 +215,14 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun createEnvironmentWithScriptingSupport(rootDisposable: Disposable,
|
||||
configuration: CompilerConfiguration,
|
||||
arguments: K2JVMCompilerArguments,
|
||||
messageCollector: MessageCollector
|
||||
): KotlinCoreEnvironment? {
|
||||
|
||||
val scriptResolverEnv = hashMapOf<String, Any?>()
|
||||
val scriptResolverEnv = createScriptResolverEnvironment(arguments, messageCollector) ?: return null
|
||||
configureScriptDefinitions(arguments.scriptTemplates, configuration, messageCollector, scriptResolverEnv)
|
||||
if (!messageCollector.hasErrors()) {
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration)
|
||||
@@ -416,6 +417,27 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
|
||||
}
|
||||
|
||||
fun createScriptResolverEnvironment(arguments: K2JVMCompilerArguments, messageCollector: MessageCollector): HashMap<String, Any?>? {
|
||||
val scriptResolverEnv = hashMapOf<String, Any?>()
|
||||
// parses key/value pairs in the form <key>=<value>, where
|
||||
// <key> - is a single word (\w+ pattern)
|
||||
// <value> - optionally quoted string with allowed escaped chars (only double-quote and backslash chars are supported)
|
||||
// TODO: implement generic unescaping
|
||||
val envParseRe = """(\w+)=(?:"([^"\\]*(\\.[^"\\]*)*)"|([^\s]*))""".toRegex()
|
||||
val unescapeRe = """\\(["\\])""".toRegex()
|
||||
if (arguments.scriptResolverEnvironment != null) {
|
||||
for (envParam in arguments.scriptResolverEnvironment) {
|
||||
val match = envParseRe.matchEntire(envParam)
|
||||
if (match == null || match.groupValues.size < 4 || match.groupValues[1].isBlank()) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Unable to parse script-resolver-environment argument $envParam", CompilerMessageLocation.NO_LOCATION)
|
||||
return null
|
||||
}
|
||||
scriptResolverEnv.put(match.groupValues[1], match.groupValues.drop(2).firstOrNull { it.isNotEmpty() }?.let { unescapeRe.replace(it, "\$1") })
|
||||
}
|
||||
}
|
||||
return scriptResolverEnv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,7 @@ import com.intellij.core.CoreJavaFileManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiClassOwner
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiPackage
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
@@ -35,6 +32,9 @@ import org.jetbrains.kotlin.util.PerformanceCounter
|
||||
import java.util.*
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
// TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices
|
||||
// Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage,
|
||||
// which is indirectly invoked from PsiPackage.getSubPackages
|
||||
class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJavaFileManager(myPsiManager), KotlinCliJavaFileManager {
|
||||
private val perfCounter = PerformanceCounter.create("Find Java class")
|
||||
private var index: JvmDependenciesIndex by Delegates.notNull()
|
||||
@@ -44,44 +44,64 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
this.index = packagesCache
|
||||
}
|
||||
|
||||
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): PsiClass? {
|
||||
return perfCounter.time {
|
||||
val classNameWithInnerClasses = classId.relativeClassName.asString()
|
||||
index.findClass(classId) { dir, type ->
|
||||
findClassGivenPackage(allScope, dir, classNameWithInnerClasses, type)
|
||||
}?.takeIf { it.containingFile.virtualFile in searchScope }
|
||||
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): PsiClass? = perfCounter.time {
|
||||
val relativeClassName = classId.relativeClassName.asString()
|
||||
index.findClass(classId) { dir, type ->
|
||||
findClassGivenPackage(allScope, dir, relativeClassName, type)
|
||||
}?.takeIf { it.containingFile.virtualFile in searchScope }
|
||||
}
|
||||
|
||||
// this method is called from IDEA to resolve dependencies in Java code
|
||||
// which supposedly shouldn't have errors so the dependencies exist in general
|
||||
override fun findClass(qName: String, scope: GlobalSearchScope): PsiClass? {
|
||||
// String cannot be reliably converted to ClassId because we don't know where the package name ends and class names begin.
|
||||
// For example, if qName is "a.b.c.d.e", we should either look for a top level class "e" in the package "a.b.c.d",
|
||||
// or, for example, for a nested class with the relative qualified name "c.d.e" in the package "a.b".
|
||||
// Below, we start by looking for the top level class "e" in the package "a.b.c.d" first, then for the class "d.e" in the package
|
||||
// "a.b.c", and so on, until we find something. Most classes are top level, so most of the times the search ends quickly
|
||||
|
||||
forEachClassId(qName) { classId ->
|
||||
findClass(classId, scope)?.let { return it }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private inline fun forEachClassId(fqName: String, block: (ClassId) -> Unit) {
|
||||
var classId = fqName.toSafeTopLevelClassId() ?: return
|
||||
|
||||
while (true) {
|
||||
block(classId)
|
||||
|
||||
val packageFqName = classId.packageFqName
|
||||
if (packageFqName.isRoot) break
|
||||
|
||||
classId = ClassId(
|
||||
packageFqName.parent(),
|
||||
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun findClass(qName: String, scope: GlobalSearchScope): PsiClass? {
|
||||
// this method is called from IDEA to resolve dependencies in Java code
|
||||
// which supposedly shouldn't have errors so the dependencies exist in general
|
||||
// Most classes are top level classes so we will try to find them fast
|
||||
// but we must sometimes fallback to support finding inner/nested classes
|
||||
return qName.toSafeTopLevelClassId()?.let { classId -> findClass(classId, scope) } ?: super.findClass(qName, scope)
|
||||
}
|
||||
|
||||
override fun findClasses(qName: String, scope: GlobalSearchScope): Array<PsiClass> {
|
||||
return perfCounter.time {
|
||||
val classIdAsTopLevelClass = qName.toSafeTopLevelClassId() ?: return@time super.findClasses(qName, scope)
|
||||
|
||||
val result = ArrayList<PsiClass>()
|
||||
val classNameWithInnerClasses = classIdAsTopLevelClass.relativeClassName.asString()
|
||||
index.traverseDirectoriesInPackage(classIdAsTopLevelClass.packageFqName) { dir, rootType ->
|
||||
val psiClass = findClassGivenPackage(scope, dir, classNameWithInnerClasses, rootType)
|
||||
override fun findClasses(qName: String, scope: GlobalSearchScope): Array<PsiClass> = perfCounter.time {
|
||||
val result = ArrayList<PsiClass>(1)
|
||||
forEachClassId(qName) { classId ->
|
||||
val relativeClassName = classId.relativeClassName.asString()
|
||||
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
||||
val psiClass = findClassGivenPackage(scope, dir, relativeClassName, rootType)
|
||||
if (psiClass != null) {
|
||||
result.add(psiClass)
|
||||
}
|
||||
// traverse all
|
||||
true
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
super.findClasses(qName, scope)
|
||||
}
|
||||
else {
|
||||
result.toTypedArray()
|
||||
if (result.isNotEmpty()) {
|
||||
return@time result.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
PsiClass.EMPTY_ARRAY
|
||||
}
|
||||
|
||||
override fun findPackage(packageName: String): PsiPackage? {
|
||||
@@ -121,7 +141,29 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
return findClassInPsiFile(classNameWithInnerClasses, file)
|
||||
}
|
||||
|
||||
override fun knownClassNamesInPackage(packageFqName: FqName) = index.collectKnownClassNamesInPackage(packageFqName)
|
||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
||||
val result = hashSetOf<String>()
|
||||
index.traverseDirectoriesInPackage(packageFqName, continueSearch = {
|
||||
dir, _ ->
|
||||
|
||||
for (child in dir.children) {
|
||||
if (child.extension == "class" || child.extension == "java") {
|
||||
result.add(child.nameWithoutExtension)
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun findModules(moduleName: String, scope: GlobalSearchScope): Collection<PsiJavaModule> {
|
||||
// TODO
|
||||
return emptySet()
|
||||
}
|
||||
|
||||
override fun getNonTrivialPackagePrefixes(): Collection<String> = emptyList()
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(KotlinCliJavaFileManagerImpl::class.java)
|
||||
@@ -168,4 +210,4 @@ catch (e: AssertionError) {
|
||||
}
|
||||
|
||||
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
||||
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
||||
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
|
||||
class JvmDependenciesDynamicCompoundIndex : JvmDependenciesIndex {
|
||||
private val indices = arrayListOf<JvmDependenciesIndex>()
|
||||
private val lock = ReentrantReadWriteLock()
|
||||
|
||||
@@ -36,13 +36,9 @@ class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
|
||||
fun addNewIndexForRoots(roots: Iterable<JavaRoot>): JvmDependenciesIndex? =
|
||||
lock.read {
|
||||
val alreadyIndexed = indexedRoots.toHashSet()
|
||||
val newRoots = roots.filter { !alreadyIndexed.contains(it) }
|
||||
val newRoots = roots.filter { root -> root !in alreadyIndexed }
|
||||
if (newRoots.isEmpty()) null
|
||||
else {
|
||||
val index = JvmDependenciesIndexImpl(newRoots)
|
||||
addIndex(index)
|
||||
index
|
||||
}
|
||||
else JvmDependenciesIndexImpl(newRoots).also(this::addIndex)
|
||||
}
|
||||
|
||||
override val indexedRoots: Sequence<JavaRoot> get() = indices.asSequence().flatMap { it.indexedRoots }
|
||||
@@ -51,22 +47,15 @@ class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T? =
|
||||
lock.read {
|
||||
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
|
||||
}
|
||||
): T? = lock.read {
|
||||
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
|
||||
}
|
||||
|
||||
override fun traverseDirectoriesInPackage(
|
||||
packageFqName: FqName,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
) {
|
||||
lock.read {
|
||||
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun collectKnownClassNamesInPackage(packageFqName: FqName): Set<String> = lock.read {
|
||||
indices.flatMapTo(hashSetOf()) { it.collectKnownClassNamesInPackage(packageFqName) }
|
||||
) = lock.read {
|
||||
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,6 @@ interface JvmDependenciesIndex {
|
||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
)
|
||||
|
||||
fun collectKnownClassNamesInPackage(
|
||||
packageFqName: FqName
|
||||
): Set<String>
|
||||
}
|
||||
|
||||
data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName: FqName? = null) {
|
||||
|
||||
@@ -39,24 +39,21 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
private class Cache {
|
||||
private val innerPackageCaches = HashMap<String, Cache>()
|
||||
|
||||
operator fun get(name: String) = innerPackageCaches.getOrPut(name) { Cache() }
|
||||
operator fun get(name: String) = innerPackageCaches.getOrPut(name, ::Cache)
|
||||
|
||||
// indices of roots that are known to contain this package
|
||||
// if this list contains [1, 3, 5] then roots with indices 1, 3 and 5 are known to contain this package, 2 and 4 are known not to (no information about roots 6 or higher)
|
||||
// if this list contains maxIndex that means that all roots containing this package are known
|
||||
val rootIndices = IntArrayList()
|
||||
val rootIndices = IntArrayList(2)
|
||||
}
|
||||
|
||||
// root "Cache" object corresponds to DefaultPackage which exists in every root. Roots with non-default fqname are also listed here but
|
||||
// they will be ignored on requests with invalid fqname prefix.
|
||||
private val rootCache: Cache by lazy {
|
||||
with(Cache()) {
|
||||
roots.indices.forEach {
|
||||
rootIndices.add(it)
|
||||
}
|
||||
Cache().apply {
|
||||
roots.indices.forEach(rootIndices::add)
|
||||
rootIndices.add(maxIndex)
|
||||
rootIndices.trimToSize()
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +69,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T? {
|
||||
return search(FindClassRequest(classId, acceptedRootTypes)) { dir, rootType ->
|
||||
return findClassCached(classId, acceptedRootTypes) { dir, rootType ->
|
||||
val found = findClassGivenDirectory(dir, rootType)
|
||||
HandleResult(found, continueSearch = found == null)
|
||||
}
|
||||
@@ -88,73 +85,51 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
}
|
||||
}
|
||||
|
||||
override fun collectKnownClassNamesInPackage(
|
||||
packageFqName: FqName
|
||||
): Set<String> {
|
||||
val result = hashSetOf<String>()
|
||||
traverseDirectoriesInPackage(packageFqName, continueSearch = {
|
||||
dir, _ ->
|
||||
|
||||
for (child in dir.children) {
|
||||
if (child.extension != "class" && child.extension != "java") continue
|
||||
result.add(child.nameWithoutExtension)
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private data class HandleResult<out T : Any>(val result: T?, val continueSearch: Boolean)
|
||||
|
||||
private fun <T : Any> search(
|
||||
request: SearchRequest,
|
||||
private fun <T : Any> findClassCached(
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
handler: (VirtualFile, JavaRoot.RootType) -> HandleResult<T>
|
||||
): T? {
|
||||
// make a decision based on information saved from last class search
|
||||
if (request !is FindClassRequest || lastClassSearch?.first?.classId != request.classId) {
|
||||
return doSearch(request, handler)
|
||||
if (lastClassSearch?.first?.classId != classId) {
|
||||
return search(FindClassRequest(classId, acceptedRootTypes), handler)
|
||||
}
|
||||
|
||||
|
||||
val (cachedRequest, cachedResult) = lastClassSearch!!
|
||||
return when (cachedResult) {
|
||||
is SearchResult.NotFound -> {
|
||||
val limitedRootTypes = request.acceptedRootTypes.toHashSet()
|
||||
limitedRootTypes.removeAll(cachedRequest.acceptedRootTypes)
|
||||
val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes
|
||||
if (limitedRootTypes.isEmpty()) {
|
||||
null
|
||||
}
|
||||
else {
|
||||
doSearch(FindClassRequest(request.classId, limitedRootTypes), handler)
|
||||
search(FindClassRequest(classId, limitedRootTypes), handler)
|
||||
}
|
||||
}
|
||||
is SearchResult.Found -> {
|
||||
if (cachedRequest.acceptedRootTypes == request.acceptedRootTypes) {
|
||||
if (cachedRequest.acceptedRootTypes == acceptedRootTypes) {
|
||||
handler(cachedResult.packageDirectory, cachedResult.root.type).result
|
||||
}
|
||||
else {
|
||||
doSearch(request, handler)
|
||||
search(FindClassRequest(classId, acceptedRootTypes), handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : Any> doSearch(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult<T>): T? {
|
||||
val findClassRequest = request as? FindClassRequest
|
||||
|
||||
fun <T : Any> found(packageDirectory: VirtualFile, root: JavaRoot, result: T): T {
|
||||
if (findClassRequest != null) {
|
||||
lastClassSearch = Pair(findClassRequest, SearchResult.Found(packageDirectory, root))
|
||||
private fun <T : Any> search(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult<T>): T? {
|
||||
fun <T : Any> found(packageDirectory: VirtualFile, root: JavaRoot, result: T): T = result.also {
|
||||
if (request is FindClassRequest) {
|
||||
lastClassSearch = Pair(request, SearchResult.Found(packageDirectory, root))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun <T : Any> notFound(): T? {
|
||||
if (findClassRequest != null) {
|
||||
lastClassSearch = Pair(findClassRequest, SearchResult.NotFound)
|
||||
fun <T : Any> notFound(): T? = null.also {
|
||||
if (request is FindClassRequest) {
|
||||
lastClassSearch = Pair(request, SearchResult.NotFound)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun handle(root: JavaRoot, targetDirInRoot: VirtualFile): T? {
|
||||
@@ -197,7 +172,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
return notFound()
|
||||
}
|
||||
|
||||
// try to find a target directory corresponding to package represented by packagesPath in a given root reprenting by index
|
||||
// try to find a target directory corresponding to package represented by packagesPath in a given root represented by index
|
||||
// possibly filling "Cache" objects with new information
|
||||
private fun travelPath(rootIndex: Int, packagesPath: List<String>, fillCachesAfter: Int, cachesPath: List<Cache>): VirtualFile? {
|
||||
if (rootIndex >= maxIndex) {
|
||||
|
||||
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.script.dependencies.KotlinScriptExternalDependencies
|
||||
|
||||
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
|
||||
|
||||
|
||||
@@ -68,10 +68,7 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
|
||||
val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true, inheritAdditionalProperties = true)
|
||||
|
||||
val daemonReportMessages = ArrayList<DaemonReportMessage>()
|
||||
val daemonReportingTargets = when {
|
||||
log.isDebugEnabled -> DaemonReportingTargets(messages = daemonReportMessages)
|
||||
else -> DaemonReportingTargets(messageCollector = environment.messageCollector)
|
||||
}
|
||||
val daemonReportingTargets = DaemonReportingTargets(messages = daemonReportMessages)
|
||||
|
||||
val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
|
||||
|
||||
@@ -86,10 +83,15 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
|
||||
sessionAliveFlagFile = sessionAliveFlagFile)
|
||||
}
|
||||
|
||||
for (msg in daemonReportMessages) {
|
||||
environment.messageCollector.report(CompilerMessageSeverity.INFO,
|
||||
(if (msg.category == DaemonReportCategory.EXCEPTION && connection == null) "Falling back to compilation without daemon due to error: " else "") + msg.message,
|
||||
CompilerMessageLocation.NO_LOCATION)
|
||||
if (connection == null || log.isDebugEnabled) {
|
||||
for (message in daemonReportMessages) {
|
||||
val severity = when(message.category) {
|
||||
DaemonReportCategory.DEBUG -> CompilerMessageSeverity.INFO
|
||||
DaemonReportCategory.INFO -> CompilerMessageSeverity.INFO
|
||||
DaemonReportCategory.EXCEPTION -> CompilerMessageSeverity.EXCEPTION
|
||||
}
|
||||
environment.messageCollector.report(severity, message.message, CompilerMessageLocation.NO_LOCATION)
|
||||
}
|
||||
}
|
||||
|
||||
fun reportTotalAndThreadPerf(message: String, daemonOptions: DaemonOptions, messageCollector: MessageCollector, profiler: Profiler) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompil
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.utils.rethrow
|
||||
import java.rmi.server.UnicastRemoteObject
|
||||
import kotlin.reflect.full.allSuperclasses
|
||||
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.client
|
||||
|
||||
import net.rubygrapefruit.platform.Native
|
||||
import net.rubygrapefruit.platform.NativeException
|
||||
import net.rubygrapefruit.platform.ProcessLauncher
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
@@ -26,6 +23,7 @@ import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
import java.io.PrintStream
|
||||
import java.net.SocketException
|
||||
@@ -98,7 +96,7 @@ object KotlinCompilerClient {
|
||||
leaseSession: Boolean,
|
||||
sessionAliveFlagFile: File? = null
|
||||
): CompileServiceSession? = connectLoop(reportingTargets) {
|
||||
setupServerHostName()
|
||||
ensureServerHostnameIsSetUp()
|
||||
val (service, newJVMOptions) = tryFindSuitableDaemonOrNewOpts(File(daemonOptions.runFilesPath), compilerId, daemonJVMOptions, { cat, msg -> reportingTargets.report(cat, msg) })
|
||||
if (service != null) {
|
||||
// the newJVMOptions could be checked here for additional parameters, if needed
|
||||
@@ -373,9 +371,11 @@ object KotlinCompilerClient {
|
||||
|
||||
private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) {
|
||||
val javaExecutable = File(File(System.getProperty("java.home"), "bin"), "java")
|
||||
val serverHostname = System.getProperty(JAVA_RMI_SERVER_HOSTNAME) ?: error("$JAVA_RMI_SERVER_HOSTNAME is not set!")
|
||||
val platformSpecificOptions = listOf(
|
||||
// hide daemon window
|
||||
"-Djava.awt.headless=true")
|
||||
"-Djava.awt.headless=true",
|
||||
"-D$JAVA_RMI_SERVER_HOSTNAME=$serverHostname")
|
||||
val args = listOf(
|
||||
javaExecutable.absolutePath, "-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)) +
|
||||
platformSpecificOptions +
|
||||
@@ -389,13 +389,17 @@ object KotlinCompilerClient {
|
||||
// assuming daemon process is deaf and (mostly) silent, so do not handle streams
|
||||
val daemon =
|
||||
try {
|
||||
val nativeLauncher = Native.get(ProcessLauncher::class.java)
|
||||
nativeLauncher.start(processBuilder)
|
||||
launchWithNativePlatformLauncher(processBuilder)
|
||||
}
|
||||
catch (e: NativeException) {
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "Could not start daemon with native process launcher, falling back to ProcessBuilder#start")
|
||||
processBuilder.start()
|
||||
catch (e: IOException) {
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "Could not start daemon with native process launcher, falling back to ProcessBuilder#start (${e.cause})")
|
||||
null
|
||||
}
|
||||
catch (e: NoClassDefFoundError) {
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "net.rubygrapefruit.platform library is not in the classpath, falling back to ProcessBuilder#start")
|
||||
null
|
||||
}
|
||||
?: processBuilder.start()
|
||||
|
||||
val isEchoRead = Semaphore(1)
|
||||
isEchoRead.acquire()
|
||||
@@ -435,7 +439,7 @@ object KotlinCompilerClient {
|
||||
if (daemonOptions.runFilesPath.isNotEmpty()) {
|
||||
val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS)
|
||||
if (!isProcessAlive(daemon))
|
||||
throw Exception("Daemon terminated unexpectedly")
|
||||
throw Exception("Daemon terminated unexpectedly with error code: ${daemon.exitValue()}")
|
||||
if (!succeeded)
|
||||
throw Exception("Unable to get response from daemon in $daemonStartupTimeout ms")
|
||||
}
|
||||
@@ -449,6 +453,7 @@ object KotlinCompilerClient {
|
||||
// TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream
|
||||
stdoutThread.stop()
|
||||
}
|
||||
reportingTargets.out?.flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.daemon.client
|
||||
|
||||
import net.rubygrapefruit.platform.Native
|
||||
import net.rubygrapefruit.platform.NativeException
|
||||
import net.rubygrapefruit.platform.ProcessLauncher
|
||||
import java.io.IOException
|
||||
|
||||
internal fun launchWithNativePlatformLauncher(processBuilder: ProcessBuilder): Process {
|
||||
return try {
|
||||
val nativeLauncher = Native.get(ProcessLauncher::class.java)
|
||||
nativeLauncher.start(processBuilder)
|
||||
}
|
||||
catch (e: NativeException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import java.util.*
|
||||
|
||||
|
||||
val SOCKET_ANY_FREE_PORT = 0
|
||||
val JAVA_RMI_SERVER_HOSTNAME = "java.rmi.server.hostname"
|
||||
|
||||
object LoopbackNetworkInterface {
|
||||
|
||||
@@ -100,6 +101,8 @@ fun findPortAndCreateRegistry(attempts: Int, portRangeStart: Int, portRangeEnd:
|
||||
* Needs to be set up on both client and server to prevent localhost resolution,
|
||||
* which may be slow and can cause a timeout when there is a network problem/misconfiguration.
|
||||
*/
|
||||
fun setupServerHostName() {
|
||||
System.setProperty("java.rmi.server.hostname", LoopbackNetworkInterface.loopbackInetAddressName)
|
||||
fun ensureServerHostnameIsSetUp() {
|
||||
if (System.getProperty(JAVA_RMI_SERVER_HOSTNAME) == null) {
|
||||
System.setProperty(JAVA_RMI_SERVER_HOSTNAME, LoopbackNetworkInterface.loopbackInetAddressName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ class CompileServiceImpl(
|
||||
CompileService.CallResult.Ok()
|
||||
}
|
||||
|
||||
override fun scheduleShutdown(graceful: Boolean): CompileService.CallResult<Boolean> = ifAlive(minAliveness = Aliveness.Alive) {
|
||||
override fun scheduleShutdown(graceful: Boolean): CompileService.CallResult<Boolean> = ifAlive(minAliveness = Aliveness.LastSession, ignoreCompilerChanged = true) {
|
||||
when {
|
||||
!graceful -> {
|
||||
shutdownWithDelay()
|
||||
|
||||
@@ -89,7 +89,7 @@ object KotlinCompileDaemon {
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
setupServerHostName()
|
||||
ensureServerHostnameIsSetUp()
|
||||
|
||||
log.info("Kotlin compiler daemon version " + (loadVersionFromResource() ?: "<unknown>"))
|
||||
log.info("daemon JVM args: " + ManagementFactory.getRuntimeMXBean().inputArguments.joinToString(" "))
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
interface ModuleVisibilityManager {
|
||||
val chunk: Collection<Module>
|
||||
@@ -63,10 +64,12 @@ fun isContainedByCompiledPartOfOurModule(descriptor: DeclarationDescriptor, outD
|
||||
|
||||
if (binaryClass is VirtualFileKotlinClass) {
|
||||
val file = binaryClass.file
|
||||
if (file.fileSystem.protocol == StandardFileSystems.FILE_PROTOCOL) {
|
||||
val ioFile = VfsUtilCore.virtualToIoFile(file)
|
||||
return ioFile.absolutePath.startsWith(outDirectory.absolutePath + File.separator)
|
||||
val ioFile = when (file.fileSystem.protocol) {
|
||||
StandardFileSystems.FILE_PROTOCOL -> VfsUtilCore.virtualToIoFile(file)
|
||||
StandardFileSystems.JAR_PROTOCOL -> VfsUtilCore.getVirtualFileForJar(file)?.let(VfsUtilCore::virtualToIoFile)
|
||||
else -> null
|
||||
}
|
||||
return ioFile != null && Paths.get(ioFile.toURI()).startsWith(Paths.get(outDirectory.toURI()))
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
@@ -44,9 +44,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -112,8 +112,8 @@ public class KotlinJavaPsiFacade {
|
||||
}
|
||||
|
||||
for (KotlinPsiElementFinderWrapper finder : finders()) {
|
||||
if (finder instanceof KotlinPsiElementFinderImpl) {
|
||||
PsiClass aClass = ((KotlinPsiElementFinderImpl) finder).findClass(classId, scope);
|
||||
if (finder instanceof CliFinder) {
|
||||
PsiClass aClass = ((CliFinder) finder).findClass(classId, scope);
|
||||
if (aClass != null) return aClass;
|
||||
}
|
||||
else {
|
||||
@@ -152,8 +152,8 @@ public class KotlinJavaPsiFacade {
|
||||
public Set<String> knownClassNamesInPackage(@NotNull FqName packageFqName) {
|
||||
KotlinPsiElementFinderWrapper[] finders = finders();
|
||||
|
||||
if (finders.length == 1) {
|
||||
return ((KotlinPsiElementFinderImpl) finders[0]).knownClassNamesInPackage(packageFqName);
|
||||
if (finders.length == 1 && finders[0] instanceof CliFinder) {
|
||||
return ((CliFinder) finders[0]).knownClassNamesInPackage(packageFqName);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -197,9 +197,14 @@ public class KotlinJavaPsiFacade {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected KotlinPsiElementFinderWrapper[] calcFinders() {
|
||||
private KotlinPsiElementFinderWrapper[] calcFinders() {
|
||||
List<KotlinPsiElementFinderWrapper> elementFinders = new ArrayList<KotlinPsiElementFinderWrapper>();
|
||||
elementFinders.add(new KotlinPsiElementFinderImpl(getProject()));
|
||||
JavaFileManager javaFileManager = findJavaFileManager(project);
|
||||
elementFinders.add(
|
||||
javaFileManager instanceof KotlinCliJavaFileManager
|
||||
? new CliFinder((KotlinCliJavaFileManager) javaFileManager)
|
||||
: new NonCliFinder(project, javaFileManager)
|
||||
);
|
||||
|
||||
List<PsiElementFinder> nonKotlinFinders = ArraysKt.filter(
|
||||
getProject().getExtensions(PsiElementFinder.EP_NAME), new Function1<PsiElementFinder, Boolean>() {
|
||||
@@ -220,6 +225,15 @@ public class KotlinJavaPsiFacade {
|
||||
return elementFinders.toArray(new KotlinPsiElementFinderWrapper[elementFinders.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JavaFileManager findJavaFileManager(@NotNull Project project) {
|
||||
JavaFileManager javaFileManager = ServiceManager.getService(project, JavaFileManager.class);
|
||||
if (javaFileManager == null) {
|
||||
throw new IllegalStateException("JavaFileManager component is not found in project");
|
||||
}
|
||||
return javaFileManager;
|
||||
}
|
||||
|
||||
public PsiPackage findPackage(@NotNull String qualifiedName, GlobalSearchScope searchScope) {
|
||||
PackageCache cache = SoftReference.dereference(packageCache);
|
||||
if (cache == null) {
|
||||
@@ -342,59 +356,56 @@ public class KotlinJavaPsiFacade {
|
||||
}
|
||||
}
|
||||
|
||||
static class KotlinPsiElementFinderImpl implements KotlinPsiElementFinderWrapper, DumbAware {
|
||||
private final JavaFileManager javaFileManager;
|
||||
private final boolean isCliFileManager;
|
||||
private static class CliFinder implements KotlinPsiElementFinderWrapper, DumbAware {
|
||||
private final KotlinCliJavaFileManager javaFileManager;
|
||||
|
||||
private final PsiManager psiManager;
|
||||
private final PackageIndex packageIndex;
|
||||
|
||||
public KotlinPsiElementFinderImpl(Project project) {
|
||||
this.javaFileManager = findJavaFileManager(project);
|
||||
this.isCliFileManager = javaFileManager instanceof KotlinCliJavaFileManager;
|
||||
|
||||
this.packageIndex = PackageIndex.getInstance(project);
|
||||
this.psiManager = PsiManager.getInstance(project);
|
||||
public CliFinder(@NotNull KotlinCliJavaFileManager javaFileManager) {
|
||||
this.javaFileManager = javaFileManager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JavaFileManager findJavaFileManager(@NotNull Project project) {
|
||||
JavaFileManager javaFileManager = ServiceManager.getService(project, JavaFileManager.class);
|
||||
if (javaFileManager == null) {
|
||||
throw new IllegalStateException("JavaFileManager component is not found in project");
|
||||
}
|
||||
|
||||
return javaFileManager;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return javaFileManager.findClass(qualifiedName, scope);
|
||||
}
|
||||
|
||||
public PsiClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) {
|
||||
if (isCliFileManager) {
|
||||
return ((KotlinCliJavaFileManager) javaFileManager).findClass(classId, scope);
|
||||
}
|
||||
return findClass(classId.asSingleFqName().asString(), scope);
|
||||
return javaFileManager.findClass(classId, scope);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Set<String> knownClassNamesInPackage(@NotNull FqName packageFqName) {
|
||||
if (isCliFileManager) {
|
||||
return ((KotlinCliJavaFileManager) javaFileManager).knownClassNamesInPackage(packageFqName);
|
||||
}
|
||||
|
||||
return null;
|
||||
return javaFileManager.knownClassNamesInPackage(packageFqName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiPackage findPackage(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
if (isCliFileManager) {
|
||||
return javaFileManager.findPackage(qualifiedName);
|
||||
}
|
||||
return javaFileManager.findPackage(qualifiedName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameResultForAnyScope() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class NonCliFinder implements KotlinPsiElementFinderWrapper, DumbAware {
|
||||
private final JavaFileManager javaFileManager;
|
||||
private final PsiManager psiManager;
|
||||
private final PackageIndex packageIndex;
|
||||
|
||||
public NonCliFinder(@NotNull Project project, @NotNull JavaFileManager javaFileManager) {
|
||||
this.javaFileManager = javaFileManager;
|
||||
this.packageIndex = PackageIndex.getInstance(project);
|
||||
this.psiManager = PsiManager.getInstance(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return javaFileManager.findClass(qualifiedName, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiPackage findPackage(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
Query<VirtualFile> dirs = packageIndex.getDirsByPackageName(qualifiedName, true);
|
||||
return hasDirectoriesInScope(dirs, scope) ? new PsiPackageImpl(psiManager, qualifiedName) : null;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ enum class JvmDeclarationOriginKind {
|
||||
OTHER,
|
||||
PACKAGE_PART,
|
||||
INTERFACE_DEFAULT_IMPL,
|
||||
DELEGATION_TO_DEFAULT_IMPLS,
|
||||
CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL,
|
||||
DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL,
|
||||
DELEGATION,
|
||||
SAM_DELEGATION,
|
||||
BRIDGE,
|
||||
@@ -84,8 +85,6 @@ fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor): Jvm
|
||||
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor)
|
||||
|
||||
fun DefaultImpls(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)
|
||||
fun DelegationToDefaultImpls(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(DELEGATION_TO_DEFAULT_IMPLS, element, descriptor)
|
||||
|
||||
fun Delegation(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(DELEGATION, element, descriptor)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.platform
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
@@ -25,25 +24,28 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import java.util.*
|
||||
|
||||
object JvmPlatform : TargetPlatform("JVM") {
|
||||
private val builtIns by lazy(LazyThreadSafetyMode.PUBLICATION) { JvmBuiltIns(LockBasedStorageManager()) }
|
||||
private val defaultImports = LockBasedStorageManager().createMemoizedFunction<Boolean, List<ImportPath>> { includeKotlinComparisons ->
|
||||
ArrayList<ImportPath>().apply {
|
||||
addAll(Default.getDefaultImports(includeKotlinComparisons))
|
||||
|
||||
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
|
||||
addAll(Default.getDefaultImports(languageVersionSettings))
|
||||
add(ImportPath.fromString("java.lang.*"))
|
||||
add(ImportPath.fromString("kotlin.jvm.*"))
|
||||
|
||||
add(ImportPath.fromString("java.lang.*"))
|
||||
add(ImportPath.fromString("kotlin.jvm.*"))
|
||||
fun addAllClassifiersFromScope(scope: MemberScope) {
|
||||
for (descriptor in scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.ALL_NAME_FILTER)) {
|
||||
add(ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false))
|
||||
}
|
||||
}
|
||||
|
||||
fun addAllClassifiersFromScope(scope: MemberScope) {
|
||||
for (descriptor in scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.ALL_NAME_FILTER)) {
|
||||
add(ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false))
|
||||
for (builtinPackageFragment in JvmBuiltIns(LockBasedStorageManager.NO_LOCKS).builtInsPackageFragmentsImportedByDefault) {
|
||||
addAllClassifiersFromScope(builtinPackageFragment.getMemberScope())
|
||||
}
|
||||
}
|
||||
|
||||
for (builtinPackageFragment in builtIns.builtInsPackageFragmentsImportedByDefault) {
|
||||
addAllClassifiersFromScope(builtinPackageFragment.getMemberScope())
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDefaultImports(includeKotlinComparisons: Boolean): List<ImportPath> = defaultImports(includeKotlinComparisons)
|
||||
|
||||
override val platformConfigurator: PlatformConfigurator = JvmPlatformConfigurator
|
||||
|
||||
override val multiTargetPlatform = MultiTargetPlatform.Specific(platformName)
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
<orderEntry type="library" scope="TEST" name="kotlin-test" level="project" />
|
||||
<orderEntry type="module" module-name="resolution" exported="" />
|
||||
<orderEntry type="library" exported="" name="kotlin-script-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="script.runtime" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -196,6 +196,12 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
return module.modulesWhoseInternalsAreVisible().mapTo(LinkedHashSet()) { resolverForProject.descriptorForModule(it as M) }
|
||||
}
|
||||
|
||||
fun computeImplementingModules(module: M): Set<ModuleDescriptorImpl> =
|
||||
if (modulePlatforms(module) != MultiTargetPlatform.Common) emptySet()
|
||||
else modules
|
||||
.filter { modulePlatforms(it) != MultiTargetPlatform.Common && module in it.dependencies() }
|
||||
.mapTo(mutableSetOf(), resolverForProject::descriptorForModule)
|
||||
|
||||
fun setupModuleDependencies() {
|
||||
modules.forEach {
|
||||
module ->
|
||||
@@ -203,7 +209,8 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
LazyModuleDependencies(
|
||||
storageManager,
|
||||
{ computeDependencyDescriptors(module) },
|
||||
{ computeModulesWhoseInternalsAreVisible(module) }
|
||||
{ computeModulesWhoseInternalsAreVisible(module) },
|
||||
{ computeImplementingModules(module) }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -646,8 +646,8 @@ class ControlFlowInformationProvider private constructor(
|
||||
}
|
||||
}
|
||||
is KtFunction -> {
|
||||
if (owner is KtFunctionLiteral &&
|
||||
!languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
|
||||
val anonymous = owner is KtFunctionLiteral || owner is KtNamedFunction && owner.name == null
|
||||
if (anonymous && !languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
|
||||
return
|
||||
}
|
||||
val mainFunctionDetector = MainFunctionDetector(trace.bindingContext)
|
||||
@@ -666,7 +666,12 @@ class ControlFlowInformationProvider private constructor(
|
||||
|| OperatorNameConventions.PROVIDE_DELEGATE == functionName) {
|
||||
return
|
||||
}
|
||||
report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt)
|
||||
if (anonymous) {
|
||||
report(UNUSED_ANONYMOUS_PARAMETER.on(element, variableDescriptor), ctxt)
|
||||
}
|
||||
else {
|
||||
report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1121,6 +1126,7 @@ class ControlFlowInformationProvider private constructor(
|
||||
private fun mustBeReportedOnAllCopies(diagnosticFactory: DiagnosticFactory<*>) =
|
||||
diagnosticFactory === UNUSED_VARIABLE
|
||||
|| diagnosticFactory === UNUSED_PARAMETER
|
||||
|| diagnosticFactory === UNUSED_ANONYMOUS_PARAMETER
|
||||
|| diagnosticFactory === UNUSED_CHANGED_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,7 +570,8 @@ public interface Errors {
|
||||
|
||||
enum BadNamedArgumentsTarget {
|
||||
NON_KOTLIN_FUNCTION,
|
||||
INVOKE_ON_FUNCTION_TYPE
|
||||
INVOKE_ON_FUNCTION_TYPE,
|
||||
HEADER_CLASS_MEMBER,
|
||||
}
|
||||
|
||||
DiagnosticFactory0<KtExpression> VARARG_OUTSIDE_PARENTHESES = DiagnosticFactory0.create(ERROR);
|
||||
@@ -705,6 +706,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtSimpleNameExpression, KotlinType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> YIELD_IS_RESERVED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_RESERVED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> UNDERSCORE_USAGE_WITHOUT_BACKTICKS = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> INVALID_CHARACTERS = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, String> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory1.create(ERROR);
|
||||
@@ -742,6 +744,7 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory1<KtNamedDeclaration, VariableDescriptor> UNUSED_VARIABLE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||
DiagnosticFactory1<KtParameter, VariableDescriptor> UNUSED_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||
DiagnosticFactory1<KtParameter, VariableDescriptor> UNUSED_ANONYMOUS_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||
DiagnosticFactory1<KtDestructuringDeclarationEntry, VariableDescriptor> UNUSED_DESTRUCTURED_PARAMETER_ENTRY =
|
||||
DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||
DiagnosticFactory2<KtTypeParameter, TypeParameterDescriptor, KotlinType> UNUSED_TYPEALIAS_PARAMETER =
|
||||
|
||||
@@ -207,6 +207,8 @@ public class DefaultErrorMessages {
|
||||
return "non-Kotlin functions";
|
||||
case INVOKE_ON_FUNCTION_TYPE:
|
||||
return "function types";
|
||||
case HEADER_CLASS_MEMBER:
|
||||
return "members of header classes";
|
||||
default:
|
||||
throw new AssertionError(target);
|
||||
}
|
||||
@@ -304,6 +306,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(UNINITIALIZED_ENUM_COMPANION, "Companion object of enum class ''{0}'' is uninitialized here", NAME);
|
||||
MAP.put(UNUSED_VARIABLE, "Variable ''{0}'' is never used", NAME);
|
||||
MAP.put(UNUSED_PARAMETER, "Parameter ''{0}'' is never used", NAME);
|
||||
MAP.put(UNUSED_ANONYMOUS_PARAMETER, "Parameter ''{0}'' is never used, could be renamed to _", NAME);
|
||||
MAP.put(UNUSED_DESTRUCTURED_PARAMETER_ENTRY, "Destructured parameter ''{0}'' is never used", NAME);
|
||||
MAP.put(ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE, "Variable ''{0}'' is assigned but never accessed", NAME);
|
||||
MAP.put(VARIABLE_WITH_REDUNDANT_INITIALIZER, "Variable ''{0}'' initializer is redundant", NAME);
|
||||
@@ -463,6 +466,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return Int, but returns {0}", RENDER_TYPE);
|
||||
|
||||
MAP.put(UNDERSCORE_IS_RESERVED, "Names _, __, ___, ..., are reserved in Kotlin");
|
||||
MAP.put(UNDERSCORE_USAGE_WITHOUT_BACKTICKS, "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)");
|
||||
MAP.put(YIELD_IS_RESERVED, "{0}", STRING);
|
||||
MAP.put(INVALID_CHARACTERS, "Name {0}", STRING);
|
||||
|
||||
|
||||
@@ -48,10 +48,14 @@ object PlatformIncompatibilityDiagnosticRenderer :
|
||||
append("The following declaration")
|
||||
if (descriptors.size == 1) append(" is") else append("s are")
|
||||
append(" incompatible")
|
||||
incompatibility.reason?.let { append(" because $it") }
|
||||
incompatibility.reason?.let { appendln(" because $it:") }
|
||||
|
||||
for (descriptor in descriptors) {
|
||||
append(indent + " ")
|
||||
appendln(renderDescriptor(descriptor))
|
||||
}
|
||||
|
||||
incompatibility.unimplemented?.let { unimplemented ->
|
||||
appendln(".")
|
||||
append(indent)
|
||||
appendln("No implementations are found for members listed below:")
|
||||
for ((descriptor, mapping) in unimplemented) {
|
||||
@@ -63,12 +67,6 @@ object PlatformIncompatibilityDiagnosticRenderer :
|
||||
}
|
||||
render(mapping, indent + INDENTATION_UNIT, renderDescriptor)
|
||||
}
|
||||
} ?: run {
|
||||
appendln(":")
|
||||
for (descriptor in descriptors) {
|
||||
append(indent + " ")
|
||||
appendln(renderDescriptor(descriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,4 +298,17 @@ public class KtProperty extends KtTypeParameterListOwnerStub<KotlinPropertyStub>
|
||||
// Suppress Java check for out-of-block
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasBody() {
|
||||
if (hasDelegateExpressionOrInitializer()) return true;
|
||||
KtPropertyAccessor getter = getGetter();
|
||||
if (getter != null && getter.hasBody()) {
|
||||
return true;
|
||||
}
|
||||
KtPropertyAccessor setter = getSetter();
|
||||
if (setter != null && setter.hasBody()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
|
||||
@JvmOverloads
|
||||
fun KtPsiFactory(project: Project?, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(project!!, markGenerated)
|
||||
@@ -45,6 +46,7 @@ private val DO_NOT_ANALYZE_NOTIFICATION = "This file was created by KtPsiFactory
|
||||
var KtFile.doNotAnalyze: String? by UserDataProperty(Key.create("DO_NOT_ANALYZE"))
|
||||
var KtFile.analysisContext: PsiElement? by UserDataProperty(Key.create("ANALYSIS_CONTEXT"))
|
||||
var PsiFile.moduleInfo: ModuleInfo? by UserDataProperty(Key.create("MODULE_INFO"))
|
||||
var KtFile.targetPlatform: TargetPlatform? by UserDataProperty(Key.create("TARGET_PLATFORM"))
|
||||
|
||||
/**
|
||||
* @param markGenerated This needs to be set to true if the `KtPsiFactory` is going to be used for creating elements that are going
|
||||
|
||||
@@ -775,11 +775,14 @@ public class KtPsiUtil {
|
||||
return (KtElement) parent;
|
||||
}
|
||||
}
|
||||
if (current instanceof KtBlockExpression || current instanceof KtParameter) {
|
||||
if (current instanceof KtBlockExpression || current instanceof KtParameter || current instanceof KtValueArgument) {
|
||||
return (KtElement) current;
|
||||
}
|
||||
if (current instanceof KtValueArgument) {
|
||||
return (KtElement) current;
|
||||
if (current instanceof KtDelegatedSuperTypeEntry) {
|
||||
PsiElement grandParent = current.getParent().getParent();
|
||||
if (grandParent instanceof KtClassOrObject && !(grandParent.getParent() instanceof KtObjectLiteralExpression)) {
|
||||
return (KtElement) grandParent;
|
||||
}
|
||||
}
|
||||
|
||||
current = parent;
|
||||
|
||||
@@ -66,6 +66,13 @@ fun KtSimpleNameExpression.getQualifiedElement(): KtElement {
|
||||
}
|
||||
}
|
||||
|
||||
fun KtSimpleNameExpression.getQualifiedElementOrCallableRef(): KtElement {
|
||||
val parent = parent
|
||||
if (parent is KtCallableReferenceExpression && parent.callableReference == this) return parent
|
||||
|
||||
return getQualifiedElement()
|
||||
}
|
||||
|
||||
fun KtSimpleNameExpression.getTopmostParentQualifiedExpressionForSelector(): KtQualifiedExpression? {
|
||||
return generateSequence<KtExpression>(this) {
|
||||
val parentQualified = it.parent as? KtQualifiedExpression
|
||||
@@ -519,4 +526,10 @@ fun KtCallExpression.getOrCreateValueArgumentList(): KtValueArgumentList {
|
||||
valueArgumentList?.let { return it }
|
||||
return addAfter(KtPsiFactory(this).createCallArguments("()"),
|
||||
typeArgumentList ?: calleeExpression) as KtValueArgumentList
|
||||
}
|
||||
}
|
||||
|
||||
fun KtDeclaration.hasBody() = when (this) {
|
||||
is KtFunction -> hasBody()
|
||||
is KtProperty -> hasBody()
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ interface KotlinImportDirectiveStub : StubElement<KtImportDirective> {
|
||||
fun isValid(): Boolean
|
||||
}
|
||||
|
||||
interface KotlinModifierListStub : StubElement<KtModifierList> {
|
||||
interface KotlinModifierListStub : StubElement<KtDeclarationModifierList> {
|
||||
fun hasModifier(modifierToken: KtModifierKeywordToken): Boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class KotlinClassStubImpl(
|
||||
private val qualifiedName: StringRef?,
|
||||
private val name: StringRef?,
|
||||
private val superNames: Array<StringRef>,
|
||||
private val isTrait: Boolean,
|
||||
private val isInterface: Boolean,
|
||||
private val isEnumEntry: Boolean,
|
||||
private val isLocal: Boolean,
|
||||
private val isTopLevel: Boolean
|
||||
@@ -42,7 +42,7 @@ class KotlinClassStubImpl(
|
||||
return FqName(stringRef)
|
||||
}
|
||||
|
||||
override fun isInterface() = isTrait
|
||||
override fun isInterface() = isInterface
|
||||
override fun isEnumEntry() = isEnumEntry
|
||||
override fun isLocal() = isLocal
|
||||
override fun getName() = StringRef.toString(name)
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.psi.stubs.impl;
|
||||
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.psi.KtModifierList;
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationModifierList;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinModifierListStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtModifierListElementType;
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||
|
||||
public class KotlinModifierListStubImpl extends KotlinStubBaseImpl<KtModifierList> implements KotlinModifierListStub {
|
||||
public class KotlinModifierListStubImpl extends KotlinStubBaseImpl<KtDeclarationModifierList> implements KotlinModifierListStub {
|
||||
|
||||
private final int mask;
|
||||
|
||||
|
||||
@@ -803,10 +803,9 @@ public class DescriptorResolver {
|
||||
KtModifierList modifierList = property.getModifierList();
|
||||
boolean isVar = property.isVar();
|
||||
|
||||
boolean hasBody = hasBody(property);
|
||||
Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
|
||||
Modality modality = containingDeclaration instanceof ClassDescriptor
|
||||
? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody),
|
||||
? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, property.hasBody()),
|
||||
trace.getBindingContext(), containingDeclaration)
|
||||
: Modality.FINAL;
|
||||
|
||||
@@ -915,22 +914,6 @@ public class DescriptorResolver {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
public static boolean hasBody(KtProperty property) {
|
||||
boolean hasBody = property.hasDelegateExpressionOrInitializer();
|
||||
if (!hasBody) {
|
||||
KtPropertyAccessor getter = property.getGetter();
|
||||
if (getter != null && getter.hasBody()) {
|
||||
hasBody = true;
|
||||
}
|
||||
KtPropertyAccessor setter = property.getSetter();
|
||||
if (!hasBody && setter != null && setter.hasBody()) {
|
||||
hasBody = true;
|
||||
}
|
||||
}
|
||||
return hasBody;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
/*package*/ static KotlinType transformAnonymousTypeIfNeeded(
|
||||
@NotNull DeclarationDescriptorWithVisibility descriptor,
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
|
||||
import org.jetbrains.kotlin.resolve.calls.CallExpressionElement
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.UnderscoreUsageChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.unrollToLeftMostQualifiedExpression
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||
@@ -143,7 +144,6 @@ class QualifiedExpressionResolver {
|
||||
val (name, simpleName) = qualifierPartList.single()
|
||||
val descriptor = scope.findClassifier(name, KotlinLookupLocation(simpleName))
|
||||
storeResult(trace, simpleName, descriptor, ownerDescriptor, position = QualifierPosition.TYPE, isQualifier = true)
|
||||
|
||||
return TypeQualifierResolutionResult(qualifierPartList, descriptor)
|
||||
}
|
||||
|
||||
@@ -597,6 +597,8 @@ class QualifiedExpressionResolver {
|
||||
|
||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptor)
|
||||
|
||||
UnderscoreUsageChecker.checkSimpleNameUsage(descriptor, referenceExpression, trace)
|
||||
|
||||
if (descriptor is DeclarationDescriptorWithVisibility) {
|
||||
val fromToCheck =
|
||||
if (shouldBeVisibleFrom is PackageFragmentDescriptor && shouldBeVisibleFrom.source == SourceElement.NO_SOURCE && referenceExpression.containingFile !is DummyHolder) {
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.container.StorageComponentContainer
|
||||
import org.jetbrains.kotlin.container.composeContainer
|
||||
import org.jetbrains.kotlin.container.useInstance
|
||||
@@ -29,6 +27,7 @@ import org.jetbrains.kotlin.resolve.checkers.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticConstructorsProvider
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.DynamicTypesSettings
|
||||
import java.util.*
|
||||
|
||||
@@ -36,28 +35,33 @@ abstract class TargetPlatform(val platformName: String) {
|
||||
override fun toString() = platformName
|
||||
|
||||
abstract val platformConfigurator: PlatformConfigurator
|
||||
abstract fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath>
|
||||
abstract fun getDefaultImports(includeKotlinComparisons: Boolean): List<ImportPath>
|
||||
open val excludedImports: List<FqName> get() = emptyList()
|
||||
|
||||
abstract val multiTargetPlatform: MultiTargetPlatform
|
||||
|
||||
object Default : TargetPlatform("Default") {
|
||||
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
|
||||
listOf(
|
||||
"kotlin.*",
|
||||
"kotlin.annotation.*",
|
||||
"kotlin.collections.*",
|
||||
"kotlin.ranges.*",
|
||||
"kotlin.sequences.*",
|
||||
"kotlin.text.*",
|
||||
"kotlin.io.*"
|
||||
).forEach { add(ImportPath.fromString(it)) }
|
||||
private val defaultImports = LockBasedStorageManager().createMemoizedFunction<Boolean, List<ImportPath>> {
|
||||
includeKotlinComparisons ->
|
||||
ArrayList<ImportPath>().apply {
|
||||
listOf(
|
||||
"kotlin.*",
|
||||
"kotlin.annotation.*",
|
||||
"kotlin.collections.*",
|
||||
"kotlin.ranges.*",
|
||||
"kotlin.sequences.*",
|
||||
"kotlin.text.*",
|
||||
"kotlin.io.*"
|
||||
).forEach { add(ImportPath.fromString(it)) }
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.DefaultImportOfPackageKotlinComparisons)) {
|
||||
add(ImportPath.fromString("kotlin.comparisons.*"))
|
||||
if (includeKotlinComparisons) {
|
||||
add(ImportPath.fromString("kotlin.comparisons.*"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDefaultImports(includeKotlinComparisons: Boolean): List<ImportPath> = defaultImports(includeKotlinComparisons)
|
||||
|
||||
override val platformConfigurator =
|
||||
object : PlatformConfigurator(
|
||||
DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf(),
|
||||
@@ -95,7 +99,8 @@ private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
DeprecatedCallChecker, CallReturnsArrayOfNothingChecker(), InfixCallChecker(), OperatorCallChecker(),
|
||||
ConstructorHeaderCallChecker, ProtectedConstructorCallChecker, ApiVersionCallChecker,
|
||||
CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker, MissingDependencyClassChecker,
|
||||
CallableReferenceCompatibilityChecker()
|
||||
CallableReferenceCompatibilityChecker(),
|
||||
UnderscoreUsageChecker
|
||||
)
|
||||
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
|
||||
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls;
|
||||
|
||||
import kotlin.Pair;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
|
||||
@@ -265,7 +266,7 @@ public class ArgumentTypeResolver {
|
||||
|
||||
if (overloadResolutionResults == null) return null;
|
||||
|
||||
if (overloadResolutionResults.isSingleResult()) {
|
||||
if (isSingleAndPossibleTransformToSuccess(overloadResolutionResults)) {
|
||||
ResolvedCall<?> resolvedCall =
|
||||
OverloadResolutionResultsUtil.getResultingCall(overloadResolutionResults, context.contextDependency);
|
||||
if (resolvedCall == null) return null;
|
||||
@@ -284,6 +285,12 @@ public class ArgumentTypeResolver {
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean isSingleAndPossibleTransformToSuccess(@NotNull OverloadResolutionResults<?> overloadResolutionResults) {
|
||||
if (!overloadResolutionResults.isSingleResult()) return false;
|
||||
ResolvedCall<?> call = CollectionsKt.singleOrNull(overloadResolutionResults.getResultingCalls());
|
||||
return call != null && call.getStatus().possibleTransformToSuccess();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinTypeInfo getFunctionLiteralTypeInfo(
|
||||
@NotNull KtExpression expression,
|
||||
|
||||
@@ -23,9 +23,7 @@ import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -42,8 +40,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.NON_KOTLIN_FUNCTION;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET;
|
||||
import static org.jetbrains.kotlin.resolve.calls.ValueArgumentsToParametersMapper.Status.*;
|
||||
|
||||
@@ -189,11 +186,19 @@ public class ValueArgumentsToParametersMapper {
|
||||
KtSimpleNameExpression nameReference = argumentName.getReferenceExpression();
|
||||
|
||||
KtPsiUtilKt.checkReservedYield(nameReference, candidateCall.getTrace());
|
||||
if (!candidate.hasStableParameterNames() && nameReference != null) {
|
||||
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(
|
||||
nameReference,
|
||||
candidate instanceof FunctionInvokeDescriptor ? INVOKE_ON_FUNCTION_TYPE : NON_KOTLIN_FUNCTION
|
||||
));
|
||||
if (nameReference != null) {
|
||||
if (candidate instanceof MemberDescriptor && ((MemberDescriptor) candidate).isHeader() &&
|
||||
candidate.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
// We do not allow named arguments for members of header classes until we're able to use both
|
||||
// headers and platform definitions when compiling platform code
|
||||
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(nameReference, HEADER_CLASS_MEMBER));
|
||||
}
|
||||
else if (!candidate.hasStableParameterNames()) {
|
||||
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(
|
||||
nameReference,
|
||||
candidate instanceof FunctionInvokeDescriptor ? INVOKE_ON_FUNCTION_TYPE : NON_KOTLIN_FUNCTION
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (candidate.hasStableParameterNames() && nameReference != null &&
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.resolve.calls.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
|
||||
object UnderscoreUsageChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) return
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
val namedDescriptor = if (descriptor is ConstructorDescriptor) descriptor.containingDeclaration else descriptor
|
||||
if (!namedDescriptor.name.asString().isUnderscoreOnlyName()) return
|
||||
checkCallElement(resolvedCall.call.callElement, context)
|
||||
}
|
||||
|
||||
private fun checkCallElement(ktElement: KtElement, context: CallCheckerContext) {
|
||||
when (ktElement) {
|
||||
is KtSimpleNameExpression ->
|
||||
checkSimpleNameUsage(ktElement, context.trace)
|
||||
is KtCallExpression ->
|
||||
ktElement.calleeExpression?.let { checkCallElement(it, context) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSimpleNameUsage(ktName: KtSimpleNameExpression, trace: BindingTrace) {
|
||||
if (ktName.text.isUnderscoreOnlyName()) {
|
||||
trace.report(Errors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.on(ktName))
|
||||
}
|
||||
}
|
||||
|
||||
fun checkSimpleNameUsage(descriptor: DeclarationDescriptor, ktName: KtSimpleNameExpression, trace: BindingTrace) {
|
||||
if (descriptor.name.asString().isUnderscoreOnlyName()) {
|
||||
checkSimpleNameUsage(ktName, trace)
|
||||
}
|
||||
}
|
||||
|
||||
fun String.isUnderscoreOnlyName() =
|
||||
isNotEmpty() && all { it == '_' }
|
||||
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
@@ -266,11 +267,11 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
||||
|
||||
val substitutor = Substitutor(aTypeParams, bTypeParams, parentSubstitutor)
|
||||
|
||||
if (aParams.map { substitutor(it.type) } != bParams.map { it.type } ||
|
||||
aExtensionReceiver?.type?.let(substitutor) != bExtensionReceiver?.type) return Incompatible.ParameterTypes
|
||||
if (substitutor(a.returnType) != b.returnType) return Incompatible.ReturnType
|
||||
if (!areCompatibleTypeLists(aParams.map { substitutor(it.type) }, bParams.map { it.type }) ||
|
||||
!areCompatibleTypes(aExtensionReceiver?.type?.let(substitutor), bExtensionReceiver?.type)) return Incompatible.ParameterTypes
|
||||
if (!areCompatibleTypes(substitutor(a.returnType), b.returnType)) return Incompatible.ReturnType
|
||||
|
||||
if (!equalsBy(aParams, bParams, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames
|
||||
if (b.hasStableParameterNames() && !equalsBy(aParams, bParams, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames
|
||||
if (!equalsBy(aTypeParams, bTypeParams, TypeParameterDescriptor::getName)) return Incompatible.TypeParameterNames
|
||||
|
||||
if (a.modality != b.modality) return Incompatible.Modality
|
||||
@@ -292,8 +293,19 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
||||
return Compatible
|
||||
}
|
||||
|
||||
private fun areCompatibleTypes(a: KotlinType?, b: KotlinType?): Boolean {
|
||||
return if (a != null) b != null && TypeUtils.equalTypes(a, b) else b == null
|
||||
}
|
||||
|
||||
private fun areCompatibleTypeLists(a: List<KotlinType?>, b: List<KotlinType?>): Boolean {
|
||||
for (i in a.indices) {
|
||||
if (!areCompatibleTypes(a[i], b[i])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun areCompatibleTypeParameters(a: List<TypeParameterDescriptor>, b: List<TypeParameterDescriptor>, substitutor: Substitutor): Compatibility {
|
||||
if (a.map { substitutor(it.defaultType) } != b.map { it.defaultType }) return Incompatible.TypeParameterUpperBounds
|
||||
if (!areCompatibleTypeLists(a.map { substitutor(it.defaultType) }, b.map { it.defaultType })) return Incompatible.TypeParameterUpperBounds
|
||||
if (!equalsBy(a, b, TypeParameterDescriptor::getVariance)) return Incompatible.TypeParameterVariance
|
||||
if (!equalsBy(a, b, TypeParameterDescriptor::isReified)) return Incompatible.TypeParameterReified
|
||||
|
||||
@@ -362,7 +374,9 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
||||
// and not added if an explicit supertype _is_ specified
|
||||
val aSupertypes = a.typeConstructor.supertypes.filterNot(KotlinBuiltIns::isAny)
|
||||
val bSupertypes = b.typeConstructor.supertypes.filterNot(KotlinBuiltIns::isAny)
|
||||
if (!bSupertypes.containsAll(aSupertypes.map(substitutor))) return Incompatible.Supertypes
|
||||
if (aSupertypes.map(substitutor).any { aSupertype ->
|
||||
bSupertypes.none { bSupertype -> areCompatibleTypes(aSupertype, bSupertype) }
|
||||
}) return Incompatible.Supertypes
|
||||
|
||||
areCompatibleClassScopes(a, b, checkImpl && !implTypealias, substitutor).let { if (it != Compatible) return it }
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.lazy
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.DefaultImportOfPackageKotlinComparisons
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
@@ -37,8 +38,9 @@ class DefaultImportProvider(
|
||||
private val targetPlatform: TargetPlatform,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
val defaultImports: List<ImportPath>
|
||||
by storageManager.createLazyValue { targetPlatform.getDefaultImports(languageVersionSettings) }
|
||||
val defaultImports: List<ImportPath> by storageManager.createLazyValue {
|
||||
targetPlatform.getDefaultImports(languageVersionSettings.supportsFeature(DefaultImportOfPackageKotlinComparisons))
|
||||
}
|
||||
|
||||
val excludedImports: List<FqName> by storageManager.createLazyValue {
|
||||
val packagesWithAliases = listOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.TEXT_PACKAGE_FQ_NAME)
|
||||
|
||||
@@ -23,9 +23,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import java.io.File
|
||||
import kotlin.comparisons.compareValues
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.dependencies.KotlinScriptExternalDependencies
|
||||
import kotlin.script.templates.standard.ScriptTemplateWithArgs
|
||||
|
||||
open class KotlinScriptDefinition(val template: KClass<out Any>) {
|
||||
@@ -47,33 +46,5 @@ open class KotlinScriptDefinition(val template: KClass<out Any>) {
|
||||
open fun <TF: Any> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? = null
|
||||
}
|
||||
|
||||
interface KotlinScriptExternalDependencies : Comparable<KotlinScriptExternalDependencies> {
|
||||
val javaHome: String? get() = null
|
||||
val classpath: Iterable<File> get() = emptyList()
|
||||
val imports: Iterable<String> get() = emptyList()
|
||||
val sources: Iterable<File> get() = emptyList()
|
||||
val scripts: Iterable<File> get() = emptyList()
|
||||
|
||||
override fun compareTo(other: KotlinScriptExternalDependencies): Int =
|
||||
compareValues(javaHome, other.javaHome)
|
||||
.chainCompare { compareIterables(classpath, other.classpath) }
|
||||
.chainCompare { compareIterables(imports, other.imports) }
|
||||
.chainCompare { compareIterables(sources, other.sources) }
|
||||
.chainCompare { compareIterables(scripts, other.scripts) }
|
||||
}
|
||||
|
||||
object StandardScriptDefinition : KotlinScriptDefinition(ScriptTemplateWithArgs::class)
|
||||
|
||||
private fun<T: Comparable<T>> compareIterables(a: Iterable<T>, b: Iterable<T>): Int {
|
||||
val ia = a.iterator()
|
||||
val ib = b.iterator()
|
||||
while (true) {
|
||||
if (ia.hasNext() && !ib.hasNext()) return 1
|
||||
if (!ia.hasNext() && !ib.hasNext()) return 0
|
||||
if (!ia.hasNext()) return -1
|
||||
val compRes = compareValues(ia.next(), ib.next())
|
||||
if (compRes != 0) return compRes
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn()
|
||||
@@ -34,6 +34,11 @@ import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KParameter
|
||||
import kotlin.reflect.full.memberFunctions
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
import kotlin.script.dependencies.BasicScriptDependenciesResolver
|
||||
import kotlin.script.dependencies.KotlinScriptExternalDependencies
|
||||
import kotlin.script.dependencies.ScriptContents
|
||||
import kotlin.script.dependencies.ScriptDependenciesResolver
|
||||
import kotlin.script.templates.AcceptedAnnotations
|
||||
|
||||
open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
template: KClass<out Any>,
|
||||
@@ -43,11 +48,15 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
) : KotlinScriptDefinition(template) {
|
||||
|
||||
val scriptFilePattern by lazy {
|
||||
providedScriptFilePattern ?: template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>()?.scriptFilePattern ?: DEFAULT_SCRIPT_FILE_PATTERN
|
||||
providedScriptFilePattern
|
||||
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>()?.scriptFilePattern }
|
||||
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.ScriptTemplateDefinition>()?.scriptFilePattern }
|
||||
?: DEFAULT_SCRIPT_FILE_PATTERN
|
||||
}
|
||||
|
||||
val resolver: ScriptDependenciesResolver? by lazy {
|
||||
val defAnn by lazy { template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>() }
|
||||
val defAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>() } }
|
||||
val legacyDefAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.ScriptTemplateDefinition>() } }
|
||||
when {
|
||||
providedResolver != null -> providedResolver
|
||||
// TODO: logScriptDefMessage missing or invalid constructor
|
||||
@@ -61,12 +70,27 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
log.warn("[kts] Script def error ${ex.message}")
|
||||
null
|
||||
}
|
||||
legacyDefAnn != null ->
|
||||
try {
|
||||
log.warn("[kts] Deprecated annotations on the script template are used, please update the provider")
|
||||
legacyDefAnn.resolver.primaryConstructor?.call()?.let {
|
||||
LegacyScriptDependenciesResolverWrapper(it)
|
||||
}
|
||||
?: null.apply {
|
||||
log.warn("[kts] No default constructor found for ${legacyDefAnn.resolver.qualifiedName}")
|
||||
}
|
||||
}
|
||||
catch (ex: ClassCastException) {
|
||||
log.warn("[kts] Script def error ${ex.message}")
|
||||
null
|
||||
}
|
||||
else -> BasicScriptDependenciesResolver()
|
||||
}
|
||||
}
|
||||
|
||||
val samWithReceiverAnnotations: List<String>? by lazy {
|
||||
template.annotations.firstIsInstanceOrNull<SamWithReceiverAnnotations>()?.annotations?.toList()
|
||||
takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.extensions.SamWithReceiverAnnotations>()?.annotations?.toList() }
|
||||
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.SamWithReceiverAnnotations>()?.annotations?.toList() }
|
||||
}
|
||||
|
||||
private val acceptedAnnotations: List<KClass<out Annotation>> by lazy {
|
||||
@@ -100,13 +124,9 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
|
||||
override fun <TF: Any> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
|
||||
|
||||
fun logClassloadingError(ex: Throwable) {
|
||||
logScriptDefMessage(ScriptDependenciesResolver.ReportSeverity.WARNING, ex.message ?: "Invalid script template: ${template.qualifiedName}", null)
|
||||
}
|
||||
|
||||
fun makeScriptContents() = BasicScriptContents(file, getAnnotations = {
|
||||
val classLoader = template.java.classLoader
|
||||
try {
|
||||
takeUnlessError(reportError = false) {
|
||||
getAnnotationEntries(file, project)
|
||||
.mapNotNull { psiAnn ->
|
||||
// TODO: consider advanced matching using semantic similar to actual resolving
|
||||
@@ -115,21 +135,14 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
}?.let { constructAnnotation(psiAnn, classLoader.loadClass(it.qualifiedName).kotlin as KClass<out Annotation>) }
|
||||
}
|
||||
}
|
||||
catch (ex: Throwable) {
|
||||
logClassloadingError(ex)
|
||||
emptyList()
|
||||
}
|
||||
?: emptyList()
|
||||
})
|
||||
|
||||
try {
|
||||
return takeUnlessError(reportError = false) {
|
||||
val fileDeps = resolver?.resolve(makeScriptContents(), environment, ::logScriptDefMessage, previousDependencies)
|
||||
// TODO: use it as a Future
|
||||
return fileDeps?.get()
|
||||
fileDeps?.get()
|
||||
}
|
||||
catch (ex: Throwable) {
|
||||
logClassloadingError(ex)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun <TF: Any> getAnnotationEntries(file: TF, project: Project): Iterable<KtAnnotationEntry> = when (file) {
|
||||
@@ -164,6 +177,20 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||
override val annotationsForSamWithReceivers: List<String>
|
||||
get() = samWithReceiverAnnotations ?: super.annotationsForSamWithReceivers
|
||||
|
||||
private inline fun<T> takeUnlessError(reportError: Boolean = true, body: () -> T?): T? =
|
||||
try {
|
||||
body()
|
||||
}
|
||||
catch (ex: Throwable) {
|
||||
if (reportError) {
|
||||
log.error("Invalid script template: " + template.qualifiedName, ex)
|
||||
}
|
||||
else {
|
||||
log.warn("Invalid script template: " + template.qualifiedName, ex)
|
||||
}
|
||||
null
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val log = Logger.getInstance(KotlinScriptDefinitionFromAnnotatedTemplate::class.java)
|
||||
}
|
||||
@@ -178,3 +205,10 @@ internal fun logScriptDefMessage(reportSeverity: ScriptDependenciesResolver.Repo
|
||||
ScriptDependenciesResolver.ReportSeverity.DEBUG -> KotlinScriptDefinitionFromAnnotatedTemplate.log.debug(msg)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun sameSignature(left: KFunction<*>, right: KFunction<*>): Boolean =
|
||||
left.parameters.size == right.parameters.size &&
|
||||
left.parameters.zip(right.parameters).all {
|
||||
it.first.kind == KParameter.Kind.INSTANCE ||
|
||||
it.first.type == it.second.type
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.io.File
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
import kotlin.script.dependencies.KotlinScriptExternalDependencies
|
||||
|
||||
class KotlinScriptExternalImportsProvider(val project: Project, private val scriptDefinitionProvider: KotlinScriptDefinitionProvider) {
|
||||
|
||||
@@ -39,22 +40,22 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
||||
|
||||
private fun <TF: Any> calculateExternalDependencies(file: TF): KotlinScriptExternalDependencies? {
|
||||
val path = getFilePath(file)
|
||||
return cache[path]
|
||||
?: if (cacheOfNulls.contains(path)) null
|
||||
else scriptDefinitionProvider.findScriptDefinition(file)?.getDependenciesFor(file, project, null)
|
||||
.apply {
|
||||
if (this != null) {
|
||||
log.info("[kts] new cached deps for $path: ${this.classpath.joinToString(File.pathSeparator)}")
|
||||
}
|
||||
cacheLock.write {
|
||||
if (this == null) {
|
||||
cacheOfNulls.add(path)
|
||||
}
|
||||
else {
|
||||
cache.put(path, this)
|
||||
}
|
||||
}
|
||||
val cached = cache[path]
|
||||
return when {
|
||||
cached != null -> cached
|
||||
cacheOfNulls.contains(path) -> null
|
||||
else -> scriptDefinitionProvider.findScriptDefinition(file)?.getDependenciesFor(file, project, null).apply {
|
||||
cacheLock.write {
|
||||
if (this != null) {
|
||||
cache.put(path, this)
|
||||
log.info("[kts] new cached deps for $path: ${this.classpath.joinToString(File.pathSeparator)}")
|
||||
}
|
||||
else {
|
||||
cacheOfNulls.add(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// optimized for initial caching, additional handling of possible duplicates to save a call to distinct
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -23,15 +23,21 @@ import kotlin.reflect.KClass
|
||||
|
||||
const val DEFAULT_SCRIPT_FILE_PATTERN = ".*\\.kts"
|
||||
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.templatesScriptTemplateDefinition instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.templates.ScriptTemplateDefinition"))
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ScriptTemplateDefinition(val resolver: KClass<out ScriptDependenciesResolver> = BasicScriptDependenciesResolver::class,
|
||||
annotation class ScriptTemplateDefinition(val resolver: KClass<out ScriptDependenciesResolver>,
|
||||
val scriptFilePattern: String = DEFAULT_SCRIPT_FILE_PATTERN)
|
||||
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.extensions.SamWithReceiverAnnotations instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.extensions.SamWithReceiverAnnotations"))
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class SamWithReceiverAnnotations(vararg val annotations: String)
|
||||
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptContents instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptContents"))
|
||||
interface ScriptContents {
|
||||
|
||||
data class Position(val line: Int, val col: Int)
|
||||
@@ -41,6 +47,8 @@ interface ScriptContents {
|
||||
val text: CharSequence?
|
||||
}
|
||||
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.PseudoFuture instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.dependencies.PseudoFuture"))
|
||||
class PseudoFuture<T>(private val value: T): Future<T> {
|
||||
override fun get(): T = value
|
||||
override fun get(p0: Long, p1: TimeUnit): T = value
|
||||
@@ -51,6 +59,8 @@ class PseudoFuture<T>(private val value: T): Future<T> {
|
||||
|
||||
fun KotlinScriptExternalDependencies?.asFuture(): PseudoFuture<KotlinScriptExternalDependencies?> = PseudoFuture(this)
|
||||
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptDependenciesResolver instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptDependenciesResolver"))
|
||||
interface ScriptDependenciesResolver {
|
||||
|
||||
enum class ReportSeverity { ERROR, WARNING, INFO, DEBUG }
|
||||
@@ -62,9 +72,9 @@ interface ScriptDependenciesResolver {
|
||||
): Future<KotlinScriptExternalDependencies?> = PseudoFuture(null)
|
||||
}
|
||||
|
||||
@Suppress("unused") // used in gradle-script-kotlin for a moment
|
||||
@Deprecated("Use new ScriptDependenciesResolver, this one is left for temporary compatibility of new resolvers to kotlin plugin 1.1-M01",
|
||||
ReplaceWith("ScriptDependenciesResolver"))
|
||||
@Suppress("unused")
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptDependenciesResolver instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptDependenciesResolver"))
|
||||
interface ScriptDependenciesResolverEx {
|
||||
fun resolve(script: ScriptContents,
|
||||
environment: Map<String, Any?>?,
|
||||
@@ -72,9 +82,72 @@ interface ScriptDependenciesResolverEx {
|
||||
): KotlinScriptExternalDependencies? = null
|
||||
}
|
||||
|
||||
class BasicScriptDependenciesResolver : ScriptDependenciesResolver
|
||||
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.KotlinScriptExternalDependencies instead",
|
||||
replaceWith = ReplaceWith("kotlin.script.dependencies.KotlinScriptExternalDependencies"))
|
||||
interface KotlinScriptExternalDependencies : Comparable<KotlinScriptExternalDependencies> {
|
||||
val javaHome: String? get() = null
|
||||
val classpath: Iterable<File> get() = emptyList()
|
||||
val imports: Iterable<String> get() = emptyList()
|
||||
val sources: Iterable<File> get() = emptyList()
|
||||
val scripts: Iterable<File> get() = emptyList()
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class AcceptedAnnotations(vararg val supportedAnnotationClasses: KClass<out Annotation>)
|
||||
override fun compareTo(other: KotlinScriptExternalDependencies): Int =
|
||||
compareValues(javaHome, other.javaHome)
|
||||
.chainCompare { compareIterables(classpath, other.classpath) }
|
||||
.chainCompare { compareIterables(imports, other.imports) }
|
||||
.chainCompare { compareIterables(sources, other.sources) }
|
||||
.chainCompare { compareIterables(scripts, other.scripts) }
|
||||
}
|
||||
|
||||
private fun<T: Comparable<T>> compareIterables(a: Iterable<T>, b: Iterable<T>): Int {
|
||||
val ia = a.iterator()
|
||||
val ib = b.iterator()
|
||||
while (true) {
|
||||
if (ia.hasNext() && !ib.hasNext()) return 1
|
||||
if (!ia.hasNext() && !ib.hasNext()) return 0
|
||||
if (!ia.hasNext()) return -1
|
||||
val compRes = compareValues(ia.next(), ib.next())
|
||||
if (compRes != 0) return compRes
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn()
|
||||
|
||||
class LegacyScriptDependenciesResolverWrapper(val legacyResolver: ScriptDependenciesResolver) : kotlin.script.dependencies.ScriptDependenciesResolver {
|
||||
|
||||
override fun resolve(script: kotlin.script.dependencies.ScriptContents,
|
||||
environment: Map<String, Any?>?,
|
||||
report: (kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity, String, kotlin.script.dependencies.ScriptContents.Position?) -> Unit,
|
||||
previousDependencies: kotlin.script.dependencies.KotlinScriptExternalDependencies?
|
||||
): Future<kotlin.script.dependencies.KotlinScriptExternalDependencies?> {
|
||||
val legacyDeps = legacyResolver.resolve(
|
||||
object : ScriptContents {
|
||||
override val file: File? get() = script.file
|
||||
override val annotations: Iterable<Annotation> get() = script.annotations
|
||||
override val text: CharSequence? get() = script.text
|
||||
},
|
||||
environment,
|
||||
{ sev, msg, pos -> report(kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.values()[sev.ordinal],
|
||||
msg,
|
||||
pos?.let { kotlin.script.dependencies.ScriptContents.Position(it.line, it.col) }) },
|
||||
previousDependencies?.let {
|
||||
object : KotlinScriptExternalDependencies {
|
||||
override val javaHome get() = it.javaHome
|
||||
override val classpath get() = it.classpath
|
||||
override val imports get() = it.imports
|
||||
override val sources get() = it.sources
|
||||
override val scripts get() = it.scripts
|
||||
}
|
||||
}
|
||||
).get()
|
||||
return kotlin.script.dependencies.PseudoFuture(legacyDeps?.let {
|
||||
object : kotlin.script.dependencies.KotlinScriptExternalDependencies {
|
||||
override val javaHome get() = it.javaHome
|
||||
override val classpath get() = it.classpath
|
||||
override val imports get() = it.imports
|
||||
override val sources get() = it.sources
|
||||
override val scripts get() = it.scripts
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import kotlin.script.dependencies.ScriptDependenciesResolver
|
||||
|
||||
interface ScriptTemplatesProvider {
|
||||
|
||||
|
||||
@@ -913,7 +913,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return baseTypeInfo;
|
||||
}
|
||||
DataFlowInfo dataFlowInfo = baseTypeInfo.getDataFlowInfo();
|
||||
if (isKnownToBeNotNull(baseExpression, context) && !baseType.isError()) {
|
||||
if (isKnownToBeNotNull(baseExpression, baseType, context)) {
|
||||
context.trace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, TypeUtils.makeNotNullable(baseType)));
|
||||
}
|
||||
else {
|
||||
@@ -956,15 +956,20 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return facade.getTypeInfo(baseExpression, context, isStatement);
|
||||
}
|
||||
|
||||
private static boolean isKnownToBeNotNull(KtExpression expression, ExpressionTypingContext context) {
|
||||
KotlinType type = context.trace.getType(expression);
|
||||
assert type != null : "This method is only supposed to be called when the type is not null";
|
||||
return isKnownToBeNotNull(expression, type, context);
|
||||
}
|
||||
// Returns `true` if warnings should be reported for left-hand side of elvis and not-null (!!) assertion
|
||||
private static boolean isKnownToBeNotNull(
|
||||
@NotNull KtExpression expression,
|
||||
@Nullable KotlinType ktType,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
if (ktType == null) return false;
|
||||
|
||||
private static boolean isKnownToBeNotNull(KtExpression expression, KotlinType jetType, ExpressionTypingContext context) {
|
||||
DataFlowValue dataFlowValue = createDataFlowValue(expression, jetType, context);
|
||||
return !context.dataFlowInfo.getStableNullability(dataFlowValue).canBeNull();
|
||||
if (ktType.isError() && !ErrorUtils.isUninferredParameter(ktType)) return false;
|
||||
|
||||
if (!TypeUtils.isNullableType(ktType)) return true;
|
||||
|
||||
DataFlowValue dataFlowValue = createDataFlowValue(expression, ktType, context);
|
||||
return context.dataFlowInfo.getStableNullability(dataFlowValue) == Nullability.NOT_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1296,7 +1301,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
assert leftTypeInfo != null : "Left expression was not processed: " + expression;
|
||||
KotlinType leftType = leftTypeInfo.getType();
|
||||
if (leftType != null && isKnownToBeNotNull(left, leftType, context)) {
|
||||
if (isKnownToBeNotNull(left, leftType, context)) {
|
||||
context.trace.report(USELESS_ELVIS.on(expression, leftType));
|
||||
}
|
||||
else if (KtPsiUtil.isNullConstant(right) && leftType != null && !FlexibleTypesKt.isNullabilityFlexible(leftType)) {
|
||||
|
||||
@@ -665,7 +665,7 @@ class DoubleColonExpressionResolver(
|
||||
resolutionResults.isNothing -> null
|
||||
else -> ResolutionResultsAndTraceCommitCallback(resolutionResults) {
|
||||
checkReservedYield(reference, outerContext.trace)
|
||||
if (resolutionMode != ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS || resolutionResults.isSingleResult) {
|
||||
if (resolutionMode != ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS || resolutionResults.isSuccess) {
|
||||
temporaryTrace.commit()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,21 +37,6 @@ public class ClsWrapperStubPsiFactory extends StubPsiFactory {
|
||||
|
||||
private ClsWrapperStubPsiFactory() { }
|
||||
|
||||
@Nullable
|
||||
public static LightMemberOriginForDeclaration getMemberOrigin(@NotNull PsiMember member) {
|
||||
if (member instanceof ClsRepositoryPsiElement<?>) {
|
||||
StubElement stubElement = ((ClsRepositoryPsiElement<?>) member).getStub();
|
||||
if (stubElement instanceof UserDataHolder) {
|
||||
LightElementOrigin origin = ((UserDataHolder) stubElement).getUserData(ORIGIN);
|
||||
if (origin instanceof LightMemberOriginForDeclaration) {
|
||||
return (LightMemberOriginForDeclaration) origin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass createClass(@NotNull PsiClassStub stub) {
|
||||
final PsiElement origin = getOriginalElement(stub);
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil.findClass
|
||||
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder.javaFileStub
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
@@ -110,7 +109,7 @@ fun PsiJavaFileStub.findDelegate(classOrObject: KtClassOrObject): PsiClass {
|
||||
fun PsiJavaFileStub.findDelegate(classFqName: FqName): PsiClass {
|
||||
return findClass(this) {
|
||||
classFqName.asString() == it.qualifiedName
|
||||
} ?: throw IllegalStateException("Facade class $classFqName not found; classes in Java file stub: ${collectClassNames(javaFileStub)}")
|
||||
} ?: throw IllegalStateException("Facade class $classFqName not found; classes in Java file stub: ${collectClassNames(this)}")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||
|
||||
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager) {
|
||||
abstract val lightClassData: LightClassData
|
||||
|
||||
override val clsDelegate: PsiClass by lazyPub { lightClassData.clsDelegate }
|
||||
|
||||
override fun getOwnFields() = lightClassData.getOwnFields(this)
|
||||
override fun getOwnMethods() = lightClassData.getOwnMethods(this)
|
||||
|
||||
@@ -194,12 +194,8 @@ class KtLightClassForFacade private constructor(
|
||||
|
||||
override fun copy() = KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files)
|
||||
|
||||
override val lightClassData by lazyPub {
|
||||
lightClassDataCache.value.findDataForFacade(facadeClassFqName)
|
||||
}
|
||||
|
||||
override val clsDelegate: PsiClass
|
||||
get() = lightClassData.clsDelegate
|
||||
override val lightClassData
|
||||
get() = lightClassDataCache.value.findDataForFacade(facadeClassFqName)
|
||||
|
||||
override fun getNavigationElement() = files.iterator().next()
|
||||
|
||||
|
||||
@@ -78,9 +78,8 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
abstract override fun getParent(): PsiElement?
|
||||
abstract override fun getQualifiedName(): String?
|
||||
|
||||
override val clsDelegate: PsiClass get() = lightClassData.clsDelegate
|
||||
|
||||
override val lightClassData: LightClassData by lazyPub { findLightClassData() }
|
||||
override val lightClassData: LightClassData
|
||||
get() = findLightClassData()
|
||||
|
||||
open protected fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiField
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiVariableEx
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
|
||||
interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiNamedElement {
|
||||
val kotlinOrigin: T?
|
||||
@@ -30,8 +30,18 @@ interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiNamedElemen
|
||||
val clsDelegate: D
|
||||
}
|
||||
|
||||
interface KtLightDeclaration<out T: KtDeclaration, out D: PsiElement>: KtLightElement<T, D>
|
||||
interface KtLightDeclaration<out T : KtDeclaration, out D : PsiElement> : KtLightElement<T, D>
|
||||
|
||||
interface KtLightField : PsiField, KtLightDeclaration<KtDeclaration, PsiField>, PsiVariableEx {
|
||||
interface KtLightMember<out D : PsiMember> : PsiMember, KtLightDeclaration<KtDeclaration, D>, PsiNameIdentifierOwner, PsiDocCommentOwner {
|
||||
val lightMemberOrigin: LightMemberOrigin?
|
||||
|
||||
override fun getContainingClass(): KtLightClass
|
||||
}
|
||||
|
||||
interface KtLightField : PsiField, KtLightMember<PsiField>, PsiVariableEx
|
||||
|
||||
interface KtLightMethod : PsiAnnotationMethod, KtLightMember<PsiMethod> {
|
||||
val isDelegated: Boolean
|
||||
get() = lightMemberOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
|
||||
|| lightMemberOrigin?.originKind == JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
|
||||
}
|
||||
@@ -16,12 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.navigation.ItemPresentation
|
||||
import com.intellij.navigation.ItemPresentationProviders
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiVariableEx
|
||||
import com.intellij.psi.impl.light.LightElement
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||
@@ -30,42 +26,24 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForEnumEntry
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
// Copied from com.intellij.psi.impl.light.LightField
|
||||
sealed class KtLightFieldImpl<T: PsiField>(
|
||||
sealed class KtLightFieldImpl<D : PsiField>(
|
||||
override val lightMemberOrigin: LightMemberOrigin?,
|
||||
computeRealDelegate: () -> T,
|
||||
private val containingClass: KtLightClass,
|
||||
private val dummyDelegate: PsiField?
|
||||
) : LightElement(containingClass.manager, KotlinLanguage.INSTANCE), KtLightField {
|
||||
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
|
||||
computeRealDelegate: () -> D,
|
||||
containingClass: KtLightClass,
|
||||
dummyDelegate: PsiField?
|
||||
) : KtLightMemberImpl<PsiField>(computeRealDelegate, lightMemberOrigin, containingClass, dummyDelegate), KtLightField {
|
||||
|
||||
override val clsDelegate: T by lazyPub(computeRealDelegate)
|
||||
override val clsDelegate: D
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
get() = super.clsDelegate as D
|
||||
|
||||
@Throws(IncorrectOperationException::class)
|
||||
override fun setInitializer(initializer: PsiExpression?) = throw IncorrectOperationException("Not supported")
|
||||
|
||||
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
|
||||
|
||||
override fun getPresentation(): ItemPresentation? = (kotlinOrigin ?: this).let { ItemPresentationProviders.getItemPresentation(it) }
|
||||
|
||||
override fun getName() = dummyDelegate?.name ?: clsDelegate.name
|
||||
|
||||
override fun getNameIdentifier() = lightIdentifier
|
||||
|
||||
override fun getDocComment() = clsDelegate.docComment
|
||||
|
||||
override fun isDeprecated() = clsDelegate.isDeprecated
|
||||
|
||||
override fun getContainingClass() = containingClass
|
||||
|
||||
override fun getContainingFile() = containingClass.containingFile
|
||||
|
||||
override fun getType() = clsDelegate.type
|
||||
|
||||
override fun getTypeElement() = clsDelegate.typeElement
|
||||
@@ -84,34 +62,12 @@ sealed class KtLightFieldImpl<T: PsiField>(
|
||||
return this
|
||||
}
|
||||
|
||||
private val _modifierList by lazyPub {
|
||||
if (lightMemberOrigin is LightMemberOriginForDeclaration)
|
||||
clsDelegate.modifierList?.let { KtLightModifierList(it, this) }
|
||||
else clsDelegate.modifierList
|
||||
}
|
||||
|
||||
override fun getModifierList() = _modifierList
|
||||
|
||||
override fun hasModifierProperty(@NonNls name: String) = (dummyDelegate ?: clsDelegate).hasModifierProperty(name)
|
||||
|
||||
override fun getText() = kotlinOrigin?.text ?: ""
|
||||
|
||||
override fun getTextRange() = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
override fun isValid() = containingClass.isValid
|
||||
|
||||
override fun toString(): String = "${this::class.java.simpleName}:$name"
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is KtLightFieldImpl<*> &&
|
||||
this.name == other.name &&
|
||||
this.containingClass == other.containingClass
|
||||
|
||||
override fun hashCode() = 31 * containingClass.hashCode() + (name?.hashCode() ?: 0)
|
||||
|
||||
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
|
||||
|
||||
override fun getNavigationElement() = kotlinOrigin ?: super.getNavigationElement()
|
||||
override fun hashCode() = 31 * containingClass.hashCode() + name.hashCode()
|
||||
|
||||
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?): Any? {
|
||||
return (clsDelegate as PsiVariableEx).computeConstantValue(visitedVars)
|
||||
@@ -124,8 +80,6 @@ sealed class KtLightFieldImpl<T: PsiField>(
|
||||
return super.isEquivalentTo(another)
|
||||
}
|
||||
|
||||
override fun isWritable() = kotlinOrigin?.isWritable ?: false
|
||||
|
||||
override fun copy() = Factory.create(lightMemberOrigin?.copy(), clsDelegate, containingClass)
|
||||
|
||||
|
||||
@@ -134,7 +88,7 @@ sealed class KtLightFieldImpl<T: PsiField>(
|
||||
computeDelegate: () -> PsiEnumConstant,
|
||||
containingClass: KtLightClass,
|
||||
dummyDelegate: PsiField?
|
||||
) : KtLightFieldImpl<PsiEnumConstant>(origin, computeDelegate , containingClass, dummyDelegate), PsiEnumConstant {
|
||||
) : KtLightFieldImpl<PsiEnumConstant>(origin, computeDelegate, containingClass, dummyDelegate), PsiEnumConstant {
|
||||
private val initializingClass by lazyPub {
|
||||
val kotlinEnumEntry = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement as? KtEnumEntry
|
||||
if (kotlinEnumEntry != null && kotlinEnumEntry.declarations.isNotEmpty()) {
|
||||
@@ -184,8 +138,9 @@ sealed class KtLightFieldImpl<T: PsiField>(
|
||||
}
|
||||
|
||||
fun fromClsFields(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.fields.map {
|
||||
val origin = ClsWrapperStubPsiFactory.getMemberOrigin(it)
|
||||
KtLightFieldImpl.create(origin, it, containingClass)
|
||||
KtLightFieldImpl.create(getOrigin(it), it, containingClass)
|
||||
}
|
||||
|
||||
fun getOrigin(field: PsiField) = getMemberOrigin(field)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.asJava.elements
|
||||
|
||||
import com.intellij.navigation.ItemPresentation
|
||||
import com.intellij.navigation.ItemPresentationProviders
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.compiled.ClsRepositoryPsiElement
|
||||
import com.intellij.psi.impl.light.LightElement
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory.ORIGIN
|
||||
import org.jetbrains.kotlin.asJava.builder.LightElementOrigin
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasBody
|
||||
|
||||
abstract class KtLightMemberImpl<out D : PsiMember>(
|
||||
computeRealDelegate: () -> D,
|
||||
override val lightMemberOrigin: LightMemberOrigin?,
|
||||
private val containingClass: KtLightClass,
|
||||
private val dummyDelegate: D?
|
||||
) : LightElement(containingClass.manager, KotlinLanguage.INSTANCE), PsiMember, KtLightMember<D> {
|
||||
override val clsDelegate by lazyPub(computeRealDelegate)
|
||||
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
|
||||
|
||||
private val _modifierList by lazyPub {
|
||||
if (lightMemberOrigin is LightMemberOriginForDeclaration)
|
||||
KtLightModifierList(this, dummyDelegate?.modifierList)
|
||||
else clsDelegate.modifierList!!
|
||||
}
|
||||
|
||||
override fun hasModifierProperty(name: String) = _modifierList.hasModifierProperty(name)
|
||||
|
||||
override fun getModifierList(): PsiModifierList = _modifierList
|
||||
|
||||
override fun toString(): String = "${this::class.java.simpleName}:$name"
|
||||
|
||||
override fun getContainingClass() = containingClass
|
||||
|
||||
override fun getContainingFile() = containingClass.containingFile
|
||||
|
||||
override fun getParent(): PsiElement = containingClass
|
||||
|
||||
override fun isValid() = containingClass.isValid
|
||||
|
||||
override fun getName(): String = dummyDelegate?.name ?: clsDelegate.name!!
|
||||
|
||||
override fun getNameIdentifier(): PsiIdentifier = lightIdentifier
|
||||
|
||||
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
|
||||
|
||||
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
|
||||
|
||||
override fun getNavigationElement() = kotlinOrigin ?: super.getNavigationElement()
|
||||
|
||||
override fun getPresentation(): ItemPresentation? = (kotlinOrigin ?: this).let { ItemPresentationProviders.getItemPresentation(it) }
|
||||
|
||||
override fun getText() = kotlinOrigin?.text ?: ""
|
||||
|
||||
override fun getTextRange() = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
override fun isWritable() = kotlinOrigin?.isWritable ?: false
|
||||
|
||||
override fun getDocComment() = (clsDelegate as PsiDocCommentOwner).docComment
|
||||
|
||||
override fun isDeprecated() = (clsDelegate as PsiDocCommentOwner).isDeprecated
|
||||
}
|
||||
|
||||
private val visibilityModifiers = arrayOf(PsiModifier.PRIVATE, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PUBLIC)
|
||||
|
||||
internal fun getMemberOrigin(member: PsiMember): LightMemberOriginForDeclaration? {
|
||||
if (member !is ClsRepositoryPsiElement<*>) return null
|
||||
|
||||
val stubElement = member.stub as? UserDataHolder ?: return null
|
||||
|
||||
return stubElement.getUserData<LightElementOrigin>(ORIGIN) as? LightMemberOriginForDeclaration ?: return null
|
||||
}
|
||||
|
||||
|
||||
class KtLightModifierList(
|
||||
private val owner: KtLightMember<*>,
|
||||
private val dummyDelegate: PsiModifierList?
|
||||
) : LightElement(owner.manager, KotlinLanguage.INSTANCE), PsiModifierList {
|
||||
private val clsDelegate by lazyPub { owner.clsDelegate.modifierList!! }
|
||||
private val _annotations by lazyPub { computeAnnotations(this, clsDelegate) }
|
||||
|
||||
override fun hasModifierProperty(name: String) = when {
|
||||
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
|
||||
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
|
||||
dummyDelegate != null -> {
|
||||
when {
|
||||
name in visibilityModifiers && isMethodOverride() ->
|
||||
clsDelegate.hasModifierProperty(name)
|
||||
else -> dummyDelegate.hasModifierProperty(name)
|
||||
}
|
||||
}
|
||||
else -> clsDelegate.hasModifierProperty(name)
|
||||
}
|
||||
|
||||
private fun isMethodOverride() = owner is KtLightMethod && owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
|
||||
|
||||
private fun isImplementationInInterface()
|
||||
= owner.containingClass.isInterface && owner is KtLightMethod && owner.kotlinOrigin?.hasBody() ?: false
|
||||
|
||||
override fun hasExplicitModifier(name: String) = hasModifierProperty(name)
|
||||
|
||||
override fun setModifierProperty(name: String, value: Boolean) = clsDelegate.setModifierProperty(name, value)
|
||||
override fun checkSetModifierProperty(name: String, value: Boolean) = clsDelegate.checkSetModifierProperty(name, value)
|
||||
override fun addAnnotation(qualifiedName: String) = clsDelegate.addAnnotation(qualifiedName)
|
||||
override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations
|
||||
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.value
|
||||
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
|
||||
override fun getParent() = owner
|
||||
override fun getText(): String? = ""
|
||||
override fun getTextRange() = TextRange.EMPTY_RANGE
|
||||
override fun copy(): PsiElement = KtLightModifierList(owner, dummyDelegate)
|
||||
override fun getReferences() = PsiReference.EMPTY_ARRAY
|
||||
override fun isEquivalentTo(another: PsiElement?) =
|
||||
another is KtLightModifierList && owner == another.owner
|
||||
|
||||
override fun toString() = "Light modifier list of $owner"
|
||||
}
|
||||
@@ -16,13 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.core.JavaCoreBundle
|
||||
import com.intellij.navigation.ItemPresentation
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
|
||||
import com.intellij.psi.impl.light.LightElement
|
||||
import com.intellij.psi.javadoc.PsiDocComment
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
import com.intellij.psi.util.*
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
@@ -32,29 +27,17 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.asJava.propertyNameByAccessor
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
|
||||
interface KtLightMethod : PsiAnnotationMethod, KtLightDeclaration<KtDeclaration, PsiMethod> {
|
||||
val lightMethodOrigin: LightMemberOrigin?
|
||||
val isDelegated: Boolean
|
||||
}
|
||||
|
||||
class KtLightMethodImpl private constructor(
|
||||
computeRealDelegate: () -> PsiMethod,
|
||||
override val lightMethodOrigin: LightMemberOrigin?,
|
||||
private val containingClass: KtLightClass,
|
||||
lightMemberOrigin: LightMemberOrigin?,
|
||||
containingClass: KtLightClass,
|
||||
private val dummyDelegate: PsiMethod? = null
|
||||
) : LightElement(containingClass.manager, containingClass.language), KtLightMethod {
|
||||
override val kotlinOrigin: KtDeclaration? get() = lightMethodOrigin?.originalElement as? KtDeclaration
|
||||
|
||||
override val clsDelegate by lazyPub(computeRealDelegate)
|
||||
|
||||
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
|
||||
) : KtLightMemberImpl<PsiMethod>(computeRealDelegate, lightMemberOrigin, containingClass, dummyDelegate), KtLightMethod {
|
||||
private val returnTypeElem by lazyPub {
|
||||
val delegateTypeElement = clsDelegate.returnTypeElement as? ClsTypeElementImpl
|
||||
delegateTypeElement?.let { ClsTypeElementImpl(this, it.canonicalText, /*ClsTypeElementImpl.VARIANCE_NONE */ 0.toChar()) }
|
||||
@@ -62,8 +45,6 @@ class KtLightMethodImpl private constructor(
|
||||
|
||||
private val calculatingReturnType = ThreadLocal<Boolean>()
|
||||
|
||||
override fun getContainingClass(): KtLightClass = containingClass
|
||||
|
||||
private val paramsList: PsiParameterList by lazyPub {
|
||||
KtLightParameterList(this, dummyDelegate?.parameterList?.parametersCount ?: clsDelegate.parameterList.parametersCount) {
|
||||
clsDelegate.parameterList.parameters.mapIndexed { index, clsParameter -> KtLightParameter(clsParameter, index, this@KtLightMethodImpl) }
|
||||
@@ -74,7 +55,7 @@ class KtLightMethodImpl private constructor(
|
||||
val cacheManager = CachedValuesManager.getManager(clsDelegate.project)
|
||||
cacheManager.createCachedValue<PsiTypeParameterList>(
|
||||
{
|
||||
val origin = (lightMethodOrigin as? LightMemberOriginForDeclaration)?.originalElement
|
||||
val origin = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement
|
||||
val list = if (origin != null) {
|
||||
if (origin is KtClassOrObject) {
|
||||
KotlinLightTypeParameterListBuilder(manager)
|
||||
@@ -91,16 +72,6 @@ class KtLightMethodImpl private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getNavigationElement(): PsiElement = kotlinOrigin?.navigationElement ?: super.getNavigationElement()
|
||||
override fun getPresentation(): ItemPresentation? = kotlinOrigin?.presentation ?: super.getPresentation()
|
||||
override fun getParent(): PsiElement = containingClass
|
||||
override fun getText() = kotlinOrigin?.text ?: ""
|
||||
override fun getTextRange() = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
override val isDelegated: Boolean
|
||||
get() = lightMethodOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
|
||||
|| lightMethodOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION_TO_DEFAULT_IMPLS
|
||||
|
||||
override fun accept(visitor: PsiElementVisitor) {
|
||||
if (visitor is JavaElementVisitor) {
|
||||
visitor.visitMethod(this)
|
||||
@@ -136,31 +107,22 @@ class KtLightMethodImpl private constructor(
|
||||
} ?: throwCanNotModify()
|
||||
}
|
||||
|
||||
private fun throwCanNotModify(): Nothing {
|
||||
throw IncorrectOperationException(JavaCoreBundle.message("psi.error.attempt.to.edit.class.file"))
|
||||
}
|
||||
|
||||
private val _modifierList by lazyPub {
|
||||
if (lightMethodOrigin is LightMemberOriginForDeclaration)
|
||||
KtLightModifierList(clsDelegate.modifierList, this)
|
||||
else clsDelegate.modifierList
|
||||
}
|
||||
// TODO: add message
|
||||
private fun throwCanNotModify(): Nothing = throw IncorrectOperationException()
|
||||
|
||||
override fun getModifierList(): PsiModifierList {
|
||||
if (calculatingReturnType.get() == true) {
|
||||
return KotlinJavaPsiFacade.getInstance(project).emptyModifierList
|
||||
}
|
||||
return _modifierList
|
||||
return super.getModifierList()!!
|
||||
}
|
||||
|
||||
override fun getNameIdentifier() = lightIdentifier
|
||||
|
||||
override fun getParameterList() = paramsList
|
||||
|
||||
override fun getTypeParameterList() = typeParamsList.value
|
||||
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> =
|
||||
typeParameterList?.let { it.typeParameters } ?: PsiTypeParameter.EMPTY_ARRAY
|
||||
typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
|
||||
|
||||
override fun getSignature(substitutor: PsiSubstitutor): MethodSignature {
|
||||
if (substitutor == PsiSubstitutor.EMPTY) {
|
||||
@@ -170,13 +132,9 @@ class KtLightMethodImpl private constructor(
|
||||
}
|
||||
|
||||
override fun copy(): PsiElement {
|
||||
return Factory.create(clsDelegate, lightMethodOrigin?.copy(), containingClass)
|
||||
return Factory.create(clsDelegate, lightMemberOrigin?.copy(), containingClass)
|
||||
}
|
||||
|
||||
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
|
||||
|
||||
override fun getLanguage() = KotlinLanguage.INSTANCE
|
||||
|
||||
override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean {
|
||||
return typeParameters.all { processor.execute(it, state) }
|
||||
}
|
||||
@@ -200,12 +158,10 @@ class KtLightMethodImpl private constructor(
|
||||
other is KtLightMethodImpl &&
|
||||
this.name == other.name &&
|
||||
this.containingClass == other.containingClass &&
|
||||
this.lightMethodOrigin == other.lightMethodOrigin &&
|
||||
this.lightMemberOrigin == other.lightMemberOrigin &&
|
||||
this._memberIndex == other._memberIndex
|
||||
|
||||
override fun hashCode(): Int = ((getName().hashCode() * 31 + (lightMethodOrigin?.hashCode() ?: 0)) * 31 + containingClass.hashCode()) * 31 + (_memberIndex?.hashCode() ?: 0)
|
||||
|
||||
override fun toString(): String = "${this::class.java.simpleName}:$name"
|
||||
override fun hashCode(): Int = ((getName().hashCode() * 31 + (lightMemberOrigin?.hashCode() ?: 0)) * 31 + containingClass.hashCode()) * 31 + (_memberIndex?.hashCode() ?: 0)
|
||||
|
||||
override fun getDefaultValue() = (clsDelegate as? PsiAnnotationMethod)?.defaultValue
|
||||
|
||||
@@ -244,37 +200,30 @@ class KtLightMethodImpl private constructor(
|
||||
origin: LightMemberOriginForDeclaration?,
|
||||
computeRealDelegate: () -> PsiMethod
|
||||
): KtLightMethodImpl {
|
||||
return KtLightMethodImpl(computeRealDelegate, adjustMethodOrigin(origin), containingClass, dummyDelegate)
|
||||
return KtLightMethodImpl(computeRealDelegate, origin, containingClass, dummyDelegate)
|
||||
}
|
||||
|
||||
fun fromClsMethods(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.methods.map {
|
||||
val origin = ClsWrapperStubPsiFactory.getMemberOrigin(it)
|
||||
KtLightMethodImpl.create(it, adjustMethodOrigin(origin), containingClass)
|
||||
KtLightMethodImpl.create(it, getOrigin(it), containingClass)
|
||||
}
|
||||
|
||||
fun getOrigin(method: PsiMethod) = adjustMethodOrigin(getMemberOrigin(method))
|
||||
}
|
||||
|
||||
override fun getName() = dummyDelegate?.name ?: clsDelegate.name
|
||||
|
||||
override fun hasModifierProperty(name: String) = (dummyDelegate ?: clsDelegate).hasModifierProperty(name)
|
||||
|
||||
override fun getThrowsList() = clsDelegate.throwsList
|
||||
|
||||
override fun hasTypeParameters() = clsDelegate.hasTypeParameters()
|
||||
|
||||
override fun isVarArgs() = clsDelegate.isVarArgs
|
||||
override fun isVarArgs() = (dummyDelegate ?: clsDelegate).isVarArgs
|
||||
|
||||
override fun isConstructor() = dummyDelegate?.isConstructor ?: clsDelegate.isConstructor
|
||||
|
||||
override fun getHierarchicalMethodSignature() = clsDelegate.hierarchicalMethodSignature
|
||||
|
||||
override fun getDocComment() = clsDelegate.docComment
|
||||
|
||||
override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean) = clsDelegate.findSuperMethodSignaturesIncludingStatic(checkAccess)
|
||||
|
||||
override fun getBody() = null
|
||||
|
||||
override fun isDeprecated() = clsDelegate.isDeprecated
|
||||
|
||||
override fun findDeepestSuperMethod() = clsDelegate.findDeepestSuperMethod()
|
||||
|
||||
override fun findDeepestSuperMethods() = clsDelegate.findDeepestSuperMethods()
|
||||
@@ -284,10 +233,6 @@ class KtLightMethodImpl private constructor(
|
||||
override fun findSuperMethods(checkAccess: Boolean) = clsDelegate.findSuperMethods(checkAccess)
|
||||
|
||||
override fun findSuperMethods(parentClass: PsiClass?) = clsDelegate.findSuperMethods(parentClass)
|
||||
|
||||
override fun getContainingFile() = parent.containingFile
|
||||
|
||||
override fun isValid() = containingClass.isValid
|
||||
}
|
||||
|
||||
fun KtLightMethod.isTraitFakeOverride(): Boolean {
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiModifierList
|
||||
import com.intellij.psi.impl.light.LightModifierList
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
@@ -54,43 +54,6 @@ abstract class KtLightModifierListWithExplicitModifiers(
|
||||
override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName)
|
||||
}
|
||||
|
||||
class KtLightModifierList(
|
||||
private val delegate: PsiModifierList,
|
||||
private val owner: PsiModifierListOwner
|
||||
) : PsiModifierList by delegate {
|
||||
private val _annotations by lazyPub { computeAnnotations(this, delegate) }
|
||||
|
||||
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.value
|
||||
|
||||
override fun findAnnotation(@NonNls qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
|
||||
|
||||
override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName)
|
||||
|
||||
override fun getParent() = owner
|
||||
|
||||
override fun getText(): String? = ""
|
||||
|
||||
override fun getLanguage() = KotlinLanguage.INSTANCE
|
||||
override fun getTextRange() = TextRange.EMPTY_RANGE
|
||||
override fun getStartOffsetInParent() = -1
|
||||
override fun getTextLength() = 0
|
||||
override fun getPrevSibling(): PsiElement? = null
|
||||
override fun getNextSibling(): PsiElement? = null
|
||||
override fun findElementAt(offset: Int): PsiElement? = null
|
||||
override fun findReferenceAt(offset: Int): PsiReference? = null
|
||||
override fun getTextOffset() = -1
|
||||
override fun isWritable() = false
|
||||
override fun isPhysical() = false
|
||||
override fun textToCharArray(): CharArray = ArrayUtil.EMPTY_CHAR_ARRAY;
|
||||
override fun textMatches(text: CharSequence): Boolean = getText() == text.toString()
|
||||
override fun textMatches(element: PsiElement): Boolean = text == element.text
|
||||
override fun textContains(c: Char): Boolean = text?.contains(c) ?: false
|
||||
override fun copy(): PsiElement = KtLightModifierList(delegate, owner)
|
||||
override fun getReferences() = PsiReference.EMPTY_ARRAY
|
||||
override fun isEquivalentTo(another: PsiElement?) =
|
||||
another is KtLightModifierList && delegate == another.delegate && owner == another.owner
|
||||
}
|
||||
|
||||
internal fun computeAnnotations(lightElement: PsiModifierList,
|
||||
delegate: PsiAnnotationOwner): CachedValue<Array<out PsiAnnotation>> {
|
||||
fun doCompute(): Array<PsiAnnotation> {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class KtLightParameter extends LightParameter implements KtLightDeclarati
|
||||
this.index = index;
|
||||
this.method = method;
|
||||
|
||||
if (method.getLightMethodOrigin() instanceof LightMemberOriginForDeclaration) {
|
||||
if (method.getLightMemberOrigin() instanceof LightMemberOriginForDeclaration) {
|
||||
this.modifierList = new KtLightModifierListWithExplicitModifiers(this, ArrayUtil.EMPTY_STRING_ARRAY) {
|
||||
@Override
|
||||
public PsiAnnotationOwner getDelegate() {
|
||||
|
||||
@@ -58,7 +58,7 @@ fun HierarchicalScope.collectDescriptorsFiltered(
|
||||
}
|
||||
|
||||
|
||||
@Deprecated("Use getOwnProperties instead") fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? {
|
||||
@Deprecated("Use getContributedProperties instead") fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? {
|
||||
return findFirstFromMeAndParent {
|
||||
when {
|
||||
it is LexicalScopeWrapper -> it.delegate.findLocalVariable(name)
|
||||
|
||||
@@ -65,7 +65,8 @@ class DescriptorSerializer private constructor(
|
||||
|
||||
val flags = Flags.getClassFlags(
|
||||
hasAnnotations(classDescriptor), classDescriptor.visibility, classDescriptor.modality, classDescriptor.kind,
|
||||
classDescriptor.isInner, classDescriptor.isCompanionObject, classDescriptor.isData, classDescriptor.isExternal
|
||||
classDescriptor.isInner, classDescriptor.isCompanionObject, classDescriptor.isData, classDescriptor.isExternal,
|
||||
classDescriptor.isHeader
|
||||
)
|
||||
if (flags != builder.flags) {
|
||||
builder.flags = flags
|
||||
@@ -150,8 +151,6 @@ class DescriptorSerializer private constructor(
|
||||
|
||||
var hasGetter = false
|
||||
var hasSetter = false
|
||||
val lateInit = descriptor.isLateInit
|
||||
val isConst = descriptor.isConst
|
||||
|
||||
val compileTimeConstant = descriptor.compileTimeInitializer
|
||||
val hasConstant = compileTimeConstant != null && compileTimeConstant !is NullValue
|
||||
@@ -187,8 +186,8 @@ class DescriptorSerializer private constructor(
|
||||
|
||||
val flags = Flags.getPropertyFlags(
|
||||
hasAnnotations, descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isVar,
|
||||
hasGetter, hasSetter, hasConstant, isConst, lateInit, descriptor.isExternal,
|
||||
@Suppress("DEPRECATION") descriptor.isDelegated
|
||||
hasGetter, hasSetter, hasConstant, descriptor.isConst, descriptor.isLateInit, descriptor.isExternal,
|
||||
@Suppress("DEPRECATION") descriptor.isDelegated, descriptor.isHeader
|
||||
)
|
||||
if (flags != builder.flags) {
|
||||
builder.flags = flags
|
||||
@@ -233,7 +232,8 @@ class DescriptorSerializer private constructor(
|
||||
|
||||
val flags = Flags.getFunctionFlags(
|
||||
hasAnnotations(descriptor), descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isOperator,
|
||||
descriptor.isInfix, descriptor.isInline, descriptor.isTailrec, descriptor.isExternal, descriptor.isSuspend
|
||||
descriptor.isInfix, descriptor.isInline, descriptor.isTailrec, descriptor.isExternal, descriptor.isSuspend,
|
||||
descriptor.isHeader
|
||||
)
|
||||
if (flags != builder.flags) {
|
||||
builder.flags = flags
|
||||
|
||||
70
compiler/testData/asJava/lightClasses/DataClassWithCustomImplementedMembers.java
vendored
Normal file
70
compiler/testData/asJava/lightClasses/DataClassWithCustomImplementedMembers.java
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
public final class Wrapper {
|
||||
public Wrapper() { /* compiled code */ }
|
||||
|
||||
public static final class Equals {
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final p.G code;
|
||||
|
||||
public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.G getCode() { /* compiled code */ }
|
||||
|
||||
public Equals(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.G component1() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.Wrapper.Equals copy(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
|
||||
|
||||
public java.lang.String toString() { /* compiled code */ }
|
||||
|
||||
public int hashCode() { /* compiled code */ }
|
||||
}
|
||||
|
||||
public static final class HashCode {
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final p.G code;
|
||||
|
||||
public int hashCode() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.G getCode() { /* compiled code */ }
|
||||
|
||||
public HashCode(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.G component1() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.Wrapper.HashCode copy(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
|
||||
|
||||
public java.lang.String toString() { /* compiled code */ }
|
||||
|
||||
public boolean equals(java.lang.Object p) { /* compiled code */ }
|
||||
}
|
||||
|
||||
public static final class ToString {
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final p.G code;
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public java.lang.String toString() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.G getCode() { /* compiled code */ }
|
||||
|
||||
public ToString(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.G component1() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final p.Wrapper.ToString copy(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
|
||||
|
||||
public int hashCode() { /* compiled code */ }
|
||||
|
||||
public boolean equals(java.lang.Object p) { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
20
compiler/testData/asJava/lightClasses/DataClassWithCustomImplementedMembers.kt
vendored
Normal file
20
compiler/testData/asJava/lightClasses/DataClassWithCustomImplementedMembers.kt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// p.Wrapper
|
||||
package p
|
||||
|
||||
class Wrapper {
|
||||
data class Equals(val code: G) {
|
||||
override fun equals(other: Any?): Boolean = true
|
||||
}
|
||||
|
||||
data class HashCode(val code: G) {
|
||||
override fun hashCode() = 3
|
||||
}
|
||||
|
||||
data class ToString(val code: G) {
|
||||
override fun toString() = "b"
|
||||
}
|
||||
}
|
||||
|
||||
class G
|
||||
|
||||
// LAZINESS:NoLaziness
|
||||
13
compiler/testData/asJava/lightClasses/DelegatedNested.java
vendored
Normal file
13
compiler/testData/asJava/lightClasses/DelegatedNested.java
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
public final class B {
|
||||
public B() { /* compiled code */ }
|
||||
|
||||
public static final class A implements p.I {
|
||||
private final p.I f;
|
||||
|
||||
public A(@org.jetbrains.annotations.NotNull p.I f) { /* compiled code */ }
|
||||
|
||||
public void f() { /* compiled code */ }
|
||||
|
||||
public void g() { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
15
compiler/testData/asJava/lightClasses/DelegatedNested.kt
vendored
Normal file
15
compiler/testData/asJava/lightClasses/DelegatedNested.kt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// p.B
|
||||
package p
|
||||
|
||||
class B {
|
||||
class A(private val f: I) : I by f {
|
||||
}
|
||||
}
|
||||
|
||||
interface I {
|
||||
fun g()
|
||||
|
||||
fun f()
|
||||
}
|
||||
|
||||
// LAZINESS:NoLaziness
|
||||
9
compiler/testData/asJava/lightClasses/Delegation.java
vendored
Normal file
9
compiler/testData/asJava/lightClasses/Delegation.java
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
public final class B implements p.I {
|
||||
private final p.I f;
|
||||
|
||||
public B(@org.jetbrains.annotations.NotNull p.I f) { /* compiled code */ }
|
||||
|
||||
public void f() { /* compiled code */ }
|
||||
|
||||
public void g() { /* compiled code */ }
|
||||
}
|
||||
13
compiler/testData/asJava/lightClasses/Delegation.kt
vendored
Normal file
13
compiler/testData/asJava/lightClasses/Delegation.kt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// p.B
|
||||
package p
|
||||
|
||||
class B(private val f: I) : I by f {
|
||||
}
|
||||
|
||||
interface I {
|
||||
fun g()
|
||||
|
||||
fun f()
|
||||
}
|
||||
|
||||
// LAZINESS:NoLaziness
|
||||
9
compiler/testData/asJava/lightClasses/DeprecatedNotHiddenInClass.java
vendored
Normal file
9
compiler/testData/asJava/lightClasses/DeprecatedNotHiddenInClass.java
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
public final class A {
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@kotlin.Deprecated(message = "f")
|
||||
public final void f() { /* compiled code */ }
|
||||
|
||||
public A() { /* compiled code */ }
|
||||
}
|
||||
9
compiler/testData/asJava/lightClasses/DeprecatedNotHiddenInClass.kt
vendored
Normal file
9
compiler/testData/asJava/lightClasses/DeprecatedNotHiddenInClass.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// a.A
|
||||
package a
|
||||
|
||||
class A {
|
||||
@Deprecated("f")
|
||||
fun f() {
|
||||
|
||||
}
|
||||
}
|
||||
12
compiler/testData/asJava/lightClasses/ExtendingInterfaceWithDefaultImpls.java
vendored
Normal file
12
compiler/testData/asJava/lightClasses/ExtendingInterfaceWithDefaultImpls.java
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
public interface B extends p.A {
|
||||
@org.jetbrains.annotations.NotNull
|
||||
java.lang.String b();
|
||||
|
||||
static final class DefaultImpls {
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public static java.lang.String b(p.B $this) { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public static java.lang.String a(p.B $this) { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
10
compiler/testData/asJava/lightClasses/ExtendingInterfaceWithDefaultImpls.kt
vendored
Normal file
10
compiler/testData/asJava/lightClasses/ExtendingInterfaceWithDefaultImpls.kt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// p.B
|
||||
package p
|
||||
|
||||
interface A {
|
||||
fun a() = "a"
|
||||
}
|
||||
|
||||
interface B: A {
|
||||
fun b() = "b"
|
||||
}
|
||||
2
compiler/testData/asJava/lightClasses/HiddenDeprecated.java
vendored
Normal file
2
compiler/testData/asJava/lightClasses/HiddenDeprecated.java
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
public final class HiddenDeprecatedKt {
|
||||
}
|
||||
8
compiler/testData/asJava/lightClasses/HiddenDeprecated.kt
vendored
Normal file
8
compiler/testData/asJava/lightClasses/HiddenDeprecated.kt
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// a.HiddenDeprecatedKt
|
||||
package a
|
||||
|
||||
@Deprecated("f", level = DeprecationLevel.HIDDEN)
|
||||
fun f() {
|
||||
|
||||
}
|
||||
// LAZINESS:NoLaziness
|
||||
3
compiler/testData/asJava/lightClasses/HiddenDeprecatedInClass.java
vendored
Normal file
3
compiler/testData/asJava/lightClasses/HiddenDeprecatedInClass.java
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
public final class A {
|
||||
public A() { /* compiled code */ }
|
||||
}
|
||||
11
compiler/testData/asJava/lightClasses/HiddenDeprecatedInClass.kt
vendored
Normal file
11
compiler/testData/asJava/lightClasses/HiddenDeprecatedInClass.kt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// a.A
|
||||
package a
|
||||
|
||||
class A {
|
||||
@Deprecated("f", level = DeprecationLevel.HIDDEN)
|
||||
fun f() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// LAZINESS:NoLaziness
|
||||
13
compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.compiled.java
vendored
Normal file
13
compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.compiled.java
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
public final class Inheritor implements p.I, p.I2 {
|
||||
public final void f() { /* compiled code */ }
|
||||
|
||||
public void g() { /* compiled code */ }
|
||||
|
||||
public Inheritor() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public java.lang.String foo() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public java.lang.String bar() { /* compiled code */ }
|
||||
}
|
||||
7
compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.java
vendored
Normal file
7
compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.java
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
public final class Inheritor implements p.I, p.I2 {
|
||||
public final void f() { /* compiled code */ }
|
||||
|
||||
public void g() { /* compiled code */ }
|
||||
|
||||
public Inheritor() { /* compiled code */ }
|
||||
}
|
||||
24
compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.kt
vendored
Normal file
24
compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// p.Inheritor
|
||||
package p
|
||||
|
||||
class Inheritor: I, I2 {
|
||||
|
||||
fun f() {
|
||||
|
||||
}
|
||||
|
||||
override fun g() {
|
||||
}
|
||||
}
|
||||
|
||||
interface I : I1 {
|
||||
fun g()
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
fun foo() = "foo"
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
fun bar() = "bar"
|
||||
}
|
||||
16
compiler/testData/asJava/lightClasses/NonDataClassWithComponentFunctions.java
vendored
Normal file
16
compiler/testData/asJava/lightClasses/NonDataClassWithComponentFunctions.java
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
public final class A {
|
||||
private final int y;
|
||||
|
||||
public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) { /* compiled code */ }
|
||||
|
||||
public int hashCode() { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public java.lang.String toString() { /* compiled code */ }
|
||||
|
||||
public final int component1() { /* compiled code */ }
|
||||
|
||||
public final int getY() { /* compiled code */ }
|
||||
|
||||
public A(int y) { /* compiled code */ }
|
||||
}
|
||||
18
compiler/testData/asJava/lightClasses/NonDataClassWithComponentFunctions.kt
vendored
Normal file
18
compiler/testData/asJava/lightClasses/NonDataClassWithComponentFunctions.kt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// p.A
|
||||
package p
|
||||
|
||||
class A(val y: Int) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return super.equals(other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return super.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return super.toString()
|
||||
}
|
||||
|
||||
fun component1() = y
|
||||
}
|
||||
7
compiler/testData/asJava/lightClasses/VarArgs.java
vendored
Normal file
7
compiler/testData/asJava/lightClasses/VarArgs.java
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
public final class C {
|
||||
public final void f(@org.jetbrains.annotations.NotNull int... i) { /* compiled code */ }
|
||||
|
||||
public final void p(int i, @org.jetbrains.annotations.NotNull java.lang.String... s) { /* compiled code */ }
|
||||
|
||||
public C() { /* compiled code */ }
|
||||
}
|
||||
12
compiler/testData/asJava/lightClasses/VarArgs.kt
vendored
Normal file
12
compiler/testData/asJava/lightClasses/VarArgs.kt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// C
|
||||
|
||||
class C {
|
||||
|
||||
fun f(vararg i: Int) {
|
||||
|
||||
}
|
||||
|
||||
fun p(i: Int, vararg s: String) {
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user