FqName class

for type safety, to easier distinguish between:

* short names
* qualified names
* jvm names (slash-separated)
* special names like <root>
* null values that mean "undefined" and "root ns" in different contexts
This commit is contained in:
Stepan Koltsov
2012-03-13 21:51:38 +04:00
parent 15078b1b70
commit 82d77560a2
41 changed files with 434 additions and 222 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.FqName;
import java.util.*;
@@ -26,7 +27,7 @@ import java.util.*;
*/
public class ClassFileFactory {
private final ClassBuilderFactory builderFactory;
private final Map<String, NamespaceCodegen> ns2codegen = new HashMap<String, NamespaceCodegen>();
private final Map<FqName, NamespaceCodegen> ns2codegen = new HashMap<FqName, NamespaceCodegen>();
private final Map<String, ClassBuilder> generators = new LinkedHashMap<String, ClassBuilder>();
private boolean isDone = false;
public final GenerationState state;
@@ -48,7 +49,7 @@ public class ClassFileFactory {
NamespaceCodegen forNamespace(JetFile file) {
assert !isDone : "Already done!";
String fqName = JetPsiUtil.getFQName(file);
FqName fqName = JetPsiUtil.getFQName(file);
NamespaceCodegen codegen = ns2codegen.get(fqName);
if (codegen == null) {
final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName, true) + ".class");
@@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
@@ -37,7 +38,7 @@ public class ClosureAnnotator {
private final Map<FunctionDescriptor, ClassDescriptorImpl> classesForFunctions = new HashMap<FunctionDescriptor, ClassDescriptorImpl>();
private final Map<DeclarationDescriptor,ClassDescriptor> enclosing = new HashMap<DeclarationDescriptor, ClassDescriptor>();
private final MultiMap<String,JetFile> namespaceName2Files = MultiMap.create();
private final MultiMap<FqName, JetFile> namespaceName2Files = MultiMap.create();
private final BindingContext bindingContext;
public ClosureAnnotator(BindingContext bindingContext, Collection<JetFile> files) {
@@ -66,14 +67,14 @@ public class ClosureAnnotator {
private void mapFilesToNamespaces(Collection<JetFile> files) {
for (JetFile file : files) {
String fqName = JetPsiUtil.getFQName(file);
FqName fqName = JetPsiUtil.getFQName(file);
namespaceName2Files.putValue(fqName, file);
}
}
private void prepareAnonymousClasses() {
MyJetVisitorVoid visitor = new MyJetVisitorVoid();
for (Map.Entry<String,Collection<JetFile>> entry : namespaceName2Files.entrySet()) {
for (Map.Entry<FqName, Collection<JetFile>> entry : namespaceName2Files.entrySet()) {
for (JetFile jetFile : entry.getValue()) {
jetFile.accept(visitor);
}
@@ -153,7 +154,7 @@ public class ClosureAnnotator {
@Override
public void visitJetFile(JetFile file) {
nameStack.push(JetPsiUtil.getFQName(file).replace('.', '/'));
nameStack.push(JetPsiUtil.getFQName(file).getFqName().replace('.', '/'));
file.acceptChildren(this);
nameStack.pop();
}
@@ -17,10 +17,12 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
@@ -35,7 +37,7 @@ public class NamespaceCodegen {
private final ClassBuilder v;
private final GenerationState state;
public NamespaceCodegen(ClassBuilder v, String fqName, GenerationState state, PsiFile sourceFile) {
public NamespaceCodegen(ClassBuilder v, @NotNull FqName fqName, GenerationState state, PsiFile sourceFile) {
this.v = v;
this.state = state;
@@ -136,12 +138,12 @@ public class NamespaceCodegen {
/**
* @param namespace true for "namespace" suffix
*/
public static String getJVMClassName(String fqName, boolean namespace) {
if (fqName.length() == 0) {
public static String getJVMClassName(@NotNull FqName fqName, boolean namespace) {
if (fqName.isRoot()) {
return JvmAbi.PACKAGE_CLASS;
}
String name = fqName.replace('.', '/');
String name = fqName.getFqName().replace('.', '/');
if(name.startsWith("<java_root>")) {
name = name.substring("<java_root>".length() + 1, name.length());
}
@@ -246,7 +246,7 @@ public class IntrinsicMethods {
if (annotations != null) {
for (AnnotationDescriptor annotation : annotations) {
if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName())) {
Object value = annotation.getValueArguments().get(0).getValue();
String value = (String) annotation.getValueArguments().get(0).getValue();
intrinsicMethod = namedMethods.get(value);
if(intrinsicMethod != null)
break;