Compare commits

...

6 Commits

Author SHA1 Message Date
Nikolay Krasko
4b8f942c85 Minor: remove outdated comment 2016-06-22 18:16:18 +03:00
Nikolay Krasko
c0b778e9b8 -- update bytecode version 2016-06-22 18:15:29 +03:00
Nikolay Krasko
52f90d88ab -- update tests results 2016-06-22 18:15:28 +03:00
Nikolay Krasko
e00997c2fe Change meaning of hasDefault property in PropertyAccessDescriptor 2016-06-22 18:13:53 +03:00
Nikolay Krasko
99e43c53e7 -- tests for isDeafult usages 2016-06-22 18:13:53 +03:00
Nikolay Krasko
ef40fd5d84 Don't activate building light classes if only Kotlin usages are requested 2016-06-22 18:13:53 +03:00
31 changed files with 248 additions and 47 deletions

View File

@@ -54,13 +54,12 @@ class JvmFieldApplicabilityChecker : SimpleDeclarationChecker {
val annotation = descriptor.findJvmFieldAnnotation() ?: return
val problem = when {
// First two cases just prevent duplication of WRONG_ANNOTATION_TARGET
descriptor !is PropertyDescriptor -> return
declaration is KtProperty && declaration.hasDelegate() -> DELEGATE
!descriptor.hasBackingField(bindingContext) -> return
descriptor.isOverridable -> NOT_FINAL
Visibilities.isPrivate(descriptor.visibility) -> PRIVATE
descriptor.hasCustomAccessor() -> CUSTOM_ACCESSOR
declaration is KtProperty && hasExplicitAccessors(declaration) -> CUSTOM_ACCESSOR
descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES
descriptor.isLateInit -> LATEINIT
descriptor.isConst -> CONST
@@ -74,8 +73,8 @@ class JvmFieldApplicabilityChecker : SimpleDeclarationChecker {
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_FIELD.on(annotationEntry, problem.errorMessage))
}
private fun PropertyDescriptor.hasCustomAccessor()
= !(getter?.isDefault ?: true) || !(setter?.isDefault ?: true)
private fun hasExplicitAccessors(property: KtProperty)
= property.getter != null || property.setter != null
private fun PropertyDescriptor.hasBackingField(bindingContext: BindingContext)
= bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false

View File

@@ -60,7 +60,7 @@ object ConstModifierChecker : SimpleDeclarationChecker {
return Errors.CONST_VAL_WITH_DELEGATE.on(declaration.delegate!!)
}
if (descriptor is PropertyDescriptor && !descriptor.getter!!.isDefault) {
if (descriptor is PropertyDescriptor && declaration.getter != null) {
return Errors.CONST_VAL_WITH_GETTER.on(declaration.getter!!)
}

View File

@@ -924,7 +924,7 @@ public class DescriptorResolver {
propertyDescriptor, annotations,
resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
/* isDefault = */ false, setter.hasModifier(EXTERNAL_KEYWORD),
/* isDefault = */ !setter.hasBody(), setter.hasModifier(EXTERNAL_KEYWORD),
CallableMemberDescriptor.Kind.DECLARATION, null, KotlinSourceElementKt.toSourceElement(setter)
);
KtTypeReference returnTypeReference = setter.getReturnTypeReference();
@@ -1004,7 +1004,7 @@ public class DescriptorResolver {
propertyDescriptor, getterAnnotations,
resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
/* isDefault = */ false, getter.hasModifier(EXTERNAL_KEYWORD),
/* isDefault = */ !getter.hasBody(), getter.hasModifier(EXTERNAL_KEYWORD),
CallableMemberDescriptor.Kind.DECLARATION, null, KotlinSourceElementKt.toSourceElement(getter)
);
KotlinType returnType =

View File

@@ -107,17 +107,21 @@ public class OverrideResolver {
if (descriptor.getKind() == FAKE_OVERRIDE || descriptor.getKind() == DELEGATION) {
reportOn = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class);
}
else if (descriptor instanceof PropertyAccessorDescriptor && ((PropertyAccessorDescriptor) descriptor).isDefault()) {
reportOn = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
}
else {
reportOn = descriptor;
}
//noinspection ConstantConditions
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(reportOn);
if (element == null && descriptor instanceof PropertyAccessorDescriptor) {
reportOn = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
element = DescriptorToSourceUtils.descriptorToDeclaration(reportOn);
}
if (element instanceof KtDeclaration) {
trace.report(CANNOT_INFER_VISIBILITY.on((KtDeclaration) element, descriptor));
}
return Unit.INSTANCE;
}
};

View File

@@ -141,13 +141,15 @@ class DescriptorSerializer private constructor(
val hasAnnotations = descriptor.annotations.getAllAnnotations().isNotEmpty()
val propertyFlags = Flags.getAccessorFlags(hasAnnotations, descriptor.visibility, descriptor.modality, false, false)
val propertyAccessorsFlags = Flags.getAccessorFlags(
hasAnnotations, descriptor.visibility, descriptor.modality, /*isNotDefault*/false, /*isExternal*/false)
val getter = descriptor.getter
if (getter != null) {
hasGetter = true
val accessorFlags = getAccessorFlags(getter)
if (accessorFlags != propertyFlags) {
if (accessorFlags != propertyAccessorsFlags) {
builder.getterFlags = accessorFlags
}
}
@@ -156,7 +158,8 @@ class DescriptorSerializer private constructor(
if (setter != null) {
hasSetter = true
val accessorFlags = getAccessorFlags(setter)
if (accessorFlags != propertyFlags) {
if (accessorFlags != propertyAccessorsFlags) {
builder.setterFlags = accessorFlags
}

View File

@@ -14,7 +14,13 @@ class My {
field = value + if (w == "") 1 else 0
}
var m: Int = 2
set
init {
<!DEBUG_INFO_LEAKING_THIS!>x<!> = 3
m = 6
// Writing properties using setters is dangerous
<!DEBUG_INFO_LEAKING_THIS!>y<!> = 4
this.<!DEBUG_INFO_LEAKING_THIS!>z<!> = 5

View File

@@ -2,6 +2,7 @@ package
public final class My {
public constructor My()
public final var m: kotlin.Int
public final val w: kotlin.String = "6"
public final var x: kotlin.Int
public final var y: kotlin.Int

View File

@@ -8,7 +8,16 @@ class My(var x: String) {
val z: String
var d: String = ""
get
set
val z1: String
init {
d = "d"
if (d != "") z1 = this.d else z1 = d
// Dangerous: setter!
<!DEBUG_INFO_LEAKING_THIS!>y<!> = "x"
// Dangerous: getter!

View File

@@ -2,9 +2,11 @@ package
public final class My {
public constructor My(/*0*/ x: kotlin.String)
public final var d: kotlin.String
public final var x: kotlin.String
public final var y: kotlin.String
public final val z: kotlin.String
public final val z1: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String

View File

@@ -44,6 +44,9 @@ const val delegated: Int <!CONST_VAL_WITH_DELEGATE!>by Delegate()<!>
const val withGetter: Int
<!CONST_VAL_WITH_GETTER!>get() = 13<!>
const val withExplicitDefaultGetter: Int = 1
<!CONST_VAL_WITH_GETTER!>get<!>
fun foo(): Int {
<!WRONG_MODIFIER_TARGET!>const<!> val local: Int = 14
return 15

View File

@@ -11,6 +11,7 @@ private val privateTopLevel: kotlin.Int = 3
public const var topLeveLVar: kotlin.Int
public const val topLevel: kotlin.Int = 0
public const val topLevelInferred: kotlin.Int = 1
public const val withExplicitDefaultGetter: kotlin.Int = 1
public const val withGetter: kotlin.Int
public fun foo(): kotlin.Int

View File

@@ -0,0 +1,11 @@
class ExplicitAccessorForAnnotation {
val tt: String? = "good"
get
fun foo(): String {
if (tt is String) {
return <!DEBUG_INFO_SMARTCAST!>tt<!>
}
return ""
}
}

View File

@@ -4,6 +4,8 @@ fun foo() {
<!WRONG_ANNOTATION_TARGET!>@kotlin.jvm.JvmField<!> val x = "A"
}
annotation class DemoAnnotation
<!WRONG_ANNOTATION_TARGET!>@JvmField<!>
abstract class C : I{
@@ -23,6 +25,22 @@ abstract class C : I{
val customGetter: String = ""
get() = field
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
val explicitDefaultGetter: String = ""
get
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
var explicitDefaultSetter: String = ""
set
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
val explicitDefaultAnnotatedGetter: String = ""
@DemoAnnotation get
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
var explicitDefaultAnnotatedSetter: String = ""
@DemoAnnotation set
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
var customSetter: String = ""
set(s) {

View File

@@ -14,6 +14,10 @@ package
@kotlin.jvm.JvmField() public abstract val c: kotlin.Int
@kotlin.jvm.JvmField() public final val customGetter: kotlin.String = ""
@kotlin.jvm.JvmField() public final var customSetter: kotlin.String
@kotlin.jvm.JvmField() public final val explicitDefaultAnnotatedGetter: kotlin.String = ""
@kotlin.jvm.JvmField() public final var explicitDefaultAnnotatedSetter: kotlin.String
@kotlin.jvm.JvmField() public final val explicitDefaultGetter: kotlin.String = ""
@kotlin.jvm.JvmField() public final var explicitDefaultSetter: kotlin.String
@kotlin.jvm.JvmField() public final val noBackingField: kotlin.String
@kotlin.jvm.JvmField() private final val private: kotlin.Int = 3
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -22,6 +26,13 @@ package
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class DemoAnnotation : kotlin.Annotation {
public constructor DemoAnnotation()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class G {
public constructor G()
@kotlin.jvm.JvmField() public final lateinit var lateInit: kotlin.String

View File

@@ -16890,6 +16890,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("explicitDefaultGetter.kt")
public void testExplicitDefaultGetter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/explicitDefaultGetter.kt");
doTest(fileName);
}
@TestMetadata("extensionSafeCall.kt")
public void testExtensionSafeCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/extensionSafeCall.kt");

View File

@@ -27,7 +27,7 @@ class JvmBytecodeBinaryVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
companion object {
@JvmField
val INSTANCE = JvmBytecodeBinaryVersion(1, 0, 1)
val INSTANCE = JvmBytecodeBinaryVersion(1, 1, 0)
@JvmField
val INVALID_VERSION = JvmBytecodeBinaryVersion()

View File

@@ -66,23 +66,20 @@ class MemberDeserializer(private val c: DeserializationContext) {
)
val getter = if (hasGetter) {
val getterFlags = proto.getterFlags
val getterFlags = if (proto.hasGetterFlags()) proto.getterFlags else proto.flags
val isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags)
val isExternal = proto.hasGetterFlags() && Flags.IS_EXTERNAL_ACCESSOR.get(getterFlags)
val getter = if (isNotDefault) {
PropertyGetterDescriptorImpl(
property,
getAnnotations(proto, getterFlags, AnnotatedCallableKind.PROPERTY_GETTER),
Deserialization.modality(Flags.MODALITY.get(getterFlags)),
Deserialization.visibility(Flags.VISIBILITY.get(getterFlags)),
/* isDefault = */ !isNotDefault,
/* isExternal = */ isExternal,
property.kind, null, SourceElement.NO_SOURCE
)
}
else {
DescriptorFactory.createDefaultGetter(property, Annotations.EMPTY)
}
val getter = PropertyGetterDescriptorImpl(
property,
getAnnotations(proto, getterFlags, AnnotatedCallableKind.PROPERTY_GETTER),
Deserialization.modality(Flags.MODALITY.get(getterFlags)),
Deserialization.visibility(Flags.VISIBILITY.get(getterFlags)),
/* isDefault = */ !isNotDefault,
/* isExternal = */ isExternal,
property.kind, null, SourceElement.NO_SOURCE
)
getter.initialize(property.returnType)
getter
}
@@ -91,29 +88,34 @@ class MemberDeserializer(private val c: DeserializationContext) {
}
val setter = if (Flags.HAS_SETTER.get(flags)) {
val setterFlags = proto.setterFlags
val setterFlags = if (proto.hasSetterFlags()) proto.setterFlags else proto.flags
val isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags)
val isExternal = proto.hasSetterFlags() && Flags.IS_EXTERNAL_ACCESSOR.get(setterFlags)
val setter = PropertySetterDescriptorImpl(
property,
getAnnotations(proto, setterFlags, AnnotatedCallableKind.PROPERTY_SETTER),
Deserialization.modality(Flags.MODALITY.get(setterFlags)),
Deserialization.visibility(Flags.VISIBILITY.get(setterFlags)),
/* isDefault = */ !isNotDefault,
/* isExternal = */ isExternal,
property.kind, null, SourceElement.NO_SOURCE
)
if (isNotDefault) {
val setter = PropertySetterDescriptorImpl(
property,
getAnnotations(proto, setterFlags, AnnotatedCallableKind.PROPERTY_SETTER),
Deserialization.modality(Flags.MODALITY.get(setterFlags)),
Deserialization.visibility(Flags.VISIBILITY.get(setterFlags)),
/* isDefault = */ !isNotDefault,
/* isExternal = */ isExternal,
property.kind, null, SourceElement.NO_SOURCE
)
val setterLocal = local.childContext(setter, listOf())
val valueParameters = setterLocal.memberDeserializer.valueParameters(
listOf(proto.setterValueParameter), proto, AnnotatedCallableKind.PROPERTY_SETTER
)
setter.initialize(valueParameters.single())
setter
}
else {
DescriptorFactory.createDefaultSetter(property, Annotations.EMPTY)
setter.initializeDefault()
}
setter
}
else {
null

View File

@@ -271,11 +271,6 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
}
}
private fun isOnlyKotlinSearch(searchScope: SearchScope) =
searchScope is LocalSearchScope && runReadAction {
searchScope.scope.all { it.containingFile.fileType == KotlinFileType.INSTANCE }
}
private fun searchNamedElement(queryParameters: ReferencesSearch.SearchParameters,
element: PsiNamedElement?,
name: String? = element?.name) {
@@ -293,3 +288,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
}
}
}
fun isOnlyKotlinSearch(searchScope: SearchScope) =
searchScope is LocalSearchScope && runReadAction {
searchScope.scope.all { it.containingFile.fileType == KotlinFileType.INSTANCE }
}

View File

@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchReques
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
import org.jetbrains.kotlin.idea.search.ideaExtensions.isOnlyKotlinSearch
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.idea.search.usagesSearch.isConstructorUsage
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
@@ -111,7 +112,7 @@ class KotlinFindClassUsagesHandler(
}
}
if (kotlinOptions.searchConstructorUsages) {
if (kotlinOptions.searchConstructorUsages && !isOnlyKotlinSearch(options.searchScope)) {
val result = runReadAction {
val constructors = classOrObject.toLightClass()?.constructors ?: PsiMethod.EMPTY_ARRAY
constructors.filterIsInstance<KtLightMethod>().all { constructor ->

View File

@@ -266,3 +266,15 @@ fun inForLoop(x: Any?) {
}
for (i in <error descr="[ITERATOR_MISSING] For-loop range must have an 'iterator()' method">x</error>) {}
}
class ExplicitAccessorForAnnotation {
val tt: String? = "good"
<info descr="null">get</info>
fun foo(): String {
if (tt is String) {
return <info descr="Smart cast to kotlin.String">tt</info>
}
return ""
}
}

View File

@@ -0,0 +1,8 @@
class Test {
var serial: String = ""
get
set
var name: String = ""
get
<caret>
}

View File

@@ -0,0 +1,26 @@
class Test {
var serial: String = ""
get
set
var name: String = ""
get
override fun equals(other: Any?): Boolean{
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Test
if (serial != other.serial) return false
if (name != other.name) return false
return true
}
override fun hashCode(): Int{
var result = serial.hashCode()
result = 31 * result + name.hashCode()
return result
}
}

View File

@@ -0,0 +1,8 @@
class Test {
var serial: String = ""
get
set
var name: String = ""
get
<caret>
}

View File

@@ -0,0 +1,12 @@
class Test {
var serial: String = ""
get
set
var name: String = ""
get
override fun toString(): String{
return "Test(serial='$serial', name='$name')"
}
}

View File

@@ -0,0 +1,8 @@
LineBreakpoint created at privatePropertyWithExplicitDefaultGetter.kt:7
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! privatePropertyWithExplicitDefaultGetter.PrivatePropertyWithExplicitDefaultGetterKt
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
privatePropertyWithExplicitDefaultGetter.kt:7
Compile bytecode for base.a
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0

View File

@@ -0,0 +1,18 @@
package privatePropertyWithExplicitDefaultGetter
fun main(args: Array<String>) {
val base = Some()
//Breakpoint!
args.size
}
annotation class Small
class Some {
private val a: Int = 1
@Small get
}
// EXPRESSION: base.a
// RESULT: 1: I

View File

@@ -0,0 +1,8 @@
open class <info descr="null">Test</info>
fun foo() {
val t = <info descr="null">~Test</info>()
val some = ::<info descr="null">Test</info>
val other = object : <info descr="null">Test</info>() {}
val s: <info descr="null">Test</info>? = null
}

View File

@@ -65,6 +65,12 @@ public class GenerateHashCodeAndEqualsActionTestGenerated extends AbstractGenera
doTest(fileName);
}
@TestMetadata("explicitDefaultAccessors.kt")
public void testExplicitDefaultAccessors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/explicitDefaultAccessors.kt");
doTest(fileName);
}
@TestMetadata("genericClass.kt")
public void testGenericClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/genericClass.kt");

View File

@@ -139,6 +139,12 @@ public class GenerateToStringActionTestGenerated extends AbstractGenerateToStrin
doTest(fileName);
}
@TestMetadata("explicitDefaultAccessors.kt")
public void testExplicitDefaultAccessors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/toString/singleTemplate/explicitDefaultAccessors.kt");
doTest(fileName);
}
@TestMetadata("multipleVars.kt")
public void testMultipleVars() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/toString/singleTemplate/multipleVars.kt");

View File

@@ -313,6 +313,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
doSingleBreakpointTest(fileName);
}
@TestMetadata("privatePropertyWithExplicitDefaultGetter.kt")
public void testPrivatePropertyWithExplicitDefaultGetter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/privatePropertyWithExplicitDefaultGetter.kt");
doSingleBreakpointTest(fileName);
}
@TestMetadata("protectedMember.kt")
public void testProtectedMember() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/protectedMember.kt");

View File

@@ -35,6 +35,12 @@ public class UsageHighlightingTestGenerated extends AbstractUsageHighlightingTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/usageHighlighter"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("constructorsAndClasses.kt")
public void testConstructorsAndClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/usageHighlighter/constructorsAndClasses.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt")
public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/usageHighlighter/localVal.kt");