Fix completion for top level non-imported functions

This commit is contained in:
Natalia.Ukhorskaya
2013-01-11 11:45:23 +04:00
parent fe685633b0
commit 0f2fa6bade
15 changed files with 210 additions and 124 deletions
@@ -82,7 +82,7 @@ class JetFromJavaDescriptorHelper {
Collection<PsiAnnotation> annotations = JavaAnnotationIndex.getInstance().get(JetClass.class.getSimpleName(), project, scope);
for (PsiAnnotation annotation : annotations) {
PsiModifierList modifierList = (PsiModifierList)annotation.getParent();
PsiModifierList modifierList = (PsiModifierList) annotation.getParent();
final PsiElement owner = modifierList.getParent();
if (owner instanceof PsiClass) {
PsiClass psiClass = (PsiClass) owner;
@@ -95,7 +95,7 @@ class JetFromJavaDescriptorHelper {
return jetObjectClasses;
}
static Collection<String> getTopExtensionFunctionNames(Project project, GlobalSearchScope scope) {
// Extension function should have an parameter of type JetValueParameter with explicit receiver parameter.
@@ -127,11 +127,12 @@ class JetFromJavaDescriptorHelper {
static Collection<PsiMethod> getTopExtensionFunctionPrototypesByName(String name, Project project, GlobalSearchScope scope) {
return filterJetJavaPrototypesByName(
name, project, scope,
new Predicate<JetValueParameterAnnotation>() {
new Predicate<PsiMethod>() {
@Override
public boolean apply(@Nullable JetValueParameterAnnotation jetValueParameterAnnotation) {
assert jetValueParameterAnnotation != null;
return jetValueParameterAnnotation.receiver();
public boolean apply(@Nullable PsiMethod psiMethod) {
assert psiMethod != null;
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
return parameters.length > 0 && JetValueParameterAnnotation.get(parameters[0]).receiver();
}
});
}
@@ -139,11 +140,12 @@ class JetFromJavaDescriptorHelper {
static Collection<PsiMethod> getTopLevelFunctionPrototypesByName(String name, Project project, GlobalSearchScope scope) {
return filterJetJavaPrototypesByName(
name, project, scope,
new Predicate<JetValueParameterAnnotation>() {
new Predicate<PsiMethod>() {
@Override
public boolean apply(@Nullable JetValueParameterAnnotation jetValueParameterAnnotation) {
assert jetValueParameterAnnotation != null;
return !jetValueParameterAnnotation.receiver();
public boolean apply(@Nullable PsiMethod psiMethod) {
assert psiMethod != null;
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
return parameters.length == 0 || !JetValueParameterAnnotation.get(parameters[0]).receiver();
}
});
}
@@ -169,7 +171,8 @@ class JetFromJavaDescriptorHelper {
private static Collection<PsiMethod> filterJetJavaPrototypesByName(
String name, Project project, GlobalSearchScope scope,
Predicate<JetValueParameterAnnotation> filterPredicate) {
Predicate<PsiMethod> filterPredicate
) {
Set<PsiMethod> selectedMethods = new HashSet<PsiMethod>();
Collection<PsiMethod> psiMethods = JavaMethodNameIndex.getInstance().get(name, project, scope);
@@ -185,10 +188,8 @@ class JetFromJavaDescriptorHelper {
}
// Should be parameter with JetValueParameter.receiver == true
for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) {
if (filterPredicate.apply(JetValueParameterAnnotation.get(parameter))) {
selectedMethods.add(psiMethod);
}
if (filterPredicate.apply(psiMethod)) {
selectedMethods.add(psiMethod);
}
}
@@ -0,0 +1,11 @@
package testing
fun someFun() {
defaultDocumentBuilderFa<caret>
}
// Important: This test checks that completion will find top level functions from jars.
// If you going to update it make sure that methods are not auto-imported
// RUNTIME: 1
// EXIST: defaultDocumentBuilderFactory
@@ -0,0 +1,8 @@
package testing
fun someFun() {
1.abcd<caret>
}
// EXIST: abcdCCC3, abcdDDD4
// ABSENT: abcdAAA1, abcdBBB2
@@ -0,0 +1,8 @@
package testing
fun someFun() {
abcd<caret>
}
// EXIST: abcdAAA1, abcdBBB2
// ABSENT: abcdCCC3, abcdDDD4
@@ -17,7 +17,9 @@
package org.jetbrains.jet.completion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.testing.ConfigLibraryUtil;
import java.io.File;
@@ -242,6 +244,10 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
doTest();
}
public void testTopLevelFromStandardLibraryWithoutParam() {
doTest();
}
public void testVariableClassName() {
doTest();
}
@@ -282,6 +288,27 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
doTest();
}
public void testTopLevelNonImportedFun() {
doTestWithJar();
}
public void testTopLevelNonImportedExtFun() {
doTestWithJar();
}
public void doTestWithJar() {
File libraryFile = new File(getTestDataPath() + "/" + getTestName(false) + ".jar");
JetJdkAndLibraryProjectDescriptor projectDescriptor = new JetJdkAndLibraryProjectDescriptor(libraryFile);
try {
ConfigLibraryUtil.configureLibrary(getModule(), getFullJavaJDK(), projectDescriptor);
doTest();
}
finally {
ConfigLibraryUtil.unConfigureLibrary(getModule(), getFullJavaJDK(), projectDescriptor);
}
}
@NotNull
@Override
protected String getTestDataPath() {
@@ -26,7 +26,7 @@ import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.Sdk;
import org.apache.commons.lang.SystemUtils;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.testing.ConfigRuntimeUtil;
import org.jetbrains.jet.testing.ConfigLibraryUtil;
import org.jetbrains.jet.InTextDirectivesUtils;
import org.jetbrains.jet.utils.ExceptionUtils;
@@ -51,7 +51,7 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
try {
if (withKotlinRuntime) {
ConfigRuntimeUtil.configureKotlinRuntime(getModule(), getFullJavaJDK());
ConfigLibraryUtil.configureKotlinRuntime(getModule(), getFullJavaJDK());
}
Integer completionTime = completionUtils.getExecutionTime(fileText);
@@ -82,7 +82,7 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
}
finally {
if (withKotlinRuntime) {
ConfigRuntimeUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK());
ConfigLibraryUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK());
}
}
}
@@ -0,0 +1,93 @@
/*
* 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;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public class JetJdkAndLibraryProjectDescriptor implements LightProjectDescriptor {
private final String libraryName = "myLibrary";
private final File libraryFile;
private final OrderRootType libraryRootType;
public JetJdkAndLibraryProjectDescriptor(File libraryFile, OrderRootType libraryRootType) {
assert libraryFile.exists() : "Library file doesn't exist: " + libraryFile.getAbsolutePath();
this.libraryFile = libraryFile;
this.libraryRootType = libraryRootType;
}
public JetJdkAndLibraryProjectDescriptor(File libraryFile) {
assert libraryFile.exists() : "Library file doesn't exist: " + libraryFile.getAbsolutePath();
this.libraryFile = libraryFile;
this.libraryRootType = OrderRootType.CLASSES;
}
@Override
public ModuleType getModuleType() {
return StdModuleTypes.JAVA;
}
@Override
public Sdk getSdk() {
return PluginTestCaseBase.jdkFromIdeaHome();
}
@Override
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @Nullable ContentEntry contentEntry) {
Library library = model.getModuleLibraryTable().createLibrary(libraryName);
Library.ModifiableModel modifiableModel = library.getModifiableModel();
modifiableModel.addRoot(VfsUtil.getUrlForLibraryRoot(libraryFile), libraryRootType);
modifiableModel.commit();
}
public void unConfigureModule(@NotNull ModifiableRootModel model) {
for (OrderEntry orderEntry : model.getOrderEntries()) {
if (orderEntry instanceof LibraryOrderEntry) {
LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry) orderEntry;
Library library = libraryOrderEntry.getLibrary();
if (library != null) {
String libraryName = library.getName();
if (libraryName != null && libraryName.equals(this.libraryName)) {
// Dispose attached roots
Library.ModifiableModel modifiableModel = library.getModifiableModel();
for (String rootUrl : library.getRootProvider().getUrls(OrderRootType.CLASSES)) {
modifiableModel.removeRoot(rootUrl, OrderRootType.CLASSES);
}
modifiableModel.commit();
model.getModuleLibraryTable().removeLibrary(library);
break;
}
}
}
}
}
}
@@ -16,65 +16,12 @@
package org.jetbrains.jet.plugin;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime;
public class JetWithJdkAndRuntimeLightProjectDescriptor implements LightProjectDescriptor {
public class JetWithJdkAndRuntimeLightProjectDescriptor extends JetJdkAndLibraryProjectDescriptor {
protected JetWithJdkAndRuntimeLightProjectDescriptor() {
super(ForTestCompileRuntime.runtimeJarForTests());
}
public static final JetWithJdkAndRuntimeLightProjectDescriptor INSTANCE = new JetWithJdkAndRuntimeLightProjectDescriptor();
@Override
public ModuleType getModuleType() {
return StdModuleTypes.JAVA;
}
@Override
public Sdk getSdk() {
return PluginTestCaseBase.jdkFromIdeaHome();
}
@Override
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @Nullable ContentEntry contentEntry) {
Library library = model.getModuleLibraryTable().createLibrary("ktl");
Library.ModifiableModel modifiableModel = library.getModifiableModel();
modifiableModel.addRoot(VfsUtil.getUrlForLibraryRoot(ForTestCompileRuntime.runtimeJarForTests()), OrderRootType.CLASSES);
modifiableModel.commit();
}
public static void unConfigureModule(@NotNull ModifiableRootModel model) {
for (OrderEntry orderEntry : model.getOrderEntries()) {
if (orderEntry instanceof LibraryOrderEntry) {
LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry) orderEntry;
Library library = libraryOrderEntry.getLibrary();
if (library != null) {
String libraryName = library.getName();
if (libraryName != null && libraryName.equals("ktl")) {
// Dispose attached roots
Library.ModifiableModel modifiableModel = library.getModifiableModel();
for (String rootUrl : library.getRootProvider().getUrls(OrderRootType.CLASSES)) {
modifiableModel.removeRoot(rootUrl, OrderRootType.CLASSES);
}
modifiableModel.commit();
model.getModuleLibraryTable().removeLibrary(library);
break;
}
}
}
}
}
}
@@ -24,7 +24,7 @@ import com.intellij.testFramework.LightCodeInsightTestCase;
import org.apache.commons.lang.SystemUtils;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.plugin.editor.importOptimizer.JetImportOptimizer;
import org.jetbrains.jet.testing.ConfigRuntimeUtil;
import org.jetbrains.jet.testing.ConfigLibraryUtil;
import java.io.File;
@@ -56,7 +56,7 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase {
public void testKt1850FullQualified() throws Exception {
doTest();
}
public void testKt1850InnerClass() throws Exception {
doTest();
}
@@ -77,7 +77,7 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase {
public void doTestWithKotlinRuntime() {
try {
ConfigRuntimeUtil.configureKotlinRuntime(getModule(), getFullJavaJDK());
ConfigLibraryUtil.configureKotlinRuntime(getModule(), getFullJavaJDK());
configureByFile(fileName());
invokeFormatFile();
@@ -85,7 +85,7 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase {
checkResultByFile(null, checkFileName(), false);
}
finally {
ConfigRuntimeUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK());
ConfigLibraryUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK());
}
}
@@ -114,7 +114,7 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase {
private static void invokeFormatFile() {
CommandProcessor.getInstance().executeCommand(
getProject(), new JetImportOptimizer().processFile(getFile()),
"Optimize Imports", null, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION);
getProject(), new JetImportOptimizer().processFile(getFile()),
"Optimize Imports", null, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION);
}
}
@@ -68,7 +68,7 @@ public class NavigateToStdlibSourceRegressionTest extends NavigateToLibraryRegre
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @Nullable ContentEntry contentEntry) {
super.configureModule(module, model, contentEntry);
Library library = model.getModuleLibraryTable().getLibraryByName("ktl");
Library library = model.getModuleLibraryTable().getLibraryByName("myLibrary");
assert library != null;
Library.ModifiableModel modifiableModel = library.getModifiableModel();
modifiableModel.addRoot(VfsUtil.getUrlForLibraryRoot(new File("libraries/stdlib/src")), OrderRootType.SOURCES);
@@ -29,7 +29,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.testing.ConfigRuntimeUtil;
import org.jetbrains.jet.testing.ConfigLibraryUtil;
import java.io.File;
import java.io.FilenameFilter;
@@ -85,7 +85,8 @@ public class JetQuickFixTest extends LightQuickFixTestCase {
List<String> subDirs = Arrays.asList(quickFixTestsFilter != null ? dir.list(quickFixTestsFilter) : dir.list());
Collections.sort(subDirs);
for (String subDirName : subDirs) {
final TestSuite singleFileTestSuite = JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, singleFileNameFilter, singleFileNamedTestFactory);
final TestSuite singleFileTestSuite = JetTestCaseBuilder
.suiteForDirectory(getTestDataPathBase(), subDirName, true, singleFileNameFilter, singleFileNamedTestFactory);
if (singleFileTestSuite.countTestCases() != 0) {
suite.addTest(singleFileTestSuite);
}
@@ -107,7 +108,7 @@ public class JetQuickFixTest extends LightQuickFixTestCase {
boolean isWithRuntime = name.endsWith("Runtime");
if (isWithRuntime) {
ConfigRuntimeUtil.configureKotlinRuntime(getModule(), getFullJavaJDK());
ConfigLibraryUtil.configureKotlinRuntime(getModule(), getFullJavaJDK());
}
try {
@@ -117,7 +118,7 @@ public class JetQuickFixTest extends LightQuickFixTestCase {
}
finally {
if (isWithRuntime) {
ConfigRuntimeUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK());
ConfigLibraryUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK());
}
}
}
@@ -17,21 +17,13 @@
package org.jetbrains.jet.search;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.InTextDirectivesUtils;
@@ -40,27 +32,8 @@ import java.io.IOException;
import java.util.List;
public class JUnitMembersSearcherTest extends AbstractSearcherTest {
private static final LightProjectDescriptor junitProjectDescriptor = new LightProjectDescriptor() {
@Override
public ModuleType getModuleType() {
return StdModuleTypes.JAVA;
}
@Override
public Sdk getSdk() {
return PluginTestCaseBase.jdkFromIdeaHome();
}
@Override
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
Library library = model.getModuleLibraryTable().createLibrary("junit");
Library.ModifiableModel modifiableModel = library.getModifiableModel();
modifiableModel.addRoot(VfsUtil.getUrlForLibraryRoot(
new File(PathManager.getHomePath().replace(File.separatorChar, '/') + "/lib/junit-4.10.jar")),
OrderRootType.CLASSES);
modifiableModel.commit();
}
};
private static final LightProjectDescriptor junitProjectDescriptor =
new JetJdkAndLibraryProjectDescriptor(new File(PathManager.getHomePath().replace(File.separatorChar, '/') + "/lib/junit-4.10.jar"));
public void testJunit3() throws IOException {
doJUnit3test();
@@ -100,7 +73,6 @@ public class JUnitMembersSearcherTest extends AbstractSearcherTest {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return junitProjectDescriptor;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
* 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.
@@ -21,16 +21,31 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor;
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor;
/**
* Helper for configuring kotlin runtime in tested project.
*/
public class ConfigRuntimeUtil {
private ConfigRuntimeUtil() {
public class ConfigLibraryUtil {
private ConfigLibraryUtil() {
}
public static void configureKotlinRuntime(final Module module, final Sdk sdk) {
configureLibrary(module, sdk, JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE);
}
public static void unConfigureKotlinRuntime(final Module module, final Sdk sdk) {
unConfigureLibrary(module, sdk, JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE);
}
public static void configureLibrary(
@NotNull final Module module,
@NotNull final Sdk sdk,
@NotNull final LightProjectDescriptor projectDescriptor
) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -39,24 +54,27 @@ public class ConfigRuntimeUtil {
final ModifiableRootModel rootModel = rootManager.getModifiableModel();
rootModel.setSdk(sdk);
JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE.configureModule(module, rootModel, null);
projectDescriptor.configureModule(module, rootModel, null);
rootModel.commit();
}
});
}
public static void unConfigureKotlinRuntime(final Module module, final Sdk sdk) {
public static void unConfigureLibrary(
@NotNull final Module module,
@NotNull final Sdk sdk,
@NotNull final LightProjectDescriptor projectDescriptor
) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
final ModifiableRootModel rootModel = rootManager.getModifiableModel();
rootModel.setSdk(sdk);
JetWithJdkAndRuntimeLightProjectDescriptor.unConfigureModule(rootModel);
if (projectDescriptor instanceof JetJdkAndLibraryProjectDescriptor) {
((JetJdkAndLibraryProjectDescriptor) projectDescriptor).unConfigureModule(rootModel);
}
rootModel.commit();
}
});