diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 9554d174b39..54a1549bc03 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -84,8 +84,6 @@ public class NamespaceCodegen extends MemberCodegen { } public void generate(CompilationErrorHandler errorHandler) { - boolean multiFile = CodegenBinding.isMultiFileNamespace(state.getBindingContext(), name); - if (shouldGenerateNSClass(files)) { AnnotationVisitor packageClassAnnotation = v.getClassBuilder().newAnnotation(JvmStdlibNames.JET_PACKAGE_CLASS.getDescriptor(), true); packageClassAnnotation.visit(JvmStdlibNames.ABI_VERSION_NAME, JvmAbi.VERSION); @@ -95,7 +93,7 @@ public class NamespaceCodegen extends MemberCodegen { for (JetFile file : files) { VirtualFile vFile = file.getVirtualFile(); try { - generate(file, multiFile); + generate(file); } catch (ProcessCanceledException e) { throw e; @@ -117,19 +115,17 @@ public class NamespaceCodegen extends MemberCodegen { } } - private void generate(JetFile file, boolean multiFile) { + private void generate(JetFile file) { NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file); assert descriptor != null : "No namespace found for file " + file + " declared package: " + file.getPackageName(); + int countOfDeclarationsInSrcClass = 0; for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetProperty) { final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } else if (declaration instanceof JetNamedFunction) { - if (!multiFile) { - final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); - } + countOfDeclarationsInSrcClass++; } else if (declaration instanceof JetClassOrObject) { if (state.isGenerateDeclaredClasses()) { @@ -141,47 +137,38 @@ public class NamespaceCodegen extends MemberCodegen { } } - if (multiFile) { - int k = 0; + if (countOfDeclarationsInSrcClass > 0) { + String namespaceInternalName = JvmClassName.byFqNameWithoutInnerClasses( + PackageClassUtils.getPackageClassFqName(name)).getInternalName(); + String className = getMultiFileNamespaceInternalName(namespaceInternalName, file); + ClassBuilder builder = state.getFactory().forNamespacepart(className, file); + + builder.defineClass(file, V1_6, + ACC_PUBLIC | ACC_FINAL, + className, + null, + //"jet/lang/Namespace", + "java/lang/Object", + new String[0] + ); + builder.visitSource(file.getName(), null); + for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetNamedFunction) { - k++; - } - } - - if (k > 0) { - String namespaceInternalName = JvmClassName.byFqNameWithoutInnerClasses( - PackageClassUtils.getPackageClassFqName(name)).getInternalName(); - String className = getMultiFileNamespaceInternalName(namespaceInternalName, file); - ClassBuilder builder = state.getFactory().forNamespacepart(className, file); - - builder.defineClass(file, V1_6, - ACC_PUBLIC | ACC_FINAL, - className, - null, - //"jet/lang/Namespace", - "java/lang/Object", - new String[0] - ); - builder.visitSource(file.getName(), null); - - for (JetDeclaration declaration : file.getDeclarations()) { - if (declaration instanceof JetNamedFunction) { - { - final CodegenContext context = - CodegenContext.STATIC.intoNamespace(descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, builder); - } - { - final CodegenContext context = - CodegenContext.STATIC.intoNamespacePart(className, descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); - } + { + final CodegenContext context = + CodegenContext.STATIC.intoNamespace(descriptor); + genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, builder); + } + { + final CodegenContext context = + CodegenContext.STATIC.intoNamespacePart(className, descriptor); + genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } } - - builder.done(); } + + builder.done(); } } diff --git a/compiler/testData/lineNumber/custom/compileTimeConstant.kt b/compiler/testData/lineNumber/custom/compileTimeConstant.kt index 02007f8cca1..c8e380519f3 100644 --- a/compiler/testData/lineNumber/custom/compileTimeConstant.kt +++ b/compiler/testData/lineNumber/custom/compileTimeConstant.kt @@ -3,4 +3,4 @@ fun foo() { 42 } -// 3 +// 1 3 diff --git a/compiler/testData/lineNumber/custom/ifThen.kt b/compiler/testData/lineNumber/custom/ifThen.kt index b83e386da20..e7009c5eb2a 100644 --- a/compiler/testData/lineNumber/custom/ifThen.kt +++ b/compiler/testData/lineNumber/custom/ifThen.kt @@ -8,4 +8,4 @@ fun foo() { } } -// 2 3 6 7 6 +// 1 2 3 6 7 6 diff --git a/compiler/testData/lineNumber/custom/ifThenElse.kt b/compiler/testData/lineNumber/custom/ifThenElse.kt index e6949f39c57..51f59eb7dd5 100644 --- a/compiler/testData/lineNumber/custom/ifThenElse.kt +++ b/compiler/testData/lineNumber/custom/ifThenElse.kt @@ -12,4 +12,4 @@ fun foo() { } } -// 2 3 5 8 9 11 8 +// 1 2 3 5 8 9 11 8 diff --git a/compiler/testData/lineNumber/custom/tryCatchExpression.kt b/compiler/testData/lineNumber/custom/tryCatchExpression.kt index eee47b7b032..e11a367063f 100644 --- a/compiler/testData/lineNumber/custom/tryCatchExpression.kt +++ b/compiler/testData/lineNumber/custom/tryCatchExpression.kt @@ -12,4 +12,4 @@ fun foo() { } } -// 2 3 5 8 9 11 8 +// 1 2 3 5 8 9 11 8 diff --git a/compiler/testData/lineNumber/custom/tryCatchFinally.kt b/compiler/testData/lineNumber/custom/tryCatchFinally.kt index 5bbdfc0e70d..340a26f0bd1 100644 --- a/compiler/testData/lineNumber/custom/tryCatchFinally.kt +++ b/compiler/testData/lineNumber/custom/tryCatchFinally.kt @@ -16,4 +16,4 @@ fun foo() { } } -// 2 3 7 5 7 10 11 15 13 15 10 +// 1 2 3 7 5 7 10 11 15 13 15 10 diff --git a/compiler/testData/lineNumber/custom/tryFinally.kt b/compiler/testData/lineNumber/custom/tryFinally.kt index 2ccad419548..f162aa5c8b9 100644 --- a/compiler/testData/lineNumber/custom/tryFinally.kt +++ b/compiler/testData/lineNumber/custom/tryFinally.kt @@ -12,4 +12,4 @@ fun foo() { } } -// 2 3 5 8 9 11 8 +// 1 2 3 5 8 9 11 8 diff --git a/compiler/testData/lineNumber/custom/when.kt b/compiler/testData/lineNumber/custom/when.kt index 6ca520b0d75..e197f6d0975 100644 --- a/compiler/testData/lineNumber/custom/when.kt +++ b/compiler/testData/lineNumber/custom/when.kt @@ -12,4 +12,4 @@ fun foo(x: Int) { } } -// 3 4 5 9 10 11 8 +// 1 3 4 5 9 10 11 8 diff --git a/compiler/testData/lineNumber/custom/whenSubject.kt b/compiler/testData/lineNumber/custom/whenSubject.kt index 9962712b759..c7cc28cea9f 100644 --- a/compiler/testData/lineNumber/custom/whenSubject.kt +++ b/compiler/testData/lineNumber/custom/whenSubject.kt @@ -12,4 +12,4 @@ fun foo(x: Int) { } } -// 2 3 4 5 8 9 10 11 8 +// 1 2 3 4 5 8 9 10 11 8 diff --git a/compiler/testData/lineNumber/defaultParameter.kt b/compiler/testData/lineNumber/defaultParameter.kt index 445a73bec73..50876ca7a1d 100644 --- a/compiler/testData/lineNumber/defaultParameter.kt +++ b/compiler/testData/lineNumber/defaultParameter.kt @@ -1,2 +1,4 @@ -fun foo(param: Int = test.lineNumber()) { +class A { + fun foo(param: Int = test.lineNumber()) { + } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java index 43f978b7e7a..9dfadecd9bf 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java @@ -17,7 +17,11 @@ package org.jetbrains.jet.codegen; import jet.JetObject; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.ConfigurationKind; +import org.jetbrains.jet.lang.psi.JetPsiUtil; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import java.lang.annotation.*; import java.lang.reflect.Constructor; @@ -32,41 +36,65 @@ public class AnnotationGenTest extends CodegenTestCase { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL); } - public void testPropField() throws NoSuchFieldException, NoSuchMethodException { - loadText("[Deprecated] var x = 0"); - Class aClass = generateNamespaceClass(); - assertNull(aClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); - assertNull(aClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); - assertNotNull(aClass.getDeclaredField("x").getAnnotation(Deprecated.class)); + private ClassLoader loadFileGetClassLoader(@NotNull String text) { + loadText(text); + ClassFileFactory state = generateClassesInFile(); + return createClassLoader(state); } - public void testPropGetter() throws NoSuchFieldException, NoSuchMethodException { - loadText("var x = 0\n" + + private Class getPackageClass(@NotNull ClassLoader loader) throws ClassNotFoundException { + return loader.loadClass(PackageClassUtils.getPackageClassName(JetPsiUtil.getFQName(myFiles.getPsiFile()))); + } + + private Class getPackageSrcClass(@NotNull ClassLoader loader) throws ClassNotFoundException { + return loader.loadClass(NamespaceCodegen.getNamespacePartInternalName(myFiles.getPsiFile())); + } + + public void testPropField() throws Exception { + ClassLoader loader = loadFileGetClassLoader("[Deprecated] var x = 0"); + Class packageClass = getPackageClass(loader); + assertNull(packageClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); + assertNull(packageClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); + Class srcClass = getPackageSrcClass(loader); + assertNull(srcClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); + assertNull(srcClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); + assertNotNull(srcClass.getDeclaredField("x").getAnnotation(Deprecated.class)); + } + + public void testPropGetter() throws Exception { + ClassLoader loader = loadFileGetClassLoader("var x = 0\n" + "[Deprecated] get"); - - Class aClass = generateNamespaceClass(); - assertNotNull(aClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); - assertNull(aClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); - assertNull(aClass.getDeclaredField("x").getAnnotation(Deprecated.class)); + Class packageClass = getPackageClass(loader); + assertNotNull(packageClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); + assertNull(packageClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); + Class srcClass = getPackageSrcClass(loader); + assertNotNull(srcClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); + assertNull(srcClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); + assertNull(srcClass.getDeclaredField("x").getAnnotation(Deprecated.class)); } - public void testPropSetter() throws NoSuchFieldException, NoSuchMethodException { - loadText("var x = 0\n" + + public void testPropSetter() throws Exception { + ClassLoader loader = loadFileGetClassLoader("var x = 0\n" + "[Deprecated] set"); - Class aClass = generateNamespaceClass(); - assertNull(aClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); - assertNotNull(aClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); - assertNull(aClass.getDeclaredField("x").getAnnotation(Deprecated.class)); + Class packageClass = getPackageClass(loader); + assertNull(packageClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); + assertNotNull(packageClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); + Class scrClass = getPackageSrcClass(loader); + assertNull(scrClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class)); + assertNotNull(scrClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class)); + assertNull(scrClass.getDeclaredField("x").getAnnotation(Deprecated.class)); } - public void testAnnotationForParamInGlobalFunction() throws NoSuchFieldException, NoSuchMethodException { - loadText("fun x([Deprecated] i: Int) {}"); - Class aClass = generateNamespaceClass(); - Method x = aClass.getMethod("x", int.class); - assertNotNull(x); - // Get annotations for first parameter - Annotation[] annotations = x.getParameterAnnotations()[0]; - assertNotNull(getDeprecatedAnnotationFromList(annotations)); + public void testAnnotationForParamInGlobalFunction() throws Exception { + ClassLoader loader = loadFileGetClassLoader("fun x([Deprecated] i: Int) {}"); + Class packageClass = getPackageClass(loader); + Method packageClassMethod = packageClass.getMethod("x", int.class); + assertNotNull(packageClassMethod); + assertNotNull(getDeprecatedAnnotationFromList(packageClassMethod.getParameterAnnotations()[0])); + Class srcClass = getPackageSrcClass(loader); + Method srcClassMethod = srcClass.getMethod("x", int.class); + assertNotNull(srcClassMethod); + assertNotNull(getDeprecatedAnnotationFromList(srcClassMethod.getParameterAnnotations()[0])); } public void testAnnotationForParamInLocalFunction() throws NoSuchFieldException, NoSuchMethodException { @@ -102,23 +130,29 @@ public class AnnotationGenTest extends CodegenTestCase { assertNotNull(aClass.getDeclaredField("x").getAnnotation(Deprecated.class)); } - public void testAnnotationWithParamForParamInFunction() throws NoSuchFieldException, NoSuchMethodException { - loadText("import java.lang.annotation.*\n" + + public void testAnnotationWithParamForParamInFunction() throws Exception { + ClassLoader loader = loadFileGetClassLoader("import java.lang.annotation.*\n" + "Retention(RetentionPolicy.RUNTIME) annotation class A(val a: String)\n" + "fun x(A(\"239\") i: Int) {}"); - Class aClass = generateNamespaceClass(); - Method x = aClass.getMethod("x", int.class); - assertNotNull(x); - // Get annotations for first parameter - Annotation[] annotations = x.getParameterAnnotations()[0]; - Annotation resultAnnotation = null; + Class packageClass = getPackageSrcClass(loader); + Method packageClassMethod = packageClass.getMethod("x", int.class); + assertNotNull(packageClassMethod); + assertNotNull(getAnnotationByName(packageClassMethod.getParameterAnnotations()[0], "A")); + + Class srcClass = getPackageSrcClass(loader); + Method srcClassMethod = srcClass.getMethod("x", int.class); + assertNotNull(srcClassMethod); + assertNotNull(getAnnotationByName(srcClassMethod.getParameterAnnotations()[0], "A")); + } + + @Nullable + private Annotation getAnnotationByName(@NotNull Annotation[] annotations, @NotNull String name) { for (Annotation annotation : annotations) { - if (annotation.annotationType().getCanonicalName().equals("A")) { - resultAnnotation = annotation; - break; + if (annotation.annotationType().getCanonicalName().equals(name)) { + return annotation; } } - assertNotNull(resultAnnotation); + return null; } private Deprecated getDeprecatedAnnotationFromList(Annotation[] annotations) { @@ -138,12 +172,17 @@ public class AnnotationGenTest extends CodegenTestCase { assertNotNull(annotation); } - public void testMethod() throws NoSuchFieldException, NoSuchMethodException { - loadText("[Deprecated] fun x () {}"); - Class aClass = generateNamespaceClass(); - Method x = aClass.getDeclaredMethod("x"); - Deprecated annotation = (Deprecated) x.getAnnotation(Deprecated.class); - assertNotNull(annotation); + public void testMethod() throws Exception { + ClassLoader loader = loadFileGetClassLoader("[Deprecated] fun x () {}"); + + Class packageClass = getPackageClass(loader); + Method packageClassMethod = packageClass.getDeclaredMethod("x"); + assertNotNull(packageClassMethod.getAnnotation(Deprecated.class)); + + Class srcClass = getPackageSrcClass(loader); + Method srcClassMethod = srcClass.getDeclaredMethod("x"); + assertNotNull(srcClassMethod.getAnnotation(Deprecated.class)); + } public void testClass() throws NoSuchFieldException, NoSuchMethodException { diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 354ed88a663..3432596689c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -140,6 +140,12 @@ public abstract class CodegenTestCase extends UsefulTestCase { return generateClass(name.getFqName().getFqName()); } + @NotNull + protected Class generateNamespaceSrcClass() { + String name = NamespaceCodegen.getNamespacePartInternalName(myFiles.getPsiFile()); + return generateClass(name); + } + @NotNull protected Class generateClass(@NotNull String name) { try { diff --git a/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java b/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java index d69a35177a5..7347e564752 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java @@ -66,8 +66,9 @@ public class LineNumberTest extends TestCaseWithTmpdir { super.setUp(); JetCoreEnvironment environment = createEnvironment(); - JetFile psiFile = JetPsiFactory.createFile(environment.getProject(), - "package test;\n\npublic fun " + LINE_NUMBER_FUN + "(): Int = 0\n"); + JetFile psiFile = JetTestUtils.createFile(LINE_NUMBER_FUN + ".kt", + "package test;\n\npublic fun " + LINE_NUMBER_FUN + "(): Int = 0\n", + environment.getProject()); ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile); CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileEnvironmentTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileEnvironmentTest.java index 854bf2c73f6..4e8ab9b6456 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileEnvironmentTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileEnvironmentTest.java @@ -58,7 +58,7 @@ public class CompileEnvironmentTest extends TestCase { try { final List entries = listEntries(is); assertTrue(entries.contains("Smoke/" + PackageClassUtils.getPackageClassName(new FqName("Smoke")) + ".class")); - assertEquals(1, entries.size()); + assertEquals(2, entries.size()); } finally { is.close(); @@ -88,7 +88,7 @@ public class CompileEnvironmentTest extends TestCase { "-annotations", jdkAnnotations.getAbsolutePath()); Assert.assertEquals(ExitCode.OK, exitCode); assertEquals(1, out.listFiles().length); - assertEquals(1, out.listFiles()[0].listFiles().length); + assertEquals(2, out.listFiles()[0].listFiles().length); } finally { FileUtil.delete(tempDir); } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java index 2f476d18e03..6ff342a8a2c 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java @@ -144,7 +144,7 @@ public final class LoadDescriptorUtil { public static JetFileAndExhaust createJetFileAndAnalyze(@NotNull File kotlinFile, @NotNull Disposable disposable, @NotNull ConfigurationKind configurationKind) throws IOException { JetCoreEnvironment jetCoreEnvironment = createEnvironmentWithMockJdkAndIdeaAnnotations(disposable, configurationKind); - JetFile jetFile = createFile(jetCoreEnvironment.getProject(), kotlinFile.getName(), FileUtil.loadFile(kotlinFile, true)); + JetFile jetFile = JetTestUtils.createFile(kotlinFile.getName(), FileUtil.loadFile(kotlinFile, true), jetCoreEnvironment.getProject()); AnalyzeExhaust exhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( jetFile, Collections.emptyList()); return new JetFileAndExhaust(jetFile, exhaust);