[JS IR] IC: Propagate dependencies from nested declaration to parent
JsIrLinker can't load nested declarations, therefore it is required to load their parent. This patch adds a dependency in the incremental cache graph between nested declaration user and nested declaration parent. ^KT-53931 Fixed ^KT-54120 Fixed
This commit is contained in:
committed by
Space
parent
bd085fbf43
commit
252dc01dd5
@@ -294,12 +294,41 @@ class CacheUpdater(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class SignatureSource(val lib: KotlinLibraryFile, val src: KotlinSourceFile, val symbol: IrSymbol)
|
||||||
|
|
||||||
|
private fun addParentSignatures(
|
||||||
|
signatures: Collection<IdSignature>,
|
||||||
|
idSignatureToFile: Map<IdSignature, SignatureSource>,
|
||||||
|
importerLibFile: KotlinLibraryFile,
|
||||||
|
importerSrcFile: KotlinSourceFile
|
||||||
|
): Set<IdSignature> {
|
||||||
|
val allSignatures = HashSet<IdSignature>(signatures.size)
|
||||||
|
|
||||||
|
fun addAllParents(sig: IdSignature) {
|
||||||
|
val signatureSrc = idSignatureToFile[sig] ?: return
|
||||||
|
if (signatureSrc.lib == importerLibFile && signatureSrc.src == importerSrcFile) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (allSignatures.add(sig)) {
|
||||||
|
(signatureSrc.symbol.owner as? IrDeclaration)?.let { declaration ->
|
||||||
|
(declaration.parent as? IrSymbolOwner)?.let { parent ->
|
||||||
|
parent.symbol.signature?.let(::addAllParents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signatures.forEach(::addAllParents)
|
||||||
|
|
||||||
|
return allSignatures
|
||||||
|
}
|
||||||
|
|
||||||
private fun rebuildDirtySourceMetadata(
|
private fun rebuildDirtySourceMetadata(
|
||||||
jsIrLinker: JsIrLinker,
|
jsIrLinker: JsIrLinker,
|
||||||
loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
||||||
dirtySrcFiles: KotlinSourceFileMap<KotlinSourceFileExports>,
|
dirtySrcFiles: KotlinSourceFileMap<KotlinSourceFileExports>,
|
||||||
): KotlinSourceFileMap<DirtyFileMetadata> {
|
): KotlinSourceFileMap<DirtyFileMetadata> {
|
||||||
val idSignatureToFile = mutableMapOf<IdSignature, Pair<KotlinLibraryFile, KotlinSourceFile>>()
|
val idSignatureToFile = mutableMapOf<IdSignature, SignatureSource>()
|
||||||
val updatedMetadata = KotlinSourceFileMutableMap<DirtyFileMetadata>()
|
val updatedMetadata = KotlinSourceFileMutableMap<DirtyFileMetadata>()
|
||||||
|
|
||||||
for ((lib, irModule) in loadedFragments) {
|
for ((lib, irModule) in loadedFragments) {
|
||||||
@@ -321,7 +350,7 @@ class CacheUpdater(
|
|||||||
}
|
}
|
||||||
if (symbolCanBeExported) {
|
if (symbolCanBeExported) {
|
||||||
signatureHashCalculator.addHashForSignatureIfNotExist(signature, symbol)
|
signatureHashCalculator.addHashForSignatureIfNotExist(signature, symbol)
|
||||||
idSignatureToFile[signature] = lib to libSrcFile
|
idSignatureToFile[signature] = SignatureSource(lib, libSrcFile, symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,15 +366,18 @@ class CacheUpdater(
|
|||||||
for ((srcFile, internalHeader) in srcFiles) {
|
for ((srcFile, internalHeader) in srcFiles) {
|
||||||
val dirtySrcFile = libDirtySrcFiles[srcFile] ?: continue
|
val dirtySrcFile = libDirtySrcFiles[srcFile] ?: continue
|
||||||
dirtySrcFile.inverseDependencies.forEachFile { dependentLibFile, dependentSrcFile, signatures ->
|
dirtySrcFile.inverseDependencies.forEachFile { dependentLibFile, dependentSrcFile, signatures ->
|
||||||
signatures.forEach {
|
signatures.forEach { signature ->
|
||||||
val (dependencyLib, dependencyFile) = idSignatureToFile[it] ?: (libFile to srcFile)
|
val signatureSrc = idSignatureToFile[signature]
|
||||||
|
val dependencyLib = signatureSrc?.lib ?: libFile
|
||||||
|
val dependencyFile = signatureSrc?.src ?: srcFile
|
||||||
updatedMetadata[dependencyLib, dependencyFile]?.also { dependencyMetadata ->
|
updatedMetadata[dependencyLib, dependencyFile]?.also { dependencyMetadata ->
|
||||||
dependencyMetadata.addInverseDependency(dependentLibFile, dependentSrcFile, it)
|
dependencyMetadata.addInverseDependency(dependentLibFile, dependentSrcFile, signature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (importedSignature in internalHeader.maybeImportedSignatures) {
|
val allImportedSignatures = addParentSignatures(internalHeader.maybeImportedSignatures, idSignatureToFile, libFile, srcFile)
|
||||||
|
for (importedSignature in allImportedSignatures) {
|
||||||
val (dependencyLib, dependencyFile) = idSignatureToFile[importedSignature] ?: continue
|
val (dependencyLib, dependencyFile) = idSignatureToFile[importedSignature] ?: continue
|
||||||
signatureHashCalculator[importedSignature]?.also { signatureHash ->
|
signatureHashCalculator[importedSignature]?.also { signatureHash ->
|
||||||
internalHeader.addDirectDependency(dependencyLib, dependencyFile, importedSignature, signatureHash)
|
internalHeader.addDirectDependency(dependencyLib, dependencyFile, importedSignature, signatureHash)
|
||||||
@@ -444,18 +476,18 @@ class CacheUpdater(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectFilesWithModifiedExportsOrInlineImports(
|
private fun collectFilesWithModifiedExportsAndImports(
|
||||||
loadedDirtyFiles: KotlinSourceFileMap<DirtyFileMetadata>
|
loadedDirtyFiles: KotlinSourceFileMap<DirtyFileMetadata>
|
||||||
): KotlinSourceFileMap<UpdatedDependenciesMetadata> {
|
): KotlinSourceFileMap<UpdatedDependenciesMetadata> {
|
||||||
val filesWithModifiedExports = KotlinSourceFileMutableMap<UpdatedDependenciesMetadata>()
|
val filesWithModifiedExportsAndImports = KotlinSourceFileMutableMap<UpdatedDependenciesMetadata>()
|
||||||
|
|
||||||
loadedDirtyFiles.forEachFile { libFile, srcFile, srcFileMetadata ->
|
loadedDirtyFiles.forEachFile { libFile, srcFile, srcFileMetadata ->
|
||||||
filesWithModifiedExports.addDependenciesWithUpdatedSignatures(libFile, srcFile, srcFileMetadata)
|
filesWithModifiedExportsAndImports.addDependenciesWithUpdatedSignatures(libFile, srcFile, srcFileMetadata)
|
||||||
filesWithModifiedExports.addDependenciesWithRemovedInverseDependencies(libFile, srcFile, srcFileMetadata)
|
filesWithModifiedExportsAndImports.addDependenciesWithRemovedInverseDependencies(libFile, srcFile, srcFileMetadata)
|
||||||
filesWithModifiedExports.addDependentsWithUpdatedImports(libFile, srcFile, srcFileMetadata)
|
filesWithModifiedExportsAndImports.addDependentsWithUpdatedImports(libFile, srcFile, srcFileMetadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
return filesWithModifiedExports
|
return filesWithModifiedExportsAndImports
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectFilesToRebuildSignatures(
|
private fun collectFilesToRebuildSignatures(
|
||||||
@@ -548,7 +580,7 @@ class CacheUpdater(
|
|||||||
|
|
||||||
val dirtyHeaders = rebuildDirtySourceMetadata(loadedIr.linker, loadedIr.loadedFragments, lastDirtyFiles)
|
val dirtyHeaders = rebuildDirtySourceMetadata(loadedIr.linker, loadedIr.loadedFragments, lastDirtyFiles)
|
||||||
|
|
||||||
val filesWithModifiedExportsOrImports = collectFilesWithModifiedExportsOrInlineImports(dirtyHeaders)
|
val filesWithModifiedExportsOrImports = collectFilesWithModifiedExportsAndImports(dirtyHeaders)
|
||||||
|
|
||||||
val filesToRebuild = collectFilesToRebuildSignatures(filesWithModifiedExportsOrImports)
|
val filesToRebuild = collectFilesToRebuildSignatures(filesWithModifiedExportsOrImports)
|
||||||
|
|
||||||
|
|||||||
+15
@@ -60,6 +60,16 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
|
|||||||
runTest("js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/");
|
runTest("js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companionInlineFunction")
|
||||||
|
public void testCompanionInlineFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/incremental/invalidation/companionInlineFunction/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companionWithStdLibCall")
|
||||||
|
public void testCompanionWithStdLibCall() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/incremental/invalidation/companionWithStdLibCall/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("constVals")
|
@TestMetadata("constVals")
|
||||||
public void testConstVals() throws Exception {
|
public void testConstVals() throws Exception {
|
||||||
runTest("js/js.translator/testData/incremental/invalidation/constVals/");
|
runTest("js/js.translator/testData/incremental/invalidation/constVals/");
|
||||||
@@ -205,6 +215,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
|
|||||||
runTest("js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/");
|
runTest("js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedClass")
|
||||||
|
public void testNestedClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/incremental/invalidation/nestedClass/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nonInlineBecomeInline")
|
@TestMetadata("nonInlineBecomeInline")
|
||||||
public void testNonInlineBecomeInline() throws Exception {
|
public void testNonInlineBecomeInline() throws Exception {
|
||||||
runTest("js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/");
|
runTest("js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/");
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class MyClass1 {
|
||||||
|
companion object {
|
||||||
|
inline fun companionMethod() = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class MyClass1 {
|
||||||
|
companion object {
|
||||||
|
inline fun companionMethod() = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class MyClass1 {
|
||||||
|
class InternalClass {
|
||||||
|
companion object {
|
||||||
|
inline fun companionMethod() = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class MyClass1 {
|
||||||
|
class InternalClass {
|
||||||
|
companion object {
|
||||||
|
inline fun companionMethod() = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
STEP 0:
|
||||||
|
modifications:
|
||||||
|
U : l1.0.kt -> l1.kt
|
||||||
|
added file: l1.kt
|
||||||
|
STEP 1:
|
||||||
|
modifications:
|
||||||
|
U : l1.1.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 2:
|
||||||
|
modifications:
|
||||||
|
U : l1.2.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 3:
|
||||||
|
modifications:
|
||||||
|
U : l1.3.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 4:
|
||||||
|
STEP 5:
|
||||||
|
updated exports: l1.kt
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
inline fun foo() = MyClass1.companionMethod()
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
inline fun foo() = MyClass1.InternalClass.companionMethod()
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
inline fun foo(): Int {
|
||||||
|
bar(null)
|
||||||
|
return MyClass1.InternalClass.companionMethod() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(x: Any?): Any = (x as? MyClass1) ?: 1
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
inline fun foo(): Int {
|
||||||
|
bar(null)
|
||||||
|
return MyClass1.InternalClass.companionMethod() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(x: Any?): Any = x ?: MyClass1()
|
||||||
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: lib1
|
||||||
|
modifications:
|
||||||
|
U : l2.0.kt -> l2.kt
|
||||||
|
added file: l2.kt
|
||||||
|
STEP 1:
|
||||||
|
dependencies: lib1
|
||||||
|
updated imports: l2.kt
|
||||||
|
STEP 2:
|
||||||
|
dependencies: lib1
|
||||||
|
modifications:
|
||||||
|
U : l2.2.kt -> l2.kt
|
||||||
|
modified ir: l2.kt
|
||||||
|
STEP 3:
|
||||||
|
dependencies: lib1
|
||||||
|
updated imports: l2.kt
|
||||||
|
STEP 4:
|
||||||
|
dependencies: lib1
|
||||||
|
modifications:
|
||||||
|
U : l2.4.kt -> l2.kt
|
||||||
|
modified ir: l2.kt
|
||||||
|
STEP 5:
|
||||||
|
dependencies: lib1
|
||||||
|
modifications:
|
||||||
|
U : l2.5.kt -> l2.kt
|
||||||
|
modified ir: l2.kt
|
||||||
|
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun box(stepId: Int): String {
|
||||||
|
when (stepId) {
|
||||||
|
0, 1, 2, 3, 4 -> if (foo() != stepId) return "Fail"
|
||||||
|
5 -> if (foo() != 4) return "Fail"
|
||||||
|
else -> return "Unkown"
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: lib1, lib2
|
||||||
|
added file: m.kt
|
||||||
|
STEP 1..4:
|
||||||
|
dependencies: lib1, lib2
|
||||||
|
updated imports: m.kt
|
||||||
|
STEP 5:
|
||||||
|
dependencies: lib1, lib2
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
MODULES: lib1, lib2, main
|
||||||
|
|
||||||
|
STEP 0..4:
|
||||||
|
libs: lib1, lib2, main
|
||||||
|
dirty js: lib1, lib2, main
|
||||||
|
STEP 5:
|
||||||
|
libs: lib1, lib2, main
|
||||||
|
dirty js: lib1, lib2
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
class MyClass1 {
|
||||||
|
companion object {
|
||||||
|
fun companionMethod(v: Int): Int {
|
||||||
|
return v.countTrailingZeroBits()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyClass2 {
|
||||||
|
companion object {
|
||||||
|
fun companionMethod(v: Int): Int {
|
||||||
|
return v.countTrailingZeroBits()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class MyClass1 {
|
||||||
|
companion object {
|
||||||
|
fun companionMethod(v: Int): Int {
|
||||||
|
return v.countTrailingZeroBits()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
STEP 0:
|
||||||
|
modifications:
|
||||||
|
U : l1.0.kt -> l1.kt
|
||||||
|
added file: l1.kt
|
||||||
|
STEP 1:
|
||||||
|
modifications:
|
||||||
|
U : l1.1.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 2:
|
||||||
|
modifications:
|
||||||
|
U : l1.0.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 3:
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun test(x: Int): Int {
|
||||||
|
val y = MyClass1.companionMethod(x)
|
||||||
|
return y.countTrailingZeroBits()
|
||||||
|
}
|
||||||
|
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun test(x: Int): Int {
|
||||||
|
val y = MyClass1.companionMethod(x)
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
fun box(stepId: Int): String {
|
||||||
|
val x = test(stepId)
|
||||||
|
when (stepId) {
|
||||||
|
0 -> if (x != 5) return "Fail, x == $x"
|
||||||
|
1 -> if (x != 32) return "Fail, x == $x"
|
||||||
|
2 -> if (x != 0) return "Fail, x == $x"
|
||||||
|
3 -> if (x != 0) return "Fail, x == $x"
|
||||||
|
else -> return "Unkown"
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: lib1
|
||||||
|
modifications:
|
||||||
|
U : f.0.kt -> f.kt
|
||||||
|
added file: m.kt, f.kt
|
||||||
|
STEP 1..2:
|
||||||
|
dependencies: lib1
|
||||||
|
STEP 3:
|
||||||
|
dependencies: lib1
|
||||||
|
modifications:
|
||||||
|
U : f.3.kt -> f.kt
|
||||||
|
modified ir: f.kt
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
MODULES: lib1, main
|
||||||
|
|
||||||
|
STEP 0:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1, main
|
||||||
|
STEP 1..2:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1
|
||||||
|
STEP 3:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: main
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class MyClass {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class MyClass {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class MyClass {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unusedFunction() = -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
data class MyClass(val unusedField: String) {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unusedFunction() = -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
data class MyClass(val unusedField: String) {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = 1
|
||||||
|
|
||||||
|
val field = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unusedFunction() = -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
data class MyClass(val unusedField: String) {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = field
|
||||||
|
|
||||||
|
val field = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unusedFunction() = -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
data class MyClass(val unusedField: String) {
|
||||||
|
class NestedClass {
|
||||||
|
inline fun foo() = field
|
||||||
|
|
||||||
|
val field = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unusedFunction() = -1
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
STEP 0:
|
||||||
|
modifications:
|
||||||
|
U : l1.0.kt -> l1.kt
|
||||||
|
added file: l1.kt
|
||||||
|
STEP 1:
|
||||||
|
modifications:
|
||||||
|
U : l1.1.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 2:
|
||||||
|
modifications:
|
||||||
|
U : l1.2.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 3:
|
||||||
|
modifications:
|
||||||
|
U : l1.3.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 4:
|
||||||
|
modifications:
|
||||||
|
U : l1.4.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 5:
|
||||||
|
modifications:
|
||||||
|
U : l1.5.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
|
STEP 6:
|
||||||
|
modifications:
|
||||||
|
U : l1.6.kt -> l1.kt
|
||||||
|
modified ir: l1.kt
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun box(stepId: Int): String {
|
||||||
|
when (stepId) {
|
||||||
|
0, 1, 5, 6 -> if (MyClass.NestedClass().foo() != stepId) return "Fail"
|
||||||
|
2, 3, 4 -> if (MyClass.NestedClass().foo() != 1) return "Fail"
|
||||||
|
else -> return "Unknown"
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
STEP 0:
|
||||||
|
dependencies: lib1
|
||||||
|
added file: m.kt
|
||||||
|
STEP 1:
|
||||||
|
dependencies: lib1
|
||||||
|
updated imports: m.kt
|
||||||
|
STEP 2:
|
||||||
|
dependencies: lib1
|
||||||
|
STEP 3:
|
||||||
|
dependencies: lib1
|
||||||
|
updated imports: m.kt
|
||||||
|
STEP 4:
|
||||||
|
dependencies: lib1
|
||||||
|
STEP 5:
|
||||||
|
dependencies: lib1
|
||||||
|
updated imports: m.kt
|
||||||
|
STEP 6:
|
||||||
|
dependencies: lib1
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
MODULES: lib1, main
|
||||||
|
|
||||||
|
STEP 0..1:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1, main
|
||||||
|
STEP 2:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1
|
||||||
|
STEP 3:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1, main
|
||||||
|
STEP 4:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1
|
||||||
|
STEP 5:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1, main
|
||||||
|
STEP 6:
|
||||||
|
libs: lib1, main
|
||||||
|
dirty js: lib1
|
||||||
Reference in New Issue
Block a user