Prohibit local objects and enum classes

#KT-5402 Fixed
  #KT-4838 Fixed

Resolve type of object inside local object as special, not supertype('Any').
Changed visibility of constructor of anonymous object to 'internal' to be able to resolve the following:
fun box(): String {
    var foo = object {
        val bar = object {
            val baz = "ok"
        }
    }
    return foo.bar.baz
}
The containing declaration of property initializers is constructor, so 'baz' was invisible inside private constructor.
This commit is contained in:
Svetlana Isakova
2014-08-12 17:19:02 +04:00
parent eaeed78154
commit 9d366cb896
39 changed files with 158 additions and 126 deletions
@@ -291,23 +291,19 @@ public class AsmUtil {
if (isEnumEntry(memberDescriptor)) { if (isEnumEntry(memberDescriptor)) {
return NO_FLAG_PACKAGE_PRIVATE; return NO_FLAG_PACKAGE_PRIVATE;
} }
if (memberDescriptor instanceof ConstructorDescriptor && isAnonymousObject(memberDescriptor.getContainingDeclaration())) {
return NO_FLAG_PACKAGE_PRIVATE;
}
if (memberVisibility != Visibilities.PRIVATE) { if (memberVisibility != Visibilities.PRIVATE) {
return null; return null;
} }
// the following code is only for PRIVATE visibility of member // the following code is only for PRIVATE visibility of member
if (memberDescriptor instanceof ConstructorDescriptor) { if (memberDescriptor instanceof ConstructorDescriptor) {
if (isAnonymousObject(containingDeclaration)) {
return NO_FLAG_PACKAGE_PRIVATE;
}
ClassKind kind = ((ClassDescriptor) containingDeclaration).getKind(); ClassKind kind = ((ClassDescriptor) containingDeclaration).getKind();
if (kind == ClassKind.OBJECT) { if (kind == ClassKind.OBJECT || kind == ClassKind.ENUM_ENTRY) {
return NO_FLAG_PACKAGE_PRIVATE; return NO_FLAG_PACKAGE_PRIVATE;
} }
else if (kind == ClassKind.ENUM_ENTRY) { if (kind == ClassKind.ENUM_CLASS) {
return NO_FLAG_PACKAGE_PRIVATE;
}
else if (kind == ClassKind.ENUM_CLASS) {
//TODO: should be ACC_PRIVATE //TODO: should be ACC_PRIVATE
// see http://youtrack.jetbrains.com/issue/KT-2680 // see http://youtrack.jetbrains.com/issue/KT-2680
return ACC_PROTECTED; return ACC_PROTECTED;
@@ -180,12 +180,17 @@ public interface Errors {
DiagnosticFactory1<JetClass, ClassDescriptor> ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER); DiagnosticFactory1<JetClass, ClassDescriptor> ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER);
DiagnosticFactory1<JetTypeReference, ClassDescriptor> ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1<JetTypeReference, ClassDescriptor> ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<JetClass, ClassDescriptor> LOCAL_ENUM_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER);
// Class objects // Class objects
DiagnosticFactory0<JetClassObject> MANY_CLASS_OBJECTS = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<JetClassObject> MANY_CLASS_OBJECTS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetClassObject> CLASS_OBJECT_NOT_ALLOWED = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<JetClassObject> CLASS_OBJECT_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
// Objects
DiagnosticFactory1<JetObjectDeclaration, ClassDescriptor> LOCAL_OBJECT_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER);
// Type parameter declarations // Type parameter declarations
DiagnosticFactory1<JetTypeReference, JetType> FINAL_UPPER_BOUND = DiagnosticFactory1.create(WARNING); DiagnosticFactory1<JetTypeReference, JetType> FINAL_UPPER_BOUND = DiagnosticFactory1.create(WARNING);
@@ -216,6 +216,8 @@ public class DefaultErrorMessages {
MAP.put(MANY_CLASS_OBJECTS, "Only one class object is allowed per class"); MAP.put(MANY_CLASS_OBJECTS, "Only one class object is allowed per class");
MAP.put(CLASS_OBJECT_NOT_ALLOWED, "A class object is not allowed here"); MAP.put(CLASS_OBJECT_NOT_ALLOWED, "A class object is not allowed here");
MAP.put(LOCAL_OBJECT_NOT_ALLOWED, "Named object ''{0}'' is a singleton and cannot be local. Try to use anonymous object instead", NAME);
MAP.put(LOCAL_ENUM_NOT_ALLOWED, "Enum class ''{0}'' cannot be local", NAME);
MAP.put(DELEGATION_IN_TRAIT, "Traits cannot use delegation"); MAP.put(DELEGATION_IN_TRAIT, "Traits cannot use delegation");
MAP.put(DELEGATION_NOT_TO_TRAIT, "Only traits can be delegated to"); MAP.put(DELEGATION_NOT_TO_TRAIT, "Only traits can be delegated to");
MAP.put(UNMET_TRAIT_REQUIREMENT, "Super trait ''{0}'' requires subclasses to extend ''{1}''", NAME, NAME); MAP.put(UNMET_TRAIT_REQUIREMENT, "Super trait ''{0}'' requires subclasses to extend ''{1}''", NAME, NAME);
@@ -835,6 +835,7 @@ public class JetPsiUtil {
JetBlockExpression.class, JetClassInitializer.class, JetProperty.class, JetFunction.class, JetParameter.class JetBlockExpression.class, JetClassInitializer.class, JetProperty.class, JetFunction.class, JetParameter.class
); );
if (container == null) return null; if (container == null) return null;
if (container.getParent() instanceof JetScript) return null;
return (container instanceof JetClassInitializer) ? ((JetClassInitializer) container).getBody() : container; return (container instanceof JetClassInitializer) ? ((JetClassInitializer) container).getBody() : container;
} }
@@ -182,7 +182,8 @@ public class DeclarationResolver {
scopeForPropertyInitializers, scopeForPropertyInitializers,
property, property,
trace, trace,
c.getOuterDataFlowInfo()); c.getOuterDataFlowInfo()
);
packageLike.addPropertyDescriptor(propertyDescriptor); packageLike.addPropertyDescriptor(propertyDescriptor);
c.getProperties().put(property, propertyDescriptor); c.getProperties().put(property, propertyDescriptor);
c.registerDeclaringScope(property, scopeForPropertyInitializers); c.registerDeclaringScope(property, scopeForPropertyInitializers);
@@ -76,7 +76,7 @@ public class DeclarationsChecker {
jetClass, classDescriptor, classDescriptor.getScopeForClassHeaderResolution(), trace); jetClass, classDescriptor, classDescriptor.getScopeForClassHeaderResolution(), trace);
} }
else if (classOrObject instanceof JetObjectDeclaration) { else if (classOrObject instanceof JetObjectDeclaration) {
checkObject((JetObjectDeclaration) classOrObject); checkObject((JetObjectDeclaration) classOrObject, classDescriptor);
} }
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor); modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
@@ -245,8 +245,11 @@ public class DeclarationsChecker {
public abstract boolean removeNeeded(JetType subject, JetType other); public abstract boolean removeNeeded(JetType subject, JetType other);
} }
private void checkObject(JetObjectDeclaration declaration) { private void checkObject(JetObjectDeclaration declaration, ClassDescriptor classDescriptor) {
reportErrorIfHasIllegalModifier(declaration); reportErrorIfHasIllegalModifier(declaration);
if (declaration.isLocal() && !declaration.isClassObject() && !declaration.isObjectLiteral()) {
trace.report(LOCAL_OBJECT_NOT_ALLOWED.on(declaration, classDescriptor));
}
} }
private void checkClass(BodiesResolveContext c, JetClass aClass, ClassDescriptorWithResolutionScopes classDescriptor) { private void checkClass(BodiesResolveContext c, JetClass aClass, ClassDescriptorWithResolutionScopes classDescriptor) {
@@ -264,6 +267,9 @@ public class DeclarationsChecker {
} }
else if (aClass.isEnum()) { else if (aClass.isEnum()) {
checkEnumModifiers(aClass); checkEnumModifiers(aClass);
if (aClass.isLocal()) {
trace.report(LOCAL_ENUM_NOT_ALLOWED.on(aClass, classDescriptor));
}
} }
else if (aClass instanceof JetEnumEntry) { else if (aClass instanceof JetEnumEntry) {
checkEnumEntry((JetEnumEntry) aClass, classDescriptor); checkEnumEntry((JetEnumEntry) aClass, classDescriptor);
@@ -37,9 +37,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import static org.jetbrains.jet.lang.diagnostics.Errors.ILLEGAL_MODIFIER; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.ILLEGAL_PLATFORM_NAME;
import static org.jetbrains.jet.lang.diagnostics.Errors.INAPPLICABLE_ANNOTATION;
import static org.jetbrains.jet.lexer.JetTokens.*; import static org.jetbrains.jet.lexer.JetTokens.*;
public class ModifiersChecker { public class ModifiersChecker {
@@ -121,16 +119,17 @@ public class ModifiersChecker {
} }
private void checkInnerModifier(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) { private void checkInnerModifier(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
JetModifierList modifierList = modifierListOwner.getModifierList(); if (modifierListOwner.hasModifier(INNER_KEYWORD)) {
if (modifierList != null && modifierList.hasModifier(INNER_KEYWORD)) {
if (isIllegalInner(descriptor)) { if (isIllegalInner(descriptor)) {
checkIllegalInThisContextModifiers(modifierList, Collections.singletonList(INNER_KEYWORD)); checkIllegalInThisContextModifiers(modifierListOwner.getModifierList(), Collections.singletonList(INNER_KEYWORD));
} }
return;
} }
else { if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry)) {
if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry) && isIllegalNestedClass(descriptor)) { JetClass aClass = (JetClass) modifierListOwner;
trace.report(Errors.NESTED_CLASS_NOT_ALLOWED.on((JetClass) modifierListOwner)); boolean localEnumError = aClass.isLocal() && aClass.isEnum();
if (!localEnumError && isIllegalNestedClass(descriptor)) {
trace.report(NESTED_CLASS_NOT_ALLOWED.on(aClass));
} }
} }
} }
@@ -61,15 +61,6 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(klass, klass, descriptor)); trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(klass, klass, descriptor));
} }
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
if (declaration.getParent() instanceof JetObjectLiteralExpression) {
super.visitObjectDeclaration(declaration);
} else {
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(declaration, declaration, descriptor));
}
}
@Override @Override
public void visitNamedFunction(@NotNull JetNamedFunction function) { public void visitNamedFunction(@NotNull JetNamedFunction function) {
if (function.getParent().getParent() instanceof JetObjectDeclaration) { if (function.getParent().getParent() instanceof JetObjectDeclaration) {
@@ -181,7 +181,8 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
trace, trace,
// this relies on the assumption that a lazily resolved declaration is not a local one, // this relies on the assumption that a lazily resolved declaration is not a local one,
// thus doesn't have a surrounding data flow // thus doesn't have a surrounding data flow
DataFlowInfo.EMPTY); DataFlowInfo.EMPTY
);
result.add(propertyDescriptor); result.add(propertyDescriptor);
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor, trace); AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor, trace);
} }
@@ -1,11 +0,0 @@
// KT-2948 Assertion fails on a local enum
fun foo(): String {
enum class E {
OK
}
return E.OK.toString()
}
fun box(): String = foo()
@@ -1,8 +0,0 @@
fun box(): String {
enum class K {
O
K
}
return K.O.toString() + K.K.toString()
}
@@ -1,8 +0,0 @@
fun box(): String {
enum class K {
O
K
}
return K.O.toString() + K.K.toString()
}
@@ -6,11 +6,11 @@ class A {
open fun s() : String = "O" open fun s() : String = "O"
} }
object O: B() { val o = object : B() {
override fun s(): String = "K" override fun s(): String = "K"
} }
a = B().s() + O.s() a = B().s() + o.s()
} }
} }
@@ -4,11 +4,11 @@ class A(
open fun s() : String = "O" open fun s() : String = "O"
} }
object O: B() { val o = object : B() {
override fun s(): String = "K" override fun s(): String = "K"
} }
B().s() + O.s() B().s() + o.s()
}() }()
) )
@@ -1,7 +1,7 @@
fun box(): String { fun box(): String {
object K { val k = object {
val ok = "OK" val ok = "OK"
} }
return K.ok return k.ok
} }
@@ -0,0 +1,10 @@
fun box(): String {
var boo = "OK"
var foo = object {
val bar = object {
val baz = boo
}
}
return foo.bar.baz
}
@@ -1,11 +1,11 @@
fun box(): String { trait Named {
trait Named { fun name(): String
fun name(): String }
}
enum class E : Named {
OK
}
enum class E : Named {
OK
}
fun box(): String {
return E.OK.(Named::name)() return E.OK.(Named::name)()
} }
@@ -193,7 +193,7 @@ fun testFunctionLiterals() {
val <!UNUSED_VARIABLE!>endsWithObjectDeclaration<!> : () -> Int = { val <!UNUSED_VARIABLE!>endsWithObjectDeclaration<!> : () -> Int = {
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1 var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
x = <!UNUSED_VALUE!>333<!> x = <!UNUSED_VALUE!>333<!>
<!EXPECTED_TYPE_MISMATCH!>object A {}<!> <!EXPECTED_TYPE_MISMATCH!><!LOCAL_OBJECT_NOT_ALLOWED!>object A<!> {}<!>
} }
val <!UNUSED_VARIABLE!>expectedUnitReturnType1<!> = { () : Unit -> val <!UNUSED_VARIABLE!>expectedUnitReturnType1<!> = { () : Unit ->
@@ -202,7 +202,7 @@ fun testFunctionLiterals() {
val <!UNUSED_VARIABLE!>expectedUnitReturnType2<!> = { () : Unit -> val <!UNUSED_VARIABLE!>expectedUnitReturnType2<!> = { () : Unit ->
fun meow() : Unit {} fun meow() : Unit {}
object A {} <!LOCAL_OBJECT_NOT_ALLOWED!>object A<!> {}
} }
} }
@@ -0,0 +1,18 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun foo() {
<!LOCAL_ENUM_NOT_ALLOWED!>enum class A<!> {
FOO
BAR
}
val foo = A.FOO
val b = object {
<!LOCAL_ENUM_NOT_ALLOWED!>enum class B<!> {}
}
class C {
<!LOCAL_ENUM_NOT_ALLOWED!>enum class D<!> {}
}
val f = {
<!LOCAL_ENUM_NOT_ALLOWED!>enum class E<!> {}
}
}
@@ -8,9 +8,9 @@ inline fun unsupported() {
} }
}<!> }<!>
<!NOT_YET_SUPPORTED_IN_INLINE!>object B{ <!LOCAL_OBJECT_NOT_ALLOWED!>object B<!>{
object BInner {} <!LOCAL_OBJECT_NOT_ALLOWED!>object BInner<!> {}
}<!> }
<!NOT_YET_SUPPORTED_IN_INLINE!>fun local() { <!NOT_YET_SUPPORTED_IN_INLINE!>fun local() {
fun localInner() {} fun localInner() {}
@@ -11,7 +11,7 @@ fun f() {
} }
} }
object MyObject { <!LOCAL_OBJECT_NOT_ALLOWED!>object MyObject<!> {
{ {
val <!UNUSED_VARIABLE!>obj<!>: MyObject = MyObject val <!UNUSED_VARIABLE!>obj<!>: MyObject = MyObject
} }
@@ -14,7 +14,7 @@ fun test() {
} }
b.foo() b.foo()
object B { <!LOCAL_OBJECT_NOT_ALLOWED!>object B<!> {
fun foo() {} fun foo() {}
} }
B.foo() B.foo()
@@ -0,0 +1,15 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun foo() {
<!LOCAL_OBJECT_NOT_ALLOWED!>object a<!> {}
val b = object {
<!LOCAL_OBJECT_NOT_ALLOWED!>object c<!> {}
}
b.<!NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE!>c<!>
class A {
<!LOCAL_OBJECT_NOT_ALLOWED!>object d<!> {}
}
val f = {
<!LOCAL_OBJECT_NOT_ALLOWED!>object e<!> {}
}
}
@@ -0,0 +1,5 @@
>>> fun foo() {
... object Bar {
... }
... }
ERROR: /line4.kts: (2, 1) Named object 'Bar' is a singleton and cannot be local. Try to use anonymous object instead
@@ -3194,6 +3194,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest("compiler/testData/diagnostics/tests/enum/kt2834.kt"); doTest("compiler/testData/diagnostics/tests/enum/kt2834.kt");
} }
@TestMetadata("localEnums.kt")
public void testLocalEnums() throws Exception {
doTest("compiler/testData/diagnostics/tests/enum/localEnums.kt");
}
@TestMetadata("starImportNestedClassAndEntries.kt") @TestMetadata("starImportNestedClassAndEntries.kt")
public void testStarImportNestedClassAndEntries() throws Exception { public void testStarImportNestedClassAndEntries() throws Exception {
doTest("compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt"); doTest("compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt");
@@ -5921,6 +5926,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest("compiler/testData/diagnostics/tests/objects/localObjectInsideObject.kt"); doTest("compiler/testData/diagnostics/tests/objects/localObjectInsideObject.kt");
} }
@TestMetadata("localObjects.kt")
public void testLocalObjects() throws Exception {
doTest("compiler/testData/diagnostics/tests/objects/localObjects.kt");
}
@TestMetadata("objectLiteralExpressionTypeMismatch.kt") @TestMetadata("objectLiteralExpressionTypeMismatch.kt")
public void testObjectLiteralExpressionTypeMismatch() throws Exception { public void testObjectLiteralExpressionTypeMismatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/objects/objectLiteralExpressionTypeMismatch.kt"); doTest("compiler/testData/diagnostics/tests/objects/objectLiteralExpressionTypeMismatch.kt");
@@ -2114,11 +2114,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/enum/entrywithinner.kt"); doTest("compiler/testData/codegen/box/enum/entrywithinner.kt");
} }
@TestMetadata("inFunction.kt")
public void testInFunction() throws Exception {
doTest("compiler/testData/codegen/box/enum/inFunction.kt");
}
@TestMetadata("inPackage.kt") @TestMetadata("inPackage.kt")
public void testInPackage() throws Exception { public void testInPackage() throws Exception {
doTest("compiler/testData/codegen/box/enum/inPackage.kt"); doTest("compiler/testData/codegen/box/enum/inPackage.kt");
@@ -2149,11 +2144,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/enum/kt2350.kt"); doTest("compiler/testData/codegen/box/enum/kt2350.kt");
} }
@TestMetadata("kt2673.kt")
public void testKt2673() throws Exception {
doTest("compiler/testData/codegen/box/enum/kt2673.kt");
}
@TestMetadata("name.kt") @TestMetadata("name.kt")
public void testName() throws Exception { public void testName() throws Exception {
doTest("compiler/testData/codegen/box/enum/name.kt"); doTest("compiler/testData/codegen/box/enum/name.kt");
@@ -3336,11 +3326,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/localClasses/anonymousObjectInParameterInitializer.kt"); doTest("compiler/testData/codegen/box/localClasses/anonymousObjectInParameterInitializer.kt");
} }
@TestMetadata("enum.kt")
public void testEnum() throws Exception {
doTest("compiler/testData/codegen/box/localClasses/enum.kt");
}
@TestMetadata("inExtensionFunction.kt") @TestMetadata("inExtensionFunction.kt")
public void testInExtensionFunction() throws Exception { public void testInExtensionFunction() throws Exception {
doTest("compiler/testData/codegen/box/localClasses/inExtensionFunction.kt"); doTest("compiler/testData/codegen/box/localClasses/inExtensionFunction.kt");
@@ -4059,6 +4044,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/objects/nestedObjectWithSuperclass.kt"); doTest("compiler/testData/codegen/box/objects/nestedObjectWithSuperclass.kt");
} }
@TestMetadata("objectInLocalAnonymousObject.kt")
public void testObjectInLocalAnonymousObject() throws Exception {
doTest("compiler/testData/codegen/box/objects/objectInLocalAnonymousObject.kt");
}
@TestMetadata("objectLiteral.kt") @TestMetadata("objectLiteral.kt")
public void testObjectLiteral() throws Exception { public void testObjectLiteral() throws Exception {
doTest("compiler/testData/codegen/box/objects/objectLiteral.kt"); doTest("compiler/testData/codegen/box/objects/objectLiteral.kt");
@@ -186,6 +186,11 @@ public class ReplInterpreterTestGenerated extends AbstractReplInterpreterTest {
doTest("compiler/testData/repl/objects/emptyObject.repl"); doTest("compiler/testData/repl/objects/emptyObject.repl");
} }
@TestMetadata("localObject.repl")
public void testLocalObject() throws Exception {
doTest("compiler/testData/repl/objects/localObject.repl");
}
@TestMetadata("simpleObjectDeclaration.repl") @TestMetadata("simpleObjectDeclaration.repl")
public void testSimpleObjectDeclaration() throws Exception { public void testSimpleObjectDeclaration() throws Exception {
doTest("compiler/testData/repl/objects/simpleObjectDeclaration.repl"); doTest("compiler/testData/repl/objects/simpleObjectDeclaration.repl");
@@ -134,8 +134,8 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
List<JetDeclaration> declarations = aClass.getDeclarations(); List<JetDeclaration> declarations = aClass.getDeclarations();
JetProperty property = (JetProperty) declarations.get(0); JetProperty property = (JetProperty) declarations.get(0);
PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePropertyDescriptor(classDescriptor, scope, property, PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePropertyDescriptor(
JetTestUtils.DUMMY_TRACE, DataFlowInfo.EMPTY); classDescriptor, scope, property, JetTestUtils.DUMMY_TRACE, DataFlowInfo.EMPTY);
assertEquals(expectedPropertyModality, propertyDescriptor.getModality()); assertEquals(expectedPropertyModality, propertyDescriptor.getModality());
} }
@@ -147,8 +147,8 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
List<JetDeclaration> declarations = aClass.getDeclarations(); List<JetDeclaration> declarations = aClass.getDeclarations();
JetProperty property = (JetProperty) declarations.get(0); JetProperty property = (JetProperty) declarations.get(0);
PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePropertyDescriptor(classDescriptor, scope, property, PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePropertyDescriptor(
JetTestUtils.DUMMY_TRACE, DataFlowInfo.EMPTY); classDescriptor, scope, property, JetTestUtils.DUMMY_TRACE, DataFlowInfo.EMPTY);
PropertyAccessorDescriptor propertyAccessor = isGetter PropertyAccessorDescriptor propertyAccessor = isGetter
? propertyDescriptor.getGetter() ? propertyDescriptor.getGetter()
: propertyDescriptor.getSetter(); : propertyDescriptor.getSetter();
@@ -289,9 +289,12 @@ public class DescriptorUtils {
@NotNull @NotNull
public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) { public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
ClassKind classKind = classDescriptor.getKind(); ClassKind classKind = classDescriptor.getKind();
if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton() || isAnonymousObject(classDescriptor)) { if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton()) {
return Visibilities.PRIVATE; return Visibilities.PRIVATE;
} }
if (isAnonymousObject(classDescriptor)) {
return Visibilities.INTERNAL;
}
assert classKind == ClassKind.CLASS || classKind == ClassKind.TRAIT || classKind == ClassKind.ANNOTATION_CLASS; assert classKind == ClassKind.CLASS || classKind == ClassKind.TRAIT || classKind == ClassKind.ANNOTATION_CLASS;
return Visibilities.PUBLIC; return Visibilities.PUBLIC;
} }
@@ -70,16 +70,16 @@ public fun ImportPath.isImported(alreadyImported: ImportPath): Boolean {
public fun ImportPath.isImported(imports: Iterable<ImportPath>): Boolean = imports.any { isImported(it) } public fun ImportPath.isImported(imports: Iterable<ImportPath>): Boolean = imports.any { isImported(it) }
// Check that it is javaName(\.javaName)* or an empty string
private enum class State {
BEGINNING
MIDDLE
AFTER_DOT
}
public fun isValidJavaFqName(qualifiedName: String?): Boolean { public fun isValidJavaFqName(qualifiedName: String?): Boolean {
if (qualifiedName == null) return false if (qualifiedName == null) return false
// Check that it is javaName(\.javaName)* or an empty string
enum class State {
BEGINNING
MIDDLE
AFTER_DOT
}
var state = State.BEGINNING var state = State.BEGINNING
for (c in qualifiedName) { for (c in qualifiedName) {
@@ -90,18 +90,18 @@ public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
} }
} }
private enum class UsageKind {
SIMPLE_PROPERTY_USAGE
GETTER_USAGE
SETTER_USAGE
}
override fun renameElement(element: PsiElement?, newName: String?, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) { override fun renameElement(element: PsiElement?, newName: String?, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) {
if (element !is JetProperty) { if (element !is JetProperty) {
super.renameElement(element, newName, usages, listener) super.renameElement(element, newName, usages, listener)
return return
} }
enum class UsageKind {
SIMPLE_PROPERTY_USAGE
GETTER_USAGE
SETTER_USAGE
}
val oldGetterName = PropertyCodegen.getterName(element.getNameAsName()) val oldGetterName = PropertyCodegen.getterName(element.getNameAsName())
val oldSetterName = PropertyCodegen.setterName(element.getNameAsName()) val oldSetterName = PropertyCodegen.setterName(element.getNameAsName())
@@ -159,14 +159,14 @@ public class KotlinPsiSearchHelper(private val project: Project): PsiSearchHelpe
public object UsagesSearch: QueryFactory<PsiReference, UsagesSearchRequest>() { public object UsagesSearch: QueryFactory<PsiReference, UsagesSearchRequest>() {
{ {
object ExecutorImpl: QueryExecutorBase<PsiReference, UsagesSearchRequest>() { val executorImpl = object : QueryExecutorBase<PsiReference, UsagesSearchRequest>() {
override fun processQuery(request: UsagesSearchRequest, consumer: Processor<PsiReference>) { override fun processQuery(request: UsagesSearchRequest, consumer: Processor<PsiReference>) {
val searchHelper = KotlinPsiSearchHelper(request.project) val searchHelper = KotlinPsiSearchHelper(request.project)
request.items.filter { it.filter != False }.all { searchHelper.processFilesWithText(it, consumer) } request.items.filter { it.filter != False }.all { searchHelper.processFilesWithText(it, consumer) }
} }
} }
registerExecutor(ExecutorImpl) registerExecutor(executorImpl)
} }
fun search(request: UsagesSearchRequest): Query<PsiReference> = with(request) { fun search(request: UsagesSearchRequest): Query<PsiReference> = with(request) {
+1 -1
View File
@@ -12,7 +12,7 @@
} }
b.foo() b.foo()
object B { <error>object B</error> {
fun foo() {} fun foo() {}
} }
B.foo() B.foo()
@@ -17,4 +17,4 @@ class MyClass() {
//public constructor MyClass() defined in test.MyClass //public constructor MyClass() defined in test.MyClass
//val a: test.MyClass.<init>.<no name provided> defined in test.MyClass.<init> //val a: test.MyClass.<init>.<no name provided> defined in test.MyClass.<init>
//internal final class <no name provided> : test.A defined in test.MyClass.<init> //internal final class <no name provided> : test.A defined in test.MyClass.<init>
//private constructor <no name provided>() defined in test.MyClass.<init>.<no name provided> //internal constructor <no name provided>() defined in test.MyClass.<init>.<no name provided>
@@ -15,4 +15,4 @@ class MyClass(
//public constructor MyClass(a: test.A = ...) defined in test.MyClass //public constructor MyClass(a: test.A = ...) defined in test.MyClass
//value-parameter val a: test.A = ... defined in test.MyClass.<init> //value-parameter val a: test.A = ... defined in test.MyClass.<init>
//internal final class <no name provided> : test.A defined in test.MyClass.<init> //internal final class <no name provided> : test.A defined in test.MyClass.<init>
//private constructor <no name provided>() defined in test.MyClass.<init>.<no name provided> //internal constructor <no name provided>() defined in test.MyClass.<init>.<no name provided>
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -37,6 +38,7 @@ import java.util.*;
import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*; import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isAnonymousObject;
import static org.jetbrains.k2js.translate.context.Namer.getKotlinBackingFieldName; import static org.jetbrains.k2js.translate.context.Namer.getKotlinBackingFieldName;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
@@ -418,9 +420,11 @@ public final class TranslationUtils {
public static String getSuggestedNameForInnerDeclaration(TranslationContext context, DeclarationDescriptor descriptor) { public static String getSuggestedNameForInnerDeclaration(TranslationContext context, DeclarationDescriptor descriptor) {
String suggestedName = ""; String suggestedName = "";
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
//noinspection ConstantConditions
if (containingDeclaration != null && if (containingDeclaration != null &&
!(containingDeclaration instanceof ClassOrPackageFragmentDescriptor) && !(containingDeclaration instanceof ClassOrPackageFragmentDescriptor) &&
!(containingDeclaration instanceof AnonymousFunctionDescriptor)) { !(containingDeclaration instanceof AnonymousFunctionDescriptor) &&
!(containingDeclaration instanceof ConstructorDescriptor && isAnonymousObject(containingDeclaration.getContainingDeclaration()))) {
suggestedName = context.getNameForDescriptor(containingDeclaration).getIdent(); suggestedName = context.getNameForDescriptor(containingDeclaration).getIdent();
} }
@@ -3,7 +3,7 @@ package foo
fun box(): String { fun box(): String {
var boo = "OK" var boo = "OK"
var foo = object { var foo = object {
object bar { val bar = object {
val baz = boo val baz = boo
} }
} }
@@ -2,13 +2,10 @@ package foo
class A() { class A() {
fun f(): Boolean { fun f(): Boolean {
object t {
val c = true;
}
val z = object { val z = object {
val c = true val c = true
} }
return t.c && z.c return z.c
} }
} }
@@ -4,7 +4,7 @@ class Foo {
fun bar(param: String): String { fun bar(param: String): String {
val local = "world!" val local = "world!"
var a = object { var a = object {
object b { val b = object {
val bar = param + local val bar = param + local
} }
} }