diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index 2b7dbc242ff..c301de030a4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -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 ns2codegen = new HashMap(); + private final Map ns2codegen = new HashMap(); private final Map generators = new LinkedHashMap(); 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"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java index 08a716be3d7..38d5cf1f264 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java @@ -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 classesForFunctions = new HashMap(); private final Map enclosing = new HashMap(); - private final MultiMap namespaceName2Files = MultiMap.create(); + private final MultiMap namespaceName2Files = MultiMap.create(); private final BindingContext bindingContext; public ClosureAnnotator(BindingContext bindingContext, Collection files) { @@ -66,14 +67,14 @@ public class ClosureAnnotator { private void mapFilesToNamespaces(Collection 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> entry : namespaceName2Files.entrySet()) { + for (Map.Entry> 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(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 0f54af71660..93071deef14 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -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("")) { name = name.substring("".length() + 1, name.length()); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index afa814791c2..cf748ecf115 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -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; diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java index b90876deeff..ee4ec0a0c36 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java @@ -33,6 +33,7 @@ import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.GeneratedClassLoader; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.plugin.JetLanguage; import org.jetbrains.jet.plugin.JetMainDetector; @@ -274,14 +275,14 @@ public class CompileEnvironment { return moduleCompileSession.generate(false); } - public static void writeToJar(ClassFileFactory factory, final OutputStream fos, @Nullable String mainClass, boolean includeRuntime) { + public static void writeToJar(ClassFileFactory factory, final OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime) { try { Manifest manifest = new Manifest(); final Attributes mainAttributes = manifest.getMainAttributes(); mainAttributes.putValue("Manifest-Version", "1.0"); mainAttributes.putValue("Created-By", "JetBrains Kotlin"); if (mainClass != null) { - mainAttributes.putValue("Main-Class", mainClass); + mainAttributes.putValue("Main-Class", mainClass.getFqName()); } JarOutputStream stream = new JarOutputStream(fos, manifest); try { @@ -369,11 +370,11 @@ public class CompileEnvironment { session.addSources(sourceFileOrDir); - String mainClass = null; + FqName mainClass = null; for (JetFile file : session.getSourceFileNamespaces()) { if (JetMainDetector.hasMain(file.getDeclarations())) { - String fqName = JetPsiUtil.getFQName(file); - mainClass = fqName.length() > 0 ? fqName + "." + JvmAbi.PACKAGE_CLASS : JvmAbi.PACKAGE_CLASS; + FqName fqName = JetPsiUtil.getFQName(file); + mainClass = fqName.child(JvmAbi.PACKAGE_CLASS); break; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java index ce0033c0ba5..10f6b61ae37 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import java.util.Collection; @@ -60,7 +61,7 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { delegateConfiguration.addDefaultImports(rootScope, directives); } - public static JavaNamespaceDescriptor createNamespaceDescriptor(String name, String qualifiedName) { + public static JavaNamespaceDescriptor createNamespaceDescriptor(String name, FqName qualifiedName) { return new JavaNamespaceDescriptor(null, Collections.emptyList(), name, qualifiedName, true); } @@ -73,7 +74,7 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { @Override public NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName) { - NamespaceDescriptor namespaceDescriptor = javaSemanticServices.getDescriptorResolver().resolveNamespace(shortName); + NamespaceDescriptor namespaceDescriptor = javaSemanticServices.getDescriptorResolver().resolveNamespace(FqName.topLevel(shortName)); if (namespaceDescriptor != null) { return namespaceDescriptor; } @@ -82,7 +83,7 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { @Override public void addAllTopLevelNamespacesTo(@NotNull Collection topLevelNamespaces) { - NamespaceDescriptor defaultPackage = javaSemanticServices.getDescriptorResolver().resolveNamespace(""); + NamespaceDescriptor defaultPackage = javaSemanticServices.getDescriptorResolver().resolveNamespace(FqName.ROOT); assert defaultPackage != null : "Cannot resolve Java's default package"; for (DeclarationDescriptor declarationDescriptor : defaultPackage.getMemberScope().getAllDescriptors()) { if (declarationDescriptor instanceof NamespaceDescriptor) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 11ce91ce599..e7ff901dec7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.java.alt.AltClassFinder; @@ -54,7 +55,7 @@ import java.util.*; */ public class JavaDescriptorResolver { - public static String JAVA_ROOT = ""; + public static final String JAVA_ROOT = ""; /*package*/ static final DeclarationDescriptor JAVA_METHOD_TYPE_PARAMETER_PARENT = new DeclarationDescriptorImpl(null, Collections.emptyList(), "") { @@ -186,8 +187,8 @@ public class JavaDescriptorResolver { } } - protected final Map classDescriptorCache = Maps.newHashMap(); - protected final Map namespaceDescriptorCacheByFqn = Maps.newHashMap(); + protected final Map classDescriptorCache = Maps.newHashMap(); + protected final Map namespaceDescriptorCacheByFqn = Maps.newHashMap(); protected final Map namespaceDescriptorCache = Maps.newHashMap(); protected final JavaPsiFacade javaFacade; @@ -209,9 +210,9 @@ public class JavaDescriptorResolver { @Nullable ResolverClassData resolveClassData(@NotNull PsiClass psiClass) { - String qualifiedName = psiClass.getQualifiedName(); + FqName qualifiedName = new FqName(psiClass.getQualifiedName()); - if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { + if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { // TODO: only if -$$TImpl class is created by Kotlin return null; } @@ -249,9 +250,9 @@ public class JavaDescriptorResolver { } @Nullable - public ClassDescriptor resolveClass(@NotNull String qualifiedName) { + public ClassDescriptor resolveClass(@NotNull FqName qualifiedName) { - if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { + if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { // TODO: only if -$$TImpl class is created by Kotlin return null; } @@ -276,7 +277,7 @@ public class JavaDescriptorResolver { } private ResolverBinaryClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) { - if (classDescriptorCache.containsKey(psiClass.getQualifiedName())) { + if (classDescriptorCache.containsKey(new FqName(psiClass.getQualifiedName()))) { throw new IllegalStateException(psiClass.getQualifiedName()); } @@ -284,7 +285,7 @@ public class JavaDescriptorResolver { String name = psiClass.getName(); ResolverBinaryClassData classData = new ResolverBinaryClassData(); - classDescriptorCache.put(psiClass.getQualifiedName(), classData); + classDescriptorCache.put(new FqName(psiClass.getQualifiedName()), classData); ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS; ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass); classData.classDescriptor = new MutableClassDescriptorLite(containingDeclaration, kind); @@ -459,7 +460,7 @@ public class JavaDescriptorResolver { classData.kotlin = true; classData.classDescriptor = new MutableClassDescriptorLite(containing, ClassKind.OBJECT); - classDescriptorCache.put(classObjectPsiClass.getQualifiedName(), classData); + classDescriptorCache.put(new FqName(classObjectPsiClass.getQualifiedName()), classData); classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData.classDescriptor, new ArrayList(0))); classData.classDescriptor.setName(JetPsiUtil.NO_NAME_PROVIDED); // TODO @@ -506,7 +507,7 @@ public class JavaDescriptorResolver { @NotNull private ClassDescriptor getJavaLangObject() { if (javaLangObject == null) { - javaLangObject = resolveClass("java.lang.Object"); + javaLangObject = resolveClass(new FqName("java.lang.Object")); } return javaLangObject; } @@ -653,16 +654,7 @@ public class JavaDescriptorResolver { return resolveClass(containingClass); } - return resolveNamespace(packageNameOfClass(psiClass.getQualifiedName())); - } - - private static String packageNameOfClass(@NotNull String qualifiedName) { - int lastDot = qualifiedName.lastIndexOf('.'); - if (lastDot < 0) { - return ""; - } else { - return qualifiedName.substring(0, lastDot); - } + return resolveNamespace(new FqName(psiClass.getQualifiedName()).parent()); } private List makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) { @@ -792,7 +784,7 @@ public class JavaDescriptorResolver { } @Nullable - public NamespaceDescriptor resolveNamespace(@NotNull String qualifiedName) { + public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) { // First, let's check that there is no Kotlin package: NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(qualifiedName); if (kotlinNamespaceDescriptor != null) { @@ -809,8 +801,8 @@ public class JavaDescriptorResolver { } @Nullable - public PsiClass findClass(@NotNull String qualifiedName) { - PsiClass original = javaFacade.findClass(qualifiedName, javaSearchScope); + public PsiClass findClass(@NotNull FqName qualifiedName) { + PsiClass original = javaFacade.findClass(qualifiedName.getFqName(), javaSearchScope); PsiClass altClass = altClassFinder.findClass(qualifiedName); PsiClass result = original; if (altClass != null) { @@ -822,7 +814,7 @@ public class JavaDescriptorResolver { } if (result != null) { - String actualQualifiedName = result.getQualifiedName(); + FqName actualQualifiedName = new FqName(result.getQualifiedName()); if (!actualQualifiedName.equals(qualifiedName)) { // throw new IllegalStateException("requested " + qualifiedName + ", got " + actualQualifiedName); } @@ -831,8 +823,8 @@ public class JavaDescriptorResolver { return result; } - /*package*/ PsiPackage findPackage(String qualifiedName) { - return javaFacade.findPackage(qualifiedName); + /*package*/ PsiPackage findPackage(@NotNull FqName qualifiedName) { + return javaFacade.findPackage(qualifiedName.getFqName()); } private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) { @@ -840,7 +832,7 @@ public class JavaDescriptorResolver { if (namespaceData == null) { namespaceData = createJavaNamespaceDescriptor(psiPackage); namespaceDescriptorCache.put(psiPackage, namespaceData); - namespaceDescriptorCacheByFqn.put(psiPackage.getQualifiedName(), namespaceData); + namespaceDescriptorCacheByFqn.put(new FqName(psiPackage.getQualifiedName()), namespaceData); } return namespaceData.namespaceDescriptor; } @@ -850,7 +842,7 @@ public class JavaDescriptorResolver { if (namespaceData == null) { namespaceData = createJavaNamespaceDescriptor(psiClass); namespaceDescriptorCache.put(psiClass, namespaceData); - namespaceDescriptorCacheByFqn.put(psiClass.getQualifiedName(), namespaceData); + namespaceDescriptorCacheByFqn.put(new FqName(psiClass.getQualifiedName()), namespaceData); } return namespaceData.namespaceDescriptor; } @@ -862,11 +854,11 @@ public class JavaDescriptorResolver { resolveParentDescriptor(psiPackage), Collections.emptyList(), // TODO name == null ? JAVA_ROOT : name, - name == null ? JAVA_ROOT : psiPackage.getQualifiedName(), + name == null ? FqName.ROOT : new FqName(psiPackage.getQualifiedName()), true ); - namespaceData.namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceData.namespaceDescriptor, semanticServices)); + namespaceData.namespaceDescriptor.setMemberScope(new JavaPackageScope(new FqName(psiPackage.getQualifiedName()), namespaceData.namespaceDescriptor, semanticServices)); semanticServices.getTrace().record(BindingContext.NAMESPACE, psiPackage, namespaceData.namespaceDescriptor); // TODO: hack namespaceData.kotlin = true; @@ -894,7 +886,7 @@ public class JavaDescriptorResolver { resolveParentDescriptor(psiClass), Collections.emptyList(), // TODO psiClass.getName(), - psiClass.getQualifiedName(), + new FqName(psiClass.getQualifiedName()), false ); namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true)); @@ -1340,7 +1332,7 @@ public class JavaDescriptorResolver { scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName()); staticMembers = true; } else if (owner instanceof ClassDescriptor) { - scopeData = classDescriptorCache.get(psiClass.getQualifiedName()); + scopeData = classDescriptorCache.get(new FqName(psiClass.getQualifiedName())); staticMembers = false; } else { throw new IllegalStateException("unknown owner: " + owner.getClass().getName()); @@ -1428,7 +1420,7 @@ public class JavaDescriptorResolver { } kotlin = namespaceData.kotlin; } else { - ResolverBinaryClassData classData = classDescriptorCache.get(psiClass.getQualifiedName()); + ResolverBinaryClassData classData = classDescriptorCache.get(new FqName(psiClass.getQualifiedName())); if (classData == null) { throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName()); } @@ -1516,7 +1508,7 @@ public class JavaDescriptorResolver { return null; } - ClassDescriptor clazz = resolveClass(psiAnnotation.getQualifiedName()); + ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName())); if (clazz == null) { return null; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java index bfb97010243..a885e3866cb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.AbstractNamespaceDescriptorImpl; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import java.util.List; @@ -29,12 +30,12 @@ import java.util.List; */ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl { private JetScope memberScope; - private final String qualifiedName; + private final FqName qualifiedName; /** Namespace of class with static methods */ private final boolean namespace; public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List annotations, - @NotNull String name, @NotNull String qualifiedName, boolean namespace) { + @NotNull String name, @NotNull FqName qualifiedName, boolean namespace) { super(containingDeclaration, annotations, name); this.qualifiedName = qualifiedName; this.namespace = namespace; @@ -50,7 +51,7 @@ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl { return memberScope; } - public String getQualifiedName() { + public FqName getQualifiedName() { return qualifiedName; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index 9df7843202f..198b4aa3ef9 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -18,21 +18,18 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Sets; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiPackage; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import java.util.Collection; -import java.util.HashSet; /** * @author abreslav @@ -42,19 +39,19 @@ public class JavaPackageScope extends JavaClassOrPackageScope { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.migration.PsiMigrationImpl"); @NotNull - private final String packageFQN; + private final FqName packageFQN; private Collection allDescriptors; public JavaPackageScope( - @NotNull String packageFQN, + @NotNull FqName packageFQN, @NotNull NamespaceDescriptor containingDescriptor, @NotNull JavaSemanticServices semanticServices) { super(containingDescriptor, semanticServices, getPiClass(packageFQN, semanticServices)); this.packageFQN = packageFQN; } - private static PsiClass getPiClass(String packageFQN, JavaSemanticServices semanticServices) { + private static PsiClass getPiClass(FqName packageFQN, JavaSemanticServices semanticServices) { // TODO: move this check outside // If this package is actually a Kotlin namespace, then we access it through a namespace descriptor, and // Kotlin functions are already there @@ -63,7 +60,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope { return null; } else { // TODO: what is GlobalSearchScope - return semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName(packageFQN, JvmAbi.PACKAGE_CLASS)); + return semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName(packageFQN, JvmAbi.PACKAGE_CLASS).getFqName()); } } @@ -113,12 +110,12 @@ public class JavaPackageScope extends JavaClassOrPackageScope { final PsiPackage javaPackage = semanticServices.getDescriptorResolver().findPackage(packageFQN); if (javaPackage != null) { - boolean isKotlinNamespace = semanticServices.getKotlinNamespaceDescriptor(javaPackage.getQualifiedName()) != null; + boolean isKotlinNamespace = semanticServices.getKotlinNamespaceDescriptor(new FqName(javaPackage.getQualifiedName())) != null; final JavaDescriptorResolver descriptorResolver = semanticServices.getDescriptorResolver(); for (PsiPackage psiSubPackage : javaPackage.getSubPackages()) { - if (semanticServices.getKotlinNamespaceDescriptor(psiSubPackage.getQualifiedName()) == null) { - allDescriptors.add(descriptorResolver.resolveNamespace(psiSubPackage.getQualifiedName())); + if (semanticServices.getKotlinNamespaceDescriptor(new FqName(psiSubPackage.getQualifiedName())) == null) { + allDescriptors.add(descriptorResolver.resolveNamespace(new FqName(psiSubPackage.getQualifiedName()))); } } @@ -128,7 +125,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope { } // If this is a Kotlin class, we have already taken it through a containing namespace descriptor - ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(psiClass.getQualifiedName()); + ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(new FqName(psiClass.getQualifiedName())); if (kotlinClassDescriptor != null) { continue; } @@ -151,7 +148,8 @@ public class JavaPackageScope extends JavaClassOrPackageScope { return allDescriptors; } - private static String getQualifiedName(@NotNull String packageFQN, @NotNull String name) { - return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name; + @NotNull + private static FqName getQualifiedName(@NotNull FqName packageFQN, @NotNull String name) { + return packageFQN.child(name); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java index 9fa00bcb29c..b7296338f1f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; /** @@ -55,9 +56,9 @@ public class JavaSemanticServices { } @Nullable - public ClassDescriptor getKotlinClassDescriptor(String qualifiedName) { - if (qualifiedName.startsWith("jet.")) { - ClassDescriptor r = (ClassDescriptor) JetStandardLibrary.getInstance().getLibraryScope().getClassifier(qualifiedName.substring("jet.".length())); + public ClassDescriptor getKotlinClassDescriptor(@NotNull FqName qualifiedName) { + if (qualifiedName.getFqName().startsWith("jet.")) { + ClassDescriptor r = (ClassDescriptor) JetStandardLibrary.getInstance().getLibraryScope().getClassifier(qualifiedName.getFqName().substring("jet.".length())); if (r == null) { // TODO: better error //throw new IllegalStateException(); @@ -68,7 +69,7 @@ public class JavaSemanticServices { } @Nullable - public NamespaceDescriptor getKotlinNamespaceDescriptor(String qualifiedName) { + public NamespaceDescriptor getKotlinNamespaceDescriptor(@NotNull FqName qualifiedName) { return getTrace().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, qualifiedName); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 0a76cdf990b..a74c29a558c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; @@ -85,30 +86,30 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public void visitClassType(String name, boolean nullable, boolean forceReal) { - String ourName = name + FqName ourName = new FqName(name .replace('/', '.') .replace('$', '.') // TODO: not sure - ; + ); this.classDescriptor = null; if (this.classDescriptor == null && !forceReal) { - this.classDescriptor = this.javaSemanticServices.getTypeTransformer().getPrimitiveWrappersClassDescriptorMap().get(ourName); + this.classDescriptor = this.javaSemanticServices.getTypeTransformer().getPrimitiveWrappersClassDescriptorMap().get(ourName.getFqName()); } - if (this.classDescriptor == null && ourName.equals("java.lang.Object") && !forceReal) { + if (this.classDescriptor == null && ourName.equals(new FqName("java.lang.Object")) && !forceReal) { this.classDescriptor = JetStandardClasses.getAny(); } if (classDescriptor == null) { // TODO: this is the worst code in Kotlin project - Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName); + Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName.getFqName()); if (matcher.matches()) { classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1))); } } if (classDescriptor == null) { - Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName); + Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName.getFqName()); if (matcher.matches()) { classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1))); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java index e50b0cb3d35..ad81c3ac7cf 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java @@ -25,6 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.plugin.compiler.PathUtil; import java.util.List; @@ -39,9 +40,9 @@ public class AltClassFinder { this.roots = PathUtil.getAltHeadersRoots(); } - public PsiClass findClass(@NotNull String qualifiedName) { + public PsiClass findClass(@NotNull FqName qualifiedName) { for (final VirtualFile classRoot : roots) { - PsiClass answer = CoreJavaFileManager.findClassInClasspathRoot(qualifiedName, classRoot, psiManager); + PsiClass answer = CoreJavaFileManager.findClassInClasspathRoot(qualifiedName.getFqName(), classRoot, psiManager); if (answer != null) return answer; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java index 7778c2e6834..0342b2d43d1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub; import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lexer.JetTokens; /** @@ -96,7 +97,7 @@ public class JetNamedFunction extends JetFunction implements StubBasedPsiElement * @return */ @Nullable - public String getQualifiedName() { + public FqName getQualifiedName() { final PsiJetFunctionStub stub = getStub(); if (stub != null) { // TODO (stubs): return stub.getQualifiedName(); @@ -105,12 +106,8 @@ public class JetNamedFunction extends JetFunction implements StubBasedPsiElement PsiElement parent = getParent(); if (parent instanceof JetFile) { JetFile jetFile = (JetFile) parent; - final String fileFQN = JetPsiUtil.getFQName(jetFile); - if (!fileFQN.isEmpty()) { - return fileFQN + "." + getName(); - } - - return getName(); + final FqName fileFQN = JetPsiUtil.getFQName(jetFile); + return fileFQN.child(getName()); } return null; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index e9af9011d91..e50f9c30a17 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -24,6 +24,7 @@ import com.intellij.psi.PsiFileFactory; import com.intellij.util.LocalTimeCounter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.JetFileType; @@ -144,11 +145,15 @@ public class JetPsiFactory { // return file.getRootNamespace(); // } - public static JetImportDirective createImportDirective(Project project, String classPath) { + public static JetImportDirective createImportDirective(Project project, @NotNull String classPath) { JetFile namespace = createFile(project, "import " + classPath); return namespace.getImportDirectives().iterator().next(); } + public static JetImportDirective createImportDirective(Project project, @NotNull FqName fqName) { + return createImportDirective(project, fqName.getFqName()); + } + public static PsiElement createPrimaryConstructor(Project project) { JetClass aClass = createClass(project, "class A()"); return aClass.findElementAt(7).getParent(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index bd0e8075768..531ffb2286a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -22,6 +22,7 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.util.QualifiedNamesUtil; @@ -129,21 +130,26 @@ public class JetPsiUtil { } } - private static String getFQName(JetNamespaceHeader header) { + private static FqName getFQName(JetNamespaceHeader header) { StringBuilder builder = new StringBuilder(); for (JetSimpleNameExpression nameExpression : header.getParentNamespaceNames()) { builder.append(nameExpression.getReferencedName()); builder.append("."); } builder.append(header.getName()); - return builder.toString(); + return new FqName(builder.toString()); } - public static String getFQName(JetFile file) { + public static FqName getFQName(JetFile file) { return getFQName(file.getNamespaceHeader()); } - public static String getFQName(JetClassOrObject jetClass) { + @Nullable + public static FqName getFQName(@NotNull JetClassOrObject jetClass) { + if (jetClass.getName() == null) { + return null; + } + PsiElement parent = jetClass.getParent(); if (parent instanceof JetFile) { return makeFQName(getFQName((JetFile) parent), jetClass); @@ -157,14 +163,15 @@ public class JetPsiUtil { if (parent instanceof JetClassOrObject) { return makeFQName(getFQName(((JetClassOrObject) parent)), jetClass); } - return jetClass.getName(); + return new FqName(jetClass.getName()); } - public static String getFQName(JetNamedFunction jetNamedFunction) { + @Nullable + public static FqName getFQName(@NotNull JetNamedFunction jetNamedFunction) { String functionName = jetNamedFunction.getName(); if (functionName == null) { - return functionName; + return null; } @SuppressWarnings("unchecked") @@ -172,7 +179,7 @@ public class JetPsiUtil { jetNamedFunction, JetFile.class, JetClassOrObject.class, JetNamedFunction.class); - String firstPart = ""; + FqName firstPart = FqName.ROOT; if (qualifiedElement instanceof JetFile) { firstPart = getFQName((JetFile) qualifiedElement); } @@ -183,7 +190,7 @@ public class JetPsiUtil { firstPart = getFQName((JetNamedFunction) qualifiedElement); } - return QualifiedNamesUtil.combine(firstPart, functionName); + return firstPart.child(functionName); } @Nullable @JetElement.IfNotParsed @@ -197,8 +204,9 @@ public class JetPsiUtil { return text.replaceAll(" ", "") + (importDirective.isAllUnder() ? ".*" : ""); } - private static String makeFQName(String prefix, JetClassOrObject jetClass) { - return ((prefix == null || prefix.length() == 0) ? "" : prefix + ".") + jetClass.getName(); + @NotNull + private static FqName makeFQName(@NotNull FqName prefix, @NotNull JetClassOrObject jetClass) { + return prefix.child(jetClass.getName()); } public static boolean isIrrefutable(JetWhenEntry entry) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetClassElementType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetClassElementType.java index 33458a5a537..f81a71066f9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetClassElementType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetClassElementType.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub; import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetClassStubImpl; +import org.jetbrains.jet.lang.resolve.FqName; import java.io.IOException; @@ -60,7 +61,8 @@ public class JetClassElementType extends JetStubElementType implements PsiJetCla public PsiJetClassStubImpl( JetClassElementType type, final StubElement parent, - final String qualifiedName, + @Nullable final String qualifiedName, final String name) { this(type, parent, StringRef.fromString(qualifiedName), StringRef.fromString(name)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index b2545dd1581..2615c7a2c50 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -171,8 +171,8 @@ public interface BindingContext { WritableSlice LABEL_TARGET = Slices.sliceBuilder().build(); WritableSlice VALUE_PARAMETER_AS_PROPERTY = Slices.sliceBuilder().build(); - WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING, true); - WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); + WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING, true); + WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); WritableSlice INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice(); 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 90009214e2a..473780af56f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -178,14 +178,25 @@ public class DescriptorUtils { return false; } - public static String getFQName(DeclarationDescriptor descriptor) { - DeclarationDescriptor container = descriptor.getContainingDeclaration(); - if (container != null && !(container instanceof ModuleDescriptor)) { - String baseName = getFQName(container); - if (!baseName.isEmpty()) return baseName + "." + descriptor.getName(); + public static FqName getFQName(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof ModuleDescriptor) { + return FqName.ROOT; } - return descriptor.getName(); + if (descriptor.getContainingDeclaration() == null) { + if (descriptor instanceof NamespaceDescriptor) { + // TODO: namespace must always have parent + if (descriptor.getName().equals("jet")) { + return FqName.topLevel("jet"); + } + if (descriptor.getName().equals("")) { + return FqName.ROOT; + } + } + throw new IllegalStateException("descriptor is not module descriptor and has null containingDeclaration: " + descriptor.getContainingDeclaration()); + } + + return getFQName(descriptor.getContainingDeclaration()).child(descriptor.getName()); } public static boolean isTopLevelFunction(@NotNull SimpleFunctionDescriptor functionDescriptor) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java new file mode 100644 index 00000000000..7f5fd8a4455 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java @@ -0,0 +1,152 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +public class FqName { + + public static final FqName ROOT = new FqName(""); + + @NotNull + private final String fqName; + + // cache + private transient FqName parent; + private transient String shortName; + + + public FqName(@NotNull String fqName) { + this.fqName = fqName; + + validateFqName(); + } + + private FqName(@NotNull String fqName, FqName parent, String shortName) { + this.fqName = fqName; + this.parent = parent; + this.shortName = shortName; + + validateFqName(); + } + + + private void validateFqName() { + if (fqName.indexOf('/') >= 0 || fqName.indexOf('<') >= 0) { + throw new IllegalArgumentException("incorrect fq name: " + fqName); + } + } + + private void compute() { + int lastDot = fqName.lastIndexOf('.'); + if (lastDot >= 0) { + shortName = fqName.substring(lastDot + 1); + parent = new FqName(fqName.substring(0, lastDot)); + } else { + shortName = fqName; + parent = ROOT; + } + } + + + + @NotNull + public String getFqName() { + return fqName; + } + + public boolean isRoot() { + return fqName.equals(""); + } + @NotNull + public FqName parent() { + if (parent != null) { + return parent; + } + + if (isRoot()) { + throw new IllegalStateException("root"); + } + + compute(); + + return parent; + } + + @NotNull + public FqName child(@NotNull String name) { + String childFqName; + if (isRoot()) { + childFqName = name; + } else { + childFqName = fqName + "." + name; + } + return new FqName(childFqName, this, name); + } + + @NotNull + public String shortName() { + if (shortName != null) { + return shortName; + } + + if (isRoot()) { + throw new IllegalStateException("root"); + } + + compute(); + + return shortName; + } + + + @NotNull + public static FqName topLevel(@NotNull String shortName) { + if (shortName.indexOf('.') >= 0) { + throw new IllegalArgumentException(); + } + return new FqName(shortName, ROOT, shortName); + } + + + @Override + public String toString() { + return isRoot() ? "" : fqName; + } + + @Override + public boolean equals(Object o) { + // generated by Idea + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FqName that = (FqName) o; + + if (fqName != null ? !fqName.equals(that.fqName) : that.fqName != null) return false; + + return true; + } + + @Override + public int hashCode() { + // generated by Idea + return fqName != null ? fqName.hashCode() : 0; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java index b38f5a6eff7..09f8526d118 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java @@ -69,7 +69,7 @@ public class OverloadResolver { } Key(NamespaceDescriptor namespaceDescriptor, String name) { - this(DescriptorUtils.getFQName(namespaceDescriptor), name); + this(DescriptorUtils.getFQName(namespaceDescriptor).getFqName(), name); } public String getNamespace() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index d00138f036e..085a9cc6511 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -177,13 +177,13 @@ public class ExpressionTypingUtils { * @return */ public static List canFindSuitableCall( - @NotNull String callableFQN, + @NotNull FqName callableFQN, @NotNull Project project, @NotNull JetExpression receiverExpression, @NotNull JetType receiverType, @NotNull JetScope scope) { - JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN); + JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN.getFqName()); Collection declarationDescriptors = ImportsResolver.analyseImportReference(importDirective, scope, new BindingTraceContext()); diff --git a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java index 89901ce6b2c..c490792ccd9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java @@ -16,9 +16,9 @@ package org.jetbrains.jet.util; -import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.FqName; /** * Common methods for working with qualified names strings. @@ -27,14 +27,14 @@ import org.jetbrains.annotations.Nullable; */ public final class QualifiedNamesUtil { - public static boolean isSubpackageOf(@NotNull final String subpackageName, @NotNull String packageName) { + public static boolean isSubpackageOf(@NotNull final FqName subpackageName, @NotNull FqName packageName) { return subpackageName.equals(packageName) || - (subpackageName.startsWith(packageName) && subpackageName.charAt(packageName.length()) == '.'); + (subpackageName.getFqName().startsWith(packageName.getFqName()) && subpackageName.getFqName().charAt(packageName.getFqName().length()) == '.'); } - public static boolean isShortNameForFQN(@NotNull final String name, @NotNull final String fqn) { - return fqn.equals(name) || - (fqn.endsWith(name) && fqn.charAt(fqn.length() - name.length() - 1) == '.'); + public static boolean isShortNameForFQN(@NotNull final String name, @NotNull final FqName fqn) { + return fqn.getFqName().equals(name) || + (fqn.getFqName().endsWith(name) && fqn.getFqName().charAt(fqn.getFqName().length() - name.length() - 1) == '.'); } public static boolean isOneSegmentFQN(@NotNull final String fqn) { @@ -46,14 +46,13 @@ public final class QualifiedNamesUtil { } @NotNull - public static String fqnToShortName(@NotNull String fqn) { + public static String fqnToShortName(@NotNull FqName fqn) { return getLastSegment(fqn); } @NotNull - public static String getLastSegment(@NotNull String fqn) { - int lastDotIndex = fqn.lastIndexOf('.'); - return (lastDotIndex != -1) ? fqn.substring(lastDotIndex + 1, fqn.length()) : fqn; + public static String getLastSegment(@NotNull FqName fqn) { + return fqn.shortName(); } @NotNull @@ -72,9 +71,14 @@ public final class QualifiedNamesUtil { return ""; } - public static String combine(@Nullable String first, @NotNull String second) { - if (StringUtil.isEmpty(first)) return second; - return first + "." + second; + @NotNull + public static FqName withoutLastSegment(@NotNull FqName fqName) { + return fqName.parent(); + } + + @NotNull + public static FqName combine(@NotNull FqName first, @NotNull String second) { + return first.child(second); } /** @@ -85,14 +89,14 @@ public final class QualifiedNamesUtil { * @return tail fqn. If first part is not a begging of the full fqn, fullFQN will be returned. */ @NotNull - public static String tail(@NotNull String headFQN, @NotNull String fullFQN) { + public static String tail(@NotNull FqName headFQN, @NotNull FqName fullFQN) { if (!isSubpackageOf(fullFQN, headFQN)) { - return fullFQN; + return fullFQN.getFqName(); } return fullFQN.equals(headFQN) ? "" : - fullFQN.substring(headFQN.length() + 1); // (headFQN + '.').length + fullFQN.getFqName().substring(headFQN.getFqName().length() + 1); // (headFQN + '.').length } /** @@ -103,7 +107,7 @@ public final class QualifiedNamesUtil { * @return qualified name with one more segment or null if fqn is not head part of fullFQN or there's no additional segment. */ @Nullable - public static String plusOneSegment(String fqn, String fullFQN) { + public static FqName plusOneSegment(@NotNull FqName fqn, @NotNull FqName fullFQN) { if (!isSubpackageOf(fullFQN, fqn)) { return null; } @@ -121,11 +125,11 @@ public final class QualifiedNamesUtil { * Check that given fqn could be imported with import. * * @param importPath path from the import. Could contain .* part - * @param fqn - * @return + * @param fqn or another import directive */ public static boolean isImported(@NotNull String importPath, @NotNull String fqn) { if (importPath.endsWith("*")) { + // TODO: import path is not valid FQN return withoutLastSegment(importPath).equals(withoutLastSegment(fqn)); } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java index 406f7482b1f..f1f109184cc 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java @@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.util.QualifiedNamesUtil; @@ -81,15 +82,17 @@ public class JavaElementFinder extends PsiElementFinder { @NotNull @Override - public PsiClass[] findClasses(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) { + public PsiClass[] findClasses(@NotNull String qualifiedName0, @NotNull GlobalSearchScope scope) { + FqName qualifiedName = new FqName(qualifiedName0); + // Backend searches for java.lang.String. Will fail with SOE if continue - if (qualifiedName.startsWith("java.")) return PsiClass.EMPTY_ARRAY; + if (qualifiedName.getFqName().startsWith("java.")) return PsiClass.EMPTY_ARRAY; List answer = new SmartList(); final List filesInScope = collectProjectJetFiles(project, scope); for (JetFile file : filesInScope) { - final String packageName = JetPsiUtil.getFQName(file); - if (packageName != null && qualifiedName.startsWith(packageName)) { + final FqName packageName = JetPsiUtil.getFQName(file); + if (packageName != null && qualifiedName.getFqName().startsWith(packageName.getFqName())) { if (qualifiedName.equals(QualifiedNamesUtil.combine(packageName, JvmAbi.PACKAGE_CLASS))) { answer.add(new JetLightClass(psiManager, file, qualifiedName)); } @@ -103,11 +106,11 @@ public class JavaElementFinder extends PsiElementFinder { return answer.toArray(new PsiClass[answer.size()]); } - private void scanClasses(List answer, JetDeclaration declaration, String qualifiedName, String containerFqn, JetFile file) { + private void scanClasses(List answer, JetDeclaration declaration, FqName qualifiedName, FqName containerFqn, JetFile file) { if (declaration instanceof JetClassOrObject) { String localName = getLocalName(declaration); if (localName != null) { - String fqn = QualifiedNamesUtil.combine(containerFqn, localName); + FqName fqn = QualifiedNamesUtil.combine(containerFqn, localName); if (qualifiedName.equals(fqn)) { answer.add(new JetLightClass(psiManager, file, qualifiedName)); } @@ -139,7 +142,7 @@ public class JavaElementFinder extends PsiElementFinder { public Set getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { Set answer = new HashSet(); - String packageFQN = psiPackage.getQualifiedName(); + FqName packageFQN = new FqName(psiPackage.getQualifiedName()); for (JetFile psiFile : collectProjectJetFiles(project, GlobalSearchScope.allScope(project))) { if (packageFQN.equals(JetPsiUtil.getFQName(psiFile))) { answer.add(JvmAbi.PACKAGE_CLASS); @@ -155,12 +158,14 @@ public class JavaElementFinder extends PsiElementFinder { } @Override - public PsiPackage findPackage(@NotNull String qualifiedName) { + public PsiPackage findPackage(@NotNull String qualifiedName0) { + FqName fqName = new FqName(qualifiedName0); + final List psiFiles = collectProjectJetFiles(project, GlobalSearchScope.allScope(project)); for (JetFile psiFile : psiFiles) { - if (QualifiedNamesUtil.isSubpackageOf(JetPsiUtil.getFQName(psiFile), qualifiedName)) { - return new JetLightPackage(psiManager, qualifiedName, psiFile.getNamespaceHeader()); + if (QualifiedNamesUtil.isSubpackageOf(JetPsiUtil.getFQName(psiFile), fqName)) { + return new JetLightPackage(psiManager, fqName, psiFile.getNamespaceHeader()); } } @@ -175,9 +180,9 @@ public class JavaElementFinder extends PsiElementFinder { Set answer = new HashSet(); for (JetFile psiFile : psiFiles) { - String jetRootNamespace = JetPsiUtil.getFQName(psiFile); + FqName jetRootNamespace = JetPsiUtil.getFQName(psiFile); - final String subPackageFQN = QualifiedNamesUtil.plusOneSegment(psiPackage.getQualifiedName(), jetRootNamespace); + final FqName subPackageFQN = QualifiedNamesUtil.plusOneSegment(new FqName(psiPackage.getQualifiedName()), jetRootNamespace); if (subPackageFQN != null) { answer.add(new JetLightPackage(psiManager, subPackageFQN, psiFile.getNamespaceHeader())); } @@ -191,7 +196,7 @@ public class JavaElementFinder extends PsiElementFinder { public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { List answer = new SmartList(); final List filesInScope = collectProjectJetFiles(project, scope); - String packageFQN = psiPackage.getQualifiedName(); + FqName packageFQN = new FqName(psiPackage.getQualifiedName()); for (JetFile file : filesInScope) { if (packageFQN.equals(JetPsiUtil.getFQName(file))) { answer.add(new JetLightClass(psiManager, file, QualifiedNamesUtil.combine(packageFQN, JvmAbi.PACKAGE_CLASS))); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java index 1f483c08dad..4d8d37c1e79 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java @@ -48,6 +48,7 @@ import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker; import org.jetbrains.jet.plugin.JetLanguage; @@ -62,10 +63,10 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa private final static Key> JAVA_API_STUB = Key.create("JAVA_API_STUB"); private final JetFile file; - private final String qualifiedName; + private final FqName qualifiedName; private PsiClass delegate; - public JetLightClass(PsiManager manager, JetFile file, String qualifiedName) { + public JetLightClass(PsiManager manager, JetFile file, FqName qualifiedName) { super(manager, JetLanguage.INSTANCE); this.file = file; this.qualifiedName = qualifiedName; @@ -98,8 +99,8 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa return delegate; } - private static PsiClass findClass(String fqn, StubElement stub) { - if (stub instanceof PsiClassStub && Comparing.equal(fqn, ((PsiClassStub) stub).getQualifiedName())) { + private static PsiClass findClass(FqName fqn, StubElement stub) { + if (stub instanceof PsiClassStub && Comparing.equal(fqn.getFqName(), ((PsiClassStub) stub).getQualifiedName())) { return (PsiClass) stub.getPsi(); } @@ -113,7 +114,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa @Override public String getQualifiedName() { - return qualifiedName; + return qualifiedName.getFqName(); } private PsiJavaFileStub getStub() { @@ -132,7 +133,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa } private PsiJavaFileStub calcStub() { - final PsiJavaFileStubImpl answer = new PsiJavaFileStubImpl(JetPsiUtil.getFQName(file), true); + final PsiJavaFileStubImpl answer = new PsiJavaFileStubImpl(JetPsiUtil.getFQName(file).getFqName(), true); final Project project = getProject(); final Stack stubStack = new Stack(); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java index 5f00276932d..fbc0cdacdf3 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.asJava; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.file.PsiPackageImpl; +import org.jetbrains.jet.lang.resolve.FqName; /** * TODO: make more accurate wrapper @@ -28,15 +29,17 @@ import com.intellij.psi.impl.file.PsiPackageImpl; public class JetLightPackage extends PsiPackageImpl { private final PsiElement namespaceElement; + private final FqName fqName; - public JetLightPackage(PsiManager manager, String qualifiedName, PsiElement namespaceElement) { - super(manager, qualifiedName); + public JetLightPackage(PsiManager manager, FqName qualifiedName, PsiElement namespaceElement) { + super(manager, qualifiedName.getFqName()); + this.fqName = qualifiedName; this.namespaceElement = namespaceElement; } @Override public PsiElement copy() { - return new JetLightPackage(getManager(), getQualifiedName(), namespaceElement); + return new JetLightPackage(getManager(), fqName, namespaceElement); } @Override diff --git a/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java index b9cd5068055..5b1a8ab6b23 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java @@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; @@ -86,7 +87,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(psiFile, JetControlFlowDataTraceFactory.EMPTY); AnalyzingUtils.throwExceptionOnErrors(bindingContext); - return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, "test"); + return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel("test")); } private NamespaceDescriptor compileJava() throws Exception { @@ -114,7 +115,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { JavaSemanticServices semanticServices = new JavaSemanticServices(jetCoreEnvironment.getProject(), new BindingTraceContext()); JavaDescriptorResolver javaDescriptorResolver = semanticServices.getDescriptorResolver(); - return javaDescriptorResolver.resolveNamespace("test"); + return javaDescriptorResolver.resolveNamespace(FqName.topLevel("test")); } public static Test suite() { diff --git a/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java index 53464129b40..d3ae41cea21 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java @@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; import org.jetbrains.jet.plugin.JetLanguage; @@ -92,7 +93,7 @@ public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir { JavaSemanticServices semanticServices = new JavaSemanticServices(jetCoreEnvironment.getProject(), new BindingTraceContext()); JavaDescriptorResolver javaDescriptorResolver = semanticServices.getDescriptorResolver(); - NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace("test"); + NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace(FqName.topLevel("test")); NamespaceComparator.compareNamespaces(namespaceFromSource, namespaceFromClass, false, txtFile); } diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java index b6aed150017..92a38d5bafb 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; @@ -43,7 +44,11 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.parsing.JetParsingTest; import java.io.File; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author abreslav @@ -119,7 +124,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase { private PsiClass findClass(String qualifiedName) { Project project = getProject(); JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, new BindingTraceContext()); - return javaSemanticServices.getDescriptorResolver().findClass(qualifiedName); + return javaSemanticServices.getDescriptorResolver().findClass(new FqName(qualifiedName)); } @NotNull diff --git a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 99272589fe1..6cc7b185019 100644 --- a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -588,8 +588,8 @@ public class JetTypeCheckerTest extends JetLiteFixture { WritableScopeImpl writableScope = new WritableScopeImpl(scope, scope.getContainingDeclaration(), RedeclarationHandler.DO_NOTHING); writableScope.importScope(library.getLibraryScope()); JavaSemanticServices javaSemanticServices = new JavaSemanticServices(getProject(), JetTestUtils.DUMMY_TRACE); - writableScope.importScope(new JavaPackageScope("", JavaBridgeConfiguration.createNamespaceDescriptor(JavaDescriptorResolver.JAVA_ROOT, ""), javaSemanticServices)); - writableScope.importScope(new JavaPackageScope("java.lang", JavaBridgeConfiguration.createNamespaceDescriptor("lang", "java.lang"), javaSemanticServices)); + writableScope.importScope(new JavaPackageScope(FqName.ROOT, JavaBridgeConfiguration.createNamespaceDescriptor(JavaDescriptorResolver.JAVA_ROOT, FqName.ROOT), javaSemanticServices)); + writableScope.importScope(new JavaPackageScope(new FqName("java.lang"), JavaBridgeConfiguration.createNamespaceDescriptor("lang", new FqName("java.lang")), javaSemanticServices)); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); return writableScope; } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java index 9ac9a6778f9..413af71822f 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java @@ -27,6 +27,7 @@ import com.intellij.psi.util.PsiTreeUtil; import jet.runtime.typeinfo.JetValueParameter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.kt.JetValueParameterAnnotation; import org.jetbrains.jet.util.QualifiedNamesUtil; @@ -127,15 +128,15 @@ class JetFromJavaDescriptorHelper { } @Nullable - static String getJetTopLevelDeclarationFQN(@NotNull PsiMethod method) { + static FqName getJetTopLevelDeclarationFQN(@NotNull PsiMethod method) { PsiClass containingClass = method.getContainingClass(); if (containingClass != null) { - String classFQN = containingClass.getQualifiedName(); + FqName classFQN = new FqName(containingClass.getQualifiedName()); if (classFQN != null) { if (QualifiedNamesUtil.fqnToShortName(classFQN).equals(JvmAbi.PACKAGE_CLASS)) { - String classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN); + FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN); return QualifiedNamesUtil.combine(classParentFQN, method.getName()); } } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 6563785f178..e544f7d3be6 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.ImportsResolver; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; @@ -94,7 +95,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { List result = new ArrayList(); for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { - if (QualifiedNamesUtil.fqnToShortName(fqName).equals(name)) { + if (QualifiedNamesUtil.fqnToShortName(new FqName(fqName)).equals(name)) { PsiClass psiClass = javaElementFinder.findClass(fqName, scope); if (psiClass != null) { result.add(psiClass); @@ -131,11 +132,11 @@ public class JetShortNamesCache extends PsiShortNamesCache { } @NotNull - public Collection getFQNamesByName(@NotNull final String name, @NotNull GlobalSearchScope scope) { + public Collection getFQNamesByName(@NotNull final String name, @NotNull GlobalSearchScope scope) { BindingContext context = getResolutionContext(scope); - return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate() { + return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate() { @Override - public boolean apply(@Nullable String fqName) { + public boolean apply(@Nullable FqName fqName) { return fqName != null && QualifiedNamesUtil.isShortNameForFQN(name, fqName); } }); @@ -174,7 +175,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { Collection topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(name, project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { - String functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); + FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, functionFQN); Collection declarationDescriptors = ImportsResolver.analyseImportReference(importDirective, jetScope, new BindingTraceContext()); @@ -246,7 +247,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { if (expressionType != null && scope != null) { Collection extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope); - Set functionFQNs = new java.util.HashSet(); + Set functionFQNs = new java.util.HashSet(); // Collect all possible extension function qualified names for (String name : extensionFunctionsNames) { @@ -258,7 +259,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction)); } else if (extensionFunction instanceof PsiMethod) { - String functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN((PsiMethod) extensionFunction); + FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN((PsiMethod) extensionFunction); if (functionFQN != null) { functionFQNs.add(functionFQN); } @@ -268,7 +269,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { } // Iterate through the function with attempt to resolve found functions - for (String functionFQN : functionFQNs) { + for (FqName functionFQN : functionFQNs) { for (CallableDescriptor functionDescriptor : ExpressionTypingUtils.canFindSuitableCall( functionFQN, project, receiverExpression, expressionType, scope)) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java index 9e46c7c00d4..e9498fb272d 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java @@ -31,8 +31,10 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetImportDirective; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetQualifiedExpression; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.plugin.completion.JetLookupObject; import org.jetbrains.jet.plugin.quickfix.ImportClassHelper; @@ -120,9 +122,7 @@ public class JetFunctionInsertHandler implements InsertHandler { if (descriptor instanceof SimpleFunctionDescriptor) { final JetFile file = (JetFile) context.getFile(); - SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) descriptor; - final String fqn = DescriptorUtils.getFQName(functionDescriptor); - + final SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) descriptor; // Don't insert import for qualified expression if don't try to insert extension function if (PsiTreeUtil.getParentOfType(element, JetQualifiedExpression.class) != null && !functionDescriptor.getReceiverParameter().exists()) { @@ -134,7 +134,8 @@ public class JetFunctionInsertHandler implements InsertHandler { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - ImportClassHelper.addImportDirective(fqn, file); + final FqName fqn = DescriptorUtils.getFQName(functionDescriptor); + ImportClassHelper.addImportDirective(fqn.getFqName(), file); } }); } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java index c1ec96c9c8f..b9b96f7accc 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java @@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.actions.JetAddImportAction; import org.jetbrains.jet.plugin.caches.JetCacheManager; @@ -60,14 +61,14 @@ import java.util.*; public class ImportClassAndFunFix extends JetHintAction implements HighPriorityAction { @NotNull - private final List suggestions; + private final List suggestions; public ImportClassAndFunFix(@NotNull JetSimpleNameExpression element) { super(element); suggestions = computeSuggestions(element); } - private static List computeSuggestions(@NotNull JetSimpleNameExpression element) { + private static List computeSuggestions(@NotNull JetSimpleNameExpression element) { final PsiFile file = element.getContainingFile(); if (!(file instanceof JetFile)) { return Collections.emptyList(); @@ -81,7 +82,7 @@ public class ImportClassAndFunFix extends JetHintAction assert referenceName != null; - final ArrayList result = new ArrayList(); + final ArrayList result = Lists.newArrayList(); result.addAll(getClassNames(referenceName, file.getProject())); result.addAll(getJetTopLevelFunctions(referenceName, element, file.getProject())); result.addAll(getJetExtensionFunctions(referenceName, element, file.getProject())); @@ -89,23 +90,23 @@ public class ImportClassAndFunFix extends JetHintAction return result; } - private static Collection getJetTopLevelFunctions(@NotNull String referenceName, JetSimpleNameExpression expression, @NotNull Project project) { + private static Collection getJetTopLevelFunctions(@NotNull String referenceName, JetSimpleNameExpression expression, @NotNull Project project) { JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache(); Collection topLevelFunctions = namesCache.getTopLevelFunctionDescriptorsByName( referenceName, expression, GlobalSearchScope.allScope(project)); - return Collections2.transform(topLevelFunctions, new Function() { + return Collections2.transform(topLevelFunctions, new Function() { @Override - public String apply(@Nullable DeclarationDescriptor declarationDescriptor) { + public FqName apply(@Nullable DeclarationDescriptor declarationDescriptor) { assert declarationDescriptor != null; return DescriptorUtils.getFQName(declarationDescriptor); } }); } - private static Collection getJetExtensionFunctions( + private static Collection getJetExtensionFunctions( @NotNull final String referenceName, @NotNull JetSimpleNameExpression expression, @NotNull Project project @@ -121,9 +122,9 @@ public class ImportClassAndFunFix extends JetHintAction expression, GlobalSearchScope.allScope(project)); - return Collections2.transform(jetCallableExtensions, new Function() { + return Collections2.transform(jetCallableExtensions, new Function() { @Override - public String apply(@Nullable DeclarationDescriptor declarationDescriptor) { + public FqName apply(@Nullable DeclarationDescriptor declarationDescriptor) { assert declarationDescriptor != null; return DescriptorUtils.getFQName(declarationDescriptor); } @@ -133,9 +134,9 @@ public class ImportClassAndFunFix extends JetHintAction /* * Searches for possible class names in kotlin context and java facade. */ - public static List getClassNames(@NotNull String referenceName, @NotNull Project project) { + public static ArrayList getClassNames(@NotNull String referenceName, @NotNull Project project) { final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - Set possibleResolveNames = Sets.newHashSet(); + Set possibleResolveNames = Sets.newHashSet(); possibleResolveNames.addAll(JetCacheManager.getInstance(project).getNamesCache().getFQNamesByName(referenceName, scope)); possibleResolveNames.addAll(getJavaClasses(referenceName, project, scope)); @@ -143,7 +144,7 @@ public class ImportClassAndFunFix extends JetHintAction return Lists.newArrayList(possibleResolveNames); } - private static Collection getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) { + private static Collection getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) { PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); PsiClass[] classes = cache.getClassesByName(typeName, new DelegatingGlobalSearchScope(scope) { @@ -153,12 +154,12 @@ public class ImportClassAndFunFix extends JetHintAction } }); - return Collections2.transform(Lists.newArrayList(classes), new Function() { + return Collections2.transform(Lists.newArrayList(classes), new Function() { @Nullable @Override - public String apply(@Nullable PsiClass javaClass) { + public FqName apply(@Nullable PsiClass javaClass) { assert javaClass != null; - return javaClass.getQualifiedName(); + return new FqName(javaClass.getQualifiedName()); } }); } @@ -179,7 +180,7 @@ public class ImportClassAndFunFix extends JetHintAction } if (!ApplicationManager.getApplication().isUnitTestMode()) { - String hintText = ShowAutoImportPass.getMessage(suggestions.size() > 1, suggestions.get(0)); + String hintText = ShowAutoImportPass.getMessage(suggestions.size() > 1, suggestions.get(0).getFqName()); HintManager.getInstance().showQuestionHint( editor, hintText, @@ -224,7 +225,13 @@ public class ImportClassAndFunFix extends JetHintAction @NotNull private JetAddImportAction createAction(@NotNull Project project, @NotNull Editor editor) { - return new JetAddImportAction(project, editor, element, suggestions); + Collection suggesionStrings = Collections2.transform(suggestions, new Function() { + @Override + public String apply(FqName fqName) { + return fqName.getFqName(); + } + }); + return new JetAddImportAction(project, editor, element, suggesionStrings); } @Nullable diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java index de691695983..e13f75a8352 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.DefaultModuleConfiguration; 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.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; @@ -101,9 +102,9 @@ public class ImportClassHelper { } // Check that import is useless - private static boolean isImportedByDefault(@NotNull String importString, @NotNull String filePackageFqn) { + private static boolean isImportedByDefault(@NotNull String importString, @NotNull FqName filePackageFqn) { if (QualifiedNamesUtil.isOneSegmentFQN(importString) || - filePackageFqn.equals(QualifiedNamesUtil.withoutLastSegment(importString))) { + filePackageFqn.getFqName().equals(QualifiedNamesUtil.withoutLastSegment(importString))) { return true; } diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java index 6350f95cf42..b9e2adc1c94 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java @@ -31,6 +31,7 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.FqName; import java.util.Arrays; import java.util.Collection; @@ -41,7 +42,7 @@ import java.util.Map; * @author yole */ public class JetRunConfiguration extends ModuleBasedConfiguration implements CommonJavaRunConfigurationParameters { - public String MAIN_CLASS_NAME; + public FqName MAIN_CLASS_NAME; public String VM_PARAMETERS; public String PROGRAM_PARAMETERS; public String WORKING_DIRECTORY; @@ -132,7 +133,7 @@ public class JetRunConfiguration extends ModuleBasedConfiguration standardObjects = new HashMap(); + private final Map standardObjects = Maps.newHashMap(); @NotNull - private final Map scopeMap = new HashMap(); + private final Map scopeMap = Maps.newHashMap(); private StandardClasses(@NotNull JsScope kotlinScope) { this.kotlinScope = kotlinScope; } - private void declareTopLevelObjectInScope(@NotNull JsScope scope, @NotNull Map map, - @NotNull String fullQualifiedName, @NotNull String name) { + private void declareTopLevelObjectInScope(@NotNull JsScope scope, @NotNull Map map, + @NotNull FqName fullQualifiedName, @NotNull String name) { JsName declaredName = scope.declareName(name); declaredName.setObfuscatable(false); map.put(fullQualifiedName, declaredName); scopeMap.put(fullQualifiedName, new JsScope(scope, "scope for " + name)); } - private void declareKotlinObject(@NotNull String fullQualifiedName, @NotNull String kotlinLibName) { + private void declareKotlinObject(@NotNull FqName fullQualifiedName, @NotNull String kotlinLibName) { declareTopLevelObjectInScope(kotlinScope, standardObjects, fullQualifiedName, kotlinLibName); } - private void declareInner(@NotNull String fullQualifiedClassName, + private void declareInner(@NotNull FqName fullQualifiedClassName, @NotNull String shortMethodName, @NotNull String javascriptName) { JsScope classScope = scopeMap.get(fullQualifiedClassName); assert classScope != null; - String fullQualifiedMethodName = fullQualifiedClassName + "." + shortMethodName; + FqName fullQualifiedMethodName = new FqName(fullQualifiedClassName + "." + shortMethodName); JsName declaredName = classScope.declareName(javascriptName); declaredName.setObfuscatable(false); standardObjects.put(fullQualifiedMethodName, declaredName); } - private void declareMethods(@NotNull String classFQName, + private void declareMethods(@NotNull FqName classFQName, @NotNull String... methodNames) { for (String methodName : methodNames) { declareInner(classFQName, methodName, methodName); } } - private void declareReadonlyProperties(@NotNull String classFQName, + private void declareReadonlyProperties(@NotNull FqName classFQName, @NotNull String... propertyNames) { for (String propertyName : propertyNames) { declareInner(classFQName, propertyName, propertyName); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java index 3f82ea51994..8067255bc0f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java @@ -84,7 +84,7 @@ public final class AnnotationsUtils { DeclarationDescriptor annotationDeclaration = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); assert annotationDeclaration != null : "Annotation supposed to have a declaration"; - return DescriptorUtils.getFQName(annotationDeclaration); + return DescriptorUtils.getFQName(annotationDeclaration).getFqName(); } public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {