Treat nested class of header class as header
Note that the quick fix to implement header class works incorrectly when that class has nested classes at the moment; this should be fixed separately #KT-15494 Fixed #KT-18573 Fixed
This commit is contained in:
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
|
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier;
|
import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker;
|
|
||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Incompatible;
|
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Incompatible;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData;
|
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo;
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo;
|
||||||
@@ -568,7 +567,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE);
|
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE);
|
||||||
|
|
||||||
DiagnosticFactory2<KtDeclaration, ClassDescriptor,
|
DiagnosticFactory2<KtDeclaration, ClassDescriptor,
|
||||||
List<Pair<CallableMemberDescriptor, Map<Incompatible, Collection<CallableMemberDescriptor>>>>> HEADER_CLASS_MEMBERS_ARE_NOT_IMPLEMENTED =
|
List<Pair<MemberDescriptor, Map<Incompatible, Collection<MemberDescriptor>>>>> HEADER_CLASS_MEMBERS_ARE_NOT_IMPLEMENTED =
|
||||||
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE);
|
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE);
|
||||||
DiagnosticFactory0<KtDeclaration> IMPL_MISSING = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
DiagnosticFactory0<KtDeclaration> IMPL_MISSING = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.diagnostics.rendering
|
package org.jetbrains.kotlin.diagnostics.rendering
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Incompatible
|
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Incompatible
|
||||||
@@ -44,9 +43,9 @@ class PlatformIncompatibilityDiagnosticRenderer(
|
|||||||
|
|
||||||
class IncompatibleHeaderImplClassScopesRenderer(
|
class IncompatibleHeaderImplClassScopesRenderer(
|
||||||
private val mode: MultiplatformDiagnosticRenderingMode
|
private val mode: MultiplatformDiagnosticRenderingMode
|
||||||
) : DiagnosticParameterRenderer<List<Pair<CallableMemberDescriptor, Map<Incompatible, Collection<CallableMemberDescriptor>>>>> {
|
) : DiagnosticParameterRenderer<List<Pair<MemberDescriptor, Map<Incompatible, Collection<MemberDescriptor>>>>> {
|
||||||
override fun render(
|
override fun render(
|
||||||
obj: List<Pair<CallableMemberDescriptor, Map<Incompatible, Collection<CallableMemberDescriptor>>>>,
|
obj: List<Pair<MemberDescriptor, Map<Incompatible, Collection<MemberDescriptor>>>>,
|
||||||
renderingContext: RenderingContext
|
renderingContext: RenderingContext
|
||||||
): String {
|
): String {
|
||||||
if (obj.isEmpty()) return ""
|
if (obj.isEmpty()) return ""
|
||||||
@@ -110,7 +109,7 @@ private fun StringBuilder.renderIncompatibilityInformation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.renderIncompatibleClassScopes(
|
private fun StringBuilder.renderIncompatibleClassScopes(
|
||||||
unimplemented: List<Pair<CallableMemberDescriptor, Map<Incompatible, Collection<CallableMemberDescriptor>>>>,
|
unimplemented: List<Pair<MemberDescriptor, Map<Incompatible, Collection<MemberDescriptor>>>>,
|
||||||
indent: String,
|
indent: String,
|
||||||
context: RenderingContext,
|
context: RenderingContext,
|
||||||
mode: MultiplatformDiagnosticRenderingMode
|
mode: MultiplatformDiagnosticRenderingMode
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
|
|||||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension;
|
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension;
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker;
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.PublishedApiUsageChecker;
|
import org.jetbrains.kotlin.resolve.checkers.PublishedApiUsageChecker;
|
||||||
@@ -35,8 +36,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.NESTED_CLASS_NOT_ALLOWED;
|
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.NESTED_OBJECT_NOT_ALLOWED;
|
|
||||||
import static org.jetbrains.kotlin.lexer.KtTokens.*;
|
import static org.jetbrains.kotlin.lexer.KtTokens.*;
|
||||||
|
|
||||||
public class ModifiersChecker {
|
public class ModifiersChecker {
|
||||||
@@ -160,6 +160,7 @@ public class ModifiersChecker {
|
|||||||
checkObjectInsideInnerClass(modifierListOwner, descriptor);
|
checkObjectInsideInnerClass(modifierListOwner, descriptor);
|
||||||
checkTypeParametersModifiers(modifierListOwner);
|
checkTypeParametersModifiers(modifierListOwner);
|
||||||
checkModifierListCommon(modifierListOwner, descriptor);
|
checkModifierListCommon(modifierListOwner, descriptor);
|
||||||
|
checkIllegalHeader(modifierListOwner, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkObjectInsideInnerClass(@NotNull KtDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
|
private void checkObjectInsideInnerClass(@NotNull KtDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
|
||||||
@@ -195,6 +196,16 @@ public class ModifiersChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkIllegalHeader(@NotNull KtModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
||||||
|
// Most cases are already handled by ModifierCheckerCore, only check nested classes here
|
||||||
|
KtModifierList modifierList = modifierListOwner.getModifierList();
|
||||||
|
PsiElement keyword = modifierList != null ? modifierList.getModifier(HEADER_KEYWORD) : null;
|
||||||
|
if (keyword != null &&
|
||||||
|
descriptor instanceof ClassDescriptor && descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
|
trace.report(WRONG_MODIFIER_TARGET.on(keyword, KtTokens.HEADER_KEYWORD, "nested class"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkNestedClassAllowed(@NotNull KtModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
private void checkNestedClassAllowed(@NotNull KtModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
||||||
if (modifierListOwner.hasModifier(INNER_KEYWORD)) return;
|
if (modifierListOwner.hasModifier(INNER_KEYWORD)) return;
|
||||||
if (modifierListOwner instanceof KtClass && !(modifierListOwner instanceof KtEnumEntry)) {
|
if (modifierListOwner instanceof KtClass && !(modifierListOwner instanceof KtEnumEntry)) {
|
||||||
|
|||||||
+34
-22
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Compatible
|
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Compatible
|
||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Incompatible
|
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker.Compatibility.Incompatible
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
@@ -64,9 +63,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
|
|
||||||
val checkImpl = !languageVersionSettings.getFlag(AnalysisFlag.multiPlatformDoNotCheckImpl)
|
val checkImpl = !languageVersionSettings.getFlag(AnalysisFlag.multiPlatformDoNotCheckImpl)
|
||||||
if (descriptor.isHeader) {
|
if (descriptor.isHeader) {
|
||||||
if (declaration.hasModifier(KtTokens.HEADER_KEYWORD)) {
|
checkHeaderDeclarationHasImplementation(declaration, descriptor, diagnosticHolder, descriptor.module, checkImpl)
|
||||||
checkHeaderDeclarationHasImplementation(declaration, descriptor, diagnosticHolder, descriptor.module, checkImpl)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checkImplementationHasHeaderDeclaration(declaration, descriptor, diagnosticHolder, checkImpl)
|
checkImplementationHasHeaderDeclaration(declaration, descriptor, diagnosticHolder, checkImpl)
|
||||||
@@ -81,7 +78,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
checkImpl: Boolean
|
checkImpl: Boolean
|
||||||
) {
|
) {
|
||||||
// Only look for implementations of top level members; class members will be handled as a part of that header class
|
// Only look for implementations of top level members; class members will be handled as a part of that header class
|
||||||
if (descriptor is CallableMemberDescriptor && descriptor.containingDeclaration !is PackageFragmentDescriptor) return
|
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) return
|
||||||
|
|
||||||
val compatibility = findImplForHeader(descriptor, platformModule, checkImpl) ?: return
|
val compatibility = findImplForHeader(descriptor, platformModule, checkImpl) ?: return
|
||||||
|
|
||||||
@@ -180,12 +177,11 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
|
|
||||||
// This should ideally be handled by CallableMemberDescriptor.Kind, but default constructors have kind DECLARATION and non-empty source.
|
// This should ideally be handled by CallableMemberDescriptor.Kind, but default constructors have kind DECLARATION and non-empty source.
|
||||||
// Their source is the containing KtClass instance though, as opposed to explicit constructors, whose source is KtConstructor
|
// Their source is the containing KtClass instance though, as opposed to explicit constructors, whose source is KtConstructor
|
||||||
private fun CallableMemberDescriptor.isExplicitImplDeclaration(): Boolean =
|
private fun MemberDescriptor.isExplicitImplDeclaration(): Boolean =
|
||||||
if (this is ConstructorDescriptor) {
|
when (this) {
|
||||||
DescriptorToSourceUtils.getSourceFromDescriptor(this) is KtConstructor<*>
|
is ConstructorDescriptor -> DescriptorToSourceUtils.getSourceFromDescriptor(this) is KtConstructor<*>
|
||||||
}
|
is CallableMemberDescriptor -> kind == CallableMemberDescriptor.Kind.DECLARATION
|
||||||
else {
|
else -> true
|
||||||
kind == CallableMemberDescriptor.Kind.DECLARATION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findHeaderForImpl(impl: MemberDescriptor, commonModule: ModuleDescriptor): Map<Compatibility, List<MemberDescriptor>>? {
|
private fun findHeaderForImpl(impl: MemberDescriptor, commonModule: ModuleDescriptor): Map<Compatibility, List<MemberDescriptor>>? {
|
||||||
@@ -196,7 +192,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
is ClassDescriptor -> {
|
is ClassDescriptor -> {
|
||||||
// TODO: replace with 'singleOrNull' as soon as multi-module diagnostic tests are refactored
|
// TODO: replace with 'singleOrNull' as soon as multi-module diagnostic tests are refactored
|
||||||
val headerClass = findHeaderForImpl(container, commonModule)?.values?.firstOrNull()?.firstOrNull() as? ClassDescriptor
|
val headerClass = findHeaderForImpl(container, commonModule)?.values?.firstOrNull()?.firstOrNull() as? ClassDescriptor
|
||||||
headerClass?.getMembers(impl.name).orEmpty()
|
headerClass?.getMembers(impl.name)?.filterIsInstance<CallableMemberDescriptor>().orEmpty()
|
||||||
}
|
}
|
||||||
is PackageFragmentDescriptor -> impl.findNamesakesFromModule(commonModule)
|
is PackageFragmentDescriptor -> impl.findNamesakesFromModule(commonModule)
|
||||||
else -> return null // do not report anything for incorrect code, e.g. 'impl' local function
|
else -> return null // do not report anything for incorrect code, e.g. 'impl' local function
|
||||||
@@ -317,7 +313,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
object Supertypes : Incompatible("some supertypes are missing in the implementation")
|
object Supertypes : Incompatible("some supertypes are missing in the implementation")
|
||||||
|
|
||||||
class ClassScopes(
|
class ClassScopes(
|
||||||
val unimplemented: List<Pair<CallableMemberDescriptor, Map<Incompatible, Collection<CallableMemberDescriptor>>>>
|
val unimplemented: List<Pair<MemberDescriptor, Map<Incompatible, Collection<MemberDescriptor>>>>
|
||||||
) : Incompatible("some members are not implemented")
|
) : Incompatible("some members are not implemented")
|
||||||
|
|
||||||
object EnumEntries : Incompatible("some entries from header enum are missing in the impl enum")
|
object EnumEntries : Incompatible("some entries from header enum are missing in the impl enum")
|
||||||
@@ -472,7 +468,8 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun areCompatibleClassifiers(a: ClassDescriptor, other: ClassifierDescriptor, checkImpl: Boolean): Compatibility {
|
private fun areCompatibleClassifiers(a: ClassDescriptor, other: ClassifierDescriptor, checkImpl: Boolean): Compatibility {
|
||||||
assert(a.fqNameUnsafe == other.fqNameUnsafe) { "This function should be invoked only for declarations with the same name: $a, $other" }
|
// Can't check FQ names here because nested header class may be implemented via impl typealias's expansion with the other FQ name
|
||||||
|
assert(a.name == other.name) { "This function should be invoked only for declarations with the same name: $a, $other" }
|
||||||
|
|
||||||
var implTypealias = false
|
var implTypealias = false
|
||||||
val b = when (other) {
|
val b = when (other) {
|
||||||
@@ -515,6 +512,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
return Compatible
|
return Compatible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun areCompatibleClassScopes(
|
private fun areCompatibleClassScopes(
|
||||||
a: ClassDescriptor,
|
a: ClassDescriptor,
|
||||||
b: ClassDescriptor,
|
b: ClassDescriptor,
|
||||||
@@ -522,19 +520,30 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
platformModule: ModuleDescriptor,
|
platformModule: ModuleDescriptor,
|
||||||
substitutor: Substitutor
|
substitutor: Substitutor
|
||||||
): Compatibility {
|
): Compatibility {
|
||||||
val unimplemented = arrayListOf<Pair<CallableMemberDescriptor, Map<Incompatible, MutableCollection<CallableMemberDescriptor>>>>()
|
val unimplemented = arrayListOf<Pair<MemberDescriptor, Map<Incompatible, MutableCollection<MemberDescriptor>>>>()
|
||||||
|
|
||||||
val bMembersByName = b.getMembers().groupBy { it.name }
|
val bMembersByName = b.getMembers().groupBy { it.name }
|
||||||
|
|
||||||
outer@ for (aMember in a.getMembers()) {
|
outer@ for (aMember in a.getMembers()) {
|
||||||
if (!aMember.kind.isReal) continue
|
if (aMember is CallableMemberDescriptor && !aMember.kind.isReal) continue
|
||||||
|
|
||||||
val mapping = bMembersByName[aMember.name].orEmpty().keysToMap { bMember ->
|
val bMembers = bMembersByName[aMember.name]?.filter { bMember ->
|
||||||
areCompatibleCallables(aMember, bMember, checkImpl, platformModule, substitutor)
|
aMember is CallableMemberDescriptor && bMember is CallableMemberDescriptor ||
|
||||||
|
aMember is ClassDescriptor && bMember is ClassDescriptor
|
||||||
|
}.orEmpty()
|
||||||
|
|
||||||
|
val mapping = bMembers.keysToMap { bMember ->
|
||||||
|
when (aMember) {
|
||||||
|
is CallableMemberDescriptor ->
|
||||||
|
areCompatibleCallables(aMember, bMember as CallableMemberDescriptor, checkImpl, platformModule, substitutor)
|
||||||
|
is ClassDescriptor ->
|
||||||
|
areCompatibleClassifiers(aMember, bMember as ClassDescriptor, checkImpl)
|
||||||
|
else -> throw UnsupportedOperationException("Unsupported declaration: $aMember ($bMembers)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mapping.values.any { it == Compatible }) continue
|
if (mapping.values.any { it == Compatible }) continue
|
||||||
|
|
||||||
val incompatibilityMap = mutableMapOf<Incompatible, MutableCollection<CallableMemberDescriptor>>()
|
val incompatibilityMap = mutableMapOf<Incompatible, MutableCollection<MemberDescriptor>>()
|
||||||
for ((descriptor, compatibility) in mapping) {
|
for ((descriptor, compatibility) in mapping) {
|
||||||
when (compatibility) {
|
when (compatibility) {
|
||||||
Compatible -> continue@outer
|
Compatible -> continue@outer
|
||||||
@@ -561,10 +570,13 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
return Incompatible.ClassScopes(unimplemented)
|
return Incompatible.ClassScopes(unimplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ClassDescriptor.getMembers(name: Name? = null): Collection<CallableMemberDescriptor> {
|
private fun ClassDescriptor.getMembers(name: Name? = null): Collection<MemberDescriptor> {
|
||||||
val nameFilter = if (name != null) { it -> it == name } else MemberScope.ALL_NAME_FILTER
|
val nameFilter = if (name != null) { it -> it == name } else MemberScope.ALL_NAME_FILTER
|
||||||
return defaultType.memberScope.getDescriptorsFiltered(nameFilter = nameFilter).filterIsInstance<CallableMemberDescriptor>() +
|
return defaultType.memberScope
|
||||||
constructors.filter { nameFilter(it.name) }
|
.getDescriptorsFiltered(nameFilter = nameFilter)
|
||||||
|
.filterIsInstance<MemberDescriptor>()
|
||||||
|
.filterNot(DescriptorUtils::isEnumEntry)
|
||||||
|
.plus(constructors.filter { nameFilter(it.name) })
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <T, K> equalBy(first: T, second: T, selector: (T) -> K): Boolean =
|
private inline fun <T, K> equalBy(first: T, second: T, selector: (T) -> K): Boolean =
|
||||||
|
|||||||
+3
-1
@@ -165,9 +165,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
|
|
||||||
this.isInner = modifierList != null && modifierList.hasModifier(INNER_KEYWORD) && !isIllegalInner(this);
|
this.isInner = modifierList != null && modifierList.hasModifier(INNER_KEYWORD) && !isIllegalInner(this);
|
||||||
this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD);
|
this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD);
|
||||||
this.isHeader = modifierList != null && modifierList.hasModifier(KtTokens.HEADER_KEYWORD);
|
|
||||||
this.isImpl = modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD);
|
this.isImpl = modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD);
|
||||||
|
|
||||||
|
this.isHeader = modifierList != null && modifierList.hasModifier(KtTokens.HEADER_KEYWORD) ||
|
||||||
|
containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).isHeader();
|
||||||
|
|
||||||
// Annotation entries are taken from both own annotations (if any) and object literal annotations (if any)
|
// Annotation entries are taken from both own annotations (if any) and object literal annotations (if any)
|
||||||
List<KtAnnotationEntry> annotationEntries = new ArrayList<>();
|
List<KtAnnotationEntry> annotationEntries = new ArrayList<>();
|
||||||
if (classOrObject != null && classOrObject.getParent() instanceof KtObjectLiteralExpression) {
|
if (classOrObject != null && classOrObject.getParent() instanceof KtObjectLiteralExpression) {
|
||||||
|
|||||||
+5
-5
@@ -2,11 +2,11 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public final header enum class Bar : kotlin.Enum<Bar> {
|
public final header enum class Bar : kotlin.Enum<Bar> {
|
||||||
enum entry X
|
header enum entry X
|
||||||
|
|
||||||
enum entry Y
|
header enum entry Y
|
||||||
|
|
||||||
enum entry Z
|
header enum entry Z
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
@@ -22,9 +22,9 @@ public final header enum class Bar : kotlin.Enum<Bar> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final header enum class Foo : kotlin.Enum<Foo> {
|
public final header enum class Foo : kotlin.Enum<Foo> {
|
||||||
enum entry A
|
header enum entry A
|
||||||
|
|
||||||
enum entry B
|
header enum entry B
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
|||||||
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public final header enum class En : kotlin.Enum<En> {
|
public final header enum class En : kotlin.Enum<En> {
|
||||||
enum entry E1
|
header enum entry E1
|
||||||
|
|
||||||
enum entry E2
|
header enum entry E2
|
||||||
|
|
||||||
private constructor En(/*0*/ x: kotlin.Int)
|
private constructor En(/*0*/ x: kotlin.Int)
|
||||||
private constructor En(/*0*/ s: kotlin.String)
|
private constructor En(/*0*/ s: kotlin.String)
|
||||||
@@ -21,7 +21,7 @@ public final header enum class En : kotlin.Enum<En> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final header enum class En2 : kotlin.Enum<En2> {
|
public final header enum class En2 : kotlin.Enum<En2> {
|
||||||
enum entry E1
|
header enum entry E1
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
|||||||
+5
-5
@@ -2,11 +2,11 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public final header enum class Bar : kotlin.Enum<Bar> {
|
public final header enum class Bar : kotlin.Enum<Bar> {
|
||||||
enum entry X
|
header enum entry X
|
||||||
|
|
||||||
enum entry Y
|
header enum entry Y
|
||||||
|
|
||||||
enum entry Z
|
header enum entry Z
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
@@ -22,9 +22,9 @@ public final header enum class Bar : kotlin.Enum<Bar> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final header enum class Foo : kotlin.Enum<Foo> {
|
public final header enum class Foo : kotlin.Enum<Foo> {
|
||||||
enum entry A
|
header enum entry A
|
||||||
|
|
||||||
enum entry B
|
header enum entry B
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
header enum class En {
|
header enum class En {
|
||||||
E1,
|
E1,
|
||||||
<!HEADER_ENUM_ENTRY_WITH_BODY!>E2 {
|
<!HEADER_ENUM_ENTRY_WITH_BODY!>E2 {
|
||||||
fun foo() = ""
|
<!HEADER_DECLARATION_WITH_BODY!>fun foo()<!> = ""
|
||||||
},<!>
|
},<!>
|
||||||
<!HEADER_ENUM_ENTRY_WITH_BODY!>E3 { };<!>
|
<!HEADER_ENUM_ENTRY_WITH_BODY!>E3 { };<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,11 +1,11 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public final header enum class En : kotlin.Enum<En> {
|
public final header enum class En : kotlin.Enum<En> {
|
||||||
enum entry E1
|
header enum entry E1
|
||||||
|
|
||||||
enum entry E2
|
header enum entry E2
|
||||||
|
|
||||||
enum entry E3
|
header enum entry E3
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public final header enum class Foo : kotlin.Enum<Foo> {
|
public final header enum class Foo : kotlin.Enum<Foo> {
|
||||||
enum entry ENTRY1
|
header enum entry ENTRY1
|
||||||
|
|
||||||
enum entry ENTRY2
|
header enum entry ENTRY2
|
||||||
|
|
||||||
enum entry ENTRY3
|
header enum entry ENTRY3
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ public final header class Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final header enum class En : kotlin.Enum<En> {
|
public final header enum class En : kotlin.Enum<En> {
|
||||||
enum entry ENTRY
|
header enum entry ENTRY
|
||||||
|
|
||||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
|||||||
+21
-9
@@ -3,23 +3,29 @@
|
|||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
|
|
||||||
header class OuterClass {
|
header class OuterClass {
|
||||||
header class NestedClass {
|
class NestedClass {
|
||||||
header class DeepNested {
|
class DeepNested {
|
||||||
header class Another
|
class Another {
|
||||||
|
fun f(s: String)
|
||||||
|
val p: Int
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header inner class InnerClass
|
inner class InnerClass {
|
||||||
|
fun f(x: Int)
|
||||||
|
val p: String
|
||||||
|
}
|
||||||
|
|
||||||
header companion object
|
companion object
|
||||||
}
|
}
|
||||||
|
|
||||||
header class OuterClassWithNamedCompanion {
|
header class OuterClassWithNamedCompanion {
|
||||||
header companion object Factory
|
companion object Factory
|
||||||
}
|
}
|
||||||
|
|
||||||
header object OuterObject {
|
header object OuterObject {
|
||||||
header object NestedObject
|
object NestedObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODULE: m2-jvm(m1-common)
|
// MODULE: m2-jvm(m1-common)
|
||||||
@@ -28,11 +34,17 @@ header object OuterObject {
|
|||||||
impl class OuterClass {
|
impl class OuterClass {
|
||||||
impl class NestedClass {
|
impl class NestedClass {
|
||||||
impl class DeepNested {
|
impl class DeepNested {
|
||||||
impl class Another
|
impl class Another {
|
||||||
|
impl fun f(s: String) {}
|
||||||
|
impl val p: Int = 42
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl inner class InnerClass
|
impl inner class InnerClass {
|
||||||
|
impl fun f(x: Int) {}
|
||||||
|
impl val p: String = ""
|
||||||
|
}
|
||||||
|
|
||||||
impl companion object
|
impl companion object
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -15,7 +15,9 @@ public final header class OuterClass {
|
|||||||
|
|
||||||
public final header inner class InnerClass {
|
public final header inner class InnerClass {
|
||||||
public constructor InnerClass()
|
public constructor InnerClass()
|
||||||
|
public header final val p: kotlin.String
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final header fun f(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
@@ -34,7 +36,9 @@ public final header class OuterClass {
|
|||||||
|
|
||||||
public final header class Another {
|
public final header class Another {
|
||||||
public constructor Another()
|
public constructor Another()
|
||||||
|
public header final val p: kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final header fun f(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
@@ -86,7 +90,9 @@ public final impl class OuterClass {
|
|||||||
|
|
||||||
public final impl inner class InnerClass {
|
public final impl inner class InnerClass {
|
||||||
public constructor InnerClass()
|
public constructor InnerClass()
|
||||||
|
public impl final val p: kotlin.String = ""
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final impl fun f(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
@@ -105,7 +111,9 @@ public final impl class OuterClass {
|
|||||||
|
|
||||||
public final impl class Another {
|
public final impl class Another {
|
||||||
public constructor Another()
|
public constructor Another()
|
||||||
|
public impl final val p: kotlin.Int = 42
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final impl fun f(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
|
||||||
|
header class B {
|
||||||
|
class N {
|
||||||
|
<!HEADER_DECLARATION_WITH_BODY, JVM:HEADER_DECLARATION_WITH_BODY!>fun body()<!> {}
|
||||||
|
<!WRONG_MODIFIER_TARGET, JVM:WRONG_MODIFIER_TARGET!>header<!> fun extraHeader()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header class C {
|
||||||
|
<!WRONG_MODIFIER_TARGET, JVM:WRONG_MODIFIER_TARGET!>header<!> class N
|
||||||
|
<!WRONG_MODIFIER_TARGET, JVM:WRONG_MODIFIER_TARGET!>header<!> enum class E
|
||||||
|
<!WRONG_MODIFIER_TARGET, JVM:WRONG_MODIFIER_TARGET!>header<!> inner class I
|
||||||
|
}
|
||||||
|
|
||||||
|
header class D {
|
||||||
|
class N
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
|
||||||
|
impl class B {
|
||||||
|
impl class N {
|
||||||
|
impl fun body() {}
|
||||||
|
impl fun extraHeader() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl class C {
|
||||||
|
impl class N
|
||||||
|
impl enum class E
|
||||||
|
impl inner class I
|
||||||
|
}
|
||||||
|
|
||||||
|
impl class <!HEADER_CLASS_MEMBERS_ARE_NOT_IMPLEMENTED!>D<!>
|
||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
// -- Module: <m1-common> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public final header class B {
|
||||||
|
public constructor B()
|
||||||
|
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 header class N {
|
||||||
|
public constructor N()
|
||||||
|
public final header fun body(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final header fun extraHeader(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final header class C {
|
||||||
|
public constructor C()
|
||||||
|
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 header enum class E : kotlin.Enum<C.E> {
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: C.E): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): C.E
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<C.E>
|
||||||
|
}
|
||||||
|
|
||||||
|
public final header inner class I {
|
||||||
|
public constructor I()
|
||||||
|
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 header class N {
|
||||||
|
public constructor N()
|
||||||
|
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 header class D {
|
||||||
|
public constructor D()
|
||||||
|
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 header class N {
|
||||||
|
public constructor N()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- Module: <m1-jvm> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public final impl class B {
|
||||||
|
public constructor B()
|
||||||
|
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 impl class N {
|
||||||
|
public constructor N()
|
||||||
|
public final impl fun body(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final impl fun extraHeader(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final impl class C {
|
||||||
|
public constructor C()
|
||||||
|
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 impl enum class E : kotlin.Enum<C.E> {
|
||||||
|
private constructor E()
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: C.E): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||||
|
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<C.E!>!
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): C.E
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<C.E>
|
||||||
|
}
|
||||||
|
|
||||||
|
public final impl inner class I {
|
||||||
|
public constructor I()
|
||||||
|
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 impl class N {
|
||||||
|
public constructor N()
|
||||||
|
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 impl class D {
|
||||||
|
public constructor D()
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<!WRONG_MODIFIER_TARGET!>header<!> typealias Foo = String
|
<!WRONG_MODIFIER_TARGET!>header<!> typealias Foo = String
|
||||||
|
|
||||||
class Outer <!WRONG_MODIFIER_TARGET!>header<!> constructor() {
|
class Outer <!WRONG_MODIFIER_TARGET!>header<!> constructor() {
|
||||||
header class Nested
|
<!WRONG_MODIFIER_TARGET!>header<!> class Nested
|
||||||
|
|
||||||
<!WRONG_MODIFIER_TARGET!>header<!> init {}
|
<!WRONG_MODIFIER_TARGET!>header<!> init {}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
header class ByTypeAlias {
|
header class ByTypeAlias {
|
||||||
header interface Nested
|
interface Nested
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -3,8 +3,5 @@ Exit code: OK
|
|||||||
Output:
|
Output:
|
||||||
|
|
||||||
-- JVM --
|
-- JVM --
|
||||||
Exit code: COMPILATION_ERROR
|
Exit code: OK
|
||||||
Output:
|
Output:
|
||||||
compiler/testData/multiplatform/implTypeAlias/nestedClassesViaTypeAlias/common.kt:2:22: error: 'header' interface 'Nested' has no implementation in module
|
|
||||||
header interface Nested
|
|
||||||
^
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
header class O1 {
|
header class O1 {
|
||||||
header class N1
|
class N1
|
||||||
header interface N2
|
interface N2
|
||||||
header object N3
|
object N3
|
||||||
}
|
}
|
||||||
|
|
||||||
header class O2 {
|
header class O2 {
|
||||||
header class N2
|
class N2
|
||||||
header inner class I2
|
inner class I2
|
||||||
}
|
}
|
||||||
|
|
||||||
header class O3 {
|
header class O3 {
|
||||||
header object Companion
|
object Companion
|
||||||
header companion object Factory
|
companion object Factory
|
||||||
}
|
}
|
||||||
|
|
||||||
header class O4 {
|
header class O4 {
|
||||||
header companion object
|
companion object
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13782,6 +13782,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedClassesWithErrors.kt")
|
||||||
|
public void testNestedClassesWithErrors() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/nestedClassesWithErrors.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noImplKeywordOnMember.kt")
|
@TestMetadata("noImplKeywordOnMember.kt")
|
||||||
public void testNoImplKeywordOnMember() throws Exception {
|
public void testNoImplKeywordOnMember() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/noImplKeywordOnMember.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/noImplKeywordOnMember.kt");
|
||||||
|
|||||||
+8
-2
@@ -29,11 +29,12 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
|
||||||
|
|
||||||
val ModuleDescriptor.sourceKind: SourceKind
|
val ModuleDescriptor.sourceKind: SourceKind
|
||||||
@@ -55,7 +56,7 @@ val ModuleDescriptor.allImplementingCompatibleModules
|
|||||||
class PlatformHeaderAnnotator : Annotator {
|
class PlatformHeaderAnnotator : Annotator {
|
||||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||||
val declaration = element as? KtDeclaration ?: return
|
val declaration = element as? KtDeclaration ?: return
|
||||||
if (!declaration.hasModifier(KtTokens.HEADER_KEYWORD)) return
|
if (!isHeaderDeclaration(declaration)) return
|
||||||
|
|
||||||
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Default) return
|
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Default) return
|
||||||
|
|
||||||
@@ -78,4 +79,9 @@ class PlatformHeaderAnnotator : Annotator {
|
|||||||
|
|
||||||
KotlinPsiChecker().annotateElement(declaration, holder, SimpleDiagnostics(filteredList))
|
KotlinPsiChecker().annotateElement(declaration, holder, SimpleDiagnostics(filteredList))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isHeaderDeclaration(declaration: KtDeclaration): Boolean {
|
||||||
|
return declaration.hasModifier(KtTokens.HEADER_KEYWORD) ||
|
||||||
|
declaration is KtClassOrObject && KtPsiUtil.getOutermostClassOrObject(declaration)?.hasModifier(KtTokens.HEADER_KEYWORD) == true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
header class A {
|
||||||
|
class Nested
|
||||||
|
}
|
||||||
|
|
||||||
|
header class B {
|
||||||
|
class Nested {
|
||||||
|
fun foo(s: String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header class C {
|
||||||
|
<error>header</error> inner class Inner
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
impl class <error>A</error>
|
||||||
|
|
||||||
|
impl class B {
|
||||||
|
impl class <error>Nested</error>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl class C {
|
||||||
|
impl inner class Inner
|
||||||
|
}
|
||||||
@@ -6,12 +6,4 @@ header enum class <caret>MyEnum {
|
|||||||
LAST;
|
LAST;
|
||||||
|
|
||||||
val num: Int
|
val num: Int
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun byNum(num: Int): MyEnum = when (num) {
|
|
||||||
1 -> FIRST
|
|
||||||
2 -> SECOND
|
|
||||||
else -> LAST
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -6,12 +6,4 @@ header enum class MyEnum {
|
|||||||
LAST;
|
LAST;
|
||||||
|
|
||||||
val num: Int
|
val num: Int
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun byNum(num: Int): MyEnum = when (num) {
|
|
||||||
1 -> FIRST
|
|
||||||
2 -> SECOND
|
|
||||||
else -> LAST
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,14 +4,7 @@ impl enum class MyEnum {
|
|||||||
SECOND,
|
SECOND,
|
||||||
LAST;
|
LAST;
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun byNum(num: Int): MyEnum = when (num) {
|
|
||||||
1 -> FIRST
|
|
||||||
2 -> SECOND
|
|
||||||
else -> LAST
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl val num: Int
|
impl val num: Int
|
||||||
get() = TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
get() = TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,10 @@ header class <caret>WithNested {
|
|||||||
fun foo(): Int
|
fun foo(): Int
|
||||||
|
|
||||||
class Nested {
|
class Nested {
|
||||||
fun bar() = "Nested"
|
fun bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
fun baz() = "Inner"
|
fun baz()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,10 @@ header class WithNested {
|
|||||||
fun foo(): Int
|
fun foo(): Int
|
||||||
|
|
||||||
class Nested {
|
class Nested {
|
||||||
fun bar() = "Nested"
|
fun bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
fun baz() = "Inner"
|
fun baz()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
impl class WithNested {
|
impl class WithNested {
|
||||||
|
|
||||||
class Nested {
|
class Nested {
|
||||||
fun bar() = "Nested"
|
fun bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
fun baz() = "Inner"
|
fun baz()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fun foo(): Int {
|
impl fun foo(): Int {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// "Create header class implementation for platform JS" "true"
|
// "Create header class implementation for platform JS" "true"
|
||||||
|
|
||||||
header sealed class <caret>Sealed {
|
header sealed class <caret>Sealed {
|
||||||
object Obj : Sealed()
|
object Obj : Sealed
|
||||||
|
|
||||||
class Klass(val x: Int) : Sealed()
|
class Klass(x: Int) : Sealed
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// "Create header class implementation for platform JS" "true"
|
// "Create header class implementation for platform JS" "true"
|
||||||
|
|
||||||
header sealed class Sealed {
|
header sealed class Sealed {
|
||||||
object Obj : Sealed()
|
object Obj : Sealed
|
||||||
|
|
||||||
class Klass(val x: Int) : Sealed()
|
class Klass(x: Int) : Sealed
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// Sealed: to be implemented
|
// Sealed: to be implemented
|
||||||
impl sealed class Sealed {
|
impl sealed class Sealed {
|
||||||
object Obj : Sealed()
|
object Obj : Sealed
|
||||||
|
|
||||||
class Klass(val x: Int) : Sealed()
|
class Klass(x: Int) : Sealed
|
||||||
}
|
}
|
||||||
@@ -284,5 +284,9 @@ open class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testNestedClassWithoutImpl() {
|
||||||
|
doMultiPlatformTest(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ header class Regex {
|
|||||||
fun split(input: CharSequence): List<String>
|
fun split(input: CharSequence): List<String>
|
||||||
fun split(input: CharSequence, limit: Int): List<String>
|
fun split(input: CharSequence, limit: Int): List<String>
|
||||||
|
|
||||||
header companion object {
|
companion object {
|
||||||
fun fromLiteral(literal: String): Regex
|
fun fromLiteral(literal: String): Regex
|
||||||
fun escape(literal: String): String
|
fun escape(literal: String): String
|
||||||
fun escapeReplacement(literal: String): String
|
fun escapeReplacement(literal: String): String
|
||||||
|
|||||||
Reference in New Issue
Block a user