Merge branch 'master' of github.com:JetBrains/kotlin
This commit is contained in:
@@ -64,7 +64,7 @@ public class ClassFileFactory {
|
|||||||
FqName fqName = JetPsiUtil.getFQName(file);
|
FqName fqName = JetPsiUtil.getFQName(file);
|
||||||
NamespaceCodegen codegen = ns2codegen.get(fqName);
|
NamespaceCodegen codegen = ns2codegen.get(fqName);
|
||||||
if (codegen == null) {
|
if (codegen == null) {
|
||||||
final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName, true) + ".class");
|
final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassNameForKotlinNs(fqName).getInternalName() + ".class");
|
||||||
codegen = new NamespaceCodegen(builder, fqName, state, file.getContainingFile());
|
codegen = new NamespaceCodegen(builder, fqName, state, file.getContainingFile());
|
||||||
ns2codegen.put(fqName, codegen);
|
ns2codegen.put(fqName, codegen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public abstract class CodegenContext {
|
|||||||
while(!(descriptor instanceof NamespaceDescriptor)) {
|
while(!(descriptor instanceof NamespaceDescriptor)) {
|
||||||
descriptor = descriptor.getContainingDeclaration();
|
descriptor = descriptor.getContainingDeclaration();
|
||||||
}
|
}
|
||||||
return NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(descriptor).toSafe(), true);
|
return NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(descriptor).toSafe()).getInternalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public OwnerKind getContextKind() {
|
public OwnerKind getContextKind() {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
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.java.JvmStdlibNames;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
@@ -331,18 +332,18 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
|
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
|
||||||
|
|
||||||
String ownerInternalName;
|
JvmClassName ownerInternalName;
|
||||||
if (contextClass instanceof NamespaceDescriptor) {
|
if (contextClass instanceof NamespaceDescriptor) {
|
||||||
ownerInternalName = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass).toSafe(), true);
|
ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe());
|
||||||
}
|
}
|
||||||
else {
|
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)");
|
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
||||||
boolean isConstructor = "<init>".equals(jvmSignature.getName());
|
boolean isConstructor = "<init>".equals(jvmSignature.getName());
|
||||||
if(!isStatic && !isConstructor)
|
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 ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null);
|
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null);
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||||
@@ -425,17 +426,17 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
if(!isStatic) {
|
if(!isStatic) {
|
||||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||||
iv.invokeinterface(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
|
iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!isConstructor)
|
if(!isConstructor)
|
||||||
iv.invokevirtual(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
|
iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||||
else
|
else
|
||||||
iv.invokespecial(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
|
iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iv.invokestatic(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
|
iv.invokestatic(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
iv.areturn(jvmSignature.getReturnType());
|
iv.areturn(jvmSignature.getReturnType());
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -148,7 +149,7 @@ public class JetTypeMapper {
|
|||||||
String owner;
|
String owner;
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
if (containingDeclaration instanceof NamespaceDescriptor) {
|
if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||||
owner = jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration);
|
owner = jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration).getInternalName();
|
||||||
}
|
}
|
||||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||||
@@ -184,28 +185,64 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String jvmClassNameForNamespace(NamespaceDescriptor namespace) {
|
@NotNull
|
||||||
FqName fqName = DescriptorUtils.getFQName(namespace).toSafe();
|
private JavaNamespaceKind getNsKind(@NotNull NamespaceDescriptor ns) {
|
||||||
JavaNamespaceKind javaNamespaceKind = bindingContext.get(JavaBindingContext.JAVA_NAMESPACE_KIND, namespace);
|
JavaNamespaceKind javaNamespaceKind = bindingContext.get(JavaBindingContext.JAVA_NAMESPACE_KIND, ns);
|
||||||
Boolean src = bindingContext.get(BindingContext.NAMESPACE_IS_SRC, namespace);
|
Boolean src = bindingContext.get(BindingContext.NAMESPACE_IS_SRC, ns);
|
||||||
|
|
||||||
if (javaNamespaceKind == null && src == null) {
|
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 != null) {
|
||||||
if (javaNamespaceKind == JavaNamespaceKind.CLASS_STATICS && src != null) {
|
if (javaNamespaceKind == JavaNamespaceKind.CLASS_STATICS && src != null) {
|
||||||
throw new IllegalStateException(
|
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 {
|
else {
|
||||||
classStatics = false;
|
return JavaNamespaceKind.PROPER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JvmClassName jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace) {
|
||||||
|
|
||||||
|
StringBuilder r = new StringBuilder();
|
||||||
|
|
||||||
|
List<DeclarationDescriptor> 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 JvmClassName.byInternalName(r.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapReturnType(@NotNull final JetType jetType) {
|
@NotNull public Type mapReturnType(@NotNull final JetType jetType) {
|
||||||
@@ -504,7 +541,7 @@ public class JetTypeMapper {
|
|||||||
ClassDescriptor thisClass;
|
ClassDescriptor thisClass;
|
||||||
if (functionParent instanceof NamespaceDescriptor) {
|
if (functionParent instanceof NamespaceDescriptor) {
|
||||||
assert !superCall;
|
assert !superCall;
|
||||||
owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent);
|
owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent).getInternalName();
|
||||||
ownerForDefaultImpl = ownerForDefaultParam = owner;
|
ownerForDefaultImpl = ownerForDefaultParam = owner;
|
||||||
invokeOpcode = INVOKESTATIC;
|
invokeOpcode = INVOKESTATIC;
|
||||||
thisClass = null;
|
thisClass = null;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.FqName;
|
import org.jetbrains.jet.lang.resolve.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
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.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
@@ -44,7 +45,7 @@ public class NamespaceCodegen {
|
|||||||
|
|
||||||
v.defineClass(sourceFile, V1_6,
|
v.defineClass(sourceFile, V1_6,
|
||||||
ACC_PUBLIC/*|ACC_SUPER*/,
|
ACC_PUBLIC/*|ACC_SUPER*/,
|
||||||
getJVMClassName(fqName, true),
|
getJVMClassNameForKotlinNs(fqName).getInternalName(),
|
||||||
null,
|
null,
|
||||||
//"jet/lang/Namespace",
|
//"jet/lang/Namespace",
|
||||||
"java/lang/Object",
|
"java/lang/Object",
|
||||||
@@ -137,21 +138,17 @@ public class NamespaceCodegen {
|
|||||||
v.done();
|
v.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@NotNull
|
||||||
* @param namespace true for "namespace" suffix
|
public static JvmClassName getJVMClassNameForKotlinNs(@NotNull FqName fqName) {
|
||||||
*/
|
|
||||||
public static String getJVMClassName(@NotNull FqName fqName, boolean namespace) {
|
|
||||||
if (fqName.isRoot()) {
|
if (fqName.isRoot()) {
|
||||||
return JvmAbi.PACKAGE_CLASS;
|
return JvmClassName.byInternalName(JvmAbi.PACKAGE_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = fqName.getFqName().replace('.', '/');
|
String name = fqName.getFqName().replace('.', '/');
|
||||||
if (name.startsWith(JavaDescriptorResolver.JAVA_ROOT)) {
|
if (name.startsWith(JavaDescriptorResolver.JAVA_ROOT)) {
|
||||||
name = name.substring(JavaDescriptorResolver.JAVA_ROOT.length() + 1, name.length());
|
name = name.substring(JavaDescriptorResolver.JAVA_ROOT.length() + 1, name.length());
|
||||||
}
|
}
|
||||||
if (namespace) {
|
name += "/" + JvmAbi.PACKAGE_CLASS;
|
||||||
name += "/" + JvmAbi.PACKAGE_CLASS;
|
return JvmClassName.byInternalName(name);
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,14 @@ public class JvmClassName {
|
|||||||
return r;
|
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
|
@NotNull
|
||||||
public FqName getFqName() {
|
public FqName getFqName() {
|
||||||
return fqName;
|
return fqName;
|
||||||
|
|||||||
@@ -314,6 +314,19 @@ public class DescriptorUtils {
|
|||||||
return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor;
|
return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<DeclarationDescriptor> getPathWithoutRootNsAndModule(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
List<DeclarationDescriptor> 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) {
|
public static boolean isClassObject(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if(descriptor instanceof ClassDescriptor) {
|
if(descriptor instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class R {
|
||||||
|
public static class id {
|
||||||
|
public static final int main = 17;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fun box() =
|
||||||
|
if (R.id.main == 17) "OK" else "fail"
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class R {
|
||||||
|
public static class id {
|
||||||
|
public static class zzz {
|
||||||
|
public static final int main = 17;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fun box() =
|
||||||
|
if (R.id.zzz.main == 17) "OK" else "fail"
|
||||||
@@ -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.ReadOnlySlice;
|
||||||
import org.jetbrains.jet.util.slicedmap.SlicedMap;
|
import org.jetbrains.jet.util.slicedmap.SlicedMap;
|
||||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
import javax.tools.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -304,4 +304,21 @@ public class JetTestUtils {
|
|||||||
result.delete(result.length() - 1, result.length());
|
result.delete(result.length() - 1, result.length());
|
||||||
return result.toString();
|
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<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(file));
|
||||||
|
List<String> options = Arrays.asList(
|
||||||
|
"-d", outputDirectory.getPath()
|
||||||
|
);
|
||||||
|
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
|
||||||
|
|
||||||
|
Assert.assertTrue(task.call());
|
||||||
|
} finally {
|
||||||
|
fileManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,8 @@ import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
import javax.tools.*;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
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
|
* @author Stepan Koltsov
|
||||||
@@ -47,7 +41,7 @@ public class JavaDescriptorResolverTest extends TestCaseWithTmpdir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void compileFileResolveDescriptor(@NotNull String fileRelativePath, @NotNull FqName fqName) throws IOException {
|
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 jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
|
||||||
jetCoreEnvironment.addToClasspath(tmpdir);
|
jetCoreEnvironment.addToClasspath(tmpdir);
|
||||||
@@ -58,20 +52,4 @@ public class JavaDescriptorResolverTest extends TestCaseWithTmpdir {
|
|||||||
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||||
Assert.assertNotNull(classDescriptor);
|
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<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(file));
|
|
||||||
List<String> options = Arrays.asList(
|
|
||||||
"-d", outputDirectory.getPath()
|
|
||||||
);
|
|
||||||
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
|
|
||||||
|
|
||||||
Assert.assertTrue(task.call());
|
|
||||||
} finally {
|
|
||||||
fileManager.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
|
||||||
import org.jetbrains.jet.JetLiteFixture;
|
import org.jetbrains.jet.JetLiteFixture;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
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.psi.JetPsiUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
|
||||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public abstract class CodegenTestCase extends JetLiteFixture {
|
public abstract class CodegenTestCase extends JetLiteFixture {
|
||||||
|
|
||||||
|
// for environment and classloader
|
||||||
|
private List<File> extraClasspath = Lists.newArrayList();
|
||||||
|
|
||||||
|
protected void addToClasspath(@NotNull File file) {
|
||||||
|
myEnvironment.addToClasspath(file);
|
||||||
|
extraClasspath.add(file);
|
||||||
|
}
|
||||||
|
|
||||||
protected static void assertThrows(Method foo, Class<? extends Throwable> exceptionClass, Object instance, Object... args) throws IllegalAccessException {
|
protected static void assertThrows(Method foo, Class<? extends Throwable> exceptionClass, Object instance, Object... args) throws IllegalAccessException {
|
||||||
boolean caught = false;
|
boolean caught = false;
|
||||||
try {
|
try {
|
||||||
@@ -108,7 +119,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
|
|||||||
GeneratedClassLoader loader = createClassLoader(codegens);
|
GeneratedClassLoader loader = createClassLoader(codegens);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
|
String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).getFqName().getFqName();
|
||||||
Class<?> namespaceClass = loader.loadClass(fqName);
|
Class<?> namespaceClass = loader.loadClass(fqName);
|
||||||
Method method = namespaceClass.getMethod("box");
|
Method method = namespaceClass.getMethod("box");
|
||||||
return (String) method.invoke(null);
|
return (String) method.invoke(null);
|
||||||
@@ -118,7 +129,12 @@ public abstract class CodegenTestCase extends JetLiteFixture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected GeneratedClassLoader createClassLoader(ClassFileFactory codegens) throws MalformedURLException {
|
protected GeneratedClassLoader createClassLoader(ClassFileFactory codegens) throws MalformedURLException {
|
||||||
return new GeneratedClassLoader(codegens);
|
List<URL> 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() {
|
protected String generateToText() {
|
||||||
@@ -147,7 +163,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Class loadRootNamespaceClass(@NotNull ClassFileFactory state) {
|
protected Class loadRootNamespaceClass(@NotNull ClassFileFactory state) {
|
||||||
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
|
String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).getFqName().getFqName();
|
||||||
try {
|
try {
|
||||||
return createClassLoader(state).loadClass(fqName);
|
return createClassLoader(state).loadClass(fqName);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
|||||||
@@ -16,8 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
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 org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@@ -113,4 +117,25 @@ public class FunctionGenTest extends CodegenTestCase {
|
|||||||
public void testInvoke() {
|
public void testInvoke() {
|
||||||
blackBoxFile("functions/invoke.kt");
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ public class StdlibTest extends CodegenTestCase {
|
|||||||
GeneratedClassLoader loader = createClassLoader(codegens);
|
GeneratedClassLoader loader = createClassLoader(codegens);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
|
String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFile)).getFqName().getFqName();
|
||||||
Class<?> namespaceClass = loader.loadClass(fqName);
|
Class<?> namespaceClass = loader.loadClass(fqName);
|
||||||
Method method = namespaceClass.getMethod("box", Method.class);
|
Method method = namespaceClass.getMethod("box", Method.class);
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
|
|||||||
@@ -137,10 +137,10 @@ public class JetPositionManager implements PositionManager {
|
|||||||
else {
|
else {
|
||||||
JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class);
|
JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class);
|
||||||
if (namespace != null) {
|
if (namespace != null) {
|
||||||
names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(namespace), true));
|
names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace)).getInternalName());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(file), true));
|
names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(file)).getInternalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user