codegen: fix calls to global functions when loaded from java descriptors
This commit is contained in:
@@ -35,7 +35,7 @@ public class ClassFileFactory {
|
|||||||
String fqName = JetPsiUtil.getFQName(file);
|
String 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) + ".class");
|
final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName, true) + ".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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,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));
|
return NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(descriptor), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OwnerKind getContextKind() {
|
public OwnerKind getContextKind() {
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ public class FunctionCodegen {
|
|||||||
int flags = ACC_PUBLIC; // TODO.
|
int flags = ACC_PUBLIC; // TODO.
|
||||||
|
|
||||||
String ownerInternalName = contextClass instanceof NamespaceDescriptor ?
|
String ownerInternalName = contextClass instanceof NamespaceDescriptor ?
|
||||||
NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass)) :
|
NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass), true) :
|
||||||
state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||||
|
|
||||||
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
||||||
|
|||||||
@@ -92,8 +92,11 @@ public class JetTypeMapper {
|
|||||||
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
||||||
String owner;
|
String owner;
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
if (containingDeclaration instanceof NamespaceDescriptor) {
|
if (containingDeclaration instanceof JavaNamespaceDescriptor) {
|
||||||
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName((NamespaceDescriptor) containingDeclaration));
|
JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) containingDeclaration;
|
||||||
|
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName((NamespaceDescriptor) containingDeclaration), javaNamespaceDescriptor.isNamespace());
|
||||||
|
} else if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||||
|
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName((NamespaceDescriptor) containingDeclaration), true);
|
||||||
}
|
}
|
||||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||||
@@ -365,7 +368,11 @@ public class JetTypeMapper {
|
|||||||
ClassDescriptor thisClass;
|
ClassDescriptor thisClass;
|
||||||
if (functionParent instanceof NamespaceDescriptor) {
|
if (functionParent instanceof NamespaceDescriptor) {
|
||||||
assert !superCall;
|
assert !superCall;
|
||||||
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(functionParent));
|
boolean namespace = true;
|
||||||
|
if (functionParent instanceof JavaNamespaceDescriptor) {
|
||||||
|
namespace = ((JavaNamespaceDescriptor) functionParent).isNamespace();
|
||||||
|
}
|
||||||
|
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(functionParent), namespace);
|
||||||
invokeOpcode = INVOKESTATIC;
|
invokeOpcode = INVOKESTATIC;
|
||||||
thisClass = null;
|
thisClass = null;
|
||||||
}
|
}
|
||||||
@@ -711,7 +718,7 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
String baseName;
|
String baseName;
|
||||||
if (container instanceof JetFile) {
|
if (container instanceof JetFile) {
|
||||||
baseName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(((JetFile) container)));
|
baseName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(((JetFile) container)), true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container);
|
ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class NamespaceCodegen {
|
|||||||
|
|
||||||
v.defineClass(sourceFile, V1_6,
|
v.defineClass(sourceFile, V1_6,
|
||||||
ACC_PUBLIC/*|ACC_SUPER*/,
|
ACC_PUBLIC/*|ACC_SUPER*/,
|
||||||
getJVMClassName(fqName),
|
getJVMClassName(fqName, true),
|
||||||
null,
|
null,
|
||||||
//"jet/lang/Namespace",
|
//"jet/lang/Namespace",
|
||||||
"java/lang/Object",
|
"java/lang/Object",
|
||||||
@@ -118,7 +118,7 @@ public class NamespaceCodegen {
|
|||||||
|
|
||||||
private void generateTypeInfoFields(JetFile file, CodegenContext context) {
|
private void generateTypeInfoFields(JetFile file, CodegenContext context) {
|
||||||
if(context.typeInfoConstants != null) {
|
if(context.typeInfoConstants != null) {
|
||||||
String jvmClassName = getJVMClassName(JetPsiUtil.getFQName(file));
|
String jvmClassName = getJVMClassName(JetPsiUtil.getFQName(file), true);
|
||||||
for(int index = 0; index != context.typeInfoConstantsCount; index++) {
|
for(int index = 0; index != context.typeInfoConstantsCount; index++) {
|
||||||
JetType type = context.reverseTypeInfoConstants.get(index);
|
JetType type = context.reverseTypeInfoConstants.get(index);
|
||||||
String fieldName = "$typeInfoCache$" + index;
|
String fieldName = "$typeInfoCache$" + index;
|
||||||
@@ -205,14 +205,20 @@ public class NamespaceCodegen {
|
|||||||
v.done();
|
v.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getJVMClassName(String fqName) {
|
/**
|
||||||
|
* @param namespace true for "namespace" suffix
|
||||||
|
*/
|
||||||
|
public static String getJVMClassName(String fqName, boolean namespace) {
|
||||||
if (fqName.length() == 0) {
|
if (fqName.length() == 0) {
|
||||||
return JvmAbi.PACKAGE_CLASS;
|
return JvmAbi.PACKAGE_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = fqName.replace('.', '/') + "/" + JvmAbi.PACKAGE_CLASS;
|
String name = fqName.replace('.', '/');
|
||||||
if(name.startsWith("<java_root>")) {
|
if(name.startsWith("<java_root>")) {
|
||||||
name = name.substring("<java_root>".length() + 1, name.length() - 1 - JvmAbi.PACKAGE_CLASS.length());
|
name = name.substring("<java_root>".length() + 1, name.length());
|
||||||
|
}
|
||||||
|
if (namespace) {
|
||||||
|
name += "/" + JvmAbi.PACKAGE_CLASS;
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -633,7 +633,8 @@ public class JavaDescriptorResolver {
|
|||||||
resolveParentDescriptor(psiPackage),
|
resolveParentDescriptor(psiPackage),
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
name == null ? JAVA_ROOT : name,
|
name == null ? JAVA_ROOT : name,
|
||||||
name == null ? JAVA_ROOT : psiPackage.getQualifiedName()
|
name == null ? JAVA_ROOT : psiPackage.getQualifiedName(),
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
namespaceData.namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceData.namespaceDescriptor, semanticServices));
|
namespaceData.namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceData.namespaceDescriptor, semanticServices));
|
||||||
@@ -657,7 +658,8 @@ public class JavaDescriptorResolver {
|
|||||||
resolveParentDescriptor(psiClass),
|
resolveParentDescriptor(psiClass),
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
psiClass.getName(),
|
psiClass.getName(),
|
||||||
psiClass.getQualifiedName()
|
psiClass.getQualifiedName(),
|
||||||
|
false
|
||||||
);
|
);
|
||||||
namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true));
|
namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true));
|
||||||
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor);
|
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor);
|
||||||
|
|||||||
+8
-1
@@ -14,11 +14,14 @@ import java.util.List;
|
|||||||
public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
||||||
private JetScope memberScope;
|
private JetScope memberScope;
|
||||||
private final String qualifiedName;
|
private final String qualifiedName;
|
||||||
|
/** Namespace of class with static methods */
|
||||||
|
private final boolean namespace;
|
||||||
|
|
||||||
public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List<AnnotationDescriptor> annotations,
|
public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List<AnnotationDescriptor> annotations,
|
||||||
@NotNull String name, @NotNull String qualifiedName) {
|
@NotNull String name, @NotNull String qualifiedName, boolean namespace) {
|
||||||
super(containingDeclaration, annotations, name);
|
super(containingDeclaration, annotations, name);
|
||||||
this.qualifiedName = qualifiedName;
|
this.qualifiedName = qualifiedName;
|
||||||
|
this.namespace = namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemberScope(@NotNull JetScope memberScope) {
|
public void setMemberScope(@NotNull JetScope memberScope) {
|
||||||
@@ -34,4 +37,8 @@ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
|||||||
public String getQualifiedName() {
|
public String getQualifiedName() {
|
||||||
return qualifiedName;
|
return qualifiedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNamespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
|
|||||||
ClassFileFactory codegens = generateClassesInFile();
|
ClassFileFactory codegens = generateClassesInFile();
|
||||||
GeneratedClassLoader loader = new GeneratedClassLoader(codegens);
|
GeneratedClassLoader loader = new GeneratedClassLoader(codegens);
|
||||||
|
|
||||||
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile)).replace("/", ".");
|
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
|
||||||
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);
|
||||||
@@ -111,7 +111,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)).replace("/", ".");
|
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
|
||||||
Map<String, Class> classMap = loadAllClasses(state);
|
Map<String, Class> classMap = loadAllClasses(state);
|
||||||
return classMap.get(fqName);
|
return classMap.get(fqName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,10 +119,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)));
|
names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(namespace), true));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(file)));
|
names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(file), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user