Generate package$src files for each package

This commit is contained in:
Natalia.Ukhorskaya
2013-02-28 16:01:42 +04:00
parent a9415204f6
commit faf994d872
15 changed files with 138 additions and 103 deletions
@@ -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();
}
}
@@ -3,4 +3,4 @@ fun foo() {
42
}
// 3
// 1 3
@@ -8,4 +8,4 @@ fun foo() {
}
}
// 2 3 6 7 6
// 1 2 3 6 7 6
@@ -12,4 +12,4 @@ fun foo() {
}
}
// 2 3 5 8 9 11 8
// 1 2 3 5 8 9 11 8
@@ -12,4 +12,4 @@ fun foo() {
}
}
// 2 3 5 8 9 11 8
// 1 2 3 5 8 9 11 8
@@ -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
@@ -12,4 +12,4 @@ fun foo() {
}
}
// 2 3 5 8 9 11 8
// 1 2 3 5 8 9 11 8
+1 -1
View File
@@ -12,4 +12,4 @@ fun foo(x: Int) {
}
}
// 3 4 5 9 10 11 8
// 1 3 4 5 9 10 11 8
@@ -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
@@ -1,2 +1,4 @@
fun foo(param: Int = test.lineNumber()) {
class A {
fun foo(param: Int = test.lineNumber()) {
}
}
@@ -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 {
@@ -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 {
@@ -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);
@@ -58,7 +58,7 @@ public class CompileEnvironmentTest extends TestCase {
try {
final List<String> 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);
}
@@ -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.<AnalyzerScriptParameter>emptyList());
return new JetFileAndExhaust(jetFile, exhaust);