KT-1103 Public outer function from different package and source file is not visible in completion:

- Stubs elements are enabled
- Changed method for selecting indexing policy for plugin and compiler
- Quick fix for import unresolved top-level function added
This commit is contained in:
Nikolay Krasko
2012-01-31 14:10:08 +04:00
parent dbbd4c6902
commit 2826db7d9a
37 changed files with 569 additions and 270 deletions
@@ -1110,7 +1110,8 @@ public class JavaDescriptorResolver {
}
@NotNull
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor descriptor, @NotNull PsiClass psiClass, @NotNull String methodName, boolean staticMembers) {
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor descriptor, @NotNull PsiClass psiClass,
@NotNull String methodName, boolean staticMembers) {
ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass));
@@ -8,12 +8,9 @@ import org.jetbrains.annotations.NotNull;
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.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
/**
* @author abreslav
@@ -16,27 +16,14 @@ import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetNodeType;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.stubs.elements.JetFakeStubElementFactory;
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementFactory;
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementType;
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
import org.jetbrains.jet.lexer.JetLexer;
import org.jetbrains.jet.lexer.JetTokens;
public class JetParserDefinition implements ParserDefinition {
// TODO (stubs):
private static JetStubElementFactory stubElementFactory = new JetFakeStubElementFactory();
public static void setStubFactory(JetStubElementFactory factory) {
stubElementFactory = factory;
}
public static JetStubElementFactory getStubElementTypeFactory() {
return stubElementFactory;
}
public JetParserDefinition() {
if (!ApplicationManager.getApplication().isCommandLine()) {
}
@@ -52,9 +39,7 @@ public class JetParserDefinition implements ParserDefinition {
}
public IFileElementType getFileNodeType() {
// TODO (stubs)
return JetNodeTypes.JET_FILE;
// return JetStubElementTypes.FILE;
return JetStubElementTypes.FILE;
}
@NotNull
@@ -7,6 +7,8 @@ import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubTree;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetNodeTypes;
@@ -58,4 +60,19 @@ public class JetFile extends PsiFileBase {
visitor.visitFile(this);
}
}
@Override
public StubElement getStub() {
return super.getStub(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public StubTree calcStubTree() {
return super.calcStubTree(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public StubTree getStubTree() {
return super.getStubTree(); //To change body of overridden methods use File | Settings | File Templates.
}
}
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.stubs.IStubElementType;
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.lexer.JetTokens;
@@ -66,11 +67,37 @@ public class JetNamedFunction extends JetFunction implements StubBasedPsiElement
return this;
}
/**
* Returns full qualified name for function "package_fqn.function_name"
* Not null for top level functions.
* @return
*/
@Nullable
public String getQualifiedName() {
final PsiJetFunctionStub stub = getStub();
if (stub != null) {
// TODO (stubs): return stub.getQualifiedName();
}
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();
}
return null;
}
@Override
public IStubElementType getElementType() {
return JetStubElementTypes.FUNCTION;
}
@Override
public PsiJetFunctionStub<?> getStub() {
// TODO (stubs)
@@ -12,11 +12,17 @@ public interface PsiJetFunctionStub <T extends JetFunction> extends StubElement<
@Nullable
String getName();
boolean isDeclaration();
/**
* Is function defined in directly in package.
* @return
*/
boolean isTopLevel();
/**
* Does function extends some type.
*/
boolean isExtension();
@NotNull
String[] getAnnotations();
@NotNull
String getReturnTypeText();
}
@@ -13,17 +13,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetClassStubImpl;
import org.jetbrains.jet.plugin.JetLanguage;
import java.io.IOException;
/**
* @author Nikolay Krasko
*/
public abstract class JetClassElementType extends JetStubElementType<PsiJetClassStub, JetClass> {
public class JetClassElementType extends JetStubElementType<PsiJetClassStub, JetClass> {
public JetClassElementType(@NotNull @NonNls String debugName) {
super(debugName, JetLanguage.INSTANCE);
super(debugName);
}
@Override
@@ -33,7 +32,6 @@ public abstract class JetClassElementType extends JetStubElementType<PsiJetClass
@Override
public JetClass createPsi(@NotNull PsiJetClassStub stub) {
// TODO: Don't work for kotlin classes
// return getPsiFactory(stub).createClass(stub);
return null;
}
@@ -45,7 +43,7 @@ public abstract class JetClassElementType extends JetStubElementType<PsiJetClass
@Override
public PsiJetClassStub createStub(@NotNull JetClass psi, StubElement parentStub) {
return null; //To change body of implemented methods use File | Settings | File Templates.
return new PsiJetClassStubImpl(JetStubElementTypes.CLASS, parentStub, psi.getName(), psi.getName());
}
@Override
@@ -66,5 +64,7 @@ public abstract class JetClassElementType extends JetStubElementType<PsiJetClass
}
@Override
public abstract void indexStub(PsiJetClassStub stub, IndexSink sink);
public void indexStub(PsiJetClassStub stub, IndexSink sink) {
StubIndexServiceFactory.getInstance().indexClass(stub, sink);
}
}
@@ -1,28 +0,0 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
import com.intellij.psi.stubs.IndexSink;
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
/**
* @author Nikolay Krasko
*/
public class JetFakeStubElementFactory implements JetStubElementFactory {
@Override
public JetClassElementType getClassElementType() {
return new JetClassElementType("CLASS") {
@Override
public void indexStub(PsiJetClassStub stub, IndexSink sink) {
}
};
}
@Override
public JetFunctionElementType getFunctionElementType() {
return new JetFunctionElementType("FUN") {
@Override
public void indexStub(PsiJetFunctionStub stub, IndexSink sink) {
}
};
}
}
@@ -1,7 +1,5 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.StubBuilder;
import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
@@ -35,21 +33,6 @@ public class JetFileElementType extends IStubFileElementType<PsiJetFileStub> {
return STUB_VERSION;
}
@Override
public boolean shouldBuildStubFor(final VirtualFile file) {
// TODO:
return true;
// final VirtualFile dir = file.getParent();
// return dir == null || dir.getUserData(LanguageLevel.KEY) != null;
}
@Override
public ASTNode createNode(final CharSequence text) {
// TODO (stub):
return super.createNode(text);
}
@Override
public String getExternalId() {
return "jet.FILE";
@@ -17,7 +17,7 @@ public class JetFileStubBuilder extends DefaultStubBuilder {
if (!(file instanceof JetFile)) return super.createStubForFile(file);
JetFile jetFile = (JetFile) file;
// TODO (stubs):
String packageName = "default";
@@ -3,29 +3,31 @@ package org.jetbrains.jet.lang.psi.stubs.elements;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
import org.jetbrains.jet.plugin.JetLanguage;
import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetFunctionStubImpl;
import java.io.IOException;
/**
* @author Nikolay Krasko
*/
public abstract class JetFunctionElementType extends JetStubElementType<PsiJetFunctionStub, JetFunction> {
public class JetFunctionElementType extends JetStubElementType<PsiJetFunctionStub, JetNamedFunction> {
public JetFunctionElementType(@NotNull @NonNls String debugName) {
super(debugName, JetLanguage.INSTANCE);
super(debugName);
}
@Override
public JetFunction createPsiFromAst(@NotNull ASTNode node) {
public JetNamedFunction createPsiFromAst(@NotNull ASTNode node) {
return new JetNamedFunction(node);
}
@@ -35,22 +37,38 @@ public abstract class JetFunctionElementType extends JetStubElementType<PsiJetFu
}
@Override
public JetFunction createPsi(@NotNull PsiJetFunctionStub stub) {
public JetNamedFunction createPsi(@NotNull PsiJetFunctionStub stub) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public PsiJetFunctionStub createStub(@NotNull JetFunction psi, StubElement parentStub) {
return null; //To change body of implemented methods use File | Settings | File Templates.
public PsiJetFunctionStub createStub(@NotNull JetNamedFunction psi, StubElement parentStub) {
final boolean isTopLevel = parentStub instanceof PsiJetFileStub;
final boolean isExtension = psi.getReceiverTypeRef() != null;
return new PsiJetFunctionStubImpl(
JetStubElementTypes.FUNCTION, parentStub, psi.getName(),
isTopLevel, isExtension);
}
@Override
public void serialize(PsiJetFunctionStub stub, StubOutputStream dataStream) throws IOException {
//To change body of implemented methods use File | Settings | File Templates.
dataStream.writeName(stub.getName());
dataStream.writeBoolean(stub.isTopLevel());
dataStream.writeBoolean(stub.isExtension());
}
@Override
public PsiJetFunctionStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
return null; //To change body of implemented methods use File | Settings | File Templates.
final StringRef name = dataStream.readName();
final boolean isTopLevel = dataStream.readBoolean();
final boolean isExtension = dataStream.readBoolean();
return new PsiJetFunctionStubImpl(JetStubElementTypes.FUNCTION, parentStub, name, isTopLevel, isExtension);
}
@Override
public void indexStub(PsiJetFunctionStub stub, IndexSink sink) {
StubIndexServiceFactory.getInstance().indexFunction(stub, sink);
}
}
@@ -1,9 +0,0 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
/**
* @author Nikolay Krasko
*/
public interface JetStubElementFactory {
JetClassElementType getClassElementType();
JetFunctionElementType getFunctionElementType();
}
@@ -1,7 +1,6 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub;
import com.intellij.psi.impl.java.stubs.StubPsiFactory;
@@ -10,7 +9,7 @@ import com.intellij.psi.stubs.PsiFileStub;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.JetLanguage;
/**
* @author Nikolay Krasko
@@ -18,12 +17,10 @@ import org.jetbrains.annotations.Nullable;
public abstract class JetStubElementType<StubT extends StubElement, PsiT extends PsiElement>
extends ILightStubElementType<StubT, PsiT> {
public JetStubElementType(@NotNull @NonNls String debugName, @Nullable Language language) {
super(debugName, language);
public JetStubElementType(@NotNull @NonNls String debugName) {
super(debugName, JetLanguage.INSTANCE);
}
public abstract PsiT createPsiFromAst(@NotNull ASTNode node);
protected StubPsiFactory getPsiFactory(StubT stub) {
@@ -1,13 +1,11 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
/**
* @author Nikolay Krasko
*/
public interface JetStubElementTypes {
JetFileElementType FILE = new JetFileElementType();
JetClassElementType CLASS = JetParserDefinition.getStubElementTypeFactory().getClassElementType();
JetFunctionElementType FUNCTION = JetParserDefinition.getStubElementTypeFactory().getFunctionElementType();
JetClassElementType CLASS = new JetClassElementType("CLASS");
JetFunctionElementType FUNCTION = new JetFunctionElementType("FUN");
}
@@ -0,0 +1,27 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
import com.intellij.psi.stubs.IndexSink;
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
/**
* @author Nikolay Krasko
*/
public interface StubIndexService {
/**
* Default implementation with no indexing.
*/
StubIndexService NO_INDEX_SERVICE = new StubIndexService() {
@Override
public void indexClass(PsiJetClassStub stub, IndexSink sink) {
}
@Override
public void indexFunction(PsiJetFunctionStub stub, IndexSink sink) {
}
};
void indexClass(PsiJetClassStub stub, IndexSink sink);
void indexFunction(PsiJetFunctionStub stub, IndexSink sink);
}
@@ -0,0 +1,18 @@
package org.jetbrains.jet.lang.psi.stubs.elements;
import com.intellij.openapi.components.ServiceManager;
/**
* @author Nikolay Krasko
*/
final class StubIndexServiceFactory {
private StubIndexServiceFactory() {
}
public static StubIndexService getInstance() {
// If executed in plugin service will be registered
final StubIndexService registeredService = ServiceManager.getService(StubIndexService.class);
return registeredService != null ? registeredService : StubIndexService.NO_INDEX_SERVICE;
}
}
@@ -3,7 +3,9 @@ package org.jetbrains.jet.lang.psi.stubs.impl;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
@@ -11,49 +13,44 @@ import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
* @author Nikolay Krasko
*/
public class PsiJetFunctionStubImpl extends StubBase<JetFunction> implements PsiJetFunctionStub<JetFunction> {
protected PsiJetFunctionStubImpl(StubElement parent, IStubElementType elementType) {
super(parent, elementType);
private final StringRef nameRef;
private final boolean isTopLevel;
private final boolean isExtension;
public PsiJetFunctionStubImpl(@NotNull IStubElementType elementType, @NotNull StubElement parent,
@Nullable String name, boolean isTopLevel, boolean isExtension) {
this(elementType, parent, StringRef.fromString(name), isTopLevel, isExtension);
}
// public PsiJetFunctionStubImpl(
// Jet type,
// final StubElement parent,
// final String qualifiedName,
// final String name) {
//
// this(type, parent, StringRef.fromString(qualifiedName), StringRef.fromString(name));
// }
//
// public PsiJetFunctionStubImpl(
// JetClassElementType type,
// final StubElement parent,
// final StringRef qualifiedName,
// final StringRef name) {
//
// super(parent, type);
// this.qualifiedName = qualifiedName;
// this.name = name;
// }
public PsiJetFunctionStubImpl(@NotNull IStubElementType elementType, @NotNull StubElement parent,
@Nullable StringRef nameRef, boolean isTopLevel, boolean isExtension) {
super(parent, elementType);
this.nameRef = nameRef;
this.isTopLevel = isTopLevel;
this.isExtension = isExtension;
}
@Override
public String getName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
return StringRef.toString(nameRef);
}
@Override
public boolean isDeclaration() {
return false; //To change body of implemented methods use File | Settings | File Templates.
public boolean isTopLevel() {
return isTopLevel;
}
@Override
public boolean isExtension() {
return isExtension;
}
@NotNull
@Override
public String[] getAnnotations() {
return new String[0]; //To change body of implemented methods use File | Settings | File Templates.
}
@NotNull
@Override
public String getReturnTypeText() {
return null; //To change body of implemented methods use File | Settings | File Templates.
// TODO (stubs)
return new String[0];
}
}
+17 -6
View File
@@ -4,9 +4,6 @@
<version>@snapshot@</version>
<vendor>JetBrains</vendor>
<application-components>
</application-components>
<project-components>
<component>
<implementation-class>org.jetbrains.jet.plugin.compiler.JetCompilerManager</implementation-class>
@@ -44,6 +41,9 @@
</actions>
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceInterface="org.jetbrains.jet.lang.psi.stubs.elements.StubIndexService"
serviceImplementation="org.jetbrains.jet.plugin.stubindex.StubIndexServiceImpl" />
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<internalFileTemplate name="Kotlin File"/>
@@ -57,13 +57,18 @@
<lang.foldingBuilder language="jet" implementationClass="org.jetbrains.jet.plugin.JetFoldingBuilder"/>
<lang.formatter language="jet" implementationClass="org.jetbrains.jet.plugin.formatter.JetFormattingModelBuilder"/>
<lang.findUsagesProvider language="jet" implementationClass="org.jetbrains.jet.plugin.findUsages.JetFindUsagesProvider"/>
<psi.referenceContributor language="jet" implementation="org.jetbrains.jet.plugin.references.JetReferenceContributor"/>
<codeInsight.parameterInfo language="jet" implementationClass="org.jetbrains.jet.plugin.parameterInfo.JetFunctionParameterInfoHandler"/>
<completion.contributor language="jet" id="JetKeywordCompletionContributor" order="first"
implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/>
<completion.contributor language="jet" id="JetCompletionContributor"
implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/>
<completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.GlobalMemberCompletionContributor"/>
<completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/>
<completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/>
<psi.referenceContributor language="jet" order="after JetCompletionContributor" implementation="org.jetbrains.jet.plugin.references.JetReferenceContributor"/>
<liveTemplateContext implementation="org.jetbrains.jet.plugin.liveTemplates.JetTemplateContextType$Generic"/>
<liveTemplateContext implementation="org.jetbrains.jet.plugin.liveTemplates.JetTemplateContextType$Namespace"/>
@@ -91,6 +96,12 @@
<java.elementFinder implementation="org.jetbrains.jet.asJava.JavaElementFinder"/>
<java.shortNamesCache implementation="org.jetbrains.jet.plugin.caches.JetShortNamesCache"/>
<stubElementTypeHolder class="org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes"/>
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetShortClassNameIndex"/>
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex"/>
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetShortFunctionNameIndex"/>
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetExtensionFunctionNameIndex"/>
<editorNotificationProvider implementation="org.jetbrains.jet.plugin.quickfix.ConfigureKotlinLibraryNotificationProvider"/>
<psi.treeChangePreprocessor implementation="org.jetbrains.jet.asJava.JetCodeBlockModificationListener"/>
@@ -1,15 +0,0 @@
package org.jetbrains.jet.plugin;
/**
* Configures jet parser for using indexed stubs instead of default set.
* So if parser is used from IDEA it creates indexed stubs, if not direct psi elements are used.
*
* IMPORTANT: Should be called before loading parser.
*
* @author Nikolay Krasko
*/
public class ParserConfigurator {
// static {
// JetParserDefinition.setStubFactory(new JetIndexedStubElementFactory());
// }
}
@@ -129,7 +129,7 @@ public class JetAddImportAction implements QuestionAction {
};
}
protected void addImport(final PsiElement element, final Project project, final String selectedImport) {
protected static void addImport(final PsiElement element, final Project project, final String selectedImport) {
PsiDocumentManager.getInstance(project).commitAllDocuments();
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@@ -16,8 +16,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.stubindex.JetExtensionFunctionNameIndex;
import org.jetbrains.jet.plugin.stubindex.JetShortFunctionNameIndex;
import java.util.ArrayList;
import java.util.Collection;
@@ -107,6 +110,45 @@ public class JetShortNamesCache extends PsiShortNamesCache {
}
});
}
public Collection<JetNamedFunction> getAllExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
return JetExtensionFunctionNameIndex.getInstance().get(name, project, scope);
}
@NotNull
public Collection<String> getAllTopLevelFunctionNames() {
return JetShortFunctionNameIndex.getInstance().getAllKeys(project);
}
public Collection<JetNamedFunction> getTopLevelFunctionsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) {
return JetShortFunctionNameIndex.getInstance().get(name, project, scope);
}
// private Collection<FunctionDescriptor> getTopLeveFunctions(@NotNull GlobalSearchScope scope) {
// final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, scope);
// final Collection<String> keys = context.getKeys(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR);
//
// final List<FunctionDescriptor> result = new ArrayList<FunctionDescriptor>();
//
// for (String namespaceKey : keys) {
// final NamespaceDescriptor namespace = context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, namespaceKey);
// if (namespace != null) {
// final JetScope memberScope = namespace.getNamespaceType().getMemberScope();
// final Collection<DeclarationDescriptor> allDescriptors = memberScope.getAllDescriptors();
//
// for (DeclarationDescriptor descriptor : allDescriptors) {
// if (descriptor instanceof FunctionDescriptor) {
// FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
// if (functionDescriptor.getReceiverParameter() == ReceiverDescriptor.NO_RECEIVER) {
// result.add(functionDescriptor);
// }
// }
// }
// }
// }
//
// return result;
// }
@NotNull
@Override
@@ -26,9 +26,20 @@ public final class DescriptorLookupConverter {
private final static JetFunctionInsertHandler PARAMS_FUNCTION_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS);
private DescriptorLookupConverter() {}
@NotNull
public static LookupElement createLookupElement(@NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) {
LookupElementBuilder element = LookupElementBuilder.create(descriptor, descriptor.getName());
public static LookupElement createLookupElement(@Nullable BindingContext context, @NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) {
Object lookupObject = descriptor;
if (context != null) {
final PsiElement psiElement = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
if (psiElement != null) {
lookupObject = new LookupPositionObject(psiElement);
}
}
LookupElementBuilder element = LookupElementBuilder.create(lookupObject, descriptor.getName());
String typeText = "";
String tailText = "";
boolean tailTextGrayed = false;
@@ -78,8 +89,6 @@ public final class DescriptorLookupConverter {
@NotNull
public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) {
return createLookupElement(descriptor, bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal()));
return createLookupElement(bindingContext, descriptor, bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal()));
}
}
@@ -2,27 +2,35 @@ package org.jetbrains.jet.plugin.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.psi.JetUserType;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.caches.JetCacheManager;
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
import org.jetbrains.jet.plugin.references.JetSimpleNameReference;
import java.util.Collection;
import java.util.HashSet;
/**
* @author Nikolay Krasko
*/
public class JetCompletionContributor extends CompletionContributor {
// A hack to avoid doubling of completion
final HashSet<LookupPositionObject> positions = new HashSet<LookupPositionObject>();
public JetCompletionContributor() {
extend(CompletionType.BASIC, PlatformPatterns.psiElement(),
new CompletionProvider<CompletionParameters>() {
@@ -30,50 +38,115 @@ public class JetCompletionContributor extends CompletionContributor {
protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
final @NotNull CompletionResultSet result) {
if (result.getPrefixMatcher().getPrefix().isEmpty()) {
return;
}
synchronized (positions) {
positions.clear();
final PsiElement position = parameters.getPosition();
if (!(position.getContainingFile() instanceof JetFile)) {
return;
}
if (result.getPrefixMatcher().getPrefix().isEmpty()) {
return;
}
if (shouldRunClassNameCompletion(parameters, context)) {
addJavaClasses(parameters, result);
addJetClasses(result, position);
final PsiElement position = parameters.getPosition();
if (!(position.getContainingFile() instanceof JetFile)) {
return;
}
final JetSimpleNameReference jetReference = getJetReference(parameters);
if (jetReference != null) {
for (Object variant : jetReference.getVariants()) {
addReferenceVariant(result, variant);
}
}
if (shouldRunClassNameCompletion(parameters)) {
addJavaClasses(parameters, result);
addJetClasses(result, position);
}
if (shouldRunFunctionNameCompletion(parameters)) {
addJetTopLevelFunctions(result, position);
}
result.stopHere();
}
}
});
}
private static void addJetClasses(CompletionResultSet result, PsiElement position) {
if (position.getParent() instanceof JetSimpleNameExpression) {
final JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) position.getParent();
if (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) == null) {
Project project = position.getProject();
private void addReferenceVariant(@NotNull CompletionResultSet result, @NotNull Object variant) {
if (variant instanceof LookupElement) {
addCompletionToResult(result, (LookupElement) variant);
}
else {
addCompletionToResult(result, LookupElementBuilder.create(variant.toString()));
}
}
final String referencedName = nameExpression.getReferencedName();
private void addJetTopLevelFunctions(@NotNull CompletionResultSet result, @NotNull PsiElement position) {
String actualPrefix = getActualCompletionPrefix(position);
if (actualPrefix != null) {
final Project project = position.getProject();
if (referencedName != null && referencedName.endsWith(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED)) {
int lastPrefixIndex = referencedName.length() -
CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED.length();
String actualPrefix = referencedName.substring(0, lastPrefixIndex);
final JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache();
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
final Collection<String> functionNames = namesCache.getAllTopLevelFunctionNames();
final Collection<ClassDescriptor> classDescriptors =
JetCacheManager.getInstance(project).getNamesCache().getClassDescriptors();
for (String name : functionNames) {
if (name.contains(actualPrefix)) {
for (JetNamedFunction function : namesCache.getTopLevelFunctionsByName(name, scope)) {
String functionName = function.getName();
String qualifiedName = function.getQualifiedName();
assert functionName != null;
final LookupElementBuilder lookup = LookupElementBuilder.create(
new LookupPositionObject(function), functionName);
for (ClassDescriptor descriptor : classDescriptors) {
if (descriptor.getName().startsWith(actualPrefix)) {
result.addElement(DescriptorLookupConverter.createLookupElement(descriptor, null));
if (qualifiedName != null) {
lookup.setTailText(qualifiedName);
}
addCompletionToResult(result, lookup);
}
}
}
}
}
private static void addJavaClasses(CompletionParameters parameters, final CompletionResultSet result) {
private void addJetClasses(@NotNull CompletionResultSet result, @NotNull PsiElement position) {
String actualPrefix = getActualCompletionPrefix(position);
if (actualPrefix != null) {
final Collection<ClassDescriptor> classDescriptors =
JetCacheManager.getInstance(position.getProject()).getNamesCache().getClassDescriptors();
for (ClassDescriptor descriptor : classDescriptors) {
if (descriptor.getName().startsWith(actualPrefix)) {
addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(null, descriptor, null));
}
}
}
}
@Nullable
private static String getActualCompletionPrefix(@NotNull PsiElement position) {
if (position.getParent() instanceof JetSimpleNameExpression) {
final JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) position.getParent();
// Should be checked before call completion as pre-condition
assert (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) == null);
final String referencedName = nameExpression.getReferencedName();
if (referencedName != null && referencedName.endsWith(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED)) {
int lastPrefixIndex = referencedName.length() -
CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED.length();
return referencedName.substring(0, lastPrefixIndex);
}
}
return null;
}
private void addJavaClasses(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result) {
CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters));
@@ -81,14 +154,17 @@ public class JetCompletionContributor extends CompletionContributor {
parameters, tempResult), parameters.getInvocationCount() <= 1, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
result.addElement(element);
public void consume(@NotNull LookupElement element) {
addCompletionToResult(result, element);
}
});
}
private static boolean shouldRunClassNameCompletion(@NotNull CompletionParameters parameters, ProcessingContext context) {
private static boolean shouldRunFunctionNameCompletion(@NotNull CompletionParameters parameters) {
return shouldRunClassNameCompletion(parameters);
}
private static boolean shouldRunClassNameCompletion(@NotNull CompletionParameters parameters) {
final PsiElement element = parameters.getPosition();
if (parameters.getInvocationCount() > 1) {
@@ -113,8 +189,40 @@ public class JetCompletionContributor extends CompletionContributor {
return false;
}
@Override
public void beforeCompletion(@NotNull CompletionInitializationContext context) {
super.beforeCompletion(context); //To change body of overridden methods use File | Settings | File Templates.
@Nullable
private static JetSimpleNameReference getJetReference(@NotNull CompletionParameters parameters) {
final PsiElement element = parameters.getPosition();
if (element.getParent() != null) {
final PsiElement parent = element.getParent();
PsiReference[] references = parent.getReferences();
if (references.length != 0) {
for (PsiReference reference : references) {
if (reference instanceof JetSimpleNameReference) {
return (JetSimpleNameReference) reference;
}
}
}
// if (reference == null && parent instanceof CompositeElement) {
// reference = ((CompositeElement) parent).getPsi().getReference();
// }
}
return null;
}
private void addCompletionToResult(@NotNull final CompletionResultSet result, LookupElement element) {
if (element.getObject() instanceof LookupPositionObject) {
final LookupPositionObject positionObject = (LookupPositionObject) element.getObject();
if (positions.contains(positionObject)) {
return;
}
else {
positions.add(positionObject);
}
}
result.addElement(element);
}
}
@@ -0,0 +1,43 @@
package org.jetbrains.jet.plugin.completion;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* A hack decision to avoid double completion from different sources.
*
* @author Nikolay Krasko
*/
public class LookupPositionObject {
private final Pair<String, Integer> position;
public LookupPositionObject(@NotNull PsiElement psiElement) {
PsiFile file = psiElement.getContainingFile();
String fileName = file != null ? file.getName() : null;
position = new Pair<String, Integer>(fileName, psiElement.getTextOffset());
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
return Comparing.equal(position, ((LookupPositionObject) obj).position);
}
public int hashCode() {
return position.hashCode();
}
}
@@ -1,6 +1,7 @@
package org.jetbrains.jet.plugin.quickfix;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -23,27 +24,25 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.actions.JetAddImportAction;
import org.jetbrains.jet.plugin.caches.JetCacheManager;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* Check possibility and perform fix for unresolved references.
*
* @author Nikolay Krasko
*/
public class ImportClassFix extends JetHintAction<JetSimpleNameExpression> implements HighPriorityAction {
public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression> implements HighPriorityAction {
@NotNull
private final List<String> suggestions;
public ImportClassFix(@NotNull JetSimpleNameExpression element) {
public ImportClassAndFunFix(@NotNull JetSimpleNameExpression element) {
super(element);
suggestions = computeSuggestions(element);
}
@@ -54,7 +53,39 @@ public class ImportClassFix extends JetHintAction<JetSimpleNameExpression> imple
return Collections.emptyList();
}
return getClassNames(element, file.getProject());
final ArrayList<String> result = new ArrayList<String>();
result.addAll(getClassNames(element, file.getProject()));
result.addAll(getJetTopLevelFunctions(element, file.getProject()));
return result;
}
private static Collection<String> getJetTopLevelFunctions(@NotNull JetSimpleNameExpression expression, @NotNull Project project) {
final String referenceName = expression.getReferencedName();
if (referenceName == null) {
return Collections.emptyList();
}
final Collection<JetNamedFunction> namedFunctions =
JetCacheManager.getInstance(project).getNamesCache().getTopLevelFunctionsByName(
referenceName, GlobalSearchScope.allScope(project));
final Collection<String> nullableNames =
Collections2.transform(Lists.newArrayList(namedFunctions), new Function<JetNamedFunction, String>() {
@Nullable
@Override
public String apply(@Nullable JetNamedFunction jetFunction) {
return jetFunction != null ? jetFunction.getQualifiedName() : null;
}
});
return Collections2.filter(nullableNames, new Predicate<String>() {
@Override
public boolean apply(@Nullable String fqn) {
return fqn != null && !fqn.isEmpty();
}
});
}
/*
@@ -79,7 +110,7 @@ public class ImportClassFix extends JetHintAction<JetSimpleNameExpression> imple
private static Collection<String> getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) {
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
PsiClass[] classes = cache.getClassesByName(typeName, new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
PsiClass[] classes = cache.getClassesByName(typeName, new DelegatingGlobalSearchScope(scope) {
@Override
public boolean contains(@NotNull VirtualFile file) {
return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE;
@@ -166,7 +197,7 @@ public class ImportClassFix extends JetHintAction<JetSimpleNameExpression> imple
// There could be different psi elements (i.e. JetArrayAccessExpression), but we can fix only JetSimpleNameExpression case
if (diagnostic.getPsiElement() instanceof JetSimpleNameExpression) {
JetSimpleNameExpression psiElement = (JetSimpleNameExpression) diagnostic.getPsiElement();
return new ImportClassFix(psiElement);
return new ImportClassAndFunFix(psiElement);
}
return null;
@@ -108,7 +108,7 @@ public class QuickFixes {
add(Errors.INITIALIZATION_USING_BACKING_FIELD_CUSTOM_SETTER, changeToBackingFieldFactory);
add(Errors.INITIALIZATION_USING_BACKING_FIELD_OPEN_SETTER, changeToBackingFieldFactory);
JetIntentionActionFactory<JetSimpleNameExpression> unresolvedReferenceFactory = ImportClassFix.createFactory();
JetIntentionActionFactory<JetSimpleNameExpression> unresolvedReferenceFactory = ImportClassAndFunFix.createFactory();
add(Errors.UNRESOLVED_REFERENCE, unresolvedReferenceFactory);
add(Errors.SUPERTYPE_NOT_INITIALIZED_DEFAULT, ChangeToInvocationFix.createFactory());
@@ -20,7 +20,7 @@ import java.util.List;
/**
* @author yole
*/
class JetSimpleNameReference extends JetPsiReference {
public class JetSimpleNameReference extends JetPsiReference {
private final JetSimpleNameExpression myExpression;
@@ -0,0 +1,21 @@
package org.jetbrains.jet.plugin.stubindex;
import com.intellij.psi.stubs.StringStubIndexExtension;
import com.intellij.psi.stubs.StubIndexKey;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
/**
* @author Nikolay Krasko
*/
public class JetExtensionFunctionNameIndex extends StringStubIndexExtension<JetNamedFunction> {
private static final JetExtensionFunctionNameIndex instance = new JetExtensionFunctionNameIndex();
public static JetExtensionFunctionNameIndex getInstance() {
return instance;
}
@Override
public StubIndexKey<String, JetNamedFunction> getKey() {
return JetIndexKeys.EXTENSION_FUNCTION_SHORT_NAME_KEY;
}
}
@@ -2,7 +2,7 @@ package org.jetbrains.jet.plugin.stubindex;
import com.intellij.psi.stubs.StubIndexKey;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
/**
* @author Nikolay Krasko
@@ -10,11 +10,11 @@ import org.jetbrains.jet.lang.psi.JetFunction;
public interface JetIndexKeys {
StubIndexKey<String, JetClassOrObject> SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.class.shortName");
StubIndexKey<String, JetClassOrObject> FQN_KEY = StubIndexKey.createIndexKey("jet.fqn");
StubIndexKey<String, JetFunction> TOP_LEVEL_FUNCTION_SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.top.level.function.short.name");
// StubIndexKey<String, JetFunction> TOP_LEVEL_FUNCTION_FQN_KEY = StubIndexKey.createIndexKey("jet.top.level.function.short.name");
// StubIndexKey<String, JetObjectDeclaration> PACKAGE_OBJECT_KEY = StubIndexKey.createIndexKey("jet.package.object.fqn");
// StubIndexKey<String, JetFunction> EXTENSION_FUNCTION_TO_TYPE_FQN = StubIndexKey.createIndexKey("jet.extension.function.to.type.fqn");
StubIndexKey<String, JetNamedFunction> TOP_LEVEL_FUNCTION_SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.top.level.function.short.name");
StubIndexKey<String, JetNamedFunction> TOP_LEVEL_FUNCTION_FQNAME_KEY = StubIndexKey.createIndexKey("jet.top.level.function.fqname");
StubIndexKey<String, JetNamedFunction> EXTENSION_FUNCTION_SHORT_NAME_KEY = StubIndexKey.createIndexKey("jet.top.level.extension.function.short.name");
StubIndexKey<String, JetNamedFunction> EXTENSION_FUNCTION_FQNAME_KEY = StubIndexKey.createIndexKey("jet.top.level.extension.function.fqname");
}
@@ -1,40 +0,0 @@
package org.jetbrains.jet.plugin.stubindex;
import com.intellij.psi.stubs.IndexSink;
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
import org.jetbrains.jet.lang.psi.stubs.elements.JetClassElementType;
import org.jetbrains.jet.lang.psi.stubs.elements.JetFunctionElementType;
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementFactory;
/**
* @author Nikolay Krasko
*/
public class JetIndexedStubElementFactory implements JetStubElementFactory {
@Override
public JetClassElementType getClassElementType() {
return new JetClassElementType("CLASS") {
@Override
public void indexStub(PsiJetClassStub stub, IndexSink sink) {
String name = stub.getName();
if (name != null) {
sink.occurrence(JetIndexKeys.SHORT_NAME_KEY, name);
}
}
};
}
@Override
public JetFunctionElementType getFunctionElementType() {
return new JetFunctionElementType("FUN") {
@Override
public void indexStub(PsiJetFunctionStub stub, IndexSink sink) {
String name = stub.getName();
// TODO: Check that function defined in top level
if (name != null) {
sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTION_SHORT_NAME_KEY, name);
}
}
};
}
}
@@ -5,27 +5,27 @@ 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.JetFunction;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import java.util.Collection;
/**
* @author Nikolay Krasko
*/
public class JetShortFunctionNameIndex extends StringStubIndexExtension<JetFunction> {
private static final JetShortClassNameIndex ourInstance = new JetShortClassNameIndex();
public class JetShortFunctionNameIndex extends StringStubIndexExtension<JetNamedFunction> {
private static final JetShortFunctionNameIndex ourInstance = new JetShortFunctionNameIndex();
public static JetShortClassNameIndex getInstance() {
public static JetShortFunctionNameIndex getInstance() {
return ourInstance;
}
@Override
public StubIndexKey<String, JetFunction> getKey() {
public StubIndexKey<String, JetNamedFunction> getKey() {
return JetIndexKeys.TOP_LEVEL_FUNCTION_SHORT_NAME_KEY;
}
@Override
public Collection<JetFunction> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
return super.get(s, project, new JetSourceFilterScope(scope));
public Collection<JetNamedFunction> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
return super.get(s, project, new JetSourceFilterScope(scope));
}
}
@@ -0,0 +1,35 @@
package org.jetbrains.jet.plugin.stubindex;
import com.intellij.psi.stubs.IndexSink;
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
import org.jetbrains.jet.lang.psi.stubs.elements.StubIndexService;
/**
* @author Nikolay Krasko
*/
public class StubIndexServiceImpl implements StubIndexService {
@Override
public void indexClass(PsiJetClassStub stub, IndexSink sink) {
String name = stub.getName();
if (name != null) {
sink.occurrence(JetIndexKeys.SHORT_NAME_KEY, name);
}
}
@Override
public void indexFunction(PsiJetFunctionStub stub, IndexSink sink) {
String name = stub.getName();
if (name != null) {
if (!stub.isExtension()) {
if (stub.isTopLevel()) {
sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTION_SHORT_NAME_KEY, name);
}
}
else {
sink.occurrence(JetIndexKeys.EXTENSION_FUNCTION_SHORT_NAME_KEY, name);
}
}
}
}
@@ -1,3 +1,5 @@
package some;
open class MyClass() {
}
@@ -0,0 +1,8 @@
// "Import Class" "true"
package functionimporttest
import functionimporttest.data.someTestFun
fun functionImportTest() {
someTestFun()
}
@@ -0,0 +1,7 @@
package functionimporttest.data
fun String.someTestFun() {
}
fun someTestFun() {
}
@@ -0,0 +1,6 @@
// "Import Class" "true"
package functionimporttest
fun functionImportTest() {
<caret>someTestFun()
}
@@ -26,11 +26,8 @@ public class FunctionsHandlerTest extends LightCompletionTestCase {
checkResultByFile("SingleBrackets.kt.after");
}
// public void
@Override
protected String getTestDataPath() {
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() +
File.separator;
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() + File.separator;
}
}