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:
+2
-1
@@ -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();
|
||||
}
|
||||
|
||||
+6
-6
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
-28
@@ -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) {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-17
@@ -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";
|
||||
|
||||
+1
-1
@@ -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";
|
||||
|
||||
|
||||
+28
-10
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
package org.jetbrains.jet.lang.psi.stubs.elements;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public interface JetStubElementFactory {
|
||||
JetClassElementType getClassElementType();
|
||||
JetFunctionElementType getFunctionElementType();
|
||||
}
|
||||
+3
-6
@@ -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) {
|
||||
|
||||
+2
-4
@@ -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);
|
||||
}
|
||||
+18
@@ -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;
|
||||
}
|
||||
}
|
||||
+28
-31
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
+40
-9
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user