Build stubs for insides of local objects and classes
This commit is contained in:
-5
@@ -53,11 +53,6 @@ public class JetClassElementType extends JetStubElementType<PsiJetClassStub, Jet
|
||||
return node.getElementType() != JetStubElementTypes.ENUM_ENTRY ? new JetClass(node) : new JetEnumEntry(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiJetClassStub createStub(@NotNull JetClass psi, StubElement parentStub) {
|
||||
FqName fqName = ResolveSessionUtils.safeFqNameForLazyResolve(psi);
|
||||
|
||||
+1
-10
@@ -25,6 +25,7 @@ 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.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
|
||||
@@ -40,16 +41,6 @@ public class JetFunctionElementType extends JetStubElementType<PsiJetFunctionStu
|
||||
super(debugName, JetNamedFunction.class, PsiJetFunctionStub.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
if (super.shouldCreateStub(node)) {
|
||||
PsiElement psi = node.getPsi();
|
||||
return psi instanceof JetNamedFunction;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiJetFunctionStub createStub(@NotNull JetNamedFunction psi, @NotNull StubElement parentStub) {
|
||||
boolean isTopLevel = psi.getParent() instanceof JetFile;
|
||||
|
||||
-5
@@ -42,11 +42,6 @@ public class JetObjectElementType extends JetStubElementType<PsiJetObjectStub, J
|
||||
super(debugName, JetObjectDeclaration.class, PsiJetObjectStub.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiJetObjectStub createStub(@NotNull JetObjectDeclaration psi, StubElement parentStub) {
|
||||
String name = psi.getName();
|
||||
|
||||
-9
@@ -44,15 +44,6 @@ public class JetParameterElementType extends JetStubElementType<PsiJetParameterS
|
||||
psi.isMutable(), psi.hasValOrVarNode(), psi.hasDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
if (!super.shouldCreateStub(node)) {
|
||||
return false;
|
||||
}
|
||||
PsiElement psi = node.getPsi();
|
||||
return psi instanceof JetParameter && !((JetParameter) psi).isLoopParameter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull PsiJetParameterStub stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
dataStream.writeName(stub.getName());
|
||||
|
||||
+1
-10
@@ -25,6 +25,7 @@ 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.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.psi.stubs.PsiJetPropertyStub;
|
||||
import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetPropertyStubImpl;
|
||||
@@ -38,16 +39,6 @@ public class JetPropertyElementType extends JetStubElementType<PsiJetPropertyStu
|
||||
super(debugName, JetProperty.class, PsiJetPropertyStub.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
if (super.shouldCreateStub(node)) {
|
||||
PsiElement psi = node.getPsi();
|
||||
return psi instanceof JetProperty;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiJetPropertyStub createStub(@NotNull JetProperty psi, StubElement parentStub) {
|
||||
assert !psi.isLocal() :
|
||||
|
||||
+39
-8
@@ -21,8 +21,11 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.IndexSink;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayFactory;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -34,6 +37,9 @@ import java.lang.reflect.Constructor;
|
||||
|
||||
public abstract class JetStubElementType<StubT extends StubElement, PsiT extends JetElementImplStub<?>> extends IStubElementType<StubT, PsiT> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Class<? extends PsiElement>[] ALWAYS_CREATE_STUB_FOR = new Class[] { JetClass.class, JetObjectDeclaration.class };
|
||||
|
||||
@NotNull
|
||||
private final Constructor<PsiT> byNodeConstructor;
|
||||
@NotNull
|
||||
@@ -87,39 +93,64 @@ public abstract class JetStubElementType<StubT extends StubElement, PsiT extends
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
PsiElement psi = node.getPsi();
|
||||
if (ArrayUtil.contains(psi.getClass(), ALWAYS_CREATE_STUB_FOR)) {
|
||||
return true;
|
||||
}
|
||||
if (psi instanceof JetDeclaration) {
|
||||
return shouldCreateStubForDeclaration((JetDeclaration) psi);
|
||||
}
|
||||
return createStubDependingOnParent(node);
|
||||
}
|
||||
|
||||
private static boolean createStubDependingOnParent(ASTNode node) {
|
||||
ASTNode parent = node.getTreeParent();
|
||||
IElementType parentType = parent.getElementType();
|
||||
if (parentType instanceof IStubElementType) {
|
||||
return ((IStubElementType) parentType).shouldCreateStub(parent);
|
||||
}
|
||||
if (parentType instanceof IStubFileElementType) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean shouldCreateStubForDeclaration(@NotNull JetDeclaration declaration) {
|
||||
// Do not create stubs inside function literals
|
||||
if (PsiTreeUtil.getParentOfType(psi, JetFunctionLiteral.class) != null) {
|
||||
//noinspection unchecked
|
||||
if (PsiTreeUtil.getParentOfType(declaration, JetFunctionLiteral.class, false, ALWAYS_CREATE_STUB_FOR) != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't create stubs if declaration is inside function or property accessor with block
|
||||
JetBlockExpression blockExpression = PsiTreeUtil.getParentOfType(psi, JetBlockExpression.class);
|
||||
//noinspection unchecked
|
||||
JetBlockExpression blockExpression =
|
||||
PsiTreeUtil.getParentOfType(declaration, JetBlockExpression.class, false, ALWAYS_CREATE_STUB_FOR);
|
||||
if (blockExpression != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't create stubs if declaration is inside other declaration with expression initializer
|
||||
|
||||
Class<? extends PsiElement>[] stopAt = ArrayUtil.append(ALWAYS_CREATE_STUB_FOR, JetBlockExpression.class);
|
||||
@SuppressWarnings("unchecked") JetWithExpressionInitializer withInitializer =
|
||||
PsiTreeUtil.getParentOfType(psi, JetWithExpressionInitializer.class, true, JetBlockExpression.class);
|
||||
PsiTreeUtil.getParentOfType(declaration, JetWithExpressionInitializer.class, true, stopAt);
|
||||
if (withInitializer != null) {
|
||||
JetExpression initializer = withInitializer.getInitializer();
|
||||
if (PsiTreeUtil.isAncestor(initializer, psi, true)) {
|
||||
if (PsiTreeUtil.isAncestor(initializer, declaration, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't create stubs if declaration is inside property delegate
|
||||
@SuppressWarnings("unchecked") JetPropertyDelegate delegate =
|
||||
PsiTreeUtil.getParentOfType(psi, JetPropertyDelegate.class, true, JetBlockExpression.class);
|
||||
@SuppressWarnings("unchecked") JetPropertyDelegate delegate = PsiTreeUtil.getParentOfType(declaration, JetPropertyDelegate.class, true, stopAt);
|
||||
if (delegate != null) {
|
||||
JetExpression delegateExpression = delegate.getExpression();
|
||||
if (PsiTreeUtil.isAncestor(delegateExpression, psi, true)) {
|
||||
if (PsiTreeUtil.isAncestor(delegateExpression, declaration, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return super.shouldCreateStub(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,3 +4,14 @@ PsiJetFileStubImpl[package=]
|
||||
CLASS:[fqName=T, isEnumEntry=false, isLocal=false, isTopLevel=true, isTrait=true, name=T, superNames=[]]
|
||||
PROPERTY:[fqName=obj, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReceiverTypeRef=false, hasReturnTypeRef=false, isTopLevel=true, isVar=false, name=obj]
|
||||
OBJECT_DECLARATION:[fqName=null, isClassObject=false, isLocal=true, isObjectLiteral=true, isTopLevel=false, name=null, superNames=[A, T]]
|
||||
DELEGATION_SPECIFIER_LIST:
|
||||
DELEGATOR_SUPER_CALL:
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=A]
|
||||
DELEGATOR_SUPER_CLASS:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=T]
|
||||
CLASS_BODY:
|
||||
|
||||
@@ -5,3 +5,13 @@ PsiJetFileStubImpl[package=]
|
||||
FUN:[fqName=foo, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=foo]
|
||||
VALUE_PARAMETER_LIST:
|
||||
CLASS:[fqName=null, isEnumEntry=false, isLocal=true, isTopLevel=false, isTrait=false, name=Test, superNames=[A, T]]
|
||||
DELEGATION_SPECIFIER_LIST:
|
||||
DELEGATOR_SUPER_CALL:
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=A]
|
||||
DELEGATOR_SUPER_CLASS:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=T]
|
||||
|
||||
@@ -5,3 +5,13 @@ PsiJetFileStubImpl[package=]
|
||||
FUN:[fqName=foo, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=foo]
|
||||
VALUE_PARAMETER_LIST:
|
||||
CLASS:[fqName=null, isEnumEntry=false, isLocal=true, isTopLevel=false, isTrait=false, name=Test, superNames=[A, T]]
|
||||
DELEGATION_SPECIFIER_LIST:
|
||||
DELEGATOR_SUPER_CALL:
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=A]
|
||||
DELEGATOR_SUPER_CLASS:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=T]
|
||||
|
||||
@@ -5,3 +5,13 @@ PsiJetFileStubImpl[package=]
|
||||
FUN:[fqName=foo, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=foo]
|
||||
VALUE_PARAMETER_LIST:
|
||||
OBJECT_DECLARATION:[fqName=null, isClassObject=false, isLocal=true, isObjectLiteral=false, isTopLevel=false, name=O, superNames=[A, T]]
|
||||
DELEGATION_SPECIFIER_LIST:
|
||||
DELEGATOR_SUPER_CALL:
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=A]
|
||||
DELEGATOR_SUPER_CLASS:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=T]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
PsiJetFileStubImpl[package=]
|
||||
PACKAGE_DIRECTIVE:
|
||||
FUN:[fqName=f, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=f]
|
||||
MODIFIER_LIST:[public]
|
||||
CLASS:[fqName=null, isEnumEntry=false, isLocal=true, isTopLevel=false, isTrait=false, name=C, superNames=[]]
|
||||
CLASS_BODY:
|
||||
FUN:[fqName=null, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, name=f]
|
||||
VALUE_PARAMETER_LIST:
|
||||
PROPERTY:[fqName=null, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReceiverTypeRef=false, hasReturnTypeRef=true, isTopLevel=false, isVar=false, name=c]
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=Int]
|
||||
@@ -0,0 +1,8 @@
|
||||
public fun f {
|
||||
class C {
|
||||
fun f() {
|
||||
}
|
||||
|
||||
val c: Int
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
PsiJetFileStubImpl[package=]
|
||||
PACKAGE_DIRECTIVE:
|
||||
FUN:[fqName=f, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=f]
|
||||
VALUE_PARAMETER_LIST:
|
||||
OBJECT_DECLARATION:[fqName=null, isClassObject=false, isLocal=true, isObjectLiteral=false, isTopLevel=false, name=foo, superNames=[]]
|
||||
CLASS_BODY:
|
||||
FUN:[fqName=null, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, name=foo]
|
||||
VALUE_PARAMETER_LIST:
|
||||
PROPERTY:[fqName=null, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReceiverTypeRef=false, hasReturnTypeRef=true, isTopLevel=false, isVar=false, name=foo]
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=Int]
|
||||
@@ -0,0 +1,10 @@
|
||||
fun f() {
|
||||
object foo {
|
||||
fun foo() {
|
||||
for (a in listOf(1, 2, 3)) {
|
||||
}
|
||||
}
|
||||
|
||||
val foo: Int = 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
PsiJetFileStubImpl[package=]
|
||||
PACKAGE_DIRECTIVE:
|
||||
PROPERTY:[fqName=p, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReceiverTypeRef=false, hasReturnTypeRef=false, isTopLevel=true, isVar=false, name=p]
|
||||
OBJECT_DECLARATION:[fqName=null, isClassObject=false, isLocal=true, isObjectLiteral=true, isTopLevel=false, name=null, superNames=[]]
|
||||
CLASS_BODY:
|
||||
FUN:[fqName=null, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, name=f]
|
||||
VALUE_PARAMETER_LIST:
|
||||
PROPERTY:[fqName=null, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReceiverTypeRef=false, hasReturnTypeRef=true, isTopLevel=false, isVar=false, name=p]
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=Int]
|
||||
@@ -0,0 +1,4 @@
|
||||
val p = object {
|
||||
fun f() {}
|
||||
val p: Int = 3
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
PsiJetFileStubImpl[package=]
|
||||
PACKAGE_DIRECTIVE:
|
||||
PROPERTY:[fqName=p, hasDelegate=true, hasDelegateExpression=true, hasInitializer=false, hasReceiverTypeRef=false, hasReturnTypeRef=false, isTopLevel=true, isVar=false, name=p]
|
||||
OBJECT_DECLARATION:[fqName=null, isClassObject=false, isLocal=true, isObjectLiteral=true, isTopLevel=false, name=null, superNames=[]]
|
||||
CLASS_BODY:
|
||||
FUN:[fqName=null, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, name=f]
|
||||
VALUE_PARAMETER_LIST:
|
||||
PROPERTY:[fqName=null, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReceiverTypeRef=false, hasReturnTypeRef=true, isTopLevel=false, isVar=false, name=p]
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=Int]
|
||||
@@ -0,0 +1,4 @@
|
||||
val p by object {
|
||||
fun f() {}
|
||||
val p: Int = 1
|
||||
}
|
||||
@@ -37,8 +37,7 @@ public abstract class AbstractStubBuilderTest extends LightCodeInsightFixtureTes
|
||||
JetFileStubBuilder jetStubBuilder = new JetFileStubBuilder();
|
||||
StubElement lighterTree = jetStubBuilder.buildStubTree(file);
|
||||
String stubTree = DebugUtil.stubTreeToString(lighterTree)
|
||||
.replace(NO_NAME_FOR_LAZY_RESOLVE.asString(), "<no name>")
|
||||
.replace(":" + PsiJetPlaceHolderStubImpl.class.getSimpleName(), "");
|
||||
.replace(NO_NAME_FOR_LAZY_RESOLVE.asString(), "<no name>");
|
||||
String expectedFile = sourcePath.replace(".kt", ".expected");
|
||||
JetTestUtils.assertEqualsToFile(new File(expectedFile), stubTree);
|
||||
}
|
||||
|
||||
@@ -116,6 +116,16 @@ public class StubBuilderTestGenerated extends AbstractStubBuilderTest {
|
||||
doTest("idea/testData/stubs/ManyAnnotationsOnFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MembersInLocalClass.kt")
|
||||
public void testMembersInLocalClass() throws Exception {
|
||||
doTest("idea/testData/stubs/MembersInLocalClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MembersInLocalObject.kt")
|
||||
public void testMembersInLocalObject() throws Exception {
|
||||
doTest("idea/testData/stubs/MembersInLocalObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NamedObject.kt")
|
||||
public void testNamedObject() throws Exception {
|
||||
doTest("idea/testData/stubs/NamedObject.kt");
|
||||
@@ -136,6 +146,16 @@ public class StubBuilderTestGenerated extends AbstractStubBuilderTest {
|
||||
doTest("idea/testData/stubs/NotStorePropertyFromInitializer.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ObjectInInitializer.kt")
|
||||
public void testObjectInInitializer() throws Exception {
|
||||
doTest("idea/testData/stubs/ObjectInInitializer.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ObjectInPropertyDelegate.kt")
|
||||
public void testObjectInPropertyDelegate() throws Exception {
|
||||
doTest("idea/testData/stubs/ObjectInPropertyDelegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PackageProperty.kt")
|
||||
public void testPackageProperty() throws Exception {
|
||||
doTest("idea/testData/stubs/PackageProperty.kt");
|
||||
|
||||
Reference in New Issue
Block a user