Track lookups in JavaSyntheticPropertiesScope

This commit is contained in:
Zalim Bashorov
2015-10-23 17:53:54 +03:00
parent 412e078a6b
commit a5708c9c0d
15 changed files with 185 additions and 60 deletions
@@ -16,9 +16,10 @@
package org.jetbrains.kotlin.synthetic package org.jetbrains.kotlin.synthetic
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
class AdditionalScopesWithJavaSyntheticExtensions(storageManager: StorageManager) : FileScopeProvider.AdditionalScopes { class AdditionalScopesWithJavaSyntheticExtensions(storageManager: StorageManager, lookupTracker: LookupTracker) : FileScopeProvider.AdditionalScopes {
override val scopes = listOf(JavaSyntheticPropertiesScope(storageManager), SamAdapterFunctionsScope(storageManager)) override val scopes = listOf(JavaSyntheticPropertiesScope(storageManager, lookupTracker), SamAdapterFunctionsScope(storageManager))
} }
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
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.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -42,6 +44,8 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.* import java.util.*
import kotlin.properties.Delegates import kotlin.properties.Delegates
private val POSSIBLE_GETTER_NAMES_CAPACITY = 3
interface SyntheticJavaPropertyDescriptor : PropertyDescriptor { interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
val getMethod: FunctionDescriptor val getMethod: FunctionDescriptor
val setMethod: FunctionDescriptor? val setMethod: FunctionDescriptor?
@@ -69,31 +73,62 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
} }
} }
class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImportingScope(null) { class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val lookupTracker: LookupTracker) : BaseImportingScope(null) {
private val syntheticPropertyInClass = storageManager.createMemoizedFunctionWithNullableValues<Pair<ClassDescriptor, Name>, PropertyDescriptor> { pair -> private val syntheticPropertyInClass = storageManager.createMemoizedFunction<Pair<ClassDescriptor, Name>, SyntheticPropertyHolder> { pair ->
syntheticPropertyInClassNotCached(pair.first, pair.second) syntheticPropertyInClassNotCached(pair.first, pair.second)
} }
private fun syntheticPropertyInClassNotCached(ownerClass: ClassDescriptor, name: Name): PropertyDescriptor? { private fun getSyntheticPropertyAndRecordLookups(classifier: ClassDescriptor, name: Name, location: LookupLocation): PropertyDescriptor? {
if (name.isSpecial()) return null val (descriptor, lookedNames) = syntheticPropertyInClass(Pair(classifier, name))
if (location !is NoLookupLocation) {
lookedNames.forEach { lookupTracker.record(location, classifier.unsubstitutedMemberScope, it) }
}
return descriptor
}
private fun syntheticPropertyInClassNotCached(ownerClass: ClassDescriptor, name: Name): SyntheticPropertyHolder {
fun result(descriptor: PropertyDescriptor?, getterNames: Sequence<Name>, setterName: Name? = null): SyntheticPropertyHolder {
if (lookupTracker == LookupTracker.DO_NOTHING) {
return if (descriptor == null) SyntheticPropertyHolder.EMPTY else SyntheticPropertyHolder(descriptor, emptyList())
}
val names = ArrayList<Name>(POSSIBLE_GETTER_NAMES_CAPACITY + (setterName?.let { 1 } ?: 0))
names.addAll(getterNames)
names.addIfNotNull(setterName)
return SyntheticPropertyHolder(descriptor, names)
}
if (name.isSpecial) return SyntheticPropertyHolder.EMPTY
val identifier = name.identifier val identifier = name.identifier
if (identifier.isEmpty()) return null if (identifier.isEmpty()) return SyntheticPropertyHolder.EMPTY
val firstChar = identifier[0] val firstChar = identifier[0]
if (!firstChar.isJavaIdentifierStart() || firstChar in 'A'..'Z') return null if (!firstChar.isJavaIdentifierStart() || firstChar in 'A'..'Z') return SyntheticPropertyHolder.EMPTY
val memberScope = ownerClass.unsubstitutedMemberScope val memberScope = ownerClass.unsubstitutedMemberScope
val getMethod = possibleGetMethodNames(name)
.flatMap { memberScope.getFunctions(it, NoLookupLocation.UNSORTED).asSequence() } val possibleGetMethodNames = possibleGetMethodNames(name)
val getMethod = possibleGetMethodNames
.flatMap { memberScope.getFunctions(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE).asSequence() }
.singleOrNull { .singleOrNull {
isGoodGetMethod(it) && it.hasJavaOriginInHierarchy() isGoodGetMethod(it) && it.hasJavaOriginInHierarchy()
} ?: return null } ?: return result(null, possibleGetMethodNames)
val setMethod = memberScope.getFunctions(setMethodName(getMethod.name), NoLookupLocation.UNSORTED) val setMethodName = setMethodName(getMethod.name)
val setMethod = memberScope.getFunctions(setMethodName, NoLookupLocation.FROM_SYNTHETIC_SCOPE)
.singleOrNull { isGoodSetMethod(it, getMethod) } .singleOrNull { isGoodSetMethod(it, getMethod) }
val propertyType = getMethod.returnType ?: return null val propertyType = getMethod.returnType!!
return MyPropertyDescriptor.create(ownerClass, getMethod.original, setMethod?.original, name, propertyType)
val descriptor = MyPropertyDescriptor.create(ownerClass, getMethod.original, setMethod?.original, name, propertyType)
return result(descriptor, possibleGetMethodNames, setMethodName);
} }
private fun isGoodGetMethod(descriptor: FunctionDescriptor): Boolean { private fun isGoodGetMethod(descriptor: FunctionDescriptor): Boolean {
@@ -131,12 +166,10 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImporti
} }
override fun getContributedSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> { override fun getContributedSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
//TODO: use location parameter!
var result: SmartList<PropertyDescriptor>? = null var result: SmartList<PropertyDescriptor>? = null
val processedTypes: MutableSet<TypeConstructor>? = if (receiverTypes.size() > 1) HashSet<TypeConstructor>() else null val processedTypes: MutableSet<TypeConstructor>? = if (receiverTypes.size() > 1) HashSet<TypeConstructor>() else null
for (type in receiverTypes) { for (type in receiverTypes) {
result = collectSyntheticPropertiesByName(result, type.constructor, name, processedTypes) result = collectSyntheticPropertiesByName(result, type.constructor, name, processedTypes, location)
} }
return when { return when {
result == null -> emptyList() result == null -> emptyList()
@@ -145,7 +178,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImporti
} }
} }
private fun collectSyntheticPropertiesByName(result: SmartList<PropertyDescriptor>?, type: TypeConstructor, name: Name, processedTypes: MutableSet<TypeConstructor>?): SmartList<PropertyDescriptor>? { private fun collectSyntheticPropertiesByName(result: SmartList<PropertyDescriptor>?, type: TypeConstructor, name: Name, processedTypes: MutableSet<TypeConstructor>?, location: LookupLocation): SmartList<PropertyDescriptor>? {
if (processedTypes != null && !processedTypes.add(type)) return result if (processedTypes != null && !processedTypes.add(type)) return result
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
@@ -153,10 +186,10 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImporti
val classifier = type.declarationDescriptor val classifier = type.declarationDescriptor
if (classifier is ClassDescriptor) { if (classifier is ClassDescriptor) {
result = result.add(syntheticPropertyInClass(Pair(classifier, name))) result = result.add(getSyntheticPropertyAndRecordLookups(classifier, name, location))
} }
else { else {
type.supertypes.forEach { result = collectSyntheticPropertiesByName(result, it.constructor, name, processedTypes) } type.supertypes.forEach { result = collectSyntheticPropertiesByName(result, it.constructor, name, processedTypes, location) }
} }
return result return result
@@ -177,7 +210,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImporti
for (descriptor in classifier.getUnsubstitutedMemberScope().getDescriptors(DescriptorKindFilter.FUNCTIONS)) { for (descriptor in classifier.getUnsubstitutedMemberScope().getDescriptors(DescriptorKindFilter.FUNCTIONS)) {
if (descriptor is FunctionDescriptor) { if (descriptor is FunctionDescriptor) {
val propertyName = SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(descriptor.getName()) ?: continue val propertyName = SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(descriptor.getName()) ?: continue
addIfNotNull(syntheticPropertyInClass(Pair(classifier, propertyName))) addIfNotNull(syntheticPropertyInClass(Pair(classifier, propertyName)).descriptor)
} }
} }
} }
@@ -196,7 +229,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImporti
//TODO: reuse code with generation? //TODO: reuse code with generation?
private fun possibleGetMethodNames(propertyName: Name): Sequence<Name> { private fun possibleGetMethodNames(propertyName: Name): Sequence<Name> {
val result = ArrayList<Name>(3) val result = ArrayList<Name>(POSSIBLE_GETTER_NAMES_CAPACITY)
val identifier = propertyName.identifier val identifier = propertyName.identifier
if (JvmAbi.startsWithIsPrefix(identifier)) { if (JvmAbi.startsWithIsPrefix(identifier)) {
@@ -228,6 +261,12 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : BaseImporti
p.println(javaClass.simpleName) p.println(javaClass.simpleName)
} }
private data class SyntheticPropertyHolder(val descriptor: PropertyDescriptor?, val lookedNames: List<Name>) {
companion object {
val EMPTY = SyntheticPropertyHolder(null, emptyList())
}
}
private class MyPropertyDescriptor( private class MyPropertyDescriptor(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
original: PropertyDescriptor?, original: PropertyDescriptor?,
@@ -36,5 +36,6 @@ public enum class NoLookupLocation : LookupLocation {
WHEN_GET_ALL_DESCRIPTORS, WHEN_GET_ALL_DESCRIPTORS,
WHEN_TYPING, WHEN_TYPING,
WHEN_GET_SUPER_MEMBERS, WHEN_GET_SUPER_MEMBERS,
FOR_NON_TRACKED_SCOPE FOR_NON_TRACKED_SCOPE,
FROM_SYNTHETIC_SCOPE
} }
@@ -25,6 +25,7 @@ import com.intellij.util.Processor
import org.jetbrains.kotlin.asJava.namedUnwrappedElement import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope
@@ -52,7 +53,7 @@ public class KotlinPropertyAccessorsReferenceSearcher() : QueryExecutorBase<PsiR
} }
val functionDescriptor = method.getJavaMethodDescriptor() ?: return null val functionDescriptor = method.getJavaMethodDescriptor() ?: return null
val syntheticExtensionsScope = JavaSyntheticPropertiesScope(LockBasedStorageManager()) val syntheticExtensionsScope = JavaSyntheticPropertiesScope(LockBasedStorageManager(), LookupTracker.DO_NOTHING)
val property = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(functionDescriptor, syntheticExtensionsScope) ?: return null val property = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(functionDescriptor, syntheticExtensionsScope) ?: return null
return property.getName().asString() return property.getName().asString()
} }
@@ -65,4 +65,10 @@ public class LookupTrackerTestGenerated extends AbstractLookupTrackerTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("syntheticProperties")
public void testSyntheticProperties() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/lookupTracker/syntheticProperties/");
doTest(fileName);
}
} }
@@ -18,7 +18,7 @@ import bar.*
/*c:foo.A*/foo() /*c:foo.A*/foo()
this./*c:foo.A*/a this./*c:foo.A*/a
this./*c:foo.A*/foo() this./*c:foo.A*/foo()
/*c:foo.A c:foo.A.Companion p:foo p:bar*/baz() /*c:foo.A c:foo.A.Companion p:foo p:bar c:foo.A(getBaz) c:foo.A(getBAZ)*/baz()
/*c:foo.A c:foo.A.Companion p:foo p:bar*/Companion./*c:foo.A.Companion*/a /*c:foo.A c:foo.A.Companion p:foo p:bar*/Companion./*c:foo.A.Companion*/a
/*c:foo.A c:foo.A.Companion p:foo p:bar*/O./*c:foo.A.O*/v = "OK" /*c:foo.A c:foo.A.Companion p:foo p:bar*/O./*c:foo.A.O*/v = "OK"
} }
@@ -6,13 +6,13 @@ package foo.bar
na /*c:foo.bar.A(equals)*/== a na /*c:foo.bar.A(equals)*/== a
na /*c:foo.bar.A(equals)*/== null na /*c:foo.bar.A(equals)*/== null
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/> b a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/> b
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/< b a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/< b
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/>= b a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/>= b
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/<= b a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/<= b
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/> c a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/> c
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/< c a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/< c
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/>= c a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/>= c
a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo)*/<= c a /*c:foo.bar.A(compareTo) p:foo.bar(compareTo) c:foo.bar.A(getCompareTo) c:foo.bar.A(getCOMPARETo)*/<= c
} }
@@ -20,11 +20,11 @@ import kotlin.reflect.KProperty
} }
/*p:foo.bar*/val x1 by /*p:foo.bar c:foo.bar.D1(getValue) p:foo.bar(getValue) c:foo.bar.D1(get) c:foo.bar.D1(propertyDelegated) p:foo.bar(propertyDelegated)*/D1() /*p:foo.bar*/val x1 by /*p:foo.bar c:foo.bar.D1(getValue) p:foo.bar(getValue) c:foo.bar.D1(getGetValue) c:foo.bar.D1(getGETValue) c:foo.bar.D1(get) c:foo.bar.D1(propertyDelegated) p:foo.bar(propertyDelegated) c:foo.bar.D1(getPropertyDelegated) c:foo.bar.D1(getPROPERTYDelegated)*/D1()
/*p:foo.bar*/var y1 by /*p:foo.bar c:foo.bar.D1(getValue) p:foo.bar(getValue) c:foo.bar.D1(get) c:foo.bar.D1(setValue) p:foo.bar(setValue) c:foo.bar.D1(set) p:foo.bar(set) c:foo.bar.D1(propertyDelegated) p:foo.bar(propertyDelegated)*/D1() /*p:foo.bar*/var y1 by /*p:foo.bar c:foo.bar.D1(getValue) p:foo.bar(getValue) c:foo.bar.D1(getGetValue) c:foo.bar.D1(getGETValue) c:foo.bar.D1(get) c:foo.bar.D1(setValue) p:foo.bar(setValue) c:foo.bar.D1(getSetValue) c:foo.bar.D1(getSETValue) c:foo.bar.D1(set) p:foo.bar(set) c:foo.bar.D1(propertyDelegated) p:foo.bar(propertyDelegated) c:foo.bar.D1(getPropertyDelegated) c:foo.bar.D1(getPROPERTYDelegated)*/D1()
/*p:foo.bar*/val x2 by /*p:foo.bar c:foo.bar.D2(getValue) p:foo.bar(getValue) c:foo.bar.D2(get) p:foo.bar(get) c:foo.bar.D2(propertyDelegated) p:foo.bar(propertyDelegated)*/D2() /*p:foo.bar*/val x2 by /*p:foo.bar c:foo.bar.D2(getValue) p:foo.bar(getValue) c:foo.bar.D2(getGetValue) c:foo.bar.D2(getGETValue) c:foo.bar.D2(get) p:foo.bar(get) c:foo.bar.D2(propertyDelegated) p:foo.bar(propertyDelegated)*/D2()
/*p:foo.bar*/var y2 by /*p:foo.bar c:foo.bar.D2(getValue) p:foo.bar(getValue) c:foo.bar.D2(get) p:foo.bar(get) c:foo.bar.D2(setValue) p:foo.bar(setValue) c:foo.bar.D2(set) c:foo.bar.D2(propertyDelegated) p:foo.bar(propertyDelegated)*/D2() /*p:foo.bar*/var y2 by /*p:foo.bar c:foo.bar.D2(getValue) p:foo.bar(getValue) c:foo.bar.D2(getGetValue) c:foo.bar.D2(getGETValue) c:foo.bar.D2(get) p:foo.bar(get) c:foo.bar.D2(setValue) p:foo.bar(setValue) c:foo.bar.D2(getSetValue) c:foo.bar.D2(getSETValue) c:foo.bar.D2(set) c:foo.bar.D2(propertyDelegated) p:foo.bar(propertyDelegated)*/D2()
/*p:foo.bar*/val x3 by /*p:foo.bar c:foo.bar.D3(getValue) p:foo.bar(getValue) c:foo.bar.D3(get) p:foo.bar(get) c:foo.bar.D3(propertyDelegated)*/D3() /*p:foo.bar*/val x3 by /*p:foo.bar c:foo.bar.D3(getValue) p:foo.bar(getValue) c:foo.bar.D3(getGetValue) c:foo.bar.D3(getGETValue) c:foo.bar.D3(get) p:foo.bar(get) c:foo.bar.D3(propertyDelegated)*/D3()
/*p:foo.bar*/var y3 by /*p:foo.bar c:foo.bar.D3(getValue) p:foo.bar(getValue) c:foo.bar.D3(get) p:foo.bar(get) c:foo.bar.D3(setValue) p:foo.bar(setValue) c:foo.bar.D3(set) c:foo.bar.D3(propertyDelegated)*/D3() /*p:foo.bar*/var y3 by /*p:foo.bar c:foo.bar.D3(getValue) p:foo.bar(getValue) c:foo.bar.D3(getGetValue) c:foo.bar.D3(getGETValue) c:foo.bar.D3(get) p:foo.bar(get) c:foo.bar.D3(setValue) p:foo.bar(setValue) c:foo.bar.D3(getSetValue) c:foo.bar.D3(getSETValue) c:foo.bar.D3(set) c:foo.bar.D3(propertyDelegated)*/D3()
@@ -3,22 +3,22 @@ package foo.bar
/*p:foo.bar*/fun testOperators(a: /*p:foo.bar*/A, b: /*p:foo.bar*/Int) { /*p:foo.bar*/fun testOperators(a: /*p:foo.bar*/A, b: /*p:foo.bar*/Int) {
var d = a var d = a
d/*c:foo.bar.A(inc) p:foo.bar(inc)*/++ d/*c:foo.bar.A(inc) p:foo.bar(inc) c:foo.bar.A(getInc) c:foo.bar.A(getINC)*/++
/*c:foo.bar.A(inc) p:foo.bar(inc)*/++d /*c:foo.bar.A(inc) p:foo.bar(inc) c:foo.bar.A(getInc) c:foo.bar.A(getINC)*/++d
d/*c:foo.bar.A(dec) p:foo.bar(dec)*/-- d/*c:foo.bar.A(dec) p:foo.bar(dec) c:foo.bar.A(getDec) c:foo.bar.A(getDEC)*/--
/*c:foo.bar.A(dec) p:foo.bar(dec)*/--d /*c:foo.bar.A(dec) p:foo.bar(dec) c:foo.bar.A(getDec) c:foo.bar.A(getDEC)*/--d
a /*c:foo.bar.A(plus) p:foo.bar(plus)*/+ b a /*c:foo.bar.A(plus) p:foo.bar(plus) c:foo.bar.A(getPlus) c:foo.bar.A(getPLUS)*/+ b
a /*c:foo.bar.A(minus) p:foo.bar(minus)*/- b a /*c:foo.bar.A(minus) p:foo.bar(minus) c:foo.bar.A(getMinus) c:foo.bar.A(getMINUS)*/- b
/*c:foo.bar.A(not) p:foo.bar(not)*/!a /*c:foo.bar.A(not) p:foo.bar(not) c:foo.bar.A(getNot) c:foo.bar.A(getNOT)*/!a
// for val // for val
a /*c:foo.bar.A(timesAssign) p:foo.bar(timesAssign)*/*= b a /*c:foo.bar.A(timesAssign) p:foo.bar(timesAssign) c:foo.bar.A(getTimesAssign) c:foo.bar.A(getTIMESAssign)*/*= b
a /*c:foo.bar.A(divAssign) p:foo.bar(divAssign)*//= b a /*c:foo.bar.A(divAssign) p:foo.bar(divAssign) c:foo.bar.A(getDivAssign) c:foo.bar.A(getDIVAssign)*//= b
// for var // for var
d /*c:foo.bar.A(plusAssign) p:foo.bar(plusAssign) c:foo.bar.A(plus) p:foo.bar(plus)*/+= b d /*c:foo.bar.A(plusAssign) p:foo.bar(plusAssign) c:foo.bar.A(getPlusAssign) c:foo.bar.A(getPLUSAssign) c:foo.bar.A(plus) p:foo.bar(plus) c:foo.bar.A(getPlus) c:foo.bar.A(getPLUS)*/+= b
d /*c:foo.bar.A(minusAssign) p:foo.bar(minusAssign) c:foo.bar.A(minus) p:foo.bar(minus)*/-= b d /*c:foo.bar.A(minusAssign) p:foo.bar(minusAssign) c:foo.bar.A(getMinusAssign) c:foo.bar.A(getMINUSAssign) c:foo.bar.A(minus) p:foo.bar(minus) c:foo.bar.A(getMinus) c:foo.bar.A(getMINUS)*/-= b
d /*c:foo.bar.A(timesAssign) p:foo.bar(timesAssign) c:foo.bar.A(times) p:foo.bar(times)*/*= b d /*c:foo.bar.A(timesAssign) p:foo.bar(timesAssign) c:foo.bar.A(getTimesAssign) c:foo.bar.A(getTIMESAssign) c:foo.bar.A(times) p:foo.bar(times) c:foo.bar.A(getTimes) c:foo.bar.A(getTIMES)*/*= b
d /*c:foo.bar.A(divAssign) p:foo.bar(divAssign) c:foo.bar.A(div) p:foo.bar(div)*//= b d /*c:foo.bar.A(divAssign) p:foo.bar(divAssign) c:foo.bar.A(getDivAssign) c:foo.bar.A(getDIVAssign) c:foo.bar.A(div) p:foo.bar(div) c:foo.bar.A(getDiv) c:foo.bar.A(getDIV)*//= b
} }
@@ -1,16 +1,16 @@
package foo.bar package foo.bar
/*p:foo.bar*/fun testOther(a: /*p:foo.bar*/A, b: /*p:foo.bar*/Int, c: /*p:foo.bar*/Any, na: /*p:foo.bar*/A?) { /*p:foo.bar*/fun testOther(a: /*p:foo.bar*/A, b: /*p:foo.bar*/Int, c: /*p:foo.bar*/Any, na: /*p:foo.bar*/A?) {
/*c:foo.bar.A(set) p:foo.bar(set)*/a[1] = /*c:foo.bar.A(get) p:foo.bar(get)*/a[2] /*c:foo.bar.A(set) p:foo.bar(set) c:foo.bar.A(getSet) c:foo.bar.A(getSET)*/a[1] = /*c:foo.bar.A(get) p:foo.bar(get) c:foo.bar.A(getGet) c:foo.bar.A(getGET)*/a[2]
b /*c:foo.bar.A(contains) p:foo.bar(contains)*/in a b /*c:foo.bar.A(contains) p:foo.bar(contains) c:foo.bar.A(getContains) c:foo.bar.A(getCONTAINS)*/in a
"s" /*c:foo.bar.A(contains) p:foo.bar(contains)*/!in a "s" /*c:foo.bar.A(contains) p:foo.bar(contains) c:foo.bar.A(getContains) c:foo.bar.A(getCONTAINS)*/!in a
/*c:foo.bar.A(invoke) p:foo.bar(invoke)*/a() /*c:foo.bar.A(invoke) p:foo.bar(invoke)*/a()
/*c:foo.bar.A(invoke) p:foo.bar(invoke)*/a(1) /*c:foo.bar.A(invoke) p:foo.bar(invoke)*/a(1)
val (/*c:foo.bar.A(component1) p:foo.bar(component1)*/h, /*c:foo.bar.A(component2) p:foo.bar(component2)*/t) = a; val (/*c:foo.bar.A(component1) p:foo.bar(component1) c:foo.bar.A(getComponent1)*/h, /*c:foo.bar.A(component2) p:foo.bar(component2) c:foo.bar.A(getComponent2)*/t) = a;
for ((/*c:foo.bar.A(component1) p:foo.bar(component1)*/f, /*c:foo.bar.A(component2) p:foo.bar(component2)*/s) in /*c:foo.bar.A(iterator) c:foo.bar.A(hasNext) p:foo.bar(hasNext) c:foo.bar.A(next)*/a); for ((/*c:foo.bar.A(component1) p:foo.bar(component1) c:foo.bar.A(getComponent1)*/f, /*c:foo.bar.A(component2) p:foo.bar(component2) c:foo.bar.A(getComponent2)*/s) in /*c:foo.bar.A(iterator) c:foo.bar.A(hasNext) p:foo.bar(hasNext) c:foo.bar.A(next)*/a);
for ((/*c:foo.bar.A(component1) p:foo.bar(component1)*/f, /*c:foo.bar.A(component2) p:foo.bar(component2)*/s) in /*c:foo.bar.A(iterator) p:foo.bar(iterator) c:foo.bar.A(hasNext) p:foo.bar(hasNext) c:foo.bar.A(next)*/na); for ((/*c:foo.bar.A(component1) p:foo.bar(component1) c:foo.bar.A(getComponent1)*/f, /*c:foo.bar.A(component2) p:foo.bar(component2) c:foo.bar.A(getComponent2)*/s) in /*c:foo.bar.A(iterator) p:foo.bar(iterator) c:foo.bar.A(hasNext) p:foo.bar(hasNext) c:foo.bar.A(next)*/na);
} }
@@ -12,6 +12,6 @@ import baz./*p:baz*/C
} }
/*p:foo*/fun /*p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:foo*/Array</*p:foo p:bar*/B>, e: /*p:foo*/MyEnum, c: /**???*/C): /*p:foo*/MyInterface { /*p:foo*/fun /*p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:foo*/Array</*p:foo p:bar*/B>, e: /*p:foo*/MyEnum, c: /**???*/C): /*p:foo*/MyInterface {
/*c:foo.MyClass p:foo p:bar*/b /*c:foo.MyClass p:foo p:bar c:foo.MyClass(getB)*/b
return /*c:foo.MyClass p:foo p:bar*/MyClass() return /*c:foo.MyClass p:foo p:bar*/MyClass()
} }
@@ -0,0 +1,26 @@
public class JavaClass {
public int getFoo() {
return 1;
}
public String getBar() {
return "";
}
public void setBar(String s) {
}
public int getBazBaz() {
return 1;
}
public int getBAZBaz() {
return 1;
}
public void setBazBaz(int i) {
}
public void setBoo(int i) {
}
}
@@ -0,0 +1,8 @@
package foo
import /*p:<root>*/JavaClass
/*p:foo*/class KotlinClass : JavaClass() {
override fun getFoo() = 2
fun setFoo(i: /*c:foo.KotlinClass p:foo*/Int) {}
}
@@ -0,0 +1,13 @@
Compiling files:
src/KotlinClass.kt
src/usages.kt
End of files
COMPILATION FAILED
Unresolved reference: setFoo
Val cannot be reassigned
Unresolved reference: bazBaz
Unresolved reference: bazBaz
Unresolved reference: boo
Unresolved reference: bazBaz
Unresolved reference: bazBaz
Unresolved reference: boo
@@ -0,0 +1,30 @@
package foo.bar
import /*p:<root>*/JavaClass
import foo./*p:foo*/KotlinClass
/*p:foo.bar*/fun test() {
val j = /*p:foo.bar*/JavaClass()
val k = /*p:foo.bar*/KotlinClass()
j.getFoo()
j./*p:foo.bar c:JavaClass(getSetFoo) c:JavaClass(getSETFoo)*/setFoo(2)
j./*p:foo.bar c:JavaClass(getFoo) c:JavaClass(getFOO) c:JavaClass(setFoo)*/foo = 2
j./*p:foo.bar c:JavaClass(getFoo) c:JavaClass(getFOO) c:JavaClass(setFoo)*/foo
j./*p:foo.bar c:JavaClass(getBar) c:JavaClass(getBAR) c:JavaClass(setBar)*/bar
j./*p:foo.bar c:JavaClass(getBar) c:JavaClass(getBAR) c:JavaClass(setBar)*/bar = ""
j./*p:foo.bar c:JavaClass(getBazBaz) c:JavaClass(getBAZBaz)*/bazBaz
j./*p:foo.bar c:JavaClass(getBazBaz) c:JavaClass(getBAZBaz)*/bazBaz = ""
j.setBoo(2)
j./*p:foo.bar c:JavaClass(getBoo) c:JavaClass(getBOO)*/boo = 2
k./*c:foo.KotlinClass*/getFoo()
k./*c:foo.KotlinClass*/setFoo(2)
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getFoo) c:foo.KotlinClass(getFOO) c:foo.KotlinClass(setFoo)*/foo = 2
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getFoo) c:foo.KotlinClass(getFOO) c:foo.KotlinClass(setFoo)*/foo
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getBar) c:foo.KotlinClass(getBAR) c:foo.KotlinClass(setBar)*/bar
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getBar) c:foo.KotlinClass(getBAR) c:foo.KotlinClass(setBar)*/bar = ""
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getBazBaz) c:foo.KotlinClass(getBAZBaz)*/bazBaz
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getBazBaz) c:foo.KotlinClass(getBAZBaz)*/bazBaz = ""
k./*c:foo.KotlinClass*/setBoo(2)
k./*c:foo.KotlinClass p:foo.bar c:foo.KotlinClass(getBoo) c:foo.KotlinClass(getBOO)*/boo = 2
}