mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-21 00:21:29 +00:00
Compare commits
356 Commits
rr/mitropo
...
1.2.20_173
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5312bac2a9 | ||
|
|
6c5715469a | ||
|
|
ff30ce558d | ||
|
|
f33d7328b9 | ||
|
|
49e3d39327 | ||
|
|
b82daeb5fa | ||
|
|
701de5aa78 | ||
|
|
f08cb75b1f | ||
|
|
658a23ca63 | ||
|
|
ec8a3993f7 | ||
|
|
1c92139391 | ||
|
|
8ad25ff9f9 | ||
|
|
80ba1484c4 | ||
|
|
0e358021b3 | ||
|
|
4de9eb5690 | ||
|
|
c860953447 | ||
|
|
19bef952ab | ||
|
|
8b4b7c0f54 | ||
|
|
76ce624be4 | ||
|
|
1547c4e425 | ||
|
|
825095e7c8 | ||
|
|
dafbabd33d | ||
|
|
b6bee67d5f | ||
|
|
951abf5818 | ||
|
|
a6d00c68b5 | ||
|
|
6ed01fc635 | ||
|
|
3bdf0a6b1a | ||
|
|
859c39d60c | ||
|
|
f0cb8a6cac | ||
|
|
d88a83d734 | ||
|
|
ed2a85de27 | ||
|
|
e26a0c6896 | ||
|
|
23d9694707 | ||
|
|
8a55e48784 | ||
|
|
7b6834fb25 | ||
|
|
59131f294b | ||
|
|
3fb327a957 | ||
|
|
280a3e74c4 | ||
|
|
c19486b802 | ||
|
|
9a3d890437 | ||
|
|
dbb93af9bf | ||
|
|
890077c690 | ||
|
|
fee91f762b | ||
|
|
ec15a56e88 | ||
|
|
53401f25a5 | ||
|
|
017635c1fc | ||
|
|
18218bf58d | ||
|
|
ceebcfe64c | ||
|
|
56b2993ba5 | ||
|
|
fd25152db0 | ||
|
|
e8cd61c75c | ||
|
|
4b96acfbd7 | ||
|
|
b88417f98d | ||
|
|
3ed6b1e1e4 | ||
|
|
32d90fbc86 | ||
|
|
1a13f1f9ca | ||
|
|
e04dffd32c | ||
|
|
c09f4b3857 | ||
|
|
bab397f930 | ||
|
|
12d301d172 | ||
|
|
b5f32ecd42 | ||
|
|
9b244bbdf0 | ||
|
|
cf04a0dbfe | ||
|
|
15de7b25c3 | ||
|
|
adeee2ea36 | ||
|
|
415bf894fc | ||
|
|
1b19a033ce | ||
|
|
bca109473f | ||
|
|
8637125bf0 | ||
|
|
f8a207532c | ||
|
|
c1859a28af | ||
|
|
1f1323d08e | ||
|
|
881617e08a | ||
|
|
6b5059bc0e | ||
|
|
e50a774bcc | ||
|
|
034632cb5c | ||
|
|
6f9f20be66 | ||
|
|
da747f8559 | ||
|
|
bf0ea2a6f3 | ||
|
|
d13ae20275 | ||
|
|
90b79bd9c7 | ||
|
|
2607972422 | ||
|
|
00b2388c10 | ||
|
|
93b05ccec0 | ||
|
|
a8ee34865b | ||
|
|
38aa7c2e20 | ||
|
|
317f403acc | ||
|
|
5d80387406 | ||
|
|
aba4301e17 | ||
|
|
f8aa5503e6 | ||
|
|
41e486ee3a | ||
|
|
fc90512d06 | ||
|
|
e8509c0c06 | ||
|
|
56a6f89f90 | ||
|
|
66ed8c0f94 | ||
|
|
90230168d4 | ||
|
|
9ae269160a | ||
|
|
c754cd79df | ||
|
|
86ef1751e4 | ||
|
|
0aea2d94a7 | ||
|
|
ae6782642a | ||
|
|
94d6f5ac5c | ||
|
|
e23c40ac8f | ||
|
|
cf08a9e424 | ||
|
|
930574068b | ||
|
|
269f49deca | ||
|
|
f9b7447b8c | ||
|
|
ace2570e34 | ||
|
|
e65b41153f | ||
|
|
835a9c55aa | ||
|
|
6e91144fe6 | ||
|
|
34dc2f737b | ||
|
|
dee5adfc1f | ||
|
|
b94b02cfa4 | ||
|
|
ca2b0990d3 | ||
|
|
c5e6dac10f | ||
|
|
9a03a89efb | ||
|
|
bc1f7d71fb | ||
|
|
53fa6ff803 | ||
|
|
986cda3e22 | ||
|
|
b41446e586 | ||
|
|
4bc5d46fa8 | ||
|
|
0c9e23c5c5 | ||
|
|
49cb5aff4b | ||
|
|
10093b36e3 | ||
|
|
c7023c0a7e | ||
|
|
6b2f35e4d1 | ||
|
|
25b4ecae69 | ||
|
|
a538e88f2f | ||
|
|
67f1ed0803 | ||
|
|
7536dc1544 | ||
|
|
bb3afcb6b0 | ||
|
|
e4f1d4116f | ||
|
|
997b04be24 | ||
|
|
26e613e198 | ||
|
|
54813f401b | ||
|
|
9598ca900e | ||
|
|
78e39a666d | ||
|
|
12b0cdb7ed | ||
|
|
a09ca78828 | ||
|
|
15239b117d | ||
|
|
f0304af6bc | ||
|
|
9f93caea76 | ||
|
|
713f0f577f | ||
|
|
8a8120497f | ||
|
|
bdf349844e | ||
|
|
59637b1dd4 | ||
|
|
c9e413e853 | ||
|
|
88e715ed2f | ||
|
|
edd860ea18 | ||
|
|
457c2eaae7 | ||
|
|
40d92ca413 | ||
|
|
90cf47542b | ||
|
|
2e7fddbf72 | ||
|
|
e04510bea2 | ||
|
|
881be4dac0 | ||
|
|
acb9e19d4e | ||
|
|
f8ee0e12b9 | ||
|
|
5adc0bcffe | ||
|
|
0fe3ed1e31 | ||
|
|
ba60d83d9c | ||
|
|
29485df0db | ||
|
|
f788bc2f33 | ||
|
|
6ace267699 | ||
|
|
dce565e32d | ||
|
|
e141472704 | ||
|
|
4316e24243 | ||
|
|
60bffb9c21 | ||
|
|
3a7df0be10 | ||
|
|
de9f61406e | ||
|
|
15c37555bb | ||
|
|
a62543fc55 | ||
|
|
3955d6f2b0 | ||
|
|
e2bf5d298d | ||
|
|
3c05d3c3ca | ||
|
|
fbb14ada36 | ||
|
|
3af0d5745e | ||
|
|
4a530b8bf4 | ||
|
|
5eee3a31df | ||
|
|
1123fb8ee7 | ||
|
|
111623335d | ||
|
|
7938f56d25 | ||
|
|
b3f57dbe3a | ||
|
|
598adee862 | ||
|
|
d435622249 | ||
|
|
fe6ad4f8fd | ||
|
|
1f755ed331 | ||
|
|
cdd07ceb34 | ||
|
|
db791e0b60 | ||
|
|
d1c4992a9a | ||
|
|
1d82608d60 | ||
|
|
9df3359719 | ||
|
|
ad3f6bd5fa | ||
|
|
810d3bec56 | ||
|
|
9a967ec844 | ||
|
|
2cd529833c | ||
|
|
4567fd0c39 | ||
|
|
15ea032a20 | ||
|
|
0585059906 | ||
|
|
e07c1c68ea | ||
|
|
307d54391d | ||
|
|
d38dba06de | ||
|
|
c3a0e0dc6b | ||
|
|
96d6fa70f6 | ||
|
|
c11b43c03e | ||
|
|
e439c3053e | ||
|
|
21195e033c | ||
|
|
0928618979 | ||
|
|
020f54d95b | ||
|
|
769c38912f | ||
|
|
a9f31287aa | ||
|
|
82572e94a4 | ||
|
|
ce6ea5262f | ||
|
|
59d7845238 | ||
|
|
0c36b5caf6 | ||
|
|
92501a18e0 | ||
|
|
ff773fe3de | ||
|
|
96756e54a6 | ||
|
|
a351d26204 | ||
|
|
c26e150bc6 | ||
|
|
d893b4796a | ||
|
|
8462ac8ef3 | ||
|
|
d1b81a90c2 | ||
|
|
599c149a8c | ||
|
|
2778ef614a | ||
|
|
2af2497d58 | ||
|
|
13f69878c2 | ||
|
|
36e07f2d00 | ||
|
|
755de4564e | ||
|
|
4c25ab2f12 | ||
|
|
e499f24528 | ||
|
|
d4b9933ce4 | ||
|
|
08d2e29459 | ||
|
|
763740a49b | ||
|
|
0acd2b9698 | ||
|
|
4b6c3dfff1 | ||
|
|
1d9254fd92 | ||
|
|
efd90b7a36 | ||
|
|
9799c6150d | ||
|
|
792db1469c | ||
|
|
5dcdce291c | ||
|
|
3ca581876a | ||
|
|
e63a0e3823 | ||
|
|
5490746bdc | ||
|
|
5894c52d4c | ||
|
|
a000111a92 | ||
|
|
6848ea630f | ||
|
|
d202cf5314 | ||
|
|
6beee0c1ba | ||
|
|
cf7b5fec05 | ||
|
|
d1efa8e08c | ||
|
|
64a4e7b607 | ||
|
|
7a47bc1c5d | ||
|
|
edc6d162f4 | ||
|
|
b007da5ac3 | ||
|
|
579ea2e90a | ||
|
|
93e0d9336b | ||
|
|
0923c40495 | ||
|
|
def71307e3 | ||
|
|
9ba9ceeb64 | ||
|
|
a23f96a2dd | ||
|
|
d595b7d398 | ||
|
|
e7f93c6102 | ||
|
|
56881e7783 | ||
|
|
542e556577 | ||
|
|
1bb538b044 | ||
|
|
15bd424aba | ||
|
|
e44a4bb54c | ||
|
|
0e94bfd734 | ||
|
|
d317f789be | ||
|
|
058b40369c | ||
|
|
7cbd83541a | ||
|
|
e96abbebd1 | ||
|
|
03046159b0 | ||
|
|
cd1c87bfef | ||
|
|
a951af8775 | ||
|
|
8c0a2da7aa | ||
|
|
f3e4232649 | ||
|
|
5f48a4484d | ||
|
|
153e296a8e | ||
|
|
3dd3403447 | ||
|
|
99cab8129e | ||
|
|
414ea3dd2d | ||
|
|
e6e4072b55 | ||
|
|
10d6f4eddb | ||
|
|
4a615262a9 | ||
|
|
9d38d341bc | ||
|
|
01ecc145ed | ||
|
|
e017ef71d7 | ||
|
|
25a88ab707 | ||
|
|
51e964d579 | ||
|
|
8988675ad4 | ||
|
|
c3a7044405 | ||
|
|
aea040bafa | ||
|
|
cf457ae2e3 | ||
|
|
f28c7bc937 | ||
|
|
1023228335 | ||
|
|
e06adf2559 | ||
|
|
7fc586d4a5 | ||
|
|
dd2e9a0bdd | ||
|
|
a2976598f9 | ||
|
|
82d23b7ee5 | ||
|
|
3f50ae8d8d | ||
|
|
e1b1869441 | ||
|
|
c5cfd05083 | ||
|
|
ae3b331bb7 | ||
|
|
2d7f46ef34 | ||
|
|
0222539d23 | ||
|
|
af5211fcf2 | ||
|
|
4051934cbe | ||
|
|
399166d92d | ||
|
|
176d6fedfa | ||
|
|
b4c3e98955 | ||
|
|
68712713c4 | ||
|
|
149a40ba46 | ||
|
|
4e0f73520a | ||
|
|
d65a2f36f2 | ||
|
|
bd2e69ddeb | ||
|
|
982bc8efa3 | ||
|
|
59d15e1b00 | ||
|
|
e115d3d622 | ||
|
|
53e924ef6e | ||
|
|
ab2b0538ed | ||
|
|
4a7eeb9ecb | ||
|
|
ad83c4ae22 | ||
|
|
07c5845c38 | ||
|
|
84d641af4a | ||
|
|
6c7837a848 | ||
|
|
391d08bc9c | ||
|
|
030c1fb21d | ||
|
|
04a934e453 | ||
|
|
7253090595 | ||
|
|
d4c5b12c66 | ||
|
|
252a754758 | ||
|
|
b7d7241630 | ||
|
|
b7d45f7ac7 | ||
|
|
959e8ea851 | ||
|
|
108e1c2d1c | ||
|
|
1a6fb37c45 | ||
|
|
8f9b839a5c | ||
|
|
d88617cdac | ||
|
|
1710bfd11d | ||
|
|
d778febc6c | ||
|
|
f77f8e552f | ||
|
|
8a639609bb | ||
|
|
bee01ffe6e | ||
|
|
834433251c | ||
|
|
eea2612ce0 | ||
|
|
86a0356a75 | ||
|
|
8b4cf7f02b | ||
|
|
e91a31cab2 | ||
|
|
c539b3602a | ||
|
|
2fd094bb89 | ||
|
|
f350761b76 | ||
|
|
8cb29c688c | ||
|
|
76cc5556ab |
4092
ChangeLog.md
4092
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -28,18 +28,20 @@ import java.io.File
|
||||
/**
|
||||
* Incremental cache common for JVM and JS
|
||||
*/
|
||||
abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(workingDir) {
|
||||
abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOwner(workingDir) {
|
||||
companion object {
|
||||
private val SUBTYPES = "subtypes"
|
||||
private val SUPERTYPES = "supertypes"
|
||||
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
|
||||
@JvmStatic protected val SOURCE_TO_CLASSES = "source-to-classes"
|
||||
@JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||
}
|
||||
|
||||
private val dependents = arrayListOf<IncrementalCacheCommon>()
|
||||
fun addDependentCache(cache: IncrementalCacheCommon) {
|
||||
private val dependents = arrayListOf<IncrementalCacheCommon<ClassName>>()
|
||||
fun addDependentCache(cache: IncrementalCacheCommon<ClassName>) {
|
||||
dependents.add(cache)
|
||||
}
|
||||
val thisWithDependentCaches: Iterable<IncrementalCacheCommon> by lazy {
|
||||
val thisWithDependentCaches: Iterable<IncrementalCacheCommon<ClassName>> by lazy {
|
||||
val result = arrayListOf(this)
|
||||
result.addAll(dependents)
|
||||
result
|
||||
@@ -48,6 +50,8 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
|
||||
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
|
||||
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
|
||||
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
|
||||
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
|
||||
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
|
||||
|
||||
fun getSubtypesOf(className: FqName): Sequence<FqName> =
|
||||
subtypesMap[className].asSequence()
|
||||
@@ -55,7 +59,16 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
|
||||
fun getSourceFileIfClass(fqName: FqName): File? =
|
||||
classFqNameToSourceMap[fqName]
|
||||
|
||||
abstract fun markDirty(removedAndCompiledSources: List<File>)
|
||||
open fun markDirty(removedAndCompiledSources: List<File>) {
|
||||
for (sourceFile in removedAndCompiledSources) {
|
||||
val classes = sourceToClassesMap[sourceFile]
|
||||
classes.forEach {
|
||||
dirtyOutputClassesMap.markDirty(it)
|
||||
}
|
||||
|
||||
sourceToClassesMap.clearOutputsForSource(sourceFile)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun addToClassStorage(proto: ProtoBuf.Class, nameResolver: NameResolver, srcFile: File) {
|
||||
val supertypes = proto.supertypes(TypeTable(proto.typeTable))
|
||||
@@ -73,11 +86,19 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
|
||||
classFqNameToSourceMap[child] = srcFile
|
||||
}
|
||||
|
||||
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>) {
|
||||
abstract fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
|
||||
|
||||
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>, changesCollector: ChangesCollector) {
|
||||
if (removedClasses.isEmpty()) return
|
||||
|
||||
val removedFqNames = removedClasses.toSet()
|
||||
|
||||
for (removedClass in removedFqNames) {
|
||||
for (affectedClass in withSubtypes(removedClass, thisWithDependentCaches)) {
|
||||
changesCollector.collectSignature(affectedClass, areSubclassesAffected = false)
|
||||
}
|
||||
}
|
||||
|
||||
for (cache in thisWithDependentCaches) {
|
||||
val parentsFqNames = hashSetOf<FqName>()
|
||||
val childrenFqNames = hashSetOf<FqName>()
|
||||
|
||||
@@ -31,19 +31,20 @@ import java.io.DataInput
|
||||
import java.io.DataOutput
|
||||
import java.io.File
|
||||
|
||||
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDir) {
|
||||
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon<FqName>(cachesDir) {
|
||||
companion object {
|
||||
private val TRANSLATION_RESULT_MAP = "translation-result"
|
||||
private val SOURCES_TO_CLASSES_FQNS = "sources-to-classes"
|
||||
private val INLINE_FUNCTIONS = "inline-functions"
|
||||
private val HEADER_FILE_NAME = "header.meta"
|
||||
}
|
||||
|
||||
private val dirtySources = arrayListOf<File>()
|
||||
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile))
|
||||
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile))
|
||||
private val sourcesToClasses = registerMap(SourceToClassesMap(SOURCES_TO_CLASSES_FQNS.storageFile))
|
||||
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||
|
||||
private val dirtySources = hashSetOf<File>()
|
||||
|
||||
private val headerFile: File
|
||||
get() = File(cachesDir, HEADER_FILE_NAME)
|
||||
|
||||
@@ -55,30 +56,23 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
|
||||
}
|
||||
|
||||
override fun markDirty(removedAndCompiledSources: List<File>) {
|
||||
super.markDirty(removedAndCompiledSources)
|
||||
dirtySources.addAll(removedAndCompiledSources)
|
||||
}
|
||||
|
||||
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
|
||||
val translatedFiles = incrementalResults.packageParts
|
||||
|
||||
dirtySources.forEach {
|
||||
if (it !in translatedFiles) {
|
||||
translationResults.remove(it, changesCollector)
|
||||
inlineFunctions.remove(it)
|
||||
}
|
||||
|
||||
removeAllFromClassStorage(sourcesToClasses[it])
|
||||
sourcesToClasses.clearOutputsForSource(it)
|
||||
}
|
||||
dirtySources.clear()
|
||||
|
||||
for ((srcFile, data) in translatedFiles) {
|
||||
dirtySources.remove(srcFile)
|
||||
val (binaryMetadata, binaryAst) = data
|
||||
|
||||
val oldProtoMap = translationResults[srcFile]?.metadata?.let { getProtoData(srcFile, it) } ?: emptyMap()
|
||||
val newProtoMap = getProtoData(srcFile, binaryMetadata)
|
||||
|
||||
for (protoData in newProtoMap.values) {
|
||||
for ((classId, protoData) in newProtoMap) {
|
||||
registerOutputForFile(srcFile, classId.asSingleFqName())
|
||||
|
||||
if (protoData is ClassProtoData) {
|
||||
addToClassStorage(protoData.proto, protoData.nameResolver, srcFile)
|
||||
}
|
||||
@@ -96,6 +90,21 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerOutputForFile(srcFile: File, name: FqName) {
|
||||
sourceToClassesMap.add(srcFile, name)
|
||||
dirtyOutputClassesMap.notDirty(name)
|
||||
}
|
||||
|
||||
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
|
||||
dirtySources.forEach {
|
||||
translationResults.remove(it, changesCollector)
|
||||
inlineFunctions.remove(it)
|
||||
}
|
||||
removeAllFromClassStorage(dirtyOutputClassesMap.getDirtyOutputClasses(), changesCollector)
|
||||
dirtySources.clear()
|
||||
dirtyOutputClassesMap.clean()
|
||||
}
|
||||
|
||||
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
|
||||
hashMapOf<File, TranslationResultValue>().apply {
|
||||
for (path in translationResults.keys()) {
|
||||
@@ -107,25 +116,6 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
|
||||
}
|
||||
}
|
||||
|
||||
private class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(sourceFile.canonicalPath)
|
||||
}
|
||||
|
||||
fun add(sourceFile: File, className: FqName) {
|
||||
storage.append(sourceFile.canonicalPath, className.asString())
|
||||
}
|
||||
|
||||
operator fun get(sourceFile: File): Collection<FqName> =
|
||||
storage[sourceFile.canonicalPath].orEmpty().map { FqName(it) }
|
||||
|
||||
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
|
||||
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
|
||||
override fun save(output: DataOutput, value: TranslationResultValue) {
|
||||
output.writeInt(value.metadata.size)
|
||||
|
||||
@@ -44,15 +44,13 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
|
||||
open class IncrementalJvmCache(
|
||||
private val targetDataRoot: File,
|
||||
targetOutputDir: File?
|
||||
) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
|
||||
) : IncrementalCacheCommon<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
|
||||
companion object {
|
||||
private val PROTO_MAP = "proto"
|
||||
private val CONSTANTS_MAP = "constants"
|
||||
private val PACKAGE_PARTS = "package-parts"
|
||||
private val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
|
||||
private val MULTIFILE_CLASS_PARTS = "multifile-class-parts"
|
||||
private val SOURCE_TO_CLASSES = "source-to-classes"
|
||||
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||
private val INLINE_FUNCTIONS = "inline-functions"
|
||||
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
|
||||
private val JAVA_SOURCES_PROTO_MAP = "java-sources-proto-map"
|
||||
@@ -60,13 +58,14 @@ open class IncrementalJvmCache(
|
||||
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
||||
}
|
||||
|
||||
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile))
|
||||
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
|
||||
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||
// todo: try to use internal names only?
|
||||
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
|
||||
@@ -76,17 +75,6 @@ open class IncrementalJvmCache(
|
||||
|
||||
protected open fun debugLog(message: String) {}
|
||||
|
||||
override fun markDirty(removedAndCompiledSources: List<File>) {
|
||||
for (sourceFile in removedAndCompiledSources) {
|
||||
val classes = sourceToClassesMap[sourceFile]
|
||||
classes.forEach {
|
||||
dirtyOutputClassesMap.markDirty(it.internalName)
|
||||
}
|
||||
|
||||
sourceToClassesMap.clearOutputsForSource(sourceFile)
|
||||
}
|
||||
}
|
||||
|
||||
fun isTrackedFile(file: File) = sourceToClassesMap.contains(file)
|
||||
|
||||
// used in gradle
|
||||
@@ -98,7 +86,7 @@ open class IncrementalJvmCache(
|
||||
internalNameToSource[internalName]
|
||||
|
||||
fun isMultifileFacade(className: JvmClassName): Boolean =
|
||||
className.internalName in multifileFacadeToParts
|
||||
className in multifileFacadeToParts
|
||||
|
||||
override fun getClassFilePath(internalClassName: String): String {
|
||||
return toSystemIndependentName(File(outputDir, "$internalClassName.class").canonicalPath)
|
||||
@@ -107,7 +95,7 @@ open class IncrementalJvmCache(
|
||||
fun saveModuleMappingToCache(sourceFiles: Collection<File>, file: File) {
|
||||
val jvmClassName = JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)
|
||||
protoMap.storeModuleMapping(jvmClassName, file.readBytes())
|
||||
dirtyOutputClassesMap.notDirty(MODULE_MAPPING_FILE_NAME)
|
||||
dirtyOutputClassesMap.notDirty(jvmClassName)
|
||||
sourceFiles.forEach { sourceToClassesMap.add(it, jvmClassName) }
|
||||
}
|
||||
|
||||
@@ -116,7 +104,7 @@ open class IncrementalJvmCache(
|
||||
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
|
||||
val className = kotlinClass.className
|
||||
|
||||
dirtyOutputClassesMap.notDirty(className.internalName)
|
||||
dirtyOutputClassesMap.notDirty(className)
|
||||
sourceFiles.forEach {
|
||||
sourceToClassesMap.add(it, className)
|
||||
}
|
||||
@@ -181,7 +169,7 @@ open class IncrementalJvmCache(
|
||||
val (proto, nameResolver) = serializedJavaClass.toProtoData()
|
||||
addToClassStorage(proto, nameResolver, source)
|
||||
|
||||
dirtyOutputClassesMap.notDirty(jvmClassName.internalName)
|
||||
dirtyOutputClassesMap.notDirty(jvmClassName)
|
||||
}
|
||||
|
||||
fun getObsoleteJavaClasses(): Collection<ClassId> =
|
||||
@@ -192,31 +180,28 @@ open class IncrementalJvmCache(
|
||||
|
||||
fun isJavaClassToTrack(classId: ClassId): Boolean {
|
||||
val jvmClassName = JvmClassName.byClassId(classId)
|
||||
return dirtyOutputClassesMap.isDirty(jvmClassName.internalName) ||
|
||||
javaSourcesProtoMap[jvmClassName.internalName] == null
|
||||
return dirtyOutputClassesMap.isDirty(jvmClassName) ||
|
||||
jvmClassName !in javaSourcesProtoMap
|
||||
}
|
||||
|
||||
fun isJavaClassAlreadyInCache(classId: ClassId): Boolean {
|
||||
val jvmClassName = JvmClassName.byClassId(classId)
|
||||
return javaSourcesProtoMap[jvmClassName.internalName] != null
|
||||
return jvmClassName in javaSourcesProtoMap
|
||||
}
|
||||
|
||||
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
|
||||
val dirtyClasses = dirtyOutputClassesMap
|
||||
.getDirtyOutputClasses()
|
||||
.map(JvmClassName::byInternalName)
|
||||
.toList()
|
||||
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
|
||||
val dirtyClasses = dirtyOutputClassesMap.getDirtyOutputClasses()
|
||||
|
||||
val facadesWithRemovedParts = hashMapOf<JvmClassName, MutableSet<String>>()
|
||||
for (dirtyClass in dirtyClasses) {
|
||||
val facade = partToMultifileFacade.get(dirtyClass.internalName) ?: continue
|
||||
val facade = partToMultifileFacade.get(dirtyClass) ?: continue
|
||||
val facadeClassName = JvmClassName.byInternalName(facade)
|
||||
val removedParts = facadesWithRemovedParts.getOrPut(facadeClassName) { hashSetOf() }
|
||||
removedParts.add(dirtyClass.internalName)
|
||||
}
|
||||
|
||||
for ((facade, removedParts) in facadesWithRemovedParts.entries) {
|
||||
val allParts = multifileFacadeToParts[facade.internalName] ?: continue
|
||||
val allParts = multifileFacadeToParts[facade] ?: continue
|
||||
val notRemovedParts = allParts.filter { it !in removedParts }
|
||||
|
||||
if (notRemovedParts.isEmpty()) {
|
||||
@@ -238,16 +223,14 @@ open class IncrementalJvmCache(
|
||||
javaSourcesProtoMap.remove(it, changesCollector)
|
||||
}
|
||||
|
||||
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars })
|
||||
|
||||
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars }, changesCollector)
|
||||
dirtyOutputClassesMap.clean()
|
||||
}
|
||||
|
||||
override fun getObsoletePackageParts(): Collection<String> {
|
||||
val obsoletePackageParts =
|
||||
dirtyOutputClassesMap.getDirtyOutputClasses().filter { packagePartMap.isPackagePart(JvmClassName.byInternalName(it)) }
|
||||
val obsoletePackageParts = dirtyOutputClassesMap.getDirtyOutputClasses().filter(packagePartMap::isPackagePart)
|
||||
debugLog("Obsolete package parts: $obsoletePackageParts")
|
||||
return obsoletePackageParts
|
||||
return obsoletePackageParts.map { it.internalName }
|
||||
}
|
||||
|
||||
override fun getPackagePartData(partInternalName: String): JvmPackagePartProto? {
|
||||
@@ -267,8 +250,9 @@ open class IncrementalJvmCache(
|
||||
}
|
||||
|
||||
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
|
||||
val partNames = multifileFacadeToParts.get(facadeInternalName) ?: return null
|
||||
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
|
||||
val jvmClassName = JvmClassName.byInternalName(facadeInternalName)
|
||||
val partNames = multifileFacadeToParts[jvmClassName] ?: return null
|
||||
return partNames.filter { !dirtyOutputClassesMap.isDirty(JvmClassName.byInternalName(it)) }
|
||||
}
|
||||
|
||||
override fun getModuleMappingData(): ByteArray? {
|
||||
@@ -351,7 +335,11 @@ open class IncrementalJvmCache(
|
||||
changesCollector.collectProtoChanges(oldValue.toProtoData(), newData = null)
|
||||
}
|
||||
|
||||
operator fun get(internalName: String) = storage[internalName]
|
||||
operator fun get(className: JvmClassName): SerializedJavaClass? =
|
||||
storage[className.internalName]
|
||||
|
||||
operator fun contains(className: JvmClassName): Boolean =
|
||||
className.internalName in storage
|
||||
|
||||
override fun dumpValue(value: SerializedJavaClass): String =
|
||||
java.lang.Long.toHexString(value.proto.toByteArray().md5())
|
||||
@@ -419,13 +407,15 @@ open class IncrementalJvmCache(
|
||||
}
|
||||
|
||||
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
operator fun set(facadeName: JvmClassName, partNames: Collection<String>) {
|
||||
storage[facadeName.internalName] = partNames
|
||||
operator fun set(className: JvmClassName, partNames: Collection<String>) {
|
||||
storage[className.internalName] = partNames
|
||||
}
|
||||
|
||||
operator fun get(internalName: String): Collection<String>? = storage[internalName]
|
||||
operator fun get(className: JvmClassName): Collection<String>? =
|
||||
storage[className.internalName]
|
||||
|
||||
operator fun contains(internalName: String): Boolean = internalName in storage
|
||||
operator fun contains(className: JvmClassName): Boolean =
|
||||
className.internalName in storage
|
||||
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
@@ -439,9 +429,8 @@ open class IncrementalJvmCache(
|
||||
storage[partName] = facadeName
|
||||
}
|
||||
|
||||
fun get(partName: String): String? {
|
||||
return storage.get(partName)
|
||||
}
|
||||
fun get(partName: JvmClassName): String? =
|
||||
storage[partName.internalName]
|
||||
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
@@ -450,27 +439,6 @@ open class IncrementalJvmCache(
|
||||
override fun dumpValue(value: String): String = value
|
||||
}
|
||||
|
||||
inner class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(sourceFile.absolutePath)
|
||||
}
|
||||
|
||||
fun add(sourceFile: File, className: JvmClassName) {
|
||||
storage.append(sourceFile.absolutePath, className.internalName)
|
||||
}
|
||||
|
||||
fun contains(sourceFile: File) = sourceFile.absolutePath in storage
|
||||
|
||||
operator fun get(sourceFile: File): Collection<JvmClassName> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map { JvmClassName.byInternalName(it) }
|
||||
|
||||
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
|
||||
inner class InternalNameToSourcesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
|
||||
operator fun set(internalName: String, sourceFiles: Iterable<File>) {
|
||||
storage[internalName] = sourceFiles.map { it.canonicalPath }
|
||||
@@ -492,24 +460,6 @@ open class IncrementalJvmCache(
|
||||
addToClassStorage(proto, nameResolver, srcFile)
|
||||
}
|
||||
|
||||
private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
|
||||
fun markDirty(className: String) {
|
||||
storage[className] = true
|
||||
}
|
||||
|
||||
fun notDirty(className: String) {
|
||||
storage.remove(className)
|
||||
}
|
||||
|
||||
fun getDirtyOutputClasses(): Collection<String> =
|
||||
storage.keys
|
||||
|
||||
fun isDirty(className: String): Boolean =
|
||||
storage.contains(className)
|
||||
|
||||
override fun dumpValue(value: Boolean) = ""
|
||||
}
|
||||
|
||||
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
|
||||
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
|
||||
val inlineFunctions = inlineFunctionsJvmNames(header)
|
||||
|
||||
@@ -116,7 +116,7 @@ data class DirtyData(
|
||||
)
|
||||
|
||||
fun ChangesCollector.getDirtyData(
|
||||
caches: Iterable<IncrementalCacheCommon>,
|
||||
caches: Iterable<IncrementalCacheCommon<*>>,
|
||||
reporter: ICReporter
|
||||
): DirtyData {
|
||||
val dirtyLookupSymbols = HashSet<LookupSymbol>()
|
||||
@@ -170,7 +170,7 @@ fun mapLookupSymbolsToFiles(
|
||||
}
|
||||
|
||||
fun mapClassesFqNamesToFiles(
|
||||
caches: Iterable<IncrementalCacheCommon>,
|
||||
caches: Iterable<IncrementalCacheCommon<*>>,
|
||||
classesFqNames: Iterable<FqName>,
|
||||
reporter: ICReporter,
|
||||
excludes: Set<File> = emptySet()
|
||||
@@ -192,7 +192,7 @@ fun mapClassesFqNamesToFiles(
|
||||
|
||||
fun withSubtypes(
|
||||
typeFqName: FqName,
|
||||
caches: Iterable<IncrementalCacheCommon>
|
||||
caches: Iterable<IncrementalCacheCommon<*>>
|
||||
): Set<FqName> {
|
||||
val types = LinkedList(listOf(typeFqName))
|
||||
val subtypes = hashSetOf<FqName>()
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.incremental.storage
|
||||
|
||||
import com.intellij.util.io.BooleanDataDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
internal class DirtyClassesJvmNameMap(storageFile: File) : AbstractDirtyClassesMap<JvmClassName>(JvmClassNameTransformer, storageFile)
|
||||
internal class DirtyClassesFqNameMap(storageFile: File) : AbstractDirtyClassesMap<FqName>(FqNameTransformer, storageFile)
|
||||
|
||||
internal abstract class AbstractDirtyClassesMap<Name>(
|
||||
private val nameTransformer: NameTransformer<Name>,
|
||||
storageFile: File
|
||||
) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
|
||||
fun markDirty(className: Name) {
|
||||
storage[nameTransformer.asString(className)] = true
|
||||
}
|
||||
|
||||
fun notDirty(className: Name) {
|
||||
storage.remove(nameTransformer.asString(className))
|
||||
}
|
||||
|
||||
fun getDirtyOutputClasses(): Collection<Name> =
|
||||
storage.keys.map { nameTransformer.asName(it) }
|
||||
|
||||
fun isDirty(className: Name): Boolean =
|
||||
storage.contains(nameTransformer.asString(className))
|
||||
|
||||
override fun dumpValue(value: Boolean) = ""
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
|
||||
internal interface NameTransformer<Name> {
|
||||
fun asString(name: Name): String
|
||||
fun asName(string: String): Name
|
||||
}
|
||||
|
||||
internal object FqNameTransformer : NameTransformer<FqName> {
|
||||
override fun asString(name: FqName): String =
|
||||
name.asString()
|
||||
|
||||
override fun asName(string: String): FqName =
|
||||
FqName(string)
|
||||
}
|
||||
|
||||
internal object JvmClassNameTransformer : NameTransformer<JvmClassName> {
|
||||
override fun asString(name: JvmClassName): String =
|
||||
name.internalName
|
||||
|
||||
override fun asName(string: String): JvmClassName =
|
||||
JvmClassName.byInternalName(string)
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
internal class SourceToJvmNameMap(storageFile: File) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile)
|
||||
internal class SourceToFqNameMap(storageFile: File) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile)
|
||||
|
||||
internal abstract class AbstractSourceToOutputMap<Name>(
|
||||
private val nameTransformer: NameTransformer<Name>,
|
||||
storageFile: File
|
||||
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(sourceFile.absolutePath)
|
||||
}
|
||||
|
||||
fun add(sourceFile: File, className: Name) {
|
||||
storage.append(sourceFile.absolutePath, nameTransformer.asString(className))
|
||||
}
|
||||
|
||||
fun contains(sourceFile: File): Boolean =
|
||||
sourceFile.absolutePath in storage
|
||||
|
||||
operator fun get(sourceFile: File): Collection<Name> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asName)
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,9 @@ data class BuildLogFinder(
|
||||
private const val GRADLE_LOG = "gradle-build.log"
|
||||
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
|
||||
private const val SIMPLE_LOG = "build.log"
|
||||
|
||||
fun isJpsLogFile(file: File): Boolean =
|
||||
file.name.let { it == SIMPLE_LOG || it == DATA_CONTAINER_LOG }
|
||||
}
|
||||
|
||||
fun findBuildLog(dir: File): File? {
|
||||
|
||||
@@ -357,6 +357,7 @@ tasks {
|
||||
|
||||
dependsOn("scriptingTest")
|
||||
dependsOn(":kotlin-build-common:test")
|
||||
dependsOn(":compiler:incremental-compilation-impl:test")
|
||||
}
|
||||
|
||||
"examplesTest" {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
@file:Suppress("unused") // usages in build scripts are not tracked properly
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DuplicatesStrategy
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.task
|
||||
import org.gradle.kotlin.dsl.*
|
||||
@@ -104,23 +102,22 @@ fun Project.embeddableCompilerDummyForDependenciesRewriting(taskName: String = "
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.rewriteDepsToShadedJar(originalJarTask: Jar, shadowJarTask: Zip, body: Jar.() -> Unit = {}): Jar {
|
||||
val originalFiles by lazy {
|
||||
val jarContents = zipTree(originalJarTask.outputs.files.singleFile).files
|
||||
val basePath = jarContents.find { it.name == "MANIFEST.MF" }?.parentFile?.parentFile ?: throw GradleException("cannot determine the jar root dir")
|
||||
jarContents.map { it.relativeTo(basePath).path }.toSet()
|
||||
fun Project.rewriteDepsToShadedJar(originalJarTask: Jar, shadowJarTask: Jar, body: Jar.() -> Unit = {}): Jar {
|
||||
originalJarTask.apply {
|
||||
classifier = "original"
|
||||
}
|
||||
return task<Jar>("rewrittenDepsJar") {
|
||||
originalJarTask.apply {
|
||||
classifier = "original"
|
||||
}
|
||||
shadowJarTask.apply {
|
||||
dependsOn(originalJarTask)
|
||||
from(originalJarTask)// { include("**") }
|
||||
classifier = "shadow"
|
||||
}
|
||||
dependsOn(shadowJarTask)
|
||||
from(project.zipTree(shadowJarTask.outputs.files.singleFile)) { include { originalFiles.any { originalFile -> it.file.canonicalPath.endsWith(originalFile) } } }
|
||||
|
||||
val compilerDummyJarFile by lazy { configurations.getAt("compilerDummyJar").singleFile }
|
||||
|
||||
return shadowJarTask.apply {
|
||||
dependsOn(originalJarTask)
|
||||
from(originalJarTask)// { include("**") }
|
||||
|
||||
// When Gradle traverses the inputs, reject the shaded compiler JAR,
|
||||
// which leads to the content of that JAR being excluded as well:
|
||||
exclude { it.file == compilerDummyJarFile }
|
||||
|
||||
classifier = null
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -19,14 +19,22 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.util.ExceptionUtilKt;
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
||||
|
||||
public class CompilationException extends RuntimeException {
|
||||
public class CompilationException extends KotlinExceptionWithAttachments {
|
||||
private final PsiElement element;
|
||||
|
||||
public CompilationException(@NotNull String message, @Nullable Throwable cause, @Nullable PsiElement element) {
|
||||
super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause, element), cause);
|
||||
super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause,
|
||||
element == null ? null : DiagnosticUtils.atLocation(element)),
|
||||
cause);
|
||||
this.element = element;
|
||||
|
||||
if (element != null) {
|
||||
withAttachment("element.kt", element.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.intellij.openapi.diagnostic.Attachment
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
@@ -23,7 +24,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
object ExceptionLogger {
|
||||
@JvmStatic
|
||||
fun logDescriptorNotFound(problemDescription: String, psi: PsiElement): AssertionError {
|
||||
LOG.error(problemDescription, psi.getElementTextWithContext())
|
||||
LOG.error(problemDescription, Attachment("psi.kt", psi.getElementTextWithContext()))
|
||||
throw AssertionError(problemDescription)
|
||||
}
|
||||
|
||||
|
||||
@@ -223,9 +223,8 @@ public class FunctionCodegen {
|
||||
|
||||
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
|
||||
|
||||
JvmMethodSignature signature = typeMapper.mapSignatureSkipGeneric(functionDescriptor);
|
||||
generateParameterAnnotations(functionDescriptor, mv, signature);
|
||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, signature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||
generateParameterAnnotations(functionDescriptor, mv, jvmSignature);
|
||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||
|
||||
generateBridges(functionDescriptor);
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
|
||||
import org.jetbrains.kotlin.util.slicedMap.Slices;
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
@@ -124,7 +125,8 @@ public class CodegenBinding {
|
||||
return asmTypeForAnonymousClass(bindingContext, variableDescriptor);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Couldn't compute ASM type for " + PsiUtilsKt.getElementTextWithContext(expression));
|
||||
throw new KotlinExceptionWithAttachments("Couldn't compute ASM type for expression")
|
||||
.withAttachment("expression.kt", PsiUtilsKt.getElementTextWithContext(expression));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -164,7 +164,7 @@ class DefaultLambda(
|
||||
classReader.b,
|
||||
invokeMethod.name,
|
||||
invokeMethod.descriptor,
|
||||
lambdaClassType)!!
|
||||
lambdaClassType) ?: error("Can't find method '${invokeMethod.name}${invokeMethod.descriptor}' in '${classReader.className}'")
|
||||
|
||||
if (needReification) {
|
||||
//nested classes could also require reification
|
||||
|
||||
@@ -164,7 +164,9 @@ class MethodInliner(
|
||||
result.merge(transformResult)
|
||||
result.addChangedType(oldClassName, newClassName)
|
||||
|
||||
if (inliningContext.isInliningLambda && transformationInfo!!.canRemoveAfterTransformation()) {
|
||||
if (inliningContext.isInliningLambda &&
|
||||
inliningContext.lambdaInfo !is DefaultLambda && //never delete default lambda classes
|
||||
transformationInfo!!.canRemoveAfterTransformation()) {
|
||||
// this class is transformed and original not used so we should remove original one after inlining
|
||||
result.addClassToRemove(oldClassName)
|
||||
}
|
||||
@@ -220,15 +222,20 @@ class MethodInliner(
|
||||
setLambdaInlining(true)
|
||||
val lambdaSMAP = info.node.classSMAP
|
||||
|
||||
val sourceMapper = if (inliningContext.classRegeneration && !inliningContext.isInliningLambda)
|
||||
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||
else
|
||||
InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
|
||||
val childSourceMapper =
|
||||
if (inliningContext.classRegeneration && !inliningContext.isInliningLambda)
|
||||
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||
else if (info is DefaultLambda) {
|
||||
NestedSourceMapper(sourceMapper.parent!!, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||
}
|
||||
else InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
|
||||
|
||||
val inliner = MethodInliner(
|
||||
info.node.node, lambdaParameters, inliningContext.subInlineLambda(info),
|
||||
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
|
||||
newCapturedRemapper,
|
||||
if (info is DefaultLambda) isSameModule else true /*cause all nested objects in same module as lambda*/,
|
||||
"Lambda inlining " + info.lambdaClassType.internalName,
|
||||
sourceMapper, inlineCallSiteInfo, null
|
||||
childSourceMapper, inlineCallSiteInfo, null
|
||||
)
|
||||
|
||||
val varRemapper = LocalVarRemapper(lambdaParameters, valueParamShift)
|
||||
@@ -242,7 +249,7 @@ class MethodInliner(
|
||||
StackValue.onStack(info.invokeMethod.returnType).put(bridge.returnType, this)
|
||||
setLambdaInlining(false)
|
||||
addInlineMarker(this, false)
|
||||
sourceMapper.endMapping()
|
||||
childSourceMapper.endMapping()
|
||||
inlineOnlySmapSkipper?.markCallSiteLineNumber(remappingMethodAdapter)
|
||||
}
|
||||
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
|
||||
|
||||
@@ -51,7 +51,7 @@ open class DefaultValues(val defaultValue: String, val possibleValues: List<Stri
|
||||
)
|
||||
|
||||
object JsSourceMapContentModes : DefaultValues(
|
||||
"\"${K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING}\"",
|
||||
"null",
|
||||
listOf(
|
||||
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_NEVER,
|
||||
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_ALWAYS,
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.utils.Jsr305State
|
||||
import org.jetbrains.kotlin.utils.ReportLevel
|
||||
|
||||
class Jsr305Parser(private val collector: MessageCollector) {
|
||||
fun parse(value: Array<String>?): Jsr305State {
|
||||
fun parse(value: Array<String>?, supportCompatqualCheckerFrameworkAnnotations: String?): Jsr305State {
|
||||
var global: ReportLevel? = null
|
||||
var migration: ReportLevel? = null
|
||||
val userDefined = mutableMapOf<String, ReportLevel>()
|
||||
@@ -70,7 +70,25 @@ class Jsr305Parser(private val collector: MessageCollector) {
|
||||
}
|
||||
}
|
||||
|
||||
val state = Jsr305State(global ?: ReportLevel.WARN, migration, userDefined)
|
||||
val enableCompatqualCheckerFrameworkAnnotations = when (supportCompatqualCheckerFrameworkAnnotations) {
|
||||
"enable" -> true
|
||||
"disable" -> false
|
||||
null -> null
|
||||
else -> {
|
||||
collector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"Unrecognized -Xsupport-compatqual-checker-framework-annotations option: $supportCompatqualCheckerFrameworkAnnotations. Possible values are 'enable'/'disable'"
|
||||
)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val state = Jsr305State(
|
||||
global ?: ReportLevel.WARN, migration, userDefined,
|
||||
enableCompatqualCheckerFrameworkAnnotations =
|
||||
enableCompatqualCheckerFrameworkAnnotations
|
||||
?: Jsr305State.COMPATQUAL_CHECKER_FRAMEWORK_ANNOTATIONS_SUPPORT_DEFAULT_VALUE
|
||||
)
|
||||
return if (state == Jsr305State.DISABLED) Jsr305State.DISABLED else state
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.utils.Jsr305State
|
||||
import org.jetbrains.kotlin.utils.ReportLevel
|
||||
|
||||
class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
companion object {
|
||||
@@ -191,6 +188,17 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var jsr305: Array<String>? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xsupport-compatqual-checker-framework-annotations",
|
||||
valueDescription = "enable|disable",
|
||||
description =
|
||||
"""
|
||||
Specify behavior for Checker Framework compatqual annotations (NullableDecl/NonNullDecl).
|
||||
Default value is 'enable'
|
||||
"""
|
||||
)
|
||||
var supportCompatqualCheckerFrameworkAnnotations: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xno-exception-on-explicit-equals-for-boxed-null",
|
||||
description = "Do not throw NPE on explicit 'equals' call for null receiver of platform boxed primitive type"
|
||||
@@ -202,7 +210,10 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
|
||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
val result = super.configureAnalysisFlags(collector)
|
||||
result[AnalysisFlag.jsr305] = Jsr305Parser(collector).parse(jsr305)
|
||||
result[AnalysisFlag.jsr305] = Jsr305Parser(collector).parse(
|
||||
jsr305,
|
||||
supportCompatqualCheckerFrameworkAnnotations
|
||||
)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import com.intellij.util.text.VersionComparatorUtil
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
@@ -98,4 +99,10 @@ fun <T : Any> collectProperties(kClass: KClass<T>, inheritedOnly: Boolean): List
|
||||
return properties.filter {
|
||||
it.visibility == KVisibility.PUBLIC && it.findAnnotation<Transient>() == null
|
||||
}
|
||||
}
|
||||
|
||||
fun CommonCompilerArguments.setApiVersionToLanguageVersionIfNeeded() {
|
||||
if (languageVersion != null && VersionComparatorUtil.compare(languageVersion, apiVersion) < 0) {
|
||||
apiVersion = languageVersion
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
|
||||
lock.write {
|
||||
val removed = map { it.id }
|
||||
clear()
|
||||
currentGeneration.incrementAndGet()
|
||||
return removed
|
||||
}
|
||||
}
|
||||
@@ -67,7 +68,10 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
|
||||
currentGeneration.incrementAndGet()
|
||||
removed
|
||||
}
|
||||
else emptyList()
|
||||
else {
|
||||
currentGeneration.incrementAndGet()
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,15 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
val aggregatedState = state.asState(AggregatedReplStageState::class.java)
|
||||
val compiled = compiler.compile(state, codeLine)
|
||||
when (compiled) {
|
||||
is ReplCompileResult.Error -> ReplEvalResult.Error.CompileTime(compiled.message, compiled.location)
|
||||
is ReplCompileResult.Error -> {
|
||||
aggregatedState.apply {
|
||||
lock.write {
|
||||
assert(state1.history.size == state2.history.size)
|
||||
adjustHistories() // needed due to statefulness of AnalyzerEngine - in case of compilation errors the line name reuse leads to #KT-17921
|
||||
}
|
||||
}
|
||||
ReplEvalResult.Error.CompileTime(compiled.message, compiled.location)
|
||||
}
|
||||
is ReplCompileResult.Incomplete -> ReplEvalResult.Incomplete()
|
||||
is ReplCompileResult.CompiledClasses -> {
|
||||
val result = eval(state, compiled, scriptArgs, invokeWrapper)
|
||||
@@ -46,14 +54,7 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
aggregatedState.apply {
|
||||
lock.write {
|
||||
if (state1.history.size > state2.history.size) {
|
||||
if (state2.history.size == 0) {
|
||||
state1.history.reset()
|
||||
}
|
||||
else {
|
||||
state2.history.peek()?.let {
|
||||
state1.history.resetTo(it.id)
|
||||
}
|
||||
}
|
||||
adjustHistories()
|
||||
assert(state1.history.size == state2.history.size)
|
||||
}
|
||||
}
|
||||
@@ -91,3 +92,9 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
evaluator.eval(state, compiledCode, scriptArgs ?: defaultScriptArgs, invokeWrapper)
|
||||
}
|
||||
}
|
||||
|
||||
private fun AggregatedReplStageState<*, *>.adjustHistories(): Iterable<ILineId>? =
|
||||
state2.history.peek()?.let {
|
||||
state1.history.resetTo(it.id)
|
||||
}
|
||||
?: state1.history.reset()
|
||||
|
||||
@@ -44,6 +44,7 @@ import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.jetbrains.kotlin.cli.common.ExitCode.*;
|
||||
import static org.jetbrains.kotlin.cli.common.environment.UtilKt.setIdeaIoUseFallback;
|
||||
@@ -239,11 +240,12 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
// do nothing
|
||||
}
|
||||
|
||||
private static final String kotlinHomeEnvVar = System.getenv(KOTLIN_HOME_ENV_VAR);
|
||||
|
||||
@Nullable
|
||||
private static KotlinPaths computeKotlinPaths(@NotNull MessageCollector messageCollector, @NotNull CommonCompilerArguments arguments) {
|
||||
KotlinPaths paths;
|
||||
String kotlinHomeProperty = System.getProperty(KOTLIN_HOME_PROPERTY);
|
||||
String kotlinHomeEnvVar = System.getenv(KOTLIN_HOME_ENV_VAR);
|
||||
File kotlinHome =
|
||||
arguments.getKotlinHome() != null ? new File(arguments.getKotlinHome()) :
|
||||
kotlinHomeProperty != null ? new File(kotlinHomeProperty) :
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser;
|
||||
import org.jetbrains.kotlin.config.*;
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker;
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker;
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider;
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer;
|
||||
@@ -418,6 +419,11 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, lookupTracker);
|
||||
}
|
||||
|
||||
ExpectActualTracker expectActualTracker = services.get(ExpectActualTracker.class);
|
||||
if (expectActualTracker != null) {
|
||||
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, expectActualTracker);
|
||||
}
|
||||
|
||||
String sourceMapEmbedContentString = arguments.getSourceMapEmbedSources();
|
||||
SourceMapSourceEmbedding sourceMapContentEmbedding = sourceMapEmbedContentString != null ?
|
||||
sourceMapContentEmbeddingMap.get(sourceMapEmbedContentString) :
|
||||
|
||||
@@ -33,19 +33,11 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
|
||||
override fun execImpl(messageCollector: MessageCollector, services: Services, arguments: K2JSDceArguments): ExitCode {
|
||||
val baseDir = File(arguments.outputDirectory ?: "min")
|
||||
var hasErrors = false
|
||||
val files = arguments.freeArgs.flatMap { arg ->
|
||||
val files = collectInputFiles(baseDir, arg, messageCollector)
|
||||
if (files != null) {
|
||||
files
|
||||
}
|
||||
else {
|
||||
hasErrors = true
|
||||
emptyList()
|
||||
}
|
||||
collectInputFiles(baseDir, arg, messageCollector)
|
||||
}
|
||||
|
||||
if (hasErrors) return ExitCode.COMPILATION_ERROR
|
||||
if (messageCollector.hasErrors()) return ExitCode.COMPILATION_ERROR
|
||||
|
||||
if (files.isEmpty() && !arguments.version) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "no source files")
|
||||
@@ -56,8 +48,9 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
for (file in files) {
|
||||
existingFiles[file.outputPath]?.let {
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"duplicate target file will be created for '${file.resource.name}' and '${it.resource.name}'")
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"duplicate target file will be created for '${file.resource.name}' and '${it.resource.name}'"
|
||||
)
|
||||
return ExitCode.COMPILATION_ERROR
|
||||
}
|
||||
existingFiles[file.outputPath] = file
|
||||
@@ -69,8 +62,7 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
|
||||
return if (!arguments.devMode) {
|
||||
performDce(files, arguments, messageCollector)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
copyFiles(files)
|
||||
ExitCode.OK
|
||||
}
|
||||
@@ -95,8 +87,10 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
val reachabilitySeverity = if (arguments.printReachabilityInfo) CompilerMessageSeverity.INFO else CompilerMessageSeverity.LOGGING
|
||||
messageCollector.report(reachabilitySeverity, "")
|
||||
for (node in nodes.extractRoots()) {
|
||||
printTree(node, { messageCollector.report(reachabilitySeverity, it) },
|
||||
printNestedMembers = false, showLocations = true)
|
||||
printTree(
|
||||
node, { messageCollector.report(reachabilitySeverity, it) },
|
||||
printNestedMembers = false, showLocations = true
|
||||
)
|
||||
}
|
||||
|
||||
return ExitCode.OK
|
||||
@@ -123,14 +117,13 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
FileOutputStream(targetFile).use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapSourcePaths(inputFile: File, targetFile: File): Boolean {
|
||||
val json = try {
|
||||
InputStreamReader(FileInputStream(inputFile), "UTF-8").use { parseJson(it) }
|
||||
}
|
||||
catch (e: JsonSyntaxException) {
|
||||
} catch (e: JsonSyntaxException) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -145,12 +138,10 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
if (result != null) {
|
||||
if (File(targetFile.parentFile, result).exists()) {
|
||||
result
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
@@ -165,7 +156,7 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun collectInputFiles(baseDir: File, fileName: String, messageCollector: MessageCollector): List<InputFile>? {
|
||||
private fun collectInputFiles(baseDir: File, fileName: String, messageCollector: MessageCollector): List<InputFile> {
|
||||
val file = File(fileName)
|
||||
return when {
|
||||
file.isDirectory -> {
|
||||
@@ -180,15 +171,17 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
collectInputFilesFromZip(baseDir, fileName)
|
||||
}
|
||||
else -> {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR,
|
||||
"invalid file name '$fileName'; must end either with '.js', '.zip' or '.jar'")
|
||||
null
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.WARNING,
|
||||
"invalid file name '${file.absolutePath}'; must end either with '.js', '.zip' or '.jar'"
|
||||
)
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "source file or directory not found: $fileName")
|
||||
null
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,41 +190,47 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
val moduleName = getModuleNameFromPath(path)
|
||||
val pathToSourceMapCandidate = "$path.map"
|
||||
val pathToSourceMap = if (File(pathToSourceMapCandidate).exists()) pathToSourceMapCandidate else null
|
||||
return InputFile(InputResource.file(path), pathToSourceMap?.let { InputResource.file(it) },
|
||||
File(baseDir, "$moduleName.js").absolutePath, moduleName)
|
||||
return InputFile(
|
||||
InputResource.file(path), pathToSourceMap?.let { InputResource.file(it) },
|
||||
File(baseDir, "$moduleName.js").absolutePath, moduleName
|
||||
)
|
||||
}
|
||||
|
||||
private fun collectInputFilesFromZip(baseDir: File, path: String): List<InputFile> {
|
||||
return ZipFile(path).use { zipFile ->
|
||||
zipFile.entries().asSequence()
|
||||
.filter { !it.isDirectory }
|
||||
.filter { it.name.endsWith(".js") }
|
||||
.filter { zipFile.getEntry(it.name.metaJs()) != null }
|
||||
.distinctBy { it.name }
|
||||
.map { entry ->
|
||||
val moduleName = getModuleNameFromPath(entry.name)
|
||||
val pathToSourceMapCandidate = "${entry.name}.map"
|
||||
val pathToSourceMap = if (zipFile.getEntry(pathToSourceMapCandidate) != null) pathToSourceMapCandidate else null
|
||||
InputFile(InputResource.zipFile(path, entry.name), pathToSourceMap?.let { InputResource.zipFile(path, it) },
|
||||
File(baseDir, "$moduleName.js").absolutePath, moduleName)
|
||||
}
|
||||
.toList()
|
||||
.filter { !it.isDirectory }
|
||||
.filter { it.name.endsWith(".js") }
|
||||
.filter { zipFile.getEntry(it.name.metaJs()) != null }
|
||||
.distinctBy { it.name }
|
||||
.map { entry ->
|
||||
val moduleName = getModuleNameFromPath(entry.name)
|
||||
val pathToSourceMapCandidate = "${entry.name}.map"
|
||||
val pathToSourceMap = if (zipFile.getEntry(pathToSourceMapCandidate) != null) pathToSourceMapCandidate else null
|
||||
InputFile(
|
||||
InputResource.zipFile(path, entry.name), pathToSourceMap?.let { InputResource.zipFile(path, it) },
|
||||
File(baseDir, "$moduleName.js").absolutePath, moduleName
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectInputFilesFromDirectory(baseDir: File, path: String): List<InputFile> {
|
||||
return File(path).walkTopDown().asSequence()
|
||||
.filter { !it.isDirectory }
|
||||
.filter { it.name.endsWith(".js") }
|
||||
.filter { File(it.path.metaJs()).exists() }
|
||||
.map { entry ->
|
||||
val moduleName = getModuleNameFromPath(entry.name)
|
||||
val pathToSourceMapCandidate = "${entry.path}.map"
|
||||
val pathToSourceMap = if (File(pathToSourceMapCandidate).exists()) pathToSourceMapCandidate else null
|
||||
InputFile(InputResource.file(entry.path), pathToSourceMap?.let { InputResource.file(it) },
|
||||
File(baseDir, "$moduleName.js").absolutePath, moduleName)
|
||||
}
|
||||
.toList()
|
||||
.filter { !it.isDirectory }
|
||||
.filter { it.name.endsWith(".js") }
|
||||
.filter { File(it.path.metaJs()).exists() }
|
||||
.map { entry ->
|
||||
val moduleName = getModuleNameFromPath(entry.name)
|
||||
val pathToSourceMapCandidate = "${entry.path}.map"
|
||||
val pathToSourceMap = if (File(pathToSourceMapCandidate).exists()) pathToSourceMapCandidate else null
|
||||
InputFile(
|
||||
InputResource.file(entry.path), pathToSourceMap?.let { InputResource.file(it) },
|
||||
File(baseDir, "$moduleName.js").absolutePath, moduleName
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
private fun String.metaJs() = removeSuffix(".js") + ".meta.js"
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
|
||||
import org.jetbrains.kotlin.codegen.CompilationException
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
||||
@@ -300,6 +301,10 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it)
|
||||
}
|
||||
|
||||
services.get(ExpectActualTracker::class.java)?.let {
|
||||
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, it)
|
||||
}
|
||||
|
||||
services.get(IncrementalCompilationComponents::class.java)?.let {
|
||||
configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, it)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.lang.java.JavaParserDefinition
|
||||
import com.intellij.lang.jvm.facade.JvmElementProvider
|
||||
import com.intellij.lang.jvm.facade.JvmFacade
|
||||
import com.intellij.lang.jvm.facade.JvmFacadeImpl
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.application.TransactionGuardImpl
|
||||
@@ -43,6 +46,7 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||
import com.intellij.psi.FileContextProvider
|
||||
import com.intellij.psi.JavaModuleSystem
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.augment.PsiAugmentProvider
|
||||
@@ -377,7 +381,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ideaCompatibleBuildNumber = "172.9999"
|
||||
private val ideaCompatibleBuildNumber = "173.1"
|
||||
|
||||
init {
|
||||
setCompatibleBuild()
|
||||
@@ -500,6 +504,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java)
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java)
|
||||
}
|
||||
|
||||
private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) {
|
||||
@@ -549,6 +555,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
private fun registerProjectExtensionPoints(area: ExtensionsArea) {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java)
|
||||
}
|
||||
|
||||
// made public for Upsource
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDependenciesImpl
|
||||
import org.jetbrains.kotlin.frontend.java.di.createContainerForTopDownAnalyzerForJvm
|
||||
import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
|
||||
import org.jetbrains.kotlin.frontend.java.di.initialize
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.javac.components.JavacBasedClassFinder
|
||||
import org.jetbrains.kotlin.javac.components.JavacBasedSourceElementFactory
|
||||
@@ -133,6 +134,7 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
|
||||
val incrementalComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
|
||||
val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING
|
||||
val expectActualTracker = configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing
|
||||
val targetIds = configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
|
||||
|
||||
val separateModules = !configuration.getBoolean(JVMConfigurationKeys.USE_SINGLE_MODULE)
|
||||
@@ -171,7 +173,7 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
val dependencyScope = GlobalSearchScope.notScope(sourceScope)
|
||||
|
||||
val dependenciesContainer = createContainerForTopDownAnalyzerForJvm(
|
||||
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker,
|
||||
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker, expectActualTracker,
|
||||
packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder
|
||||
)
|
||||
|
||||
@@ -196,7 +198,7 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
// to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found)
|
||||
// TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport
|
||||
val container = createContainerForTopDownAnalyzerForJvm(
|
||||
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker,
|
||||
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker, expectActualTracker,
|
||||
partProvider, moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder,
|
||||
javaClassTracker = configuration[JVMConfigurationKeys.JAVA_CLASSES_TRACKER]
|
||||
).apply {
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.jvm.repl
|
||||
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
@@ -46,6 +47,9 @@ open class GenericReplCompiler(disposable: Disposable,
|
||||
messageCollector: MessageCollector
|
||||
) : ReplCompiler {
|
||||
|
||||
constructor(scriptDefinition: KotlinScriptDefinition, compilerConfiguration: CompilerConfiguration, messageCollector: MessageCollector) :
|
||||
this(Disposer.newDisposable(), scriptDefinition, compilerConfiguration, messageCollector)
|
||||
|
||||
private val checker = GenericReplChecker(disposable, scriptDefinition, compilerConfiguration, messageCollector)
|
||||
|
||||
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = GenericReplCompilerState(checker.environment, lock)
|
||||
|
||||
@@ -61,6 +61,7 @@ messages/**)
|
||||
-dontwarn net.jpountz.lz4.LZ4Factory
|
||||
-dontwarn org.jetbrains.annotations.ReadOnly
|
||||
-dontwarn org.jetbrains.annotations.Mutable
|
||||
-dontwarn com.intellij.util.io.TarUtil
|
||||
|
||||
#-libraryjars '<rtjar>'
|
||||
#-libraryjars '<jssejar>'
|
||||
|
||||
@@ -116,8 +116,9 @@ object KotlinCompilerClient {
|
||||
}
|
||||
else {
|
||||
if (!isLastAttempt && autostart) {
|
||||
startDaemon(compilerId, newJVMOptions, daemonOptions, reportingTargets)
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "new daemon started, trying to find it")
|
||||
if (startDaemon(compilerId, newJVMOptions, daemonOptions, reportingTargets)) {
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "new daemon started, trying to find it")
|
||||
}
|
||||
}
|
||||
null
|
||||
}
|
||||
@@ -361,7 +362,7 @@ object KotlinCompilerClient {
|
||||
}
|
||||
|
||||
|
||||
private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) {
|
||||
private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets): Boolean {
|
||||
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(
|
||||
@@ -420,14 +421,22 @@ object KotlinCompilerClient {
|
||||
} ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS
|
||||
if (daemonOptions.runFilesPath.isNotEmpty()) {
|
||||
val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS)
|
||||
if (!isProcessAlive(daemon))
|
||||
throw RuntimeException("Daemon terminated unexpectedly with error code: ${daemon.exitValue()}")
|
||||
if (!succeeded)
|
||||
throw RuntimeException("Unable to get response from daemon in $daemonStartupTimeout ms")
|
||||
return when {
|
||||
!isProcessAlive(daemon) -> {
|
||||
reportingTargets.report(DaemonReportCategory.INFO, "Daemon terminated unexpectedly with error code: ${daemon.exitValue()}")
|
||||
false
|
||||
}
|
||||
!succeeded -> {
|
||||
reportingTargets.report(DaemonReportCategory.INFO, "Unable to get response from daemon in $daemonStartupTimeout ms")
|
||||
false
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
else
|
||||
// without startEcho defined waiting for max timeout
|
||||
Thread.sleep(daemonStartupTimeout)
|
||||
return true
|
||||
}
|
||||
finally {
|
||||
// assuming that all important output is already done, the rest should be routed to the log by the daemon itself
|
||||
|
||||
@@ -92,13 +92,13 @@ private inline fun tryConnectToDaemon(port: Int, report: (DaemonReportCategory,
|
||||
val daemon = LocateRegistry.getRegistry(LoopbackNetworkInterface.loopbackInetAddressName, port, LoopbackNetworkInterface.clientLoopbackSocketFactory)
|
||||
?.lookup(COMPILER_SERVICE_RMI_NAME)
|
||||
when (daemon) {
|
||||
null -> report(DaemonReportCategory.EXCEPTION, "daemon not found")
|
||||
null -> report(DaemonReportCategory.INFO, "daemon not found")
|
||||
is CompileService -> return daemon
|
||||
else -> report(DaemonReportCategory.EXCEPTION, "Unable to cast compiler service, actual class received: ${daemon::class.java.name}")
|
||||
else -> report(DaemonReportCategory.INFO, "Unable to cast compiler service, actual class received: ${daemon::class.java.name}")
|
||||
}
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
report(DaemonReportCategory.EXCEPTION, "cannot connect to registry: " + (e.cause?.message ?: e.message ?: "unknown error"))
|
||||
report(DaemonReportCategory.INFO, "cannot connect to registry: " + (e.cause?.message ?: e.message ?: "unknown error"))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.daemon.common
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.Serializable
|
||||
import java.net.Inet6Address
|
||||
import java.net.InetAddress
|
||||
import java.net.ServerSocket
|
||||
import java.net.Socket
|
||||
import java.net.*
|
||||
import java.rmi.RemoteException
|
||||
import java.rmi.registry.LocateRegistry
|
||||
import java.rmi.registry.Registry
|
||||
@@ -33,6 +30,11 @@ import java.util.*
|
||||
const val SOCKET_ANY_FREE_PORT = 0
|
||||
const val JAVA_RMI_SERVER_HOSTNAME = "java.rmi.server.hostname"
|
||||
const val DAEMON_RMI_SOCKET_BACKLOG_SIZE_PROPERTY = "kotlin.daemon.socket.backlog.size"
|
||||
const val DAEMON_RMI_SOCKET_CONNECT_ATTEMPTS_PROPERTY = "kotlin.daemon.socket.connect.attempts"
|
||||
const val DAEMON_RMI_SOCKET_CONNECT_INTERVAL_PROPERTY = "kotlin.daemon.socket.connect.interval"
|
||||
const val DEFAULT_SERVER_SOCKET_BACKLOG_SIZE = 50
|
||||
const val DEFAULT_SOCKET_CONNECT_ATTEMPTS = 3
|
||||
const val DEFAULT_SOCKET_CONNECT_INTERVAL_MS = 10L
|
||||
|
||||
object LoopbackNetworkInterface {
|
||||
|
||||
@@ -41,7 +43,9 @@ object LoopbackNetworkInterface {
|
||||
|
||||
// size of the requests queue for daemon services, so far seems that we don't need any big numbers here
|
||||
// but if we'll start getting "connection refused" errors, that could be the first place to try to fix it
|
||||
val SERVER_SOCKET_BACKLOG_SIZE by lazy { System.getProperty(DAEMON_RMI_SOCKET_BACKLOG_SIZE_PROPERTY)?.toIntOrNull() ?: 50 }
|
||||
val SERVER_SOCKET_BACKLOG_SIZE by lazy { System.getProperty(DAEMON_RMI_SOCKET_BACKLOG_SIZE_PROPERTY)?.toIntOrNull() ?: DEFAULT_SERVER_SOCKET_BACKLOG_SIZE }
|
||||
val SOCKET_CONNECT_ATTEMPTS by lazy { System.getProperty(DAEMON_RMI_SOCKET_CONNECT_ATTEMPTS_PROPERTY)?.toIntOrNull() ?: DEFAULT_SOCKET_CONNECT_ATTEMPTS }
|
||||
val SOCKET_CONNECT_INTERVAL_MS by lazy { System.getProperty(DAEMON_RMI_SOCKET_CONNECT_INTERVAL_PROPERTY)?.toLongOrNull() ?: DEFAULT_SOCKET_CONNECT_INTERVAL_MS }
|
||||
|
||||
val serverLoopbackSocketFactory by lazy { ServerLoopbackSocketFactory() }
|
||||
val clientLoopbackSocketFactory by lazy { ClientLoopbackSocketFactory() }
|
||||
@@ -75,7 +79,18 @@ object LoopbackNetworkInterface {
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(host: String, port: Int): Socket = Socket(InetAddress.getByName(null), port)
|
||||
override fun createSocket(host: String, port: Int): Socket {
|
||||
var attemptsLeft = SOCKET_CONNECT_ATTEMPTS
|
||||
while (true) {
|
||||
try {
|
||||
return Socket(InetAddress.getByName(null), port)
|
||||
}
|
||||
catch (e: ConnectException) {
|
||||
if (--attemptsLeft <= 0) throw e
|
||||
}
|
||||
Thread.sleep(SOCKET_CONNECT_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -453,8 +453,8 @@ class CompileServiceImpl(
|
||||
workingDir,
|
||||
enabled = true)
|
||||
|
||||
return IncrementalJsCompilerRunner(workingDir, versions, reporter)
|
||||
.compile(allKotlinFiles, args, compilerMessageCollector, { changedFiles })
|
||||
val compiler = IncrementalJsCompilerRunner(workingDir, versions, reporter)
|
||||
return compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles)
|
||||
}
|
||||
|
||||
private fun execIncrementalCompiler(
|
||||
@@ -514,7 +514,7 @@ class CompileServiceImpl(
|
||||
friendBuildHistoryFile = incrementalCompilationOptions.friendDifferenceFile,
|
||||
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking
|
||||
)
|
||||
return compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, { changedFiles })
|
||||
return compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
|
||||
}
|
||||
|
||||
override fun leaseReplSession(
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.contracts.ContractDeserializerImpl
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.frontend.di.configureModule
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
|
||||
@@ -49,10 +50,12 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
private fun StorageComponentContainer.configureJavaTopDownAnalysis(
|
||||
moduleContentScope: GlobalSearchScope,
|
||||
project: Project,
|
||||
lookupTracker: LookupTracker
|
||||
lookupTracker: LookupTracker,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
useInstance(moduleContentScope)
|
||||
useInstance(lookupTracker)
|
||||
useInstance(expectActualTracker)
|
||||
useImpl<ResolveSession>()
|
||||
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
@@ -79,6 +82,7 @@ fun createContainerForLazyResolveWithJava(
|
||||
moduleClassResolver: ModuleClassResolver,
|
||||
targetEnvironment: TargetEnvironment,
|
||||
lookupTracker: LookupTracker,
|
||||
expectActualTracker: ExpectActualTracker,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
jvmTarget: JvmTarget,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
@@ -87,7 +91,7 @@ fun createContainerForLazyResolveWithJava(
|
||||
javaClassTracker: JavaClassesTracker? = null
|
||||
): StorageComponentContainer = createContainer("LazyResolveWithJava", JvmPlatform) {
|
||||
configureModule(moduleContext, JvmPlatform, jvmTarget, bindingTrace)
|
||||
configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker)
|
||||
configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker, expectActualTracker)
|
||||
|
||||
if (configureJavaClassFinder != null) {
|
||||
configureJavaClassFinder()
|
||||
@@ -127,6 +131,7 @@ fun createContainerForTopDownAnalyzerForJvm(
|
||||
declarationProviderFactory: DeclarationProviderFactory,
|
||||
moduleContentScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker,
|
||||
expectActualTracker: ExpectActualTracker,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
moduleClassResolver: ModuleClassResolver,
|
||||
jvmTarget: JvmTarget,
|
||||
@@ -135,7 +140,7 @@ fun createContainerForTopDownAnalyzerForJvm(
|
||||
javaClassTracker: JavaClassesTracker? = null
|
||||
): ComponentProvider = createContainerForLazyResolveWithJava(
|
||||
moduleContext, bindingTrace, declarationProviderFactory, moduleContentScope, moduleClassResolver,
|
||||
CompilerEnvironment, lookupTracker, packagePartProvider, jvmTarget, languageVersionSettings,
|
||||
CompilerEnvironment, lookupTracker, expectActualTracker, packagePartProvider, jvmTarget, languageVersionSettings,
|
||||
useBuiltInsProvider = true,
|
||||
configureJavaClassFinder = configureJavaClassFinder,
|
||||
javaClassTracker = javaClassTracker
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.*
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
@@ -26,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
@@ -72,7 +72,6 @@ object JvmAnalyzerFacade : AnalyzerFacade() {
|
||||
val resolverForReferencedModule = referencedClassModule?.let { resolverForProject.tryGetResolverForModule(it as M) }
|
||||
|
||||
val resolverForModule = resolverForReferencedModule ?: run {
|
||||
LOG.warn("Java referenced $referencedClassModule from $moduleInfo\nReferenced class was: $javaClass\n")
|
||||
// in case referenced class lies outside of our resolver, resolve the class as if it is inside our module
|
||||
// this leads to java class being resolved several times
|
||||
resolverForProject.resolverForModule(moduleInfo)
|
||||
@@ -94,6 +93,7 @@ object JvmAnalyzerFacade : AnalyzerFacade() {
|
||||
moduleClassResolver,
|
||||
targetEnvironment,
|
||||
lookupTracker,
|
||||
ExpectActualTracker.DoNothing,
|
||||
packagePartProvider,
|
||||
jvmTarget,
|
||||
languageVersionSettings,
|
||||
@@ -120,6 +120,4 @@ object JvmAnalyzerFacade : AnalyzerFacade() {
|
||||
|
||||
override val targetPlatform: TargetPlatform
|
||||
get() = JvmPlatform
|
||||
|
||||
private val LOG = Logger.getInstance(JvmAnalyzerFacade::class.java)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.frontend.di.configureModule
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -142,6 +143,7 @@ object CommonAnalyzerFacade : AnalyzerFacade() {
|
||||
|
||||
useInstance(moduleContentScope)
|
||||
useInstance(LookupTracker.DO_NOTHING)
|
||||
useInstance(ExpectActualTracker.DoNothing)
|
||||
useImpl<ResolveSession>()
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
useInstance(languageVersionSettings)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
* Copyright 2010-2018 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.
|
||||
|
||||
@@ -1447,6 +1447,10 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
generateCallOrMarkUnresolved(call)
|
||||
}
|
||||
|
||||
override fun visitInitializerList(list: KtInitializerList) {
|
||||
list.acceptChildren(this)
|
||||
}
|
||||
|
||||
private fun generateCallOrMarkUnresolved(call: KtCallElement) {
|
||||
if (!generateCall(call)) {
|
||||
val arguments = call.valueArguments.mapNotNull(ValueArgument::getArgumentExpression)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
|
||||
object CommonConfigurationKeys {
|
||||
@@ -33,6 +34,9 @@ object CommonConfigurationKeys {
|
||||
|
||||
@JvmField
|
||||
val LOOKUP_TRACKER = CompilerConfigurationKey.create<LookupTracker>("lookup tracker")
|
||||
|
||||
@JvmField
|
||||
val EXPECT_ACTUAL_TRACKER = CompilerConfigurationKey.create<ExpectActualTracker>("expect actual tracker")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.container.useImpl
|
||||
import org.jetbrains.kotlin.container.useInstance
|
||||
import org.jetbrains.kotlin.context.ModuleContext
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
@@ -127,6 +128,7 @@ fun createContainerForLazyLocalClassifierAnalyzer(
|
||||
|
||||
useInstance(localClassDescriptorHolder)
|
||||
useInstance(lookupTracker)
|
||||
useInstance(ExpectActualTracker.DoNothing)
|
||||
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
|
||||
|
||||
@@ -379,6 +379,11 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
|
||||
return whenEntry
|
||||
}
|
||||
|
||||
fun createWhenCondition(conditionText: String): KtWhenCondition {
|
||||
val whenEntry = createWhenEntry("$conditionText -> {}")
|
||||
return whenEntry.conditions[0]
|
||||
}
|
||||
|
||||
fun createBlockStringTemplateEntry(expression: KtExpression): KtStringTemplateEntryWithExpression {
|
||||
// We don't want reformatting here as it can potentially change something in raw strings
|
||||
val stringTemplateExpression = createExpressionByPattern("\"$\${$0}\"", expression, reformat = false) as KtStringTemplateExpression
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.injected.editor.VirtualFileWindow
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.tree.TreeUtil
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
@@ -400,3 +401,11 @@ fun ASTNode.siblings(forward: Boolean = true): Sequence<ASTNode> {
|
||||
return generateSequence(treePrev) { it.treePrev }
|
||||
}
|
||||
}
|
||||
|
||||
fun ASTNode.leaves(forward: Boolean = true): Sequence<ASTNode> {
|
||||
if (forward) {
|
||||
return generateSequence(TreeUtil.nextLeaf(this)) { TreeUtil.nextLeaf(it) }
|
||||
} else {
|
||||
return generateSequence(TreeUtil.prevLeaf(this)) { TreeUtil.prevLeaf(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
|
||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension;
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker;
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
@@ -280,7 +281,7 @@ public class ModifiersChecker {
|
||||
@NotNull DeclarationDescriptor descriptor
|
||||
) {
|
||||
for (DeclarationChecker checker : declarationCheckers) {
|
||||
checker.check(declaration, descriptor, trace, trace.getBindingContext(), languageVersionSettings);
|
||||
checker.check(declaration, descriptor, trace, trace.getBindingContext(), languageVersionSettings, expectActualTracker);
|
||||
}
|
||||
OperatorModifierChecker.INSTANCE.check(declaration, descriptor, trace, languageVersionSettings);
|
||||
PublishedApiUsageChecker.INSTANCE.check(declaration, descriptor, trace);
|
||||
@@ -304,14 +305,19 @@ public class ModifiersChecker {
|
||||
@NotNull
|
||||
private final LanguageVersionSettings languageVersionSettings;
|
||||
|
||||
@NotNull
|
||||
private final ExpectActualTracker expectActualTracker;
|
||||
|
||||
public ModifiersChecker(
|
||||
@NotNull AnnotationChecker annotationChecker,
|
||||
@NotNull Iterable<DeclarationChecker> declarationCheckers,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings
|
||||
@NotNull LanguageVersionSettings languageVersionSettings,
|
||||
@NotNull ExpectActualTracker expectActualTracker
|
||||
) {
|
||||
this.annotationChecker = annotationChecker;
|
||||
this.declarationCheckers = declarationCheckers;
|
||||
this.languageVersionSettings = languageVersionSettings;
|
||||
this.expectActualTracker = expectActualTracker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -136,6 +136,7 @@ class DynamicCallableDescriptors(storageManager: StorageManager, builtIns: Kotli
|
||||
Modality.FINAL,
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
functionDescriptor.setHasSynthesizedParameterNames(true)
|
||||
return functionDescriptor
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.checkers
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -29,7 +30,8 @@ interface DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
)
|
||||
}
|
||||
|
||||
@@ -38,7 +40,9 @@ interface SimpleDeclarationChecker : DeclarationChecker {
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext, languageVersionSettings: LanguageVersionSettings
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) = check(declaration, descriptor, diagnosticHolder, bindingContext)
|
||||
|
||||
fun check(
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
||||
@@ -37,7 +38,8 @@ class DelegationChecker : DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
if (declaration !is KtClassOrObject) return
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtConstructor
|
||||
@@ -40,6 +42,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||
@@ -48,7 +51,9 @@ import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckerContext
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.io.File
|
||||
|
||||
object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
override fun check(
|
||||
@@ -56,7 +61,8 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return
|
||||
|
||||
@@ -64,7 +70,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
if (descriptor !is MemberDescriptor || DescriptorUtils.isEnumEntry(descriptor)) return
|
||||
|
||||
if (descriptor.isExpect) {
|
||||
checkExpectedDeclarationHasActual(declaration, descriptor, diagnosticHolder, descriptor.module)
|
||||
checkExpectedDeclarationHasActual(declaration, descriptor, diagnosticHolder, descriptor.module, expectActualTracker)
|
||||
}
|
||||
else {
|
||||
val checkActual = !languageVersionSettings.getFlag(AnalysisFlag.multiPlatformDoNotCheckActual)
|
||||
@@ -76,7 +82,8 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
reportOn: KtNamedDeclaration,
|
||||
descriptor: MemberDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
platformModule: ModuleDescriptor
|
||||
platformModule: ModuleDescriptor,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
// Only look for top level actual members; class members will be handled as a part of that expected class
|
||||
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) return
|
||||
@@ -96,8 +103,32 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
val incompatibility = compatibility as Map<Incompatible, Collection<MemberDescriptor>>
|
||||
diagnosticHolder.report(Errors.NO_ACTUAL_FOR_EXPECT.on(reportOn, descriptor, platformModule, incompatibility))
|
||||
}
|
||||
else {
|
||||
val actualMembers = compatibility.asSequence()
|
||||
.filter { (compatibility, _) ->
|
||||
compatibility is Compatible || (compatibility is Incompatible && compatibility.kind != Compatibility.IncompatibilityKind.STRONG)
|
||||
}.flatMap { it.value.asSequence() }
|
||||
|
||||
expectActualTracker?.reportExpectActual(expected = descriptor, actualMembers = actualMembers)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence<MemberDescriptor>) {
|
||||
if (this is ExpectActualTracker.DoNothing) return
|
||||
|
||||
val expectedFile = sourceFile(expected) ?: return
|
||||
for (actual in actualMembers) {
|
||||
val actualFile = sourceFile(actual) ?: continue
|
||||
report(expectedFile = expectedFile, actualFile = actualFile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sourceFile(descriptor: MemberDescriptor): File? =
|
||||
descriptor.source
|
||||
.containingFile
|
||||
.safeAs<PsiSourceFile>()
|
||||
?.run { VfsUtilCore.virtualToIoFile(psiFile.virtualFile) }
|
||||
|
||||
fun Map<out Compatibility, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
|
||||
this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG }
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -37,7 +38,8 @@ abstract class KotlinVersionStringAnnotationValueChecker(
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
val annotation = descriptor.annotations.findAnnotation(annotationFqName) ?: return
|
||||
val version = annotation.allValueArguments.values.singleOrNull()?.value as? String ?: return
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -61,7 +62,8 @@ object UnderscoreChecker : DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
if (declaration is KtProperty && descriptor !is VariableDescriptor) return
|
||||
if (declaration is KtCallableDeclaration) {
|
||||
|
||||
@@ -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.
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.lazy
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
|
||||
interface AbsentDescriptorHandler {
|
||||
fun diagnoseDescriptorNotFound(declaration: KtDeclaration): DeclarationDescriptor
|
||||
@@ -29,5 +30,9 @@ class BasicAbsentDescriptorHandler : AbsentDescriptorHandler {
|
||||
}
|
||||
|
||||
class NoDescriptorForDeclarationException @JvmOverloads constructor(declaration: KtDeclaration, additionalDetails: String? = null) :
|
||||
IllegalStateException("Descriptor wasn't found for declaration $declaration\n${declaration.getElementTextWithContext()}"
|
||||
+ (additionalDetails?.let { "\n---------------------------------------------------\n$it" } ?: ""))
|
||||
KotlinExceptionWithAttachments("Descriptor wasn't found for declaration $declaration"
|
||||
+ (additionalDetails?.let { "\n---------------------------------------------------\n$it" } ?: "")) {
|
||||
init {
|
||||
withAttachment("declaration.kt", declaration.getElementTextWithContext())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.util.KotlinFrontEndException;
|
||||
import org.jetbrains.kotlin.util.LookupTrackerUtilKt;
|
||||
import org.jetbrains.kotlin.util.PerformanceCounter;
|
||||
import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM;
|
||||
|
||||
@@ -240,8 +241,8 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
|
||||
try {
|
||||
// This trows AssertionError in CLI and reports the error in the IDE
|
||||
LOG.error(
|
||||
"Exception while analyzing expression at " + DiagnosticUtils.atLocation(expression) + ":\n" + expression.getText() + "\n",
|
||||
e
|
||||
new KotlinExceptionWithAttachments("Exception while analyzing expression at " + DiagnosticUtils.atLocation(expression), e)
|
||||
.withAttachment("expression.kt", expression.getText())
|
||||
);
|
||||
}
|
||||
catch (AssertionError errorFromLogger) {
|
||||
|
||||
@@ -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.
|
||||
@@ -17,11 +17,15 @@
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
|
||||
class KotlinFrontEndException(message: String, cause: Throwable) : RuntimeException(message, cause) {
|
||||
class KotlinFrontEndException(message: String, cause: Throwable) : KotlinExceptionWithAttachments(message, cause) {
|
||||
constructor(
|
||||
message: String,
|
||||
cause: Throwable,
|
||||
element: PsiElement
|
||||
) : this(getExceptionMessage("Front-end", message, cause, element), cause)
|
||||
) : this(getExceptionMessage("Front-end", message, cause, DiagnosticUtils.atLocation(element)), cause) {
|
||||
withAttachment("element.kt", element.text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -17,14 +17,12 @@
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
|
||||
fun getExceptionMessage(
|
||||
subsystemName: String,
|
||||
message: String,
|
||||
cause: Throwable?,
|
||||
element: PsiElement?
|
||||
location: String?
|
||||
): String = ApplicationManager.getApplication().runReadAction<String> {
|
||||
val result = StringBuilder(subsystemName + " Internal error: ").append(message).append("\n")
|
||||
if (cause != null) {
|
||||
@@ -32,9 +30,8 @@ fun getExceptionMessage(
|
||||
result.append("Cause: ").append(causeMessage ?: cause.toString()).append("\n")
|
||||
}
|
||||
|
||||
if (element != null) {
|
||||
result.append("File being compiled and position: ").append(DiagnosticUtils.atLocation(element)).append("\n")
|
||||
result.append("PsiElement: ").append(element.text).append("\n")
|
||||
if (location != null) {
|
||||
result.append("File being compiled and position: ").append(location).append("\n")
|
||||
}
|
||||
else {
|
||||
result.append("Element is unknown")
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.incremental
|
||||
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import java.io.File
|
||||
|
||||
internal class ExpectActualTrackerImpl : ExpectActualTracker {
|
||||
private val expectToActual = hashMapOf<File, MutableSet<File>>()
|
||||
|
||||
val expectToActualMap: Map<File, Set<File>>
|
||||
get() = expectToActual
|
||||
|
||||
override fun report(expectedFile: File, actualFile: File) {
|
||||
expectToActual.getOrPut(expectedFile) { hashSetOf() }.add(actualFile)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.incremental
|
||||
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
|
||||
import java.io.File
|
||||
|
||||
abstract class IncrementalCachesManager<PlatformCache : IncrementalCacheCommon>(
|
||||
abstract class IncrementalCachesManager<PlatformCache : IncrementalCacheCommon<*>>(
|
||||
protected val cachesRootDir: File,
|
||||
protected val reporter: ICReporter
|
||||
) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem
|
||||
import org.jetbrains.kotlin.compilerRunner.toGeneratedFile
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||
@@ -54,10 +55,12 @@ abstract class IncrementalCompilerRunner<
|
||||
protected abstract fun destinationDir(args: Args): File
|
||||
|
||||
fun compile(
|
||||
allKotlinSources: List<File>,
|
||||
allSourceFiles: List<File>,
|
||||
args: Args,
|
||||
messageCollector: MessageCollector,
|
||||
getChangedFiles: (CacheManager)-> ChangedFiles
|
||||
// when [providedChangedFiles] is not null, changes are provided by external system (e.g. Gradle)
|
||||
// otherwise we track source files changes ourselves.
|
||||
providedChangedFiles: ChangedFiles?
|
||||
): ExitCode {
|
||||
assert(isICEnabled()) { "Incremental compilation is not enabled" }
|
||||
var caches = createCacheManager(args)
|
||||
@@ -70,18 +73,20 @@ abstract class IncrementalCompilerRunner<
|
||||
destinationDir(args).deleteRecursively()
|
||||
|
||||
caches = createCacheManager(args)
|
||||
// todo more optimal fix
|
||||
caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allKotlinSources)
|
||||
return compileIncrementally(args, caches, allKotlinSources, CompilationMode.Rebuild(), messageCollector)
|
||||
if (providedChangedFiles == null) {
|
||||
caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allSourceFiles)
|
||||
}
|
||||
val allKotlinFiles = allSourceFiles.filter { it.isKotlinFile() }
|
||||
return compileIncrementally(args, caches, allKotlinFiles, CompilationMode.Rebuild(), messageCollector)
|
||||
}
|
||||
|
||||
return try {
|
||||
val changedFiles = getChangedFiles(caches)
|
||||
val changedFiles = providedChangedFiles ?: caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allSourceFiles)
|
||||
val compilationMode = sourcesToCompile(caches, changedFiles, args)
|
||||
|
||||
val exitCode = when (compilationMode) {
|
||||
is CompilationMode.Incremental -> {
|
||||
compileIncrementally(args, caches, allKotlinSources, compilationMode, messageCollector)
|
||||
compileIncrementally(args, caches, allSourceFiles, compilationMode, messageCollector)
|
||||
}
|
||||
is CompilationMode.Rebuild -> {
|
||||
rebuild { "Non-incremental compilation will be performed: ${compilationMode.reason}" }
|
||||
@@ -113,7 +118,7 @@ abstract class IncrementalCompilerRunner<
|
||||
}.filterTo(dirtyFiles, File::isKotlinFile)
|
||||
|
||||
if (dirtySourcesSinceLastTimeFile.exists()) {
|
||||
val files = dirtySourcesSinceLastTimeFile.readLines().map(::File).filter(File::exists)
|
||||
val files = dirtySourcesSinceLastTimeFile.readLines().map(::File)
|
||||
if (files.isNotEmpty()) {
|
||||
reporter.report { "Source files added since last compilation: ${reporter.pathsAsString(files)}" }
|
||||
}
|
||||
@@ -149,11 +154,13 @@ abstract class IncrementalCompilerRunner<
|
||||
protected open fun makeServices(
|
||||
args: Args,
|
||||
lookupTracker: LookupTracker,
|
||||
expectActualTracker: ExpectActualTracker,
|
||||
caches: CacheManager,
|
||||
compilationMode: CompilationMode
|
||||
): Services.Builder =
|
||||
Services.Builder().apply {
|
||||
register(LookupTracker::class.java, lookupTracker)
|
||||
register(ExpectActualTracker::class.java, expectActualTracker)
|
||||
register(CompilationCanceledStatus::class.java, EmptyCompilationCanceledStatus)
|
||||
}
|
||||
|
||||
@@ -185,22 +192,24 @@ abstract class IncrementalCompilerRunner<
|
||||
val allSourcesToCompile = HashSet<File>()
|
||||
|
||||
var exitCode = ExitCode.OK
|
||||
val allGeneratedFiles = hashSetOf<GeneratedFile>()
|
||||
|
||||
while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) {
|
||||
val complementaryFiles = caches.inputsCache.clearComplementaryFilesMapping(dirtySources)
|
||||
dirtySources.addAll(complementaryFiles)
|
||||
caches.platformCache.markDirty(dirtySources)
|
||||
caches.inputsCache.removeOutputForSourceFiles(dirtySources)
|
||||
|
||||
val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING)
|
||||
val expectActualTracker = ExpectActualTrackerImpl()
|
||||
val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists)
|
||||
|
||||
// todo: more optimal to save only last iteration, but it will require adding standalone-ic specific logs
|
||||
// (because jps rebuilds all files from last build if it failed and gradle rebuilds everything)
|
||||
allSourcesToCompile.addAll(sourcesToCompile)
|
||||
val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath }
|
||||
val text = dirtySources.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath }
|
||||
dirtySourcesSinceLastTimeFile.writeText(text)
|
||||
|
||||
val services = makeServices(args, lookupTracker, caches, compilationMode).build()
|
||||
val services = makeServices(args, lookupTracker, expectActualTracker, caches, compilationMode).build()
|
||||
|
||||
args.reportOutputFiles = true
|
||||
val outputItemsCollector = OutputItemsCollectorImpl()
|
||||
@@ -224,7 +233,7 @@ abstract class IncrementalCompilerRunner<
|
||||
}
|
||||
}
|
||||
|
||||
allGeneratedFiles.addAll(generatedFiles)
|
||||
caches.inputsCache.registerComplementaryFiles(expectActualTracker)
|
||||
caches.inputsCache.registerOutputForSourceFiles(generatedFiles)
|
||||
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
|
||||
val changesCollector = ChangesCollector()
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.*
|
||||
import java.io.File
|
||||
@@ -41,9 +42,7 @@ fun makeJsIncrementally(
|
||||
|
||||
withJsIC {
|
||||
val compiler = IncrementalJsCompilerRunner(cachesDir, versions, reporter)
|
||||
compiler.compile(allKotlinFiles, args, messageCollector) {
|
||||
it.inputsCache.sourceSnapshotMap.compareAndUpdate(allKotlinFiles)
|
||||
}
|
||||
compiler.compile(allKotlinFiles, args, messageCollector, providedChangedFiles = null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +98,11 @@ class IncrementalJsCompilerRunner(
|
||||
override fun makeServices(
|
||||
args: K2JSCompilerArguments,
|
||||
lookupTracker: LookupTracker,
|
||||
expectActualTracker: ExpectActualTracker,
|
||||
caches: IncrementalJsCachesManager,
|
||||
compilationMode: CompilationMode
|
||||
): Services.Builder =
|
||||
super.makeServices(args, lookupTracker, caches, compilationMode).apply {
|
||||
super.makeServices(args, lookupTracker, expectActualTracker, caches, compilationMode).apply {
|
||||
register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl())
|
||||
|
||||
if (compilationMode is CompilationMode.Incremental) {
|
||||
@@ -121,7 +121,8 @@ class IncrementalJsCompilerRunner(
|
||||
val jsCache = caches.platformCache
|
||||
jsCache.header = incrementalResults.headerMetadata
|
||||
|
||||
return jsCache.compareAndUpdate(incrementalResults, changesCollector)
|
||||
jsCache.compareAndUpdate(incrementalResults, changesCollector)
|
||||
jsCache.clearCacheForRemovedClasses(changesCollector)
|
||||
}
|
||||
|
||||
override fun runCompiler(
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||
@@ -63,7 +64,6 @@ fun makeIncrementally(
|
||||
val rootsWalk = sourceRoots.asSequence().flatMap { it.walk() }
|
||||
val files = rootsWalk.filter(File::isFile)
|
||||
val sourceFiles = files.filter { it.extension.toLowerCase() in allExtensions }.toList()
|
||||
val kotlinFiles = sourceFiles.filter { it.extension.toLowerCase() in kotlinExtensions }
|
||||
|
||||
withIC {
|
||||
val compiler = IncrementalJvmCompilerRunner(
|
||||
@@ -73,9 +73,7 @@ fun makeIncrementally(
|
||||
// Use precise setting in case of non-Gradle build
|
||||
usePreciseJavaTracking = true
|
||||
)
|
||||
compiler.compile(kotlinFiles, args, messageCollector) {
|
||||
it.inputsCache.sourceSnapshotMap.compareAndUpdate(sourceFiles)
|
||||
}
|
||||
compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,11 +156,11 @@ class IncrementalJvmCompilerRunner(
|
||||
dirtyFiles.addAll(dirtyFilesFromFqNames)
|
||||
}
|
||||
|
||||
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile)
|
||||
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" }
|
||||
reporter.report { "Last Kotlin Build info -- $lastBuildInfo" }
|
||||
|
||||
val changesFromFriend by lazy {
|
||||
val myLastTS = lastBuildInfo?.startTS ?: return@lazy ChangesEither.Unknown()
|
||||
val myLastTS = lastBuildInfo.startTS
|
||||
val storage = friendBuildHistoryFile?.let { BuildDiffsStorage.readFromFile(it, reporter) } ?: return@lazy ChangesEither.Unknown()
|
||||
|
||||
val (prevDiffs, newDiffs) = storage.buildDiffs.partition { it.ts < myLastTS }
|
||||
@@ -226,6 +224,12 @@ class IncrementalJvmCompilerRunner(
|
||||
|
||||
for (javaFile in javaFiles) {
|
||||
if (!caches.platformCache.isTrackedFile(javaFile)) {
|
||||
if (!javaFile.exists()) {
|
||||
// todo: can we do this more optimal?
|
||||
reporter.report { "Could not get changed for untracked removed java file $javaFile" }
|
||||
return false
|
||||
}
|
||||
|
||||
val psiFile = javaFile.psiFile()
|
||||
if (psiFile !is PsiJavaFile) {
|
||||
reporter.report { "[Precise Java tracking] Expected PsiJavaFile, got ${psiFile?.javaClass}" }
|
||||
@@ -404,10 +408,11 @@ class IncrementalJvmCompilerRunner(
|
||||
override fun makeServices(
|
||||
args: K2JVMCompilerArguments,
|
||||
lookupTracker: LookupTracker,
|
||||
expectActualTracker: ExpectActualTracker,
|
||||
caches: IncrementalJvmCachesManager,
|
||||
compilationMode: CompilationMode
|
||||
): Services.Builder =
|
||||
super.makeServices(args, lookupTracker, caches, compilationMode).apply {
|
||||
super.makeServices(args, lookupTracker, expectActualTracker, caches, compilationMode).apply {
|
||||
val targetId = TargetId(args.moduleName!!, "java-production")
|
||||
val targetToCache = mapOf(targetId to caches.platformCache)
|
||||
val incrementalComponents = IncrementalCompilationComponentsImpl(targetToCache)
|
||||
|
||||
@@ -23,20 +23,63 @@ import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
|
||||
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
|
||||
import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
|
||||
import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
class InputsCache(
|
||||
workingDir: File,
|
||||
private val reporter: ICReporter
|
||||
) : BasicMapsOwner(workingDir) {
|
||||
companion object {
|
||||
private val SOURCE_TO_OUTPUT_FILES = "source-to-output"
|
||||
private val SOURCE_SNAPSHOTS = "source-snapshot"
|
||||
private val SOURCE_TO_OUTPUT_FILES = "source-to-output"
|
||||
private val COMPLEMENTARY_FILES = "complementary-files"
|
||||
}
|
||||
|
||||
internal val sourceToOutputMap = registerMap(SourceToOutputFilesMap(SOURCE_TO_OUTPUT_FILES.storageFile))
|
||||
internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile))
|
||||
private val sourceToOutputMap = registerMap(FilesMap(SOURCE_TO_OUTPUT_FILES.storageFile))
|
||||
/**
|
||||
* A file X is a complementary to a file Y if they contain corresponding expect/actual declarations.
|
||||
* Complementary files should be compiled together during IC so the compiler does not complain
|
||||
* about missing parts.
|
||||
* TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider)
|
||||
*/
|
||||
private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile))
|
||||
|
||||
fun clearComplementaryFilesMapping(dirtyFiles: Collection<File>): Collection<File> {
|
||||
val complementaryFiles = HashSet<File>()
|
||||
val filesQueue = ArrayDeque(dirtyFiles)
|
||||
while (filesQueue.isNotEmpty()) {
|
||||
val file = filesQueue.pollFirst()
|
||||
complementaryFilesMap.remove(file).filterTo(filesQueue) { complementaryFiles.add(it) }
|
||||
}
|
||||
complementaryFiles.removeAll(dirtyFiles)
|
||||
return complementaryFiles
|
||||
}
|
||||
|
||||
internal fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl) {
|
||||
val actualToExpect = hashMapOf<File, MutableSet<File>>()
|
||||
for ((expect, actuals) in expectActualTracker.expectToActualMap) {
|
||||
for (actual in actuals) {
|
||||
actualToExpect.getOrPut(actual) { hashSetOf() }.add(expect)
|
||||
}
|
||||
complementaryFilesMap[expect] = actuals
|
||||
}
|
||||
|
||||
for ((actual, expects) in actualToExpect) {
|
||||
complementaryFilesMap[actual] = expects
|
||||
}
|
||||
}
|
||||
|
||||
fun removeOutputForSourceFiles(sources: Iterable<File>) {
|
||||
for (sourceFile in sources) {
|
||||
sourceToOutputMap.remove(sourceFile).forEach { it ->
|
||||
reporter.report { "Deleting $it on clearing cache for $sourceFile" }
|
||||
it.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generatedFiles can contain multiple entries with the same source file
|
||||
// for example Kapt3 IC will generate a .java stub and .class stub for each source file
|
||||
@@ -53,29 +96,21 @@ class InputsCache(
|
||||
sourceToOutputMap[source] = outputs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeOutputForSourceFiles(sources: Iterable<File>) {
|
||||
sources.forEach { sourceToOutputMap.remove(it) }
|
||||
private class FilesMap(storageFile: File)
|
||||
: BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
|
||||
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
|
||||
storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath }
|
||||
}
|
||||
|
||||
inner class SourceToOutputFilesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
|
||||
storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath }
|
||||
}
|
||||
operator fun get(sourceFile: File): Collection<File> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map(::File)
|
||||
|
||||
operator fun get(sourceFile: File): Collection<File> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map(::File)
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
|
||||
|
||||
fun remove(file: File) {
|
||||
// TODO: do it in the code that uses cache, since cache should not generally delete anything outside of it!
|
||||
// but for a moment it is an easiest solution to implement
|
||||
get(file).forEach {
|
||||
reporter.report { "Deleting $it on clearing cache for $file" }
|
||||
it.delete()
|
||||
}
|
||||
storage.remove(file.absolutePath)
|
||||
}
|
||||
}
|
||||
fun remove(file: File): Collection<File> =
|
||||
get(file).also { storage.remove(file.absolutePath) }
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.util.containers.HashMap
|
||||
import org.jetbrains.kotlin.TestWithWorkingDir
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
@@ -23,9 +24,6 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.*
|
||||
import org.jetbrains.kotlin.incremental.utils.TestCompilationResult
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIncrementalCompilerRunnerTestBase<Args : CommonCompilerArguments> : TestWithWorkingDir() {
|
||||
@@ -83,7 +81,13 @@ abstract class AbstractIncrementalCompilerRunnerTestBase<Args : CommonCompilerAr
|
||||
}
|
||||
|
||||
if (expectedSBWithoutErrors.toString() != actualSBWithoutErrors.toString()) {
|
||||
Assert.assertEquals(expectedSB.toString(), actualSB.toString())
|
||||
if (BuildLogFinder.isJpsLogFile(buildLogFile)) {
|
||||
// JPS logs should be updated carefully, because standalone logs are a bit different (no removed classes, iterations, etc)
|
||||
Assert.assertEquals(expectedSB.toString(), actualSB.toString())
|
||||
}
|
||||
else {
|
||||
UsefulTestCase.assertSameLinesWithFile(buildLogFile.canonicalPath, actualSB.toString(), false)
|
||||
}
|
||||
}
|
||||
|
||||
// todo: also compare caches
|
||||
@@ -110,20 +114,17 @@ abstract class AbstractIncrementalCompilerRunnerTestBase<Args : CommonCompilerAr
|
||||
private fun stepLogAsString(step: Int, ktSources: Iterable<String>, errors: Collection<String>, includeErrors: Boolean = true): String {
|
||||
val sb = StringBuilder()
|
||||
|
||||
sb.appendLine("<======= STEP $step =======>")
|
||||
sb.appendLine()
|
||||
sb.appendLine("Compiled kotlin sources:")
|
||||
ktSources.toSet().toTypedArray().sortedArray().forEach { sb.appendLine(it) }
|
||||
sb.appendLine("================ Step #$step =================")
|
||||
sb.appendLine()
|
||||
sb.appendLine("Compiling files:")
|
||||
ktSources.toSet().toTypedArray().sortedArray().forEach { sb.appendLine(" $it") }
|
||||
sb.appendLine("End of files")
|
||||
sb.appendLine("Exit code: ${if (errors.isEmpty()) "OK" else "ABORT"}")
|
||||
|
||||
if (errors.isEmpty()) {
|
||||
sb.appendLine("SUCCESS")
|
||||
}
|
||||
else {
|
||||
sb.appendLine("FAILURE")
|
||||
if (includeErrors) {
|
||||
errors.filter(String::isNotEmpty).forEach { sb.appendLine(it) }
|
||||
}
|
||||
if (errors.isNotEmpty() && includeErrors) {
|
||||
sb.appendLine("------------------------------------------")
|
||||
sb.appendLine("COMPILATION FAILED")
|
||||
errors.filter(String::isNotEmpty).forEach { sb.appendLine(it) }
|
||||
}
|
||||
|
||||
return sb.toString()
|
||||
@@ -136,6 +137,11 @@ abstract class AbstractIncrementalCompilerRunnerTestBase<Args : CommonCompilerAr
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
protected val bootstrapKotlincLib: File = File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib")
|
||||
private val distKotlincLib: File = File("dist/kotlinc/lib")
|
||||
|
||||
@JvmStatic
|
||||
protected val kotlinStdlibJvm: File = File(distKotlincLib, "kotlin-stdlib.jar").also {
|
||||
UsefulTestCase.assertExists(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,6 @@ abstract class AbstractIncrementalJsCompilerRunnerTest : AbstractIncrementalComp
|
||||
override fun createCompilerArguments(destinationDir: File, testDir: File): K2JSCompilerArguments =
|
||||
K2JSCompilerArguments().apply {
|
||||
outputFile = File(destinationDir, "${testDir.name}.js").path
|
||||
libraries = File(bootstrapKotlincLib, "kotlin-stdlib-js.jar").path
|
||||
sourceMap = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.incremental
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIncrementalJsCompilerRunnerWithFriendModulesDisabledTest : AbstractIncrementalJsCompilerRunnerTest() {
|
||||
override fun createCompilerArguments(destinationDir: File, testDir: File): K2JSCompilerArguments =
|
||||
super.createCompilerArguments(destinationDir, testDir).apply {
|
||||
friendModulesDisabled = true
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ abstract class AbstractIncrementalJvmCompilerRunnerTest : AbstractIncrementalCom
|
||||
|
||||
private val compileClasspath =
|
||||
listOf(
|
||||
File(bootstrapKotlincLib, "kotlin-stdlib.jar"),
|
||||
kotlinStdlibJvm,
|
||||
KotlinTestUtils.getAnnotationsJar()
|
||||
).joinToString(File.pathSeparator) { it.canonicalPath }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.incremental
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIncrementalMultiplatformJsCompilerRunnerTest : AbstractIncrementalJsCompilerRunnerTest() {
|
||||
override fun createCompilerArguments(destinationDir: File, testDir: File): K2JSCompilerArguments {
|
||||
return super.createCompilerArguments(destinationDir, testDir).apply {
|
||||
multiPlatform = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.incremental
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIncrementalMultiplatformJvmCompilerRunnerTest : AbstractIncrementalJvmCompilerRunnerTest() {
|
||||
override fun createCompilerArguments(destinationDir: File, testDir: File): K2JVMCompilerArguments {
|
||||
return super.createCompilerArguments(destinationDir, testDir).apply {
|
||||
multiPlatform = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,12 +122,6 @@ public class IncrementalJsCompilerRunnerTestGenerated extends AbstractIncrementa
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classRedeclaration")
|
||||
public void testClassRedeclaration() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/classRedeclaration/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classSignatureChanged")
|
||||
public void testClassSignatureChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/classSignatureChanged/");
|
||||
@@ -965,4 +959,28 @@ public class IncrementalJsCompilerRunnerTestGenerated extends AbstractIncrementa
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/js")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Js extends AbstractIncrementalJsCompilerRunnerTest {
|
||||
public void testAllFilesPresentInJs() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/js/friendsModuleDisabled")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FriendsModuleDisabled extends AbstractIncrementalJsCompilerRunnerTest {
|
||||
public void testAllFilesPresentInFriendsModuleDisabled() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js/friendsModuleDisabled"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("internalInlineFunctionIsChanged")
|
||||
public void testInternalInlineFunctionIsChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/js/friendsModuleDisabled/internalInlineFunctionIsChanged/");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.incremental;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/js/friendsModuleDisabled")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IncrementalJsCompilerRunnerWithFriendModulesDisabledTestGenerated extends AbstractIncrementalJsCompilerRunnerWithFriendModulesDisabledTest {
|
||||
public void testAllFilesPresentInFriendsModuleDisabled() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/js/friendsModuleDisabled"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false);
|
||||
}
|
||||
|
||||
@TestMetadata("internalInlineFunctionIsChanged")
|
||||
public void testInternalInlineFunctionIsChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/js/friendsModuleDisabled/internalInlineFunctionIsChanged/");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
@@ -122,12 +122,6 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classRedeclaration")
|
||||
public void testClassRedeclaration() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/classRedeclaration/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classSignatureChanged")
|
||||
public void testClassSignatureChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/classSignatureChanged/");
|
||||
@@ -1363,6 +1357,12 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classRedeclaration")
|
||||
public void testClassRedeclaration() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/other/classRedeclaration/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classToPackageFacade")
|
||||
public void testClassToPackageFacade() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/other/classToPackageFacade/");
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.incremental;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("touchActual")
|
||||
public void testTouchActual() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchActual/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("touchExpect")
|
||||
public void testTouchExpect() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect/");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.incremental;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("touchActual")
|
||||
public void testTouchActual() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchActual/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("touchExpect")
|
||||
public void testTouchExpect() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect/");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
@@ -127,10 +127,10 @@ object LightClassUtil {
|
||||
return getPsiMethodWrappers(declaration).firstOrNull()
|
||||
}
|
||||
|
||||
private fun getPsiMethodWrappers(declaration: KtDeclaration): Sequence<PsiMethod> {
|
||||
return getWrappingClasses(declaration).flatMap { it.methods.asSequence() }
|
||||
.filter { method -> method is KtLightMethod && method.kotlinOrigin === declaration }
|
||||
}
|
||||
private fun getPsiMethodWrappers(declaration: KtDeclaration): Sequence<KtLightMethod> =
|
||||
getWrappingClasses(declaration).flatMap { it.methods.asSequence() }
|
||||
.filterIsInstance<KtLightMethod>()
|
||||
.filter { it.kotlinOrigin === declaration }
|
||||
|
||||
private fun getWrappingClass(declaration: KtDeclaration): PsiClass? {
|
||||
var declaration = declaration
|
||||
@@ -191,33 +191,19 @@ object LightClassUtil {
|
||||
private fun extractPropertyAccessors(
|
||||
ktDeclaration: KtDeclaration,
|
||||
specialGetter: PsiMethod?, specialSetter: PsiMethod?): PropertyAccessorsPsiMethods {
|
||||
var getterWrapper = specialGetter
|
||||
var setterWrapper = specialSetter
|
||||
val additionalAccessors = arrayListOf<PsiMethod>()
|
||||
|
||||
for (wrapper in getPsiMethodWrappers(ktDeclaration)) {
|
||||
if (wrapper !is KtLightMethod) continue
|
||||
|
||||
if (wrapper.isSetter) {
|
||||
if (setterWrapper == null || setterWrapper === specialSetter) {
|
||||
setterWrapper = wrapper
|
||||
}
|
||||
else {
|
||||
additionalAccessors.add(wrapper)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (getterWrapper == null || getterWrapper === specialGetter) {
|
||||
getterWrapper = wrapper
|
||||
}
|
||||
else {
|
||||
additionalAccessors.add(wrapper)
|
||||
}
|
||||
}
|
||||
}
|
||||
val (setters, getters) = getPsiMethodWrappers(ktDeclaration).partition { it.isSetter }
|
||||
|
||||
val allGetters = listOfNotNull(specialGetter) + getters.filterNot { it == specialGetter }
|
||||
val allSetters = listOfNotNull(specialSetter) + setters.filterNot { it == specialSetter }
|
||||
val backingField = getLightClassBackingField(ktDeclaration)
|
||||
return PropertyAccessorsPsiMethods(getterWrapper, setterWrapper, backingField, additionalAccessors)
|
||||
val additionalAccessors = allGetters.drop(1) + allSetters.drop(1)
|
||||
return PropertyAccessorsPsiMethods(
|
||||
allGetters.firstOrNull(),
|
||||
allSetters.firstOrNull(),
|
||||
backingField,
|
||||
additionalAccessors
|
||||
)
|
||||
}
|
||||
|
||||
fun buildLightTypeParameterList(
|
||||
|
||||
@@ -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.
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
|
||||
interface LightClassDataHolder {
|
||||
val javaFileStub: PsiJavaFileStub
|
||||
@@ -107,7 +108,10 @@ fun PsiJavaFileStub.findDelegate(classOrObject: KtClassOrObject): PsiClass {
|
||||
}
|
||||
|
||||
val stubFileText = DebugUtil.stubTreeToString(this)
|
||||
throw IllegalStateException("Couldn't get delegate for ${classOrObject.getDebugText()}\nin $ktFileText\nstub: \n$stubFileText")
|
||||
throw KotlinExceptionWithAttachments("Couldn't get delegate for class")
|
||||
.withAttachment(classOrObject.name ?: "unnamed class or object", classOrObject.getDebugText())
|
||||
.withAttachment("file.kt", ktFileText)
|
||||
.withAttachment("stub text", stubFileText)
|
||||
}
|
||||
|
||||
fun PsiJavaFileStub.findDelegate(classFqName: FqName): PsiClass {
|
||||
|
||||
@@ -339,7 +339,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
.create(createNoCache(classOrObject), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
|
||||
}
|
||||
|
||||
private fun createNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
||||
fun createNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
||||
if (classOrObject.hasExpectModifier()) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.lang.Language;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class KtLightParameter extends LightParameter implements KtLightDeclaration<KtParameter, PsiParameter> {
|
||||
private static String getName(PsiParameter delegate, int index) {
|
||||
String name = delegate.getName();
|
||||
return name != null ? name : "p" + index;
|
||||
}
|
||||
|
||||
private final PsiModifierList modifierList;
|
||||
private final PsiParameter delegate;
|
||||
private final int index;
|
||||
private final KtLightMethod method;
|
||||
private KtLightIdentifier lightIdentifier = null;
|
||||
|
||||
public KtLightParameter(PsiParameter delegate, int index, KtLightMethod method) {
|
||||
super(getName(delegate, index), delegate.getType(), method, KotlinLanguage.INSTANCE);
|
||||
|
||||
this.delegate = delegate;
|
||||
this.index = index;
|
||||
this.method = method;
|
||||
|
||||
if (method.getLightMemberOrigin() instanceof LightMemberOriginForDeclaration) {
|
||||
this.modifierList = new KtLightSimpleModifierList(this, Collections.emptySet());
|
||||
}
|
||||
else {
|
||||
this.modifierList = super.getModifierList();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiModifierList getModifierList() {
|
||||
return modifierList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiParameter getClsDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public KtParameter getKotlinOrigin() {
|
||||
KtDeclaration declaration = method.getKotlinOrigin();
|
||||
if (declaration == null) return null;
|
||||
|
||||
int jetIndex = KtPsiUtilKt.isExtensionDeclaration(declaration) ? index - 1 : index;
|
||||
if (jetIndex < 0) return null;
|
||||
|
||||
if (declaration instanceof KtFunction) {
|
||||
List<KtParameter> paramList = ((KtFunction) declaration).getValueParameters();
|
||||
return jetIndex < paramList.size() ? paramList.get(jetIndex) : null;
|
||||
}
|
||||
|
||||
if (jetIndex != 0) return null;
|
||||
|
||||
KtPropertyAccessor setter = null;
|
||||
if (declaration instanceof KtPropertyAccessor) {
|
||||
KtPropertyAccessor accessor = (KtPropertyAccessor) declaration;
|
||||
setter = accessor.isSetter() ? accessor : null;
|
||||
}
|
||||
else if (declaration instanceof KtProperty) {
|
||||
setter = ((KtProperty) declaration).getSetter();
|
||||
}
|
||||
else if (declaration instanceof KtParameter) {
|
||||
return (KtParameter) declaration;
|
||||
}
|
||||
|
||||
return setter != null ? setter.getParameter() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getNavigationElement() {
|
||||
KtParameter origin = getKotlinOrigin();
|
||||
return origin != null ? origin : super.getNavigationElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return method.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
||||
KtParameter origin = getKotlinOrigin();
|
||||
if (origin != null) {
|
||||
origin.setName(name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() {
|
||||
return method.getContainingFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return KotlinLanguage.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SearchScope getUseScope() {
|
||||
KtParameter origin = getKotlinOrigin();
|
||||
return origin != null ? origin.getUseScope() : new LocalSearchScope(this);
|
||||
}
|
||||
|
||||
public KtLightMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
KtParameter origin = getKotlinOrigin();
|
||||
return origin != null ? origin.getText() : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getTextRange() {
|
||||
KtParameter origin = getKotlinOrigin();
|
||||
return origin != null ? origin.getTextRange() : TextRange.EMPTY_RANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiIdentifier getNameIdentifier() {
|
||||
if (lightIdentifier == null) {
|
||||
lightIdentifier = new KtLightIdentifier(this, getKotlinOrigin());
|
||||
}
|
||||
return lightIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
return getMethod().getParameterList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(PsiElement another) {
|
||||
KtParameter kotlinOrigin = getKotlinOrigin();
|
||||
if (another instanceof KtLightParameter && kotlinOrigin != null) {
|
||||
KtLightParameter anotherParam = (KtLightParameter) another;
|
||||
return kotlinOrigin.equals(anotherParam.getKotlinOrigin()) && getClsDelegate().equals(anotherParam.getClsDelegate());
|
||||
}
|
||||
return super.isEquivalentTo(another);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof PsiElement && isEquivalentTo((PsiElement) obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
KtParameter kotlinOrigin = getKotlinOrigin();
|
||||
if (kotlinOrigin != null) {
|
||||
return kotlinOrigin.hashCode();
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.lang.Language
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
|
||||
class KtLightParameter(
|
||||
override val clsDelegate: PsiParameter,
|
||||
private val index: Int,
|
||||
val method: KtLightMethod
|
||||
) : LightParameter(clsDelegate.name ?: "p$index", clsDelegate.type, method, KotlinLanguage.INSTANCE),
|
||||
KtLightDeclaration<KtParameter, PsiParameter> {
|
||||
|
||||
private val modifierList: PsiModifierList
|
||||
private var lightIdentifier: KtLightIdentifier? = null
|
||||
|
||||
override val kotlinOrigin: KtParameter?
|
||||
get() {
|
||||
val declaration = method.kotlinOrigin ?: return null
|
||||
|
||||
val jetIndex = if (declaration.isExtensionDeclaration()) index - 1 else index
|
||||
if (jetIndex < 0) return null
|
||||
|
||||
if (declaration is KtFunction) {
|
||||
val paramList = declaration.valueParameters
|
||||
return if (jetIndex < paramList.size) paramList[jetIndex] else null
|
||||
}
|
||||
|
||||
if (jetIndex != 0) return null
|
||||
|
||||
val setter = when (declaration) {
|
||||
is KtPropertyAccessor -> if (declaration.isSetter) declaration else null
|
||||
is KtProperty -> declaration.setter
|
||||
is KtParameter -> return declaration
|
||||
else -> return null
|
||||
}
|
||||
|
||||
return setter?.parameter
|
||||
}
|
||||
|
||||
init {
|
||||
if (method.lightMemberOrigin is LightMemberOriginForDeclaration) {
|
||||
this.modifierList = KtLightSimpleModifierList(this, emptySet())
|
||||
}
|
||||
else {
|
||||
this.modifierList = super.getModifierList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList = modifierList
|
||||
|
||||
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: super.getNavigationElement()
|
||||
|
||||
override fun isValid(): Boolean = method.isValid
|
||||
|
||||
@Throws(IncorrectOperationException::class)
|
||||
override fun setName(@NonNls name: String): PsiElement {
|
||||
kotlinOrigin?.setName(name)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getContainingFile(): PsiFile = method.containingFile
|
||||
|
||||
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
|
||||
|
||||
override fun getUseScope(): SearchScope {
|
||||
return kotlinOrigin?.useScope ?: LocalSearchScope(this)
|
||||
}
|
||||
|
||||
override fun getText(): String = kotlinOrigin?.text ?: ""
|
||||
|
||||
override fun getTextRange(): TextRange = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
override fun getNameIdentifier(): PsiIdentifier? {
|
||||
if (lightIdentifier == null) {
|
||||
lightIdentifier = KtLightIdentifier(this, kotlinOrigin)
|
||||
}
|
||||
return lightIdentifier
|
||||
}
|
||||
|
||||
override fun getParent(): PsiElement = method.parameterList
|
||||
|
||||
override fun isEquivalentTo(another: PsiElement?): Boolean {
|
||||
val result = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
val kotlinOrigin = kotlinOrigin
|
||||
if (another is KtLightParameter && kotlinOrigin != null) {
|
||||
kotlinOrigin == another.kotlinOrigin && clsDelegate == another.clsDelegate
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
})
|
||||
result?.let { return it }
|
||||
|
||||
return super.isEquivalentTo(another)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is PsiElement && isEquivalentTo(other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = kotlinOrigin?.hashCode() ?: 0
|
||||
}
|
||||
@@ -53,6 +53,12 @@ abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: ()
|
||||
|
||||
override fun getParameterList() = clsDelegate.parameterList
|
||||
|
||||
override fun canNavigate(): Boolean = super<KtLightElementBase>.canNavigate()
|
||||
|
||||
override fun canNavigateToSource(): Boolean = super<KtLightElementBase>.canNavigateToSource()
|
||||
|
||||
override fun navigate(requestFocus: Boolean) = super<KtLightElementBase>.navigate(requestFocus)
|
||||
|
||||
open fun fqNameMatches(fqName: String): Boolean = qualifiedName == fqName
|
||||
}
|
||||
|
||||
@@ -194,15 +200,20 @@ class KtLightAnnotationForSourceEntry(
|
||||
delegate.initializers.mapIndexed { i, memberValue ->
|
||||
wrapAnnotationValue(memberValue, this, {
|
||||
originalExpression.let { ktOrigin ->
|
||||
when (ktOrigin) {
|
||||
is KtValueArgumentList -> ktOrigin.arguments.getOrNull(i)?.getArgumentExpression()
|
||||
is KtCallElement -> ktOrigin.valueArguments.getOrNull(i)?.getArgumentExpression()
|
||||
is KtCollectionLiteralExpression -> ktOrigin.getInnerExpressions().getOrNull(i)
|
||||
when {
|
||||
ktOrigin is KtValueArgumentList -> ktOrigin.arguments.getOrNull(i)?.getArgumentExpression()
|
||||
ktOrigin is KtCallElement -> ktOrigin.valueArguments.getOrNull(i)?.getArgumentExpression()
|
||||
ktOrigin is KtCollectionLiteralExpression -> ktOrigin.getInnerExpressions().getOrNull(i)
|
||||
delegate.initializers.size == 1 -> ktOrigin
|
||||
else -> null
|
||||
}.also {
|
||||
if (it == null)
|
||||
LOG.error("error wrapping ${memberValue.javaClass} for ${ktOrigin?.javaClass} in ${ktOrigin?.containingFile}",
|
||||
Attachment("source_fragments.txt", "origin: '${psiReport(ktOrigin)}', delegate: ${psiReport(delegate)}"))
|
||||
Attachment(
|
||||
"source_fragments.txt",
|
||||
"origin: '${psiReport(ktOrigin)}', delegate: ${psiReport(delegate)}, parent: ${psiReport(parent)}"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -283,6 +294,12 @@ class KtLightNonExistentAnnotation(parent: KtLightElement<*, *>) : KtLightElemen
|
||||
override fun findDeclaredAttributeValue(attributeName: String?) = null
|
||||
override fun getMetaData() = null
|
||||
override fun getParameterList() = KtLightEmptyAnnotationParameterList(this)
|
||||
|
||||
override fun canNavigate(): Boolean = super<KtLightElementBase>.canNavigate()
|
||||
|
||||
override fun canNavigateToSource(): Boolean = super<KtLightElementBase>.canNavigateToSource()
|
||||
|
||||
override fun navigate(requestFocus: Boolean) = super<KtLightElementBase>.navigate(requestFocus)
|
||||
}
|
||||
|
||||
class KtLightEmptyAnnotationParameterList(parent: PsiElement) : KtLightElementBase(parent), PsiAnnotationParameterList {
|
||||
|
||||
56
compiler/testData/cfg/bugs/functionalCallInEnumEntry.instructions
vendored
Normal file
56
compiler/testData/cfg/bugs/functionalCallInEnumEntry.instructions
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
== Test ==
|
||||
enum class Test(f: () -> Unit) {
|
||||
A(getFunc())
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
v(f: () -> Unit)
|
||||
magic[FAKE_INITIALIZER](f: () -> Unit) -> <v0>
|
||||
w(f|<v0>)
|
||||
v(A(getFunc()))
|
||||
magic[FAKE_INITIALIZER](A(getFunc())) -> <v1>
|
||||
w(A|<v1>)
|
||||
mark(getFunc())
|
||||
call(getFunc(), getFunc) -> <v2>
|
||||
mark((getFunc()))
|
||||
call((getFunc()), <init>|<v2>) -> <v3>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== getFunc ==
|
||||
fun getFunc(): () -> Unit = {}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
mark({})
|
||||
jmp?(L2) NEXT:[r({}) -> <v0>, d({})]
|
||||
d({}) NEXT:[<SINK>]
|
||||
L2 [after local declaration]:
|
||||
r({}) -> <v0> PREV:[jmp?(L2)]
|
||||
ret(*|<v0>) L1
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>, d({})]
|
||||
=====================
|
||||
== anonymous_0 ==
|
||||
{}
|
||||
---------------------
|
||||
L3:
|
||||
2 <START>
|
||||
3 mark()
|
||||
read (Unit)
|
||||
L4:
|
||||
2 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
5
compiler/testData/cfg/bugs/functionalCallInEnumEntry.kt
vendored
Normal file
5
compiler/testData/cfg/bugs/functionalCallInEnumEntry.kt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
enum class Test(f: () -> Unit) {
|
||||
A(getFunc())
|
||||
}
|
||||
|
||||
fun getFunc(): () -> Unit = {}
|
||||
19
compiler/testData/cfg/bugs/functionalCallInEnumEntry.values
vendored
Normal file
19
compiler/testData/cfg/bugs/functionalCallInEnumEntry.values
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
== Test ==
|
||||
enum class Test(f: () -> Unit) {
|
||||
A(getFunc())
|
||||
}
|
||||
---------------------
|
||||
<v0>: {<: () -> Unit} NEW: magic[FAKE_INITIALIZER](f: () -> Unit) -> <v0>
|
||||
<v1>: {<: Test} NEW: magic[FAKE_INITIALIZER](A(getFunc())) -> <v1>
|
||||
getFunc() <v2>: {<: () -> Unit} NEW: call(getFunc(), getFunc) -> <v2>
|
||||
(getFunc()) <v3>: * NEW: call((getFunc()), <init>|<v2>) -> <v3>
|
||||
=====================
|
||||
== getFunc ==
|
||||
fun getFunc(): () -> Unit = {}
|
||||
---------------------
|
||||
{} <v0>: {<: () -> Unit} NEW: r({}) -> <v0>
|
||||
=====================
|
||||
== anonymous_0 ==
|
||||
{}
|
||||
---------------------
|
||||
=====================
|
||||
4
compiler/testData/cli/js-dce/invalidFilename.args
vendored
Normal file
4
compiler/testData/cli/js-dce/invalidFilename.args
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
$TESTDATA_DIR$/invalidFilename.args
|
||||
$TESTDATA_DIR$/simple.js
|
||||
-output-dir
|
||||
$TEMP_DIR$/min
|
||||
2
compiler/testData/cli/js-dce/invalidFilename.out
vendored
Normal file
2
compiler/testData/cli/js-dce/invalidFilename.out
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
warning: invalid file name '$TESTDATA_DIR$/invalidFilename.args'; must end either with '.js', '.zip' or '.jar'
|
||||
OK
|
||||
1
compiler/testData/cli/js-dce/invalidFilename.test
vendored
Normal file
1
compiler/testData/cli/js-dce/invalidFilename.test
vendored
Normal file
@@ -0,0 +1 @@
|
||||
// EXISTS: min/simple.js
|
||||
3
compiler/testData/cli/jvm/compatqual/A.java
vendored
Normal file
3
compiler/testData/cli/jvm/compatqual/A.java
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
public class A {
|
||||
public void foo(@org.checkerframework.checker.nullness.compatqual.NonNullDecl String x) {}
|
||||
}
|
||||
5
compiler/testData/cli/jvm/compatqualDefault.args
vendored
Normal file
5
compiler/testData/cli/jvm/compatqualDefault.args
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
$TESTDATA_DIR$/compatqualUsage.kt
|
||||
$TESTDATA_DIR$/compatqual
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
4
compiler/testData/cli/jvm/compatqualDefault.out
vendored
Normal file
4
compiler/testData/cli/jvm/compatqualDefault.out
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
compiler/testData/cli/jvm/compatqualUsage.kt:2:11: error: null can not be a value of a non-null type String
|
||||
a.foo(null)
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
6
compiler/testData/cli/jvm/compatqualDisable.args
vendored
Normal file
6
compiler/testData/cli/jvm/compatqualDisable.args
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
-Xsupport-compatqual-checker-framework-annotations=disable
|
||||
$TESTDATA_DIR$/compatqualUsage.kt
|
||||
$TESTDATA_DIR$/compatqual
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
1
compiler/testData/cli/jvm/compatqualDisable.out
vendored
Normal file
1
compiler/testData/cli/jvm/compatqualDisable.out
vendored
Normal file
@@ -0,0 +1 @@
|
||||
OK
|
||||
6
compiler/testData/cli/jvm/compatqualEnable.args
vendored
Normal file
6
compiler/testData/cli/jvm/compatqualEnable.args
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
-Xsupport-compatqual-checker-framework-annotations=enable
|
||||
$TESTDATA_DIR$/compatqualUsage.kt
|
||||
$TESTDATA_DIR$/compatqual
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
4
compiler/testData/cli/jvm/compatqualEnable.out
vendored
Normal file
4
compiler/testData/cli/jvm/compatqualEnable.out
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
compiler/testData/cli/jvm/compatqualUsage.kt:2:11: error: null can not be a value of a non-null type String
|
||||
a.foo(null)
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
3
compiler/testData/cli/jvm/compatqualUsage.kt
vendored
Normal file
3
compiler/testData/cli/jvm/compatqualUsage.kt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fun bar(a: A) {
|
||||
a.foo(null)
|
||||
}
|
||||
6
compiler/testData/cli/jvm/compatqualWrong.args
vendored
Normal file
6
compiler/testData/cli/jvm/compatqualWrong.args
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
-Xsupport-compatqual-checker-framework-annotations=true
|
||||
$TESTDATA_DIR$/compatqualUsage.kt
|
||||
$TESTDATA_DIR$/compatqual
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
2
compiler/testData/cli/jvm/compatqualWrong.out
vendored
Normal file
2
compiler/testData/cli/jvm/compatqualWrong.out
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
error: unrecognized -Xsupport-compatqual-checker-framework-annotations option: true. Possible values are 'enable'/'disable'
|
||||
COMPILATION_ERROR
|
||||
5
compiler/testData/cli/jvm/extraHelp.out
vendored
5
compiler/testData/cli/jvm/extraHelp.out
vendored
@@ -35,6 +35,11 @@ where advanced options include:
|
||||
-Xskip-runtime-version-check Allow Kotlin runtime libraries of incompatible versions in the classpath
|
||||
-Xstrict-java-nullability-assertions
|
||||
Generate nullability assertions for non-null Java expressions
|
||||
-Xsupport-compatqual-checker-framework-annotations=enable|disable
|
||||
|
||||
Specify behavior for Checker Framework compatqual annotations (NullableDecl/NonNullDecl).
|
||||
Default value is 'enable'
|
||||
|
||||
-Xuse-javac Use javac for Java source and class files analysis
|
||||
-Xuse-old-class-files-reading Use old class files reading implementation (may slow down the build and should be used in case of problems with the new implementation)
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
||||
|
||||
20
compiler/testData/codegen/box/annotations/parameterAnnotationInDefaultImpls.kt
vendored
Normal file
20
compiler/testData/codegen/box/annotations/parameterAnnotationInDefaultImpls.kt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// FULL_JDK
|
||||
// WITH_REFLECT
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
annotation class Anno(val value: String)
|
||||
|
||||
interface Test {
|
||||
fun foo(@Anno("OK") a: String) = "123"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testMethod = Class.forName("Test\$DefaultImpls").declaredMethods.single()
|
||||
//return (::test.parameters.single().annotations.single() as Simple).value
|
||||
val receiverAnnotations = (testMethod.parameters[0]).annotations
|
||||
if (receiverAnnotations.isNotEmpty()) return "fail: receiver parameter should not have any annotations, but: ${receiverAnnotations.joinToString()}"
|
||||
|
||||
val value2 = ((testMethod.parameters[1]).annotations.single() as Anno).value
|
||||
|
||||
return value2
|
||||
}
|
||||
17
compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/checkLambdaClassIsPresent.kt
vendored
Normal file
17
compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/checkLambdaClassIsPresent.kt
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun test(p: String, s: () -> () -> String = { { p } }) =
|
||||
s()
|
||||
|
||||
val same = test("O")
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val inlined = test("K")
|
||||
return same() + inlined()
|
||||
}
|
||||
17
compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/checkLambdaClassesArePresent.kt
vendored
Normal file
17
compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/checkLambdaClassesArePresent.kt
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun test(p: String, s: () -> () -> () -> String = { { { p } } }) =
|
||||
s()
|
||||
|
||||
val same = test("O")
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val inlined = test("K")
|
||||
return same()() + inlined()()
|
||||
}
|
||||
24
compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/checkObjectClassIsPresent.kt
vendored
Normal file
24
compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/checkObjectClassIsPresent.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
interface Call {
|
||||
fun run(): String
|
||||
}
|
||||
|
||||
inline fun test(p: String, s: () -> Call = {
|
||||
object : Call {
|
||||
override fun run() = p
|
||||
} as Call
|
||||
}) = s()
|
||||
|
||||
val same = test("O")
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val inlined = test("K")
|
||||
return same.run() + inlined.run()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun test(s: () -> () -> String = { { "OK" } }) =
|
||||
s()
|
||||
|
||||
val same = test()
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val inlined = test()
|
||||
if (same() != "OK") return "fail 1: ${same()}"
|
||||
return inlined()
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user