diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index 97aae00fe59..e767085e6c8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -46,7 +46,9 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; import javax.inject.Inject; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; @@ -71,18 +73,9 @@ public class CallExpressionResolver { JetType classObjectType = classifier.getClassObjectType(); if (classObjectType != null) { context.trace.record(REFERENCE_TARGET, expression, classifier); - JetType result; - if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT && classifier instanceof ClassDescriptor) { - JetScope scope = new ChainedScope(classifier, classObjectType.getMemberScope(), - getStaticNestedClassesScope((ClassDescriptor) classifier)); - result = new NamespaceType(referencedName, scope); - } - else if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT || classifier.isClassObjectAValue()) { - result = classObjectType; - } - else { + JetType result = getExtendedClassObjectType(classObjectType, referencedName, classifier, context); + if (result == null) { context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); - result = null; } return DataFlowUtils.checkType(result, expression, context); } @@ -109,6 +102,35 @@ public class CallExpressionResolver { return result[0]; } + @Nullable + private JetType getExtendedClassObjectType( + @NotNull JetType classObjectType, + @NotNull Name referencedName, + @NotNull ClassifierDescriptor classifier, + @NotNull ResolutionContext context + ) { + if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT && classifier instanceof ClassDescriptor) { + List scopes = new ArrayList(3); + + scopes.add(classObjectType.getMemberScope()); + scopes.add(getStaticNestedClassesScope((ClassDescriptor) classifier)); + + NamespaceDescriptor namespace = context.scope.getNamespace(referencedName); + if (namespace != null) { + scopes.add(namespace.getMemberScope()); + } + + JetScope scope = new ChainedScope(classifier, scopes.toArray(new JetScope[scopes.size()])); + return new NamespaceType(referencedName, scope); + } + else if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT || classifier.isClassObjectAValue()) { + return classObjectType; + } + else { + return null; + } + } + private boolean furtherNameLookup( @NotNull JetSimpleNameExpression expression, @NotNull JetType[] result, diff --git a/compiler/testData/codegen/boxWithJava/enum/staticField.java b/compiler/testData/codegen/boxWithJava/enum/staticField.java new file mode 100644 index 00000000000..b54f56ea025 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/enum/staticField.java @@ -0,0 +1,12 @@ +package test; + +import java.util.Set; +import java.util.EnumSet; + +public enum staticField { + INSTANCE; + + public static int foo = 42; + + public static final Set INSTANCES = EnumSet.of(INSTANCE); +} diff --git a/compiler/testData/codegen/boxWithJava/enum/staticField.kt b/compiler/testData/codegen/boxWithJava/enum/staticField.kt new file mode 100644 index 00000000000..b58b3e09b89 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/enum/staticField.kt @@ -0,0 +1,12 @@ +import test.staticField as E + +fun box(): String { + val instances = E.INSTANCES + if (E.foo != 42) + return "Wrong foo ${E.foo}" + if (instances.size() != 1) + return "Wrong size ${instances.size()}" + if (E.INSTANCES.iterator().next() != E.INSTANCE) + return "Wrong instance ${E.INSTANCES.iterator().next()}" + return "OK" +} diff --git a/compiler/testData/codegen/boxWithJava/enum/staticMethod.java b/compiler/testData/codegen/boxWithJava/enum/staticMethod.java new file mode 100644 index 00000000000..f6d138dadc6 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/enum/staticMethod.java @@ -0,0 +1,9 @@ +package test; + +public enum staticMethod { + ENTRY; + + public static String foo() { + return "OK"; + } +} diff --git a/compiler/testData/codegen/boxWithJava/enum/staticMethod.kt b/compiler/testData/codegen/boxWithJava/enum/staticMethod.kt new file mode 100644 index 00000000000..bdb6abfcc0d --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/enum/staticMethod.kt @@ -0,0 +1 @@ +fun box() = test.staticMethod.foo() diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index faed30bef8d..93fe73216dd 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -63,6 +63,16 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava("compiler/testData/codegen/boxWithJava/enum/simpleJavaInnerEnum.kt"); } + @TestMetadata("staticField.kt") + public void testStaticField() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/enum/staticField.kt"); + } + + @TestMetadata("staticMethod.kt") + public void testStaticMethod() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/enum/staticMethod.kt"); + } + } @TestMetadata("compiler/testData/codegen/boxWithJava/functions")