From b0cea24faf47d29af6655034b9824f2a94970596 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Fri, 11 May 2012 01:08:26 +0400 Subject: [PATCH 1/3] move compileJavaFile --- .../tests/org/jetbrains/jet/JetTestUtils.java | 25 ++++++++++++++++--- .../compiler/JavaDescriptorResolverTest.java | 24 +----------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 2a89186fc65..20edf54bee1 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -38,13 +38,13 @@ import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.SlicedMap; import org.jetbrains.jet.util.slicedmap.WritableSlice; +import org.junit.Assert; +import javax.tools.*; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.nio.charset.Charset; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -304,4 +304,21 @@ public class JetTestUtils { result.delete(result.length() - 1, result.length()); return result.toString(); } + + public static void compileJavaFile(@NotNull File file, @NotNull File outputDirectory) throws IOException { + JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8")); + try { + Iterable javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(file)); + List options = Arrays.asList( + "-d", outputDirectory.getPath() + ); + JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles); + + Assert.assertTrue(task.call()); + } finally { + fileManager.close(); + } + } + } diff --git a/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/JavaDescriptorResolverTest.java b/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/JavaDescriptorResolverTest.java index c25584b1bd7..abe34ad4639 100644 --- a/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/JavaDescriptorResolverTest.java +++ b/compiler/tests/org/jetbrains/jet/cli/jvm/compiler/JavaDescriptorResolverTest.java @@ -26,14 +26,8 @@ import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.junit.Assert; -import javax.tools.*; import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Locale; /** * @author Stepan Koltsov @@ -47,7 +41,7 @@ public class JavaDescriptorResolverTest extends TestCaseWithTmpdir { } private void compileFileResolveDescriptor(@NotNull String fileRelativePath, @NotNull FqName fqName) throws IOException { - compileJavaFile(new File("compiler/testData/javaDescriptorResolver/" + fileRelativePath), tmpdir); + JetTestUtils.compileJavaFile(new File("compiler/testData/javaDescriptorResolver/" + fileRelativePath), tmpdir); JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS); jetCoreEnvironment.addToClasspath(tmpdir); @@ -58,20 +52,4 @@ public class JavaDescriptorResolverTest extends TestCaseWithTmpdir { ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); Assert.assertNotNull(classDescriptor); } - - private static void compileJavaFile(@NotNull File file, @NotNull File outputDirectory) throws IOException { - JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8")); - try { - Iterable javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(file)); - List options = Arrays.asList( - "-d", outputDirectory.getPath() - ); - JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles); - - Assert.assertTrue(task.call()); - } finally { - fileManager.close(); - } - } } From 9908791094f6ce2277dd11f2017ec131e63d35dd Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Fri, 11 May 2012 01:08:30 +0400 Subject: [PATCH 2/3] KT-1829 NoClassDefFoundError when using java inner classes #KT-1829 Fixed --- .../jet/codegen/ClassFileFactory.java | 2 +- .../jetbrains/jet/codegen/CodegenContext.java | 2 +- .../jet/codegen/FunctionCodegen.java | 2 +- .../jetbrains/jet/codegen/JetTypeMapper.java | 57 +++++++++++++++---- .../jet/codegen/NamespaceCodegen.java | 11 +--- .../jet/lang/resolve/DescriptorUtils.java | 13 +++++ .../referencesStaticInnerClassMethod.java | 5 ++ .../referencesStaticInnerClassMethod.kt | 2 + .../referencesStaticInnerClassMethodL2.java | 7 +++ .../referencesStaticInnerClassMethodL2.kt | 2 + .../jet/codegen/CodegenTestCase.java | 26 +++++++-- .../jet/codegen/FunctionGenTest.java | 25 ++++++++ .../org/jetbrains/jet/codegen/StdlibTest.java | 2 +- .../plugin/debugger/JetPositionManager.java | 4 +- 14 files changed, 131 insertions(+), 29 deletions(-) create mode 100644 compiler/testData/codegen/functions/referencesStaticInnerClassMethod.java create mode 100644 compiler/testData/codegen/functions/referencesStaticInnerClassMethod.kt create mode 100644 compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.java create mode 100644 compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index e612c693e4f..fda31b1f7c2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -64,7 +64,7 @@ public class ClassFileFactory { FqName fqName = JetPsiUtil.getFQName(file); NamespaceCodegen codegen = ns2codegen.get(fqName); if (codegen == null) { - final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName, true) + ".class"); + final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassNameForKotlinNs(fqName) + ".class"); codegen = new NamespaceCodegen(builder, fqName, state, file.getContainingFile()); ns2codegen.put(fqName, codegen); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index 23a53ed8160..869438c59eb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -113,7 +113,7 @@ public abstract class CodegenContext { while(!(descriptor instanceof NamespaceDescriptor)) { descriptor = descriptor.getContainingDeclaration(); } - return NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(descriptor).toSafe(), true); + return NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(descriptor).toSafe()); } public OwnerKind getContextKind() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index d759cf0e671..cc0fbb584fe 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -333,7 +333,7 @@ public class FunctionCodegen { String ownerInternalName; if (contextClass instanceof NamespaceDescriptor) { - ownerInternalName = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass).toSafe(), true); + ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe()); } else { ownerInternalName = state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), MapTypeMode.IMPL).getInternalName(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 02c480dd857..d5998ebd435 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.codegen; +import com.google.common.collect.Lists; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -184,28 +185,64 @@ public class JetTypeMapper { } } - private String jvmClassNameForNamespace(NamespaceDescriptor namespace) { - FqName fqName = DescriptorUtils.getFQName(namespace).toSafe(); - JavaNamespaceKind javaNamespaceKind = bindingContext.get(JavaBindingContext.JAVA_NAMESPACE_KIND, namespace); - Boolean src = bindingContext.get(BindingContext.NAMESPACE_IS_SRC, namespace); + @NotNull + private JavaNamespaceKind getNsKind(@NotNull NamespaceDescriptor ns) { + JavaNamespaceKind javaNamespaceKind = bindingContext.get(JavaBindingContext.JAVA_NAMESPACE_KIND, ns); + Boolean src = bindingContext.get(BindingContext.NAMESPACE_IS_SRC, ns); if (javaNamespaceKind == null && src == null) { - throw new IllegalStateException("unknown namespace origin: " + fqName); + throw new IllegalStateException("unknown namespace origin: " + ns); } - boolean classStatics; if (javaNamespaceKind != null) { if (javaNamespaceKind == JavaNamespaceKind.CLASS_STATICS && src != null) { throw new IllegalStateException( - "conflicting namespace " + fqName + ": it is both java statics and from src"); + "conflicting namespace " + ns + ": it is both java statics and from src"); } - classStatics = javaNamespaceKind == JavaNamespaceKind.CLASS_STATICS; + return javaNamespaceKind; } else { - classStatics = false; + return JavaNamespaceKind.PROPER; + } + } + + @NotNull + private String jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace) { + + StringBuilder r = new StringBuilder(); + + List path = DescriptorUtils.getPathWithoutRootNsAndModule(namespace); + + for (DeclarationDescriptor pathElement : path) { + NamespaceDescriptor ns = (NamespaceDescriptor) pathElement; + if (r.length() > 0) { + JavaNamespaceKind nsKind = getNsKind((NamespaceDescriptor) ns.getContainingDeclaration()); + if (nsKind == JavaNamespaceKind.PROPER) { + r.append("/"); + } + else if (nsKind == JavaNamespaceKind.CLASS_STATICS) { + r.append("$"); + } + } + if (ns.getName().length() == 0) { + throw new IllegalStateException( + "name must not be empty at this point when generating for " + namespace); + } + r.append(ns.getName()); } - return NamespaceCodegen.getJVMClassName(fqName, !classStatics); + if (getNsKind(namespace) == JavaNamespaceKind.PROPER) { + if (r.length() > 0) { + r.append("/"); + } + r.append("namespace"); + } + + if (r.length() == 0) { + throw new IllegalStateException("internal error: failed to generate classname for " + namespace); + } + + return r.toString(); } @NotNull public Type mapReturnType(@NotNull final JetType jetType) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 6478143b709..8b2e218742e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -44,7 +44,7 @@ public class NamespaceCodegen { v.defineClass(sourceFile, V1_6, ACC_PUBLIC/*|ACC_SUPER*/, - getJVMClassName(fqName, true), + getJVMClassNameForKotlinNs(fqName), null, //"jet/lang/Namespace", "java/lang/Object", @@ -137,10 +137,7 @@ public class NamespaceCodegen { v.done(); } - /** - * @param namespace true for "namespace" suffix - */ - public static String getJVMClassName(@NotNull FqName fqName, boolean namespace) { + public static String getJVMClassNameForKotlinNs(@NotNull FqName fqName) { if (fqName.isRoot()) { return JvmAbi.PACKAGE_CLASS; } @@ -149,9 +146,7 @@ public class NamespaceCodegen { if (name.startsWith(JavaDescriptorResolver.JAVA_ROOT)) { name = name.substring(JavaDescriptorResolver.JAVA_ROOT.length() + 1, name.length()); } - if (namespace) { - name += "/" + JvmAbi.PACKAGE_CLASS; - } + name += "/" + JvmAbi.PACKAGE_CLASS; return name; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 7a4386e4d3a..3a00c1f85eb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -314,6 +314,19 @@ public class DescriptorUtils { return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor; } + @NotNull + public static List getPathWithoutRootNsAndModule(@NotNull DeclarationDescriptor descriptor) { + List path = Lists.newArrayList(); + DeclarationDescriptor current = descriptor; + for (;;) { + if (current instanceof NamespaceDescriptor && isRootNamespace((NamespaceDescriptor) current)) { + return Lists.reverse(path); + } + path.add(current); + current = current.getContainingDeclaration(); + } + } + public static boolean isClassObject(@NotNull DeclarationDescriptor descriptor) { if(descriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; diff --git a/compiler/testData/codegen/functions/referencesStaticInnerClassMethod.java b/compiler/testData/codegen/functions/referencesStaticInnerClassMethod.java new file mode 100644 index 00000000000..13e35103696 --- /dev/null +++ b/compiler/testData/codegen/functions/referencesStaticInnerClassMethod.java @@ -0,0 +1,5 @@ +class R { + public static class id { + public static final int main = 17; + } +} diff --git a/compiler/testData/codegen/functions/referencesStaticInnerClassMethod.kt b/compiler/testData/codegen/functions/referencesStaticInnerClassMethod.kt new file mode 100644 index 00000000000..ff96695b7cf --- /dev/null +++ b/compiler/testData/codegen/functions/referencesStaticInnerClassMethod.kt @@ -0,0 +1,2 @@ +fun box() = + if (R.id.main == 17) "OK" else "fail" diff --git a/compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.java b/compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.java new file mode 100644 index 00000000000..4ccb93887ab --- /dev/null +++ b/compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.java @@ -0,0 +1,7 @@ +class R { + public static class id { + public static class zzz { + public static final int main = 17; + } + } +} diff --git a/compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.kt b/compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.kt new file mode 100644 index 00000000000..dfd0c4f6603 --- /dev/null +++ b/compiler/testData/codegen/functions/referencesStaticInnerClassMethodL2.kt @@ -0,0 +1,2 @@ +fun box() = + if (R.id.zzz.main == 17) "OK" else "fail" diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 947cfa6f98a..8cc7e6a4b01 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -16,9 +16,9 @@ package org.jetbrains.jet.codegen; +import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.CompileCompilerDependenciesTest; import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; @@ -26,20 +26,31 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; -import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.parsing.JetParsingTest; +import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; import java.util.Collections; +import java.util.List; /** * @author yole */ public abstract class CodegenTestCase extends JetLiteFixture { + // for environment and classloader + private List extraClasspath = Lists.newArrayList(); + + protected void addToClasspath(@NotNull File file) { + myEnvironment.addToClasspath(file); + extraClasspath.add(file); + } + protected static void assertThrows(Method foo, Class exceptionClass, Object instance, Object... args) throws IllegalAccessException { boolean caught = false; try { @@ -108,7 +119,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { GeneratedClassLoader loader = createClassLoader(codegens); try { - String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).replace("/", "."); Class namespaceClass = loader.loadClass(fqName); Method method = namespaceClass.getMethod("box"); return (String) method.invoke(null); @@ -118,7 +129,12 @@ public abstract class CodegenTestCase extends JetLiteFixture { } protected GeneratedClassLoader createClassLoader(ClassFileFactory codegens) throws MalformedURLException { - return new GeneratedClassLoader(codegens); + List urls = Lists.newArrayList(); + for (File file : extraClasspath) { + urls.add(file.toURI().toURL()); + } + ClassLoader parentClassLoader = new URLClassLoader(urls.toArray(new URL[0]), CodegenTestCase.class.getClassLoader()); + return new GeneratedClassLoader(codegens, parentClassLoader); } protected String generateToText() { @@ -147,7 +163,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { } protected Class loadRootNamespaceClass(@NotNull ClassFileFactory state) { - String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).replace("/", "."); try { return createClassLoader(state).loadClass(fqName); } catch (ClassNotFoundException e) { diff --git a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java index be5743cbb3b..67fd1abe0a4 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java @@ -16,8 +16,12 @@ package org.jetbrains.jet.codegen; +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; +import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -113,4 +117,25 @@ public class FunctionGenTest extends CodegenTestCase { public void testInvoke() { blackBoxFile("functions/invoke.kt"); } + + private void blackBoxFileWithJava(@NotNull String ktFile) throws Exception { + File javaClassesTempDirectory = new File(FileUtil.getTempDirectory(), "java-classes"); + JetTestUtils.mkdirs(javaClassesTempDirectory); + JetTestUtils.compileJavaFile( + new File("compiler/testData/codegen/" + ktFile.replaceFirst("\\.kt$", ".java")), + javaClassesTempDirectory); + + addToClasspath(javaClassesTempDirectory); + + blackBoxFile(ktFile); + } + + public void testReferencesStaticInnerClassMethod() throws Exception { + blackBoxFileWithJava("functions/referencesStaticInnerClassMethod.kt"); + } + + public void testReferencesStaticInnerClassMethodTwoLevels() throws Exception { + blackBoxFileWithJava("functions/referencesStaticInnerClassMethodL2.kt"); + } + } diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index 6e18a9aa08c..b9e4440a3c0 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -146,7 +146,7 @@ public class StdlibTest extends CodegenTestCase { GeneratedClassLoader loader = createClassLoader(codegens); try { - String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).replace("/", "."); Class namespaceClass = loader.loadClass(fqName); Method method = namespaceClass.getMethod("box", Method.class); method.setAccessible(true); diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index 5c2f3d532e5..8a6701c4155 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -137,10 +137,10 @@ public class JetPositionManager implements PositionManager { else { JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class); if (namespace != null) { - names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(namespace), true)); + names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace))); } else { - names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(file), true)); + names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(file))); } } } From ded824468a0662c48cf5e0097c39cef34faeee0f Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Fri, 11 May 2012 01:08:33 +0400 Subject: [PATCH 3/3] replace String with JvmClassName --- .../jetbrains/jet/codegen/ClassFileFactory.java | 2 +- .../org/jetbrains/jet/codegen/CodegenContext.java | 2 +- .../jetbrains/jet/codegen/FunctionCodegen.java | 15 ++++++++------- .../org/jetbrains/jet/codegen/JetTypeMapper.java | 8 ++++---- .../jetbrains/jet/codegen/NamespaceCodegen.java | 10 ++++++---- .../jet/lang/resolve/java/JvmClassName.java | 8 ++++++++ .../jetbrains/jet/codegen/CodegenTestCase.java | 4 ++-- .../org/jetbrains/jet/codegen/StdlibTest.java | 2 +- .../jet/plugin/debugger/JetPositionManager.java | 4 ++-- 9 files changed, 33 insertions(+), 22 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index fda31b1f7c2..e7d37753ff4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -64,7 +64,7 @@ public class ClassFileFactory { FqName fqName = JetPsiUtil.getFQName(file); NamespaceCodegen codegen = ns2codegen.get(fqName); if (codegen == null) { - final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassNameForKotlinNs(fqName) + ".class"); + final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassNameForKotlinNs(fqName).getInternalName() + ".class"); codegen = new NamespaceCodegen(builder, fqName, state, file.getContainingFile()); ns2codegen.put(fqName, codegen); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index 869438c59eb..c6c77561c07 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -113,7 +113,7 @@ public abstract class CodegenContext { while(!(descriptor instanceof NamespaceDescriptor)) { descriptor = descriptor.getContainingDeclaration(); } - return NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(descriptor).toSafe()); + return NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(descriptor).toSafe()).getInternalName(); } public OwnerKind getContextKind() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index cc0fbb584fe..c1fe5b713bd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.objectweb.asm.Label; @@ -331,18 +332,18 @@ public class FunctionCodegen { int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO. - String ownerInternalName; + JvmClassName ownerInternalName; if (contextClass instanceof NamespaceDescriptor) { ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe()); } else { - ownerInternalName = state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), MapTypeMode.IMPL).getInternalName(); + ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), MapTypeMode.IMPL)); } String descriptor = jvmSignature.getDescriptor().replace(")","I)"); boolean isConstructor = "".equals(jvmSignature.getName()); if(!isStatic && !isConstructor) - descriptor = descriptor.replace("(","(L" + ownerInternalName + ";"); + descriptor = descriptor.replace("(", "(" + ownerInternalName.getDescriptor()); final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null); InstructionAdapter iv = new InstructionAdapter(mv); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { @@ -425,17 +426,17 @@ public class FunctionCodegen { if(!isStatic) { if(kind == OwnerKind.TRAIT_IMPL) { - iv.invokeinterface(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor()); + iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); } else { if(!isConstructor) - iv.invokevirtual(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor()); + iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); else - iv.invokespecial(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor()); + iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); } } else { - iv.invokestatic(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor()); + iv.invokestatic(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); } iv.areturn(jvmSignature.getReturnType()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index d5998ebd435..8fa866ed2ef 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -149,7 +149,7 @@ public class JetTypeMapper { String owner; DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration instanceof NamespaceDescriptor) { - owner = jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration); + owner = jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration).getInternalName(); } else if (containingDeclaration instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; @@ -207,7 +207,7 @@ public class JetTypeMapper { } @NotNull - private String jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace) { + private JvmClassName jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace) { StringBuilder r = new StringBuilder(); @@ -242,7 +242,7 @@ public class JetTypeMapper { throw new IllegalStateException("internal error: failed to generate classname for " + namespace); } - return r.toString(); + return JvmClassName.byInternalName(r.toString()); } @NotNull public Type mapReturnType(@NotNull final JetType jetType) { @@ -541,7 +541,7 @@ public class JetTypeMapper { ClassDescriptor thisClass; if (functionParent instanceof NamespaceDescriptor) { assert !superCall; - owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent); + owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent).getInternalName(); ownerForDefaultImpl = ownerForDefaultParam = owner; invokeOpcode = INVOKESTATIC; thisClass = null; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 8b2e218742e..b1b4f7c6251 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; @@ -44,7 +45,7 @@ public class NamespaceCodegen { v.defineClass(sourceFile, V1_6, ACC_PUBLIC/*|ACC_SUPER*/, - getJVMClassNameForKotlinNs(fqName), + getJVMClassNameForKotlinNs(fqName).getInternalName(), null, //"jet/lang/Namespace", "java/lang/Object", @@ -137,9 +138,10 @@ public class NamespaceCodegen { v.done(); } - public static String getJVMClassNameForKotlinNs(@NotNull FqName fqName) { + @NotNull + public static JvmClassName getJVMClassNameForKotlinNs(@NotNull FqName fqName) { if (fqName.isRoot()) { - return JvmAbi.PACKAGE_CLASS; + return JvmClassName.byInternalName(JvmAbi.PACKAGE_CLASS); } String name = fqName.getFqName().replace('.', '/'); @@ -147,6 +149,6 @@ public class NamespaceCodegen { name = name.substring(JavaDescriptorResolver.JAVA_ROOT.length() + 1, name.length()); } name += "/" + JvmAbi.PACKAGE_CLASS; - return name; + return JvmClassName.byInternalName(name); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java index 4d630efd16f..ba9786826ef 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java @@ -42,6 +42,14 @@ public class JvmClassName { return r; } + public static JvmClassName byType(@NotNull Type type) { + if (type.getSort() != Type.OBJECT) { + throw new IllegalArgumentException( + "must be an object to be converted to " + JvmClassName.class.getSimpleName()); + } + return byInternalName(type.getInternalName()); + } + @NotNull public FqName getFqName() { return fqName; diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 8cc7e6a4b01..9127ce36391 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -119,7 +119,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { GeneratedClassLoader loader = createClassLoader(codegens); try { - String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).getFqName().getFqName(); Class namespaceClass = loader.loadClass(fqName); Method method = namespaceClass.getMethod("box"); return (String) method.invoke(null); @@ -163,7 +163,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { } protected Class loadRootNamespaceClass(@NotNull ClassFileFactory state) { - String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).getFqName().getFqName(); try { return createClassLoader(state).loadClass(fqName); } catch (ClassNotFoundException e) { diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index b9e4440a3c0..6333a97ac2a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -146,7 +146,7 @@ public class StdlibTest extends CodegenTestCase { GeneratedClassLoader loader = createClassLoader(codegens); try { - String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).getFqName().getFqName(); Class namespaceClass = loader.loadClass(fqName); Method method = namespaceClass.getMethod("box", Method.class); method.setAccessible(true); diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index 8a6701c4155..5c81d38e28c 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -137,10 +137,10 @@ public class JetPositionManager implements PositionManager { else { JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class); if (namespace != null) { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace))); + names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace)).getInternalName()); } else { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(file))); + names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(file)).getInternalName()); } } }