Allow default object to be denoted with 'default' modifier
Report 'default' modifier in illegal positions
This commit is contained in:
@@ -91,7 +91,7 @@ public class JetObjectDeclaration extends JetNamedDeclarationStub<KotlinObjectSt
|
||||
if (stub != null) {
|
||||
return stub.isDefault();
|
||||
}
|
||||
return getClassKeyword() != null;
|
||||
return getClassKeyword() != null || hasModifier(JetTokens.DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.lexer.JetTokens.*;
|
||||
import static org.jetbrains.kotlin.psi.JetStubbedPsiUtil.getContainingDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isDefaultObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
|
||||
|
||||
@@ -141,6 +142,7 @@ public class ModifiersChecker {
|
||||
}
|
||||
else {
|
||||
checkInnerModifier(modifierListOwner, descriptor);
|
||||
checkDefaultModifier(modifierListOwner);
|
||||
checkModalityModifiers(modifierListOwner);
|
||||
checkVisibilityModifiers(modifierListOwner, descriptor);
|
||||
checkVarianceModifiersOfTypeParameters(modifierListOwner);
|
||||
@@ -232,6 +234,24 @@ public class ModifiersChecker {
|
||||
IN_OBJECT,
|
||||
}
|
||||
|
||||
private void checkDefaultModifier(@NotNull JetDeclaration declaration) {
|
||||
if (declaration.hasModifier(DEFAULT_KEYWORD) && !isDefaultModifierAllowed(declaration)) {
|
||||
reportIllegalModifiers(declaration, Collections.singletonList(DEFAULT_KEYWORD));
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: just checks if this is legal context for default modifier (Default object descriptor can be created)
|
||||
// DEFAULT_OBJECT_NOT_ALLOWED can be reported later
|
||||
public static boolean isDefaultModifierAllowed(@NotNull JetDeclaration declaration) {
|
||||
if (declaration instanceof JetObjectDeclaration) {
|
||||
JetDeclaration containingDeclaration = getContainingDeclaration(declaration);
|
||||
if (containingDeclaration instanceof JetClassOrObject) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static InnerModifierCheckResult checkIllegalInner(DeclarationDescriptor descriptor) {
|
||||
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||
|
||||
+1
-1
@@ -20,9 +20,9 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind;
|
||||
import org.jetbrains.kotlin.psi.JetObjectDeclaration;
|
||||
import org.jetbrains.kotlin.psi.JetParameter;
|
||||
import org.jetbrains.kotlin.psi.JetTypeParameterList;
|
||||
import org.jetbrains.kotlin.resolve.ModifiersChecker;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -54,6 +55,6 @@ public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
|
||||
}
|
||||
|
||||
public boolean isDefaultObject() {
|
||||
return element.isDefault();
|
||||
return element.isDefault() && ModifiersChecker.isDefaultModifierAllowed(element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class A {
|
||||
inner class I {
|
||||
default <!DEFAULT_OBJECT_NOT_ALLOWED!>object A<!>
|
||||
|
||||
default <!MANY_DEFAULT_OBJECTS, MANY_DEFAULT_OBJECTS, DEFAULT_OBJECT_NOT_ALLOWED!>object B<!>
|
||||
|
||||
default <!MANY_DEFAULT_OBJECTS, MANY_DEFAULT_OBJECTS, DEFAULT_OBJECT_NOT_ALLOWED!>object C<!>
|
||||
}
|
||||
}
|
||||
|
||||
object O {
|
||||
default <!DEFAULT_OBJECT_NOT_ALLOWED!>object A<!>
|
||||
|
||||
default <!MANY_DEFAULT_OBJECTS, DEFAULT_OBJECT_NOT_ALLOWED!>object B<!>
|
||||
|
||||
default <!MANY_DEFAULT_OBJECTS, DEFAULT_OBJECT_NOT_ALLOWED!>object C<!>
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package
|
||||
|
||||
internal final class A {
|
||||
public constructor A()
|
||||
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
|
||||
|
||||
internal final 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
|
||||
|
||||
internal class object A {
|
||||
private constructor A()
|
||||
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
|
||||
}
|
||||
|
||||
internal class object B {
|
||||
private 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
|
||||
}
|
||||
|
||||
internal class object C {
|
||||
private 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object O {
|
||||
private constructor O()
|
||||
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
|
||||
|
||||
internal class object A {
|
||||
private constructor A()
|
||||
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
|
||||
}
|
||||
|
||||
internal class object B {
|
||||
private 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
|
||||
}
|
||||
|
||||
internal class object C {
|
||||
private 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<!ILLEGAL_MODIFIER!>default<!> class A {
|
||||
default object {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
default object
|
||||
|
||||
val c: Int = 1
|
||||
}
|
||||
|
||||
class C {
|
||||
default object A {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class D {
|
||||
default object A {
|
||||
default <!DEFAULT_OBJECT_NOT_ALLOWED!>object<!> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<!ILLEGAL_MODIFIER!>default<!> object G {
|
||||
default <!DEFAULT_OBJECT_NOT_ALLOWED!>object<!>
|
||||
}
|
||||
|
||||
<!ILLEGAL_MODIFIER!>default<!> trait H {
|
||||
default object
|
||||
}
|
||||
|
||||
class J {
|
||||
default object C {
|
||||
default <!DEFAULT_OBJECT_NOT_ALLOWED!>object<!>
|
||||
}
|
||||
}
|
||||
|
||||
<!ILLEGAL_MODIFIER!>default<!> enum class Enum {
|
||||
E1
|
||||
E2
|
||||
|
||||
default object
|
||||
}
|
||||
|
||||
<!ILLEGAL_MODIFIER!>default<!> fun main() {
|
||||
|
||||
}
|
||||
|
||||
<!ILLEGAL_MODIFIER!>default<!> var prop: Int = 1
|
||||
<!ILLEGAL_MODIFIER!>default<!> get
|
||||
<!ILLEGAL_MODIFIER!>default<!> set
|
||||
|
||||
class Z(<!ILLEGAL_MODIFIER!>default<!> val c: Int)
|
||||
@@ -0,0 +1,165 @@
|
||||
package
|
||||
|
||||
internal var prop: kotlin.Int
|
||||
internal fun main(): kotlin.Unit
|
||||
|
||||
internal final class A {
|
||||
public constructor A()
|
||||
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
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal final class B {
|
||||
public constructor B()
|
||||
internal final val c: kotlin.Int = 1
|
||||
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
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal final 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
|
||||
|
||||
internal class object A {
|
||||
private constructor A()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal final 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
|
||||
|
||||
internal class object A {
|
||||
private constructor A()
|
||||
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
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal final enum class Enum : kotlin.Enum<Enum> {
|
||||
public enum entry E1 : Enum {
|
||||
private constructor E1()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Enum): 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 final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry E2 : Enum {
|
||||
private constructor E2()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Enum): 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 final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor Enum()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Enum): 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 final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Enum
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Enum>
|
||||
}
|
||||
|
||||
internal object G {
|
||||
private constructor G()
|
||||
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
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal trait H {
|
||||
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
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
internal final class J {
|
||||
public constructor J()
|
||||
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
|
||||
|
||||
internal class object C {
|
||||
private 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
|
||||
|
||||
internal class object Default {
|
||||
private constructor Default()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal final class Z {
|
||||
public constructor Z(/*0*/ c: kotlin.Int)
|
||||
internal final val c: kotlin.Int
|
||||
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
|
||||
}
|
||||
@@ -1576,6 +1576,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleDissallowedDefaultObjects.kt")
|
||||
public void testMultipleDissallowedDefaultObjects() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/classObjects/multipleDissallowedDefaultObjects.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassInPrivateClassObject.kt")
|
||||
public void testNestedClassInPrivateClassObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.kt");
|
||||
@@ -7380,6 +7386,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/modifiers"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultModifier.kt")
|
||||
public void testDefaultModifier() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/defaultModifier.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("IllegalModifiers.kt")
|
||||
public void testIllegalModifiers() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt");
|
||||
|
||||
Reference in New Issue
Block a user