diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java index b83bbe2ef13..ba699508f52 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java @@ -100,7 +100,7 @@ public abstract class AbstractLazyMemberScope result = Sets.newLinkedHashSet(); - List declarations = declarationProvider.getFunctionDeclarations(name); + Collection declarations = declarationProvider.getFunctionDeclarations(name); for (JetNamedFunction functionDeclaration : declarations) { JetScope resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration); result.add(resolveSession.getInjector().getDescriptorResolver().resolveFunctionDescriptor(thisDescriptor, resolutionScope, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/DeclarationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/DeclarationProvider.java index 5fa3f8b4b8a..8537be7eb88 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/DeclarationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/DeclarationProvider.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.name.Name; +import java.util.Collection; import java.util.List; /** @@ -33,7 +34,7 @@ public interface DeclarationProvider { List getAllDeclarations(); @NotNull - List getFunctionDeclarations(@NotNull Name name); + Collection getFunctionDeclarations(@NotNull Name name); @NotNull List getPropertyDeclarations(@NotNull Name name); diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/JetIndexKeys.java b/idea/src/org/jetbrains/jet/plugin/stubindex/JetIndexKeys.java index c080de4fd3d..ce711eeec20 100644 --- a/idea/src/org/jetbrains/jet/plugin/stubindex/JetIndexKeys.java +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/JetIndexKeys.java @@ -28,10 +28,15 @@ public interface JetIndexKeys { StubIndexKey SUPERCLASS_NAME_KEY = StubIndexKey.createIndexKey("jet.class.superClassName"); StubIndexKey FQN_KEY = StubIndexKey.createIndexKey("jet.fqn"); - StubIndexKey TOP_LEVEL_FUNCTION_SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.top.level.function.short.name"); - StubIndexKey TOP_LEVEL_EXTENSION_FUNCTION_SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.top.level.extension.function.short.name"); + StubIndexKey TOP_LEVEL_FUNCTION_SHORT_NAME_KEY = + StubIndexKey.createIndexKey("jet.top.level.function.short.name"); - StubIndexKey TOP_LEVEL_FUNCTIONS_FQN_NAME_KEY = StubIndexKey.createIndexKey("jet.top.level.functions.fqn.name"); + StubIndexKey TOP_LEVEL_EXTENSION_FUNCTION_SHORT_NAME_KEY = + StubIndexKey.createIndexKey("jet.top.level.extension.function.short.name"); + + /** Stores package top level function (both extension and non-extension) full qualified names. */ + StubIndexKey TOP_LEVEL_FUNCTIONS_FQN_NAME_KEY = + StubIndexKey.createIndexKey("jet.top.level.functions.fqn.name"); StubIndexKey FUNCTIONS_SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.functions.short.name"); } diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/JetTopLevelFunctionsFqnNameIndex.java b/idea/src/org/jetbrains/jet/plugin/stubindex/JetTopLevelFunctionsFqnNameIndex.java new file mode 100644 index 00000000000..83d7387acb4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/JetTopLevelFunctionsFqnNameIndex.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-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.plugin.stubindex; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.stubs.StringStubIndexExtension; +import com.intellij.psi.stubs.StubIndexKey; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetNamedFunction; + +import java.util.Collection; + +/** + * @author Nikolay Krasko + */ +public class JetTopLevelFunctionsFqnNameIndex extends StringStubIndexExtension { + private static final JetTopLevelFunctionsFqnNameIndex INSTANCE = new JetTopLevelFunctionsFqnNameIndex(); + + public static JetTopLevelFunctionsFqnNameIndex getInstance() { + return INSTANCE; + } + + @NotNull + @Override + public StubIndexKey getKey() { + return JetIndexKeys.TOP_LEVEL_FUNCTIONS_FQN_NAME_KEY; + } + + @Override + public Collection get(final String s, final Project project, @NotNull final GlobalSearchScope scope) { + return super.get(s, project, new JetSourceFilterScope(scope)); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java b/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java index ff7859c1e5f..2cda41679d7 100644 --- a/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java @@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub; import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub; import org.jetbrains.jet.lang.psi.stubs.PsiJetObjectStub; import org.jetbrains.jet.lang.psi.stubs.elements.StubIndexService; +import org.jetbrains.jet.lang.resolve.name.FqName; /** * @author Nikolay Krasko @@ -61,16 +62,18 @@ public class StubIndexServiceImpl implements StubIndexService { // Collection only top level functions as only they are expected in completion without explicit import if (!stub.isExtension()) { sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTION_SHORT_NAME_KEY, name); - // sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTION_FQNAME_KEY, name); } else { sink.occurrence(JetIndexKeys.TOP_LEVEL_EXTENSION_FUNCTION_SHORT_NAME_KEY, name); - // sink.occurrence(JetIndexKeys.EXTENSION_FUNCTION_FQNAME_KEY, name); + } + + FqName topFQName = stub.getTopFQName(); + if (topFQName != null) { + sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTIONS_FQN_NAME_KEY, topFQName.toString()); } } sink.occurrence(JetIndexKeys.FUNCTIONS_SHORT_NAME_KEY, name); - // sink.occurrence(JetIndexKeys.FUNCTIONS_FQN_NAME_KEY); } } } diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/AbstractStubDeclarationProvider.java b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/AbstractStubDeclarationProvider.java new file mode 100644 index 00000000000..593726f45ab --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/AbstractStubDeclarationProvider.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010-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.plugin.stubindex.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetDeclaration; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.lang.resolve.lazy.DeclarationProvider; +import org.jetbrains.jet.lang.resolve.name.Name; + +import java.util.Collection; +import java.util.List; + +/** + * @author Nikolay Krasko + */ +public abstract class AbstractStubDeclarationProvider implements DeclarationProvider { + @Override + public List getAllDeclarations() { + // TODO: + return null; + } + + @NotNull + @Override + public Collection getFunctionDeclarations(@NotNull Name name) { + // TODO: + return null; + } + + @NotNull + @Override + public List getPropertyDeclarations(@NotNull Name name) { + // TODO: + return null; + } + + @Override + public JetClassOrObject getClassOrObjectDeclaration(@NotNull Name name) { + // TODO: + return null; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubClassMemberDeclarationProvider.java b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubClassMemberDeclarationProvider.java new file mode 100644 index 00000000000..d612e3dcd5e --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubClassMemberDeclarationProvider.java @@ -0,0 +1,33 @@ +/* + * Copyright 2010-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.plugin.stubindex.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.lazy.ClassMemberDeclarationProvider; +import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; + +/** + * @author Nikolay Krasko + */ +public class StubClassMemberDeclarationProvider extends AbstractStubDeclarationProvider implements ClassMemberDeclarationProvider { + @NotNull + @Override + public JetClassLikeInfo getOwnerInfo() { + // TODO: + return null; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubDeclarationProviderFactory.java b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubDeclarationProviderFactory.java new file mode 100644 index 00000000000..b6f207ae748 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubDeclarationProviderFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010-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.plugin.stubindex.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.lazy.ClassMemberDeclarationProvider; +import org.jetbrains.jet.lang.resolve.lazy.DeclarationProviderFactory; +import org.jetbrains.jet.lang.resolve.lazy.PackageMemberDeclarationProvider; +import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; +import org.jetbrains.jet.lang.resolve.name.FqName; + +/** + * @author Nikolay Krasko + */ +public class StubDeclarationProviderFactory implements DeclarationProviderFactory { + @NotNull + @Override + public ClassMemberDeclarationProvider getClassMemberDeclarationProvider(@NotNull JetClassLikeInfo classLikeInfo) { + // TODO: + return null; + } + + @Override + public PackageMemberDeclarationProvider getPackageMemberDeclarationProvider(@NotNull FqName packageFqName) { + // TODO: + return null; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubPackageMemberDeclarationProvider.java b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubPackageMemberDeclarationProvider.java new file mode 100644 index 00000000000..d27ff25301c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/resolve/StubPackageMemberDeclarationProvider.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010-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.plugin.stubindex.resolve; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.lang.resolve.lazy.PackageMemberDeclarationProvider; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.plugin.stubindex.JetTopLevelFunctionsFqnNameIndex; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +/** + * @author Nikolay Krasko + */ +public class StubPackageMemberDeclarationProvider extends AbstractStubDeclarationProvider implements PackageMemberDeclarationProvider { + @NotNull private final FqName fqName; + @NotNull private final Project project; + + public StubPackageMemberDeclarationProvider(@NotNull FqName fqName, @NotNull Project project) { + this.fqName = fqName; + this.project = project; + } + + @Override + public boolean isPackageDeclared(@NotNull Name name) { + FqName childFqName = fqName.child(name); + + for (JetFile jetFile : getJetFiles()) { + if (childFqName.toString().equals(jetFile.getPackageName())) { + return true; + } + } + + return false; + } + + @NotNull + @Override + public Collection getFunctionDeclarations(@NotNull Name name) { + return JetTopLevelFunctionsFqnNameIndex.getInstance().get(fqName.child(name).toString(), project, GlobalSearchScope.allScope(project)); + } + + @NotNull + @Override + public List getPropertyDeclarations(@NotNull Name name) { + return super.getPropertyDeclarations(name); //To change body of overridden methods use File | Settings | File Templates. + } + + @Override + public Collection getAllDeclaredPackages() { + Collection subPackages = new HashSet(); + + for (JetFile file : getJetFiles()) { + String packageName = file.getPackageName(); + if (packageName != null) { + FqName packageFqName = new FqName(packageName); + if (!packageFqName.isRoot() && packageFqName.parent().equalsTo(fqName)) { + subPackages.add(packageFqName); + } + } + } + + return subPackages; + } + + private Collection getJetFiles() { + Collection kotlinFiles = FilenameIndex.getAllFilesByExt(project, "kt"); + kotlinFiles.addAll(FilenameIndex.getAllFilesByExt(project, "jet")); + + Collection jetFiles = new HashSet(kotlinFiles.size()); + + for (VirtualFile file : kotlinFiles) { + PsiFile kotlinFile = PsiManager.getInstance(project).findFile(file); + if (kotlinFile instanceof JetFile) { + jetFiles.add((JetFile) kotlinFile); + } + } + + return jetFiles; + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/stubs/resolve/JetStubResolveTest.java b/idea/tests/org/jetbrains/jet/plugin/stubs/resolve/JetStubResolveTest.java new file mode 100644 index 00000000000..dd7c0508612 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/stubs/resolve/JetStubResolveTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010-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.plugin.stubs.resolve; + +import com.google.common.base.Function; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.plugin.stubindex.resolve.StubPackageMemberDeclarationProvider; + +import java.util.Collection; +import java.util.List; + +/** + * @author Nikolay Krasko + */ +public class JetStubResolveTest extends LightCodeInsightFixtureTestCase { + public void testSinglePackageFunction() { + myFixture.configureByText(JetFileType.INSTANCE, + "package test.testing\n" + + "fun some() {}"); + StubPackageMemberDeclarationProvider provider = + new StubPackageMemberDeclarationProvider(new FqName("test.testing"), getProject()); + + List some = Lists.newArrayList(provider.getFunctionDeclarations(Name.identifier("some"))); + + assertSize(1, some); + assertEquals("fun some() {}", some.get(0).getText()); + } + + public void testMultiPackageFunction() { + myFixture.configureByText(JetFileType.INSTANCE, + "package test.testing\n" + + "fun other(v : Int) = 12\n" + + "fun other(v : String) {}"); + + StubPackageMemberDeclarationProvider provider = + new StubPackageMemberDeclarationProvider(new FqName("test.testing"), getProject()); + + List other = Lists.newArrayList(provider.getFunctionDeclarations(Name.identifier("other"))); + Collection functionTexts = Collections2.transform(other, new Function() { + @Override + public String apply(JetNamedFunction function) { + return function.getText(); + } + }); + + assertSize(2, other); + assertTrue(functionTexts.contains("fun other(v : Int) = 12")); + assertTrue(functionTexts.contains("fun other(v : String) {}")); + } +}