diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java index 7e711909d20..dc8b759a3c9 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java @@ -21,6 +21,7 @@ import com.google.common.collect.Collections2; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiSearchScopeUtil; @@ -28,14 +29,18 @@ import com.intellij.util.Function; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration; import org.jetbrains.jet.asJava.LightClassConstructionContext; import org.jetbrains.jet.asJava.LightClassGenerationSupport; +import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import java.util.Collection; @@ -175,4 +180,10 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport } }); } + + @Nullable + @Override + public PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject) { + return KotlinLightClassForExplicitDeclaration.create(classOrObject.getManager(), classOrObject); + } } 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 9e9cc725203..31f55551716 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 @@ -34,15 +34,12 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.java.JavaPsiFacadeKotlinHacks; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; -import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.util.QualifiedNamesUtil; import java.util.Collection; import java.util.List; import java.util.Set; -import static org.jetbrains.jet.codegen.CodegenUtil.getLocalNameForObject; - public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacadeKotlinHacks.KotlinFinderMarker { @NotNull @@ -102,8 +99,7 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade for (JetClassOrObject declaration : classOrObjectDeclarations) { if (!(declaration instanceof JetEnumEntry)) { - KotlinLightClassForExplicitDeclaration - lightClass = KotlinLightClassForExplicitDeclaration.create(psiManager, qualifiedName, declaration); + PsiClass lightClass = LightClassUtil.createLightClass(declaration); if (lightClass != null) { answer.add(lightClass); } @@ -129,18 +125,6 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade } } - @Nullable - private static String getLocalName(JetDeclaration declaration) { - String given = declaration.getName(); - if (given != null) return given; - - if (declaration instanceof JetObjectDeclaration) { - return getLocalNameForObject((JetObjectDeclaration) declaration); - } - - return null; - } - @NotNull @Override public Set getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { @@ -205,13 +189,9 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade Collection declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope); for (JetClassOrObject declaration : declarations) { - String localName = getLocalName(declaration); - if (localName != null) { - KotlinLightClassForExplicitDeclaration aClass = KotlinLightClassForExplicitDeclaration - .create(psiManager, packageFQN.child(Name.identifier(localName)), declaration); - if (aClass != null) { - answer.add(aClass); - } + PsiClass aClass = LightClassUtil.createLightClass(declaration); + if (aClass != null) { + answer.add(aClass); } } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java index 71164d21b73..7dd8e57f799 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java @@ -39,10 +39,12 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -59,11 +61,15 @@ public class KotlinLightClassForExplicitDeclaration extends AbstractLightClass i private final static Key> JAVA_API_STUB = Key.create("JAVA_API_STUB"); @Nullable - public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull FqName qualifiedName, @NotNull JetClassOrObject classOrObject) { + public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull JetClassOrObject classOrObject) { if (LightClassUtil.belongsToKotlinBuiltIns((JetFile) classOrObject.getContainingFile())) { return null; } - return new KotlinLightClassForExplicitDeclaration(manager, qualifiedName, classOrObject); + + JvmClassName jvmClassName = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject); + if (jvmClassName == null) return null; + + return new KotlinLightClassForExplicitDeclaration(manager, jvmClassName.getFqName(), classOrObject); } private final FqName classFqName; // FqName of (possibly inner) class diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java index 159afe1024b..6512f21b581 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassGenerationSupport.java @@ -18,8 +18,10 @@ package org.jetbrains.jet.asJava; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -60,4 +62,7 @@ public abstract class LightClassGenerationSupport { @NotNull public abstract Collection getSubPackages(@NotNull FqName fqn, @NotNull GlobalSearchScope scope); + + @Nullable + public abstract PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject); } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index 644eb7bdf33..80296bbd3b6 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -111,13 +111,9 @@ public class LightClassUtil { } @Nullable - public static KotlinLightClass createLightClass(@Nullable JetClassOrObject classOrObject) { + public static PsiClass createLightClass(@Nullable JetClassOrObject classOrObject) { if (classOrObject == null) return null; - - JvmClassName jvmClassName = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject); - if (jvmClassName == null) return null; - - return KotlinLightClassForExplicitDeclaration.create(classOrObject.getManager(), jvmClassName.getFqName(), classOrObject); + return LightClassGenerationSupport.getInstance(classOrObject.getProject()).getPsiClass(classOrObject); } @Nullable diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java b/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java index b040db76cad..a35c2cf6997 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java @@ -19,18 +19,26 @@ package org.jetbrains.jet.plugin.caches.resolve; import com.google.common.collect.Sets; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration; import org.jetbrains.jet.asJava.LightClassConstructionContext; import org.jetbrains.jet.asJava.LightClassGenerationSupport; +import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper; import org.jetbrains.jet.plugin.stubindex.*; import org.jetbrains.jet.util.QualifiedNamesUtil; @@ -113,6 +121,17 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport return result; } + @Nullable + @Override + public PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject) { + VirtualFile virtualFile = classOrObject.getContainingFile().getVirtualFile(); + if (virtualFile != null && LibraryUtil.findLibraryEntry(virtualFile, classOrObject.getProject()) != null) { + return JetSourceNavigationHelper.getOriginalClass(classOrObject); + } + + return KotlinLightClassForExplicitDeclaration.create(classOrObject.getManager(), classOrObject); + } + @NotNull public MultiMap getAllPackageClasses(@NotNull GlobalSearchScope scope) { Collection packageFqNames = JetAllPackagesIndex.getInstance().getAllKeys(project); diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java index a2350388ffe..186c49fd80f 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java @@ -24,7 +24,6 @@ import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.daemon.impl.MarkerType; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.codeInsight.navigation.NavigationUtil; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; @@ -37,7 +36,6 @@ import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Function; import com.intellij.util.PsiNavigateUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.asJava.KotlinLightClass; import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; @@ -81,11 +79,11 @@ public class JetLineMarkerProvider implements LineMarkerProvider { return null; } } - KotlinLightClass lightClass = LightClassUtil.createLightClass((JetClass) element); + PsiClass lightClass = LightClassUtil.createLightClass((JetClass) element); if (lightClass == null) { return null; } - PsiElement[] children = lightClass.getDelegate().getChildren(); + PsiElement[] children = lightClass.getChildren(); return children.length > 0 ? children[0] : null; } diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java index 34a31efcba0..91f070473a7 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java @@ -31,7 +31,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.asJava.KotlinLightClass; import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.psi.*; @@ -65,7 +64,7 @@ public class JetJUnitConfigurationProducer extends RuntimeConfigurationProducer JetElement owner = PsiTreeUtil.getParentOfType(function, JetFunction.class, JetClass.class); if (owner instanceof JetClass) { - KotlinLightClass delegate = LightClassUtil.createLightClass((JetClass) owner); + PsiClass delegate = LightClassUtil.createLightClass((JetClass) owner); if (delegate != null) { for (PsiMethod method : delegate.getMethods()) { if (method.getNavigationElement() == function) { diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java index 8b96d001b5c..e00d46c23a4 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java @@ -33,7 +33,6 @@ import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.Processor; import com.intellij.util.indexing.FileBasedIndex; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.asJava.KotlinLightClass; import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -82,7 +81,7 @@ public class KotlinAnnotatedElementsSearcher extends AnnotatedElementsSearcher { if (!(DescriptorUtils.getFQName(descriptor).getFqName().equals(annotationFQN))) return; if (parentOfType instanceof JetClass) { - KotlinLightClass lightClass = LightClassUtil.createLightClass((JetClass) parentOfType); + PsiClass lightClass = LightClassUtil.createLightClass((JetClass) parentOfType); consumer.process(lightClass); } else if (parentOfType instanceof JetNamedFunction) { diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index 7d557931cc9..d139bacbec4 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -149,7 +149,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { assertInstanceOf(element, JetClass.class); JetClass aClass = (JetClass) element; - KotlinLightClass createdByWrapDelegate = LightClassUtil.createLightClass(aClass); + PsiClass createdByWrapDelegate = LightClassUtil.createLightClass(aClass); assertNull(createdByWrapDelegate); } @@ -189,7 +189,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { assertNotNull("Caret should be placed to class definition", jetClass); // Should not fail! - KotlinLightClass lightClass = LightClassUtil.createLightClass(jetClass); + KotlinLightClass lightClass = (KotlinLightClass) LightClassUtil.createLightClass(jetClass); assertNotNull(String.format("Failed to wrap jetClass '%s' to class", jetClass.getText()), lightClass); diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java index e5838caed31..48a7b8d58ec 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java @@ -67,6 +67,11 @@ public class NavigateToStdlibSourceRegressionTest extends NavigateToLibraryRegre } private void doNavigationInSourcesTest(@NotNull String path, @NotNull String element, @NotNull String expectedFqName) throws IOException { + PsiElement navigationElement = getNavigationElement(path, element); + checkNavigationElement(navigationElement, expectedFqName); + } + + protected PsiElement getNavigationElement(String path, String element) { File file = new File(path); PsiFile psiFile = getPsiFileForFileFromSources(file); String text = psiFile.getText(); @@ -76,8 +81,7 @@ public class NavigateToStdlibSourceRegressionTest extends NavigateToLibraryRegre text.substring(index - 20, index) + "" + text.substring(index, index + 20), ref); PsiElement resolvedElement = ref.resolve(); assertNotNull("Cannot resolve reference: " + ref.getElement().getText(), resolvedElement); - PsiElement navigationElement = resolvedElement.getNavigationElement(); - checkNavigationElement(navigationElement, expectedFqName); + return resolvedElement.getNavigationElement(); } @NotNull diff --git a/idea/tests/org/jetbrains/jet/plugin/lightClasses/LightClassForLibrarySourceFileTest.java b/idea/tests/org/jetbrains/jet/plugin/lightClasses/LightClassForLibrarySourceFileTest.java new file mode 100644 index 00000000000..f57eeafc9d0 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/lightClasses/LightClassForLibrarySourceFileTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2013 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.plugin.lightClasses; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import org.jetbrains.jet.asJava.KotlinLightClass; +import org.jetbrains.jet.asJava.LightClassUtil; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.plugin.libraries.NavigateToStdlibSourceRegressionTest; + +public class LightClassForLibrarySourceFileTest extends NavigateToStdlibSourceRegressionTest { + + public void testLightClassForFileFromLibrarySource() throws Exception { + PsiElement navigationElement = getNavigationElement("libraries/stdlib/src/kotlin/Iterators.kt", "FunctionIterator"); + assertTrue("FunctionIterator should navigate to JetClassOrObject", navigationElement instanceof JetClassOrObject); + PsiClass lightClass = LightClassUtil.createLightClass((JetClassOrObject) navigationElement); + assertTrue("Do not create Kotlin Light Class for file from library sources", !(lightClass instanceof KotlinLightClass)); + } + +}