Record special name lookup when trying use interface as a SAM
It was already working in JPS, because it see our synthetic classes as subclasses for SAM's, but with non-JPS build we have to manually tracking places that should be recompiled after SAM members are changed
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
|||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||||
|
import org.jetbrains.kotlin.synthetic.SAM_LOOKUP_NAME
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -141,10 +142,10 @@ fun ChangesCollector.getDirtyData(
|
|||||||
dirtyClassesFqNames.addAll(fqNames)
|
dirtyClassesFqNames.addAll(fqNames)
|
||||||
|
|
||||||
for (name in change.names) {
|
for (name in change.names) {
|
||||||
for (fqName in fqNames) {
|
fqNames.mapTo(dirtyLookupSymbols) { LookupSymbol(name, it.asString()) }
|
||||||
dirtyLookupSymbols.add(LookupSymbol(name, fqName.asString()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fqNames.mapTo(dirtyLookupSymbols) { LookupSymbol(SAM_LOOKUP_NAME.asString(), it.asString()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ class JavaSyntheticScopes(
|
|||||||
): SyntheticScopes {
|
): SyntheticScopes {
|
||||||
override val scopes = listOf(
|
override val scopes = listOf(
|
||||||
JavaSyntheticPropertiesScope(storageManager, lookupTracker),
|
JavaSyntheticPropertiesScope(storageManager, lookupTracker),
|
||||||
SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver, deprecationResolver)
|
SamAdapterFunctionsScope(
|
||||||
|
storageManager, languageVersionSettings, samConventionResolver, deprecationResolver,
|
||||||
|
lookupTracker
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-4
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.incremental.record
|
||||||
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
|
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
@@ -48,11 +50,14 @@ interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticM
|
|||||||
override val baseDescriptorForSynthetic: FunctionDescriptor
|
override val baseDescriptorForSynthetic: FunctionDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
|
||||||
|
|
||||||
class SamAdapterFunctionsScope(
|
class SamAdapterFunctionsScope(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
private val languageVersionSettings: LanguageVersionSettings,
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
private val samResolver: SamConversionResolver,
|
private val samResolver: SamConversionResolver,
|
||||||
private val deprecationResolver: DeprecationResolver
|
private val deprecationResolver: DeprecationResolver,
|
||||||
|
private val lookupTracker: LookupTracker
|
||||||
) : SyntheticScope {
|
) : SyntheticScope {
|
||||||
private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
|
private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
|
||||||
extensionForFunctionNotCached(function)
|
extensionForFunctionNotCached(function)
|
||||||
@@ -94,6 +99,7 @@ class SamAdapterFunctionsScope(
|
|||||||
for (function in type.memberScope.getContributedFunctions(name, location)) {
|
for (function in type.memberScope.getContributedFunctions(name, location)) {
|
||||||
val extension = extensionForFunction(function.original)?.substituteForReceiverType(type)
|
val extension = extensionForFunction(function.original)?.substituteForReceiverType(type)
|
||||||
if (extension != null) {
|
if (extension != null) {
|
||||||
|
recordSamLookupsForParameters(function, location)
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = SmartList()
|
result = SmartList()
|
||||||
}
|
}
|
||||||
@@ -108,6 +114,12 @@ class SamAdapterFunctionsScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun recordSamLookupsForParameters(function: FunctionDescriptor, location: LookupLocation) {
|
||||||
|
for (valueParameter in function.valueParameters) {
|
||||||
|
recordSamLookupsToClassifier(valueParameter.type.constructor.declarationDescriptor ?: continue, location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun FunctionDescriptor.substituteForReceiverType(receiverType: KotlinType): FunctionDescriptor? {
|
private fun FunctionDescriptor.substituteForReceiverType(receiverType: KotlinType): FunctionDescriptor? {
|
||||||
val containingClass = containingDeclaration as? ClassDescriptor ?: return null
|
val containingClass = containingDeclaration as? ClassDescriptor ?: return null
|
||||||
val correspondingSupertype = findCorrespondingSupertype(receiverType, containingClass.defaultType) ?: return null
|
val correspondingSupertype = findCorrespondingSupertype(receiverType, containingClass.defaultType) ?: return null
|
||||||
@@ -135,16 +147,25 @@ class SamAdapterFunctionsScope(
|
|||||||
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> = emptyList()
|
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> = emptyList()
|
||||||
|
|
||||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||||
return getSamFunctions(scope.getContributedFunctions(name, location))
|
return getSamFunctions(scope.getContributedFunctions(name, location), location)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||||
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList()
|
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList()
|
||||||
|
recordSamLookupsToClassifier(classifier, location)
|
||||||
return getAllSamConstructors(classifier)
|
return getAllSamConstructors(classifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun recordSamLookupsToClassifier(classifier: ClassifierDescriptor, location: LookupLocation) {
|
||||||
|
if (classifier !is JavaClassDescriptor || classifier.kind != ClassKind.INTERFACE) return
|
||||||
|
// TODO: We should also record SAM lookups even when the interface is not SAM
|
||||||
|
if (!SingleAbstractMethodUtils.isSamType(classifier.defaultType)) return
|
||||||
|
|
||||||
|
lookupTracker.record(location, classifier, SAM_LOOKUP_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
||||||
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS))
|
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS), location = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
||||||
@@ -172,12 +193,17 @@ class SamAdapterFunctionsScope(
|
|||||||
return samConstructorForJavaConstructor(constructor)
|
return samConstructorForJavaConstructor(constructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSamFunctions(functions: Collection<DeclarationDescriptor>): List<SamAdapterDescriptor<JavaMethodDescriptor>> {
|
private fun getSamFunctions(
|
||||||
|
functions: Collection<DeclarationDescriptor>,
|
||||||
|
location: LookupLocation?
|
||||||
|
): List<SamAdapterDescriptor<JavaMethodDescriptor>> {
|
||||||
return functions.mapNotNull { function ->
|
return functions.mapNotNull { function ->
|
||||||
if (function !is JavaMethodDescriptor) return@mapNotNull null
|
if (function !is JavaMethodDescriptor) return@mapNotNull null
|
||||||
if (function.dispatchReceiverParameter != null) return@mapNotNull null // consider only statics
|
if (function.dispatchReceiverParameter != null) return@mapNotNull null // consider only statics
|
||||||
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return@mapNotNull null
|
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return@mapNotNull null
|
||||||
|
|
||||||
|
location?.let { recordSamLookupsForParameters(function, it) }
|
||||||
|
|
||||||
samAdapterForStaticFunction(function)
|
samAdapterForStaticFunction(function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -1230,11 +1230,23 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("methodAddedSamAdapter")
|
||||||
|
public void testMethodAddedSamAdapter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodAddedSamAdapter/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("methodSignatureChanged")
|
@TestMetadata("methodSignatureChanged")
|
||||||
public void testMethodSignatureChanged() throws Exception {
|
public void testMethodSignatureChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodSignatureChanged/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodSignatureChanged/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("methodSignatureChangedSamAdapter")
|
||||||
|
public void testMethodSignatureChangedSamAdapter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodSignatureChangedSamAdapter/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
@@ -1071,11 +1071,23 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("methodAddedSamAdapter")
|
||||||
|
public void testMethodAddedSamAdapter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodAddedSamAdapter/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("methodSignatureChanged")
|
@TestMetadata("methodSignatureChanged")
|
||||||
public void testMethodSignatureChanged() throws Exception {
|
public void testMethodSignatureChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodSignatureChanged/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodSignatureChanged/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("methodSignatureChangedSamAdapter")
|
||||||
|
public void testMethodSignatureChangedSamAdapter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions/methodSignatureChangedSamAdapter/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -72,6 +72,12 @@ public class JvmLookupTrackerTestGenerated extends AbstractJvmLookupTrackerTest
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SAM")
|
||||||
|
public void testSAM() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/lookupTracker/jvm/SAM/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simple")
|
@TestMetadata("simple")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/lookupTracker/jvm/simple/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/lookupTracker/jvm/simple/");
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public class C {
|
||||||
|
public void foo(SAMInterface x) {}
|
||||||
|
public static void bar(SAMInterface x) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package bar;
|
||||||
|
|
||||||
|
public interface SAMInterface {
|
||||||
|
void apply(String x);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
==== INITIAL BUILD ====
|
||||||
|
Compiling files:
|
||||||
|
src/usages.kt
|
||||||
|
Exit code: COMPILATION_ERROR
|
||||||
|
None of the following functions can be called with the arguments supplied:
|
||||||
|
public final fun foo(x: ((x: String!) -> Unit)!): Unit defined in bar.C
|
||||||
|
public open fun foo(x: SAMInterface!): Unit defined in bar.C
|
||||||
|
None of the following functions can be called with the arguments supplied:
|
||||||
|
public final fun bar(x: ((x: String!) -> Unit)!): Unit defined in bar.C
|
||||||
|
public open fun bar(x: SAMInterface!): Unit defined in bar.C
|
||||||
|
No value passed for parameter 'function'
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package foo
|
||||||
|
/*p:bar(C)*/import bar.C
|
||||||
|
/*p:bar(SAMInterface)*/import bar.SAMInterface
|
||||||
|
|
||||||
|
/*p:foo*/fun foo(c: /*p:bar*/C) /*p:bar(SAMInterface)*/{
|
||||||
|
/*p:bar(C)*/c./*c:bar.C c:bar.SAMInterface(<SAM-CONSTRUCTOR>) c:bar.C(getFoo) c:bar.C(getFOO) p:foo p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io p:kotlin.comparisons p:java.lang p:kotlin.jvm*/foo()
|
||||||
|
/*p:bar(C)*/c./*c:bar.C c:bar.SAMInterface(<SAM-CONSTRUCTOR>)*/foo /*p:kotlin(Function1) p:kotlin(String)*/{ }
|
||||||
|
|
||||||
|
/*p:bar p:foo p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io p:kotlin.comparisons p:java.lang p:kotlin.jvm*/C./*c:bar.C c:bar.SAMInterface(<SAM-CONSTRUCTOR>)*/bar()
|
||||||
|
/*p:bar p:foo p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io p:kotlin.comparisons p:java.lang p:kotlin.jvm*/C./*c:bar.C c:bar.SAMInterface(<SAM-CONSTRUCTOR>)*/bar /*p:kotlin(Function1) p:kotlin(String)*/{}
|
||||||
|
|
||||||
|
/*p:bar c:bar.SAMInterface(<SAM-CONSTRUCTOR>) p:foo p:kotlin p:kotlin.annotation p:kotlin.collections p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io p:kotlin.comparisons p:java.lang p:kotlin.jvm*/SAMInterface()
|
||||||
|
/*p:bar c:bar.SAMInterface(<SAM-CONSTRUCTOR>)*/SAMInterface /*p:kotlin(Function1) p:kotlin(String)*/{}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public void foo(SamInterface s) {}
|
||||||
|
public static void bar(SamInterface s) {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public interface SamInterface {
|
||||||
|
Object run();
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public interface SamInterface {
|
||||||
|
Object run();
|
||||||
|
Object walk();
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/SamInterface.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/SamInterface.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/UsageWithMemberKt$usageWithMember$1.class
|
||||||
|
out/production/module/UsageWithMemberKt.class
|
||||||
|
out/production/module/UsageWithStaticKt$usageWithStatic$1.class
|
||||||
|
out/production/module/UsageWithStaticKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/usageWithMember.kt
|
||||||
|
src/usageWithStatic.kt
|
||||||
|
End of files
|
||||||
|
Exit code: ABORT
|
||||||
|
------------------------------------------
|
||||||
|
COMPILATION FAILED
|
||||||
|
Type mismatch: inferred type is () -> String but SamInterface! was expected
|
||||||
|
Type mismatch: inferred type is () -> String but SamInterface! was expected
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun notUsage() {
|
||||||
|
JavaClass().hashCode()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun usageWithMember() {
|
||||||
|
JavaClass().foo { "" }
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun usageWithStatic() {
|
||||||
|
JavaClass.bar { "" }
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public void foo(SamInterface s) {}
|
||||||
|
public static void bar(SamInterface s) {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public interface SamInterface {
|
||||||
|
Object run();
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public interface SamInterface {
|
||||||
|
String run();
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/SamInterface.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/SamInterface.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/UsageWithMemberKt$usageWithMember$1.class
|
||||||
|
out/production/module/UsageWithMemberKt.class
|
||||||
|
out/production/module/UsageWithStaticKt$usageWithStatic$1.class
|
||||||
|
out/production/module/UsageWithStaticKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/usageWithMember.kt
|
||||||
|
src/usageWithStatic.kt
|
||||||
|
End of files
|
||||||
|
Exit code: OK
|
||||||
|
------------------------------------------
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun notUsage() {
|
||||||
|
JavaClass().hashCode()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun usageWithMember() {
|
||||||
|
JavaClass().foo { "" }
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun usageWithStatic() {
|
||||||
|
JavaClass.bar { "" }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user