mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
[java-tests] Convert Groovy to Java; restore copyrights
GitOrigin-RevId: 2c1ab0479b2f26bc51926f0a78663436b9bf5852
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4942586999
commit
b4d12c1883
@@ -1,148 +1,135 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.java.psi
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.psi;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.impl.source.tree.java.JavaFileElement
|
||||
import com.intellij.psi.impl.source.tree.java.MethodElement
|
||||
import com.intellij.psi.impl.source.tree.java.ParameterElement
|
||||
import com.intellij.testFramework.LeakHunter
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.intellij.util.ref.GCWatcher
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.impl.source.tree.java.JavaFileElement;
|
||||
import com.intellij.psi.impl.source.tree.java.MethodElement;
|
||||
import com.intellij.psi.impl.source.tree.java.ParameterElement;
|
||||
import com.intellij.testFramework.LeakHunter;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.ref.GCWatcher;
|
||||
|
||||
import java.util.function.Predicate
|
||||
public class AstLeaksTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public void test_AST_should_be_on_a_soft_reference__for_changed_files_as_well() {
|
||||
final PsiFile file = myFixture.addClass("class Foo {}").getContainingFile();
|
||||
assertTrue(file.findElementAt(0) instanceof PsiKeyword);
|
||||
LeakHunter.checkLeak(file, JavaFileElement.class, e -> e.getPsi().equals(file));
|
||||
|
||||
class AstLeaksTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
|
||||
void "test AST should be on a soft reference, for changed files as well"() {
|
||||
def file = myFixture.addClass('class Foo {}').containingFile
|
||||
assert file.findElementAt(0) instanceof PsiKeyword
|
||||
LeakHunter.checkLeak(file, JavaFileElement) { e -> e.psi == file }
|
||||
|
||||
WriteCommandAction.runWriteCommandAction project, {
|
||||
file.viewProvider.document.insertString(0, ' ')
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
}
|
||||
assert file.findElementAt(0) instanceof PsiWhiteSpace
|
||||
LeakHunter.checkLeak(file, JavaFileElement) { e -> e.psi == file }
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
file.getViewProvider().getDocument().insertString(0, " ");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
});
|
||||
assertTrue(file.findElementAt(0) instanceof PsiWhiteSpace);
|
||||
LeakHunter.checkLeak(file, JavaFileElement.class, e -> e.getPsi().equals(file));
|
||||
}
|
||||
|
||||
void "test super methods held via their signatures in class user data"() {
|
||||
def superClass = myFixture.addClass('class Super { void foo() {} }')
|
||||
superClass.text // load AST
|
||||
public void test_super_methods_held_via_their_signatures_in_class_user_data() {
|
||||
final PsiClass superClass = myFixture.addClass("class Super { void foo() {} }");
|
||||
assertNotNull(superClass.getText()); // load AST
|
||||
|
||||
def file = myFixture.addFileToProject('Main.java', 'class Main extends Super { void foo() { System.out.println("hello"); } }')
|
||||
myFixture.configureFromExistingVirtualFile(file.virtualFile)
|
||||
myFixture.doHighlighting()
|
||||
PsiFile file = myFixture.addFileToProject("Main.java", "class Main extends Super { void foo() { System.out.println(\"hello\"); } }");
|
||||
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
|
||||
myFixture.doHighlighting();
|
||||
|
||||
def mainClass = ((PsiJavaFile)file).classes[0]
|
||||
LeakHunter.checkLeak(mainClass, MethodElement) { MethodElement node ->
|
||||
superClass == node.psi.parent
|
||||
}
|
||||
PsiClass mainClass = ((PsiJavaFile)file).getClasses()[0];
|
||||
LeakHunter.checkLeak(mainClass, MethodElement.class, node -> superClass.equals(node.getPsi().getParent()));
|
||||
}
|
||||
|
||||
void "test no hard refs to AST after highlighting"() {
|
||||
def sup = myFixture.addFileToProject('sup.java', 'class Super { Super() {} }')
|
||||
assert sup.findElementAt(0) // load AST
|
||||
assert !((PsiFileImpl)sup).stub
|
||||
public void test_no_hard_refs_to_AST_after_highlighting() {
|
||||
final PsiFile sup = myFixture.addFileToProject("sup.java", "class Super { Super() {} }");
|
||||
assertNotNull(sup.findElementAt(0));// load AST
|
||||
assertNull(((PsiFileImpl)sup).getStub());
|
||||
|
||||
LeakHunter.checkLeak(sup, MethodElement, { it.psi.containingFile == sup })
|
||||
LeakHunter.checkLeak(sup, MethodElement.class, it -> it.getPsi().getContainingFile().equals(sup));
|
||||
|
||||
def foo = myFixture.addFileToProject('a.java', 'class Foo extends Super { void bar() { bar(); } }')
|
||||
myFixture.configureFromExistingVirtualFile(foo.virtualFile)
|
||||
myFixture.doHighlighting()
|
||||
final PsiFile foo = myFixture.addFileToProject("a.java", "class Foo extends Super { void bar() { bar(); } }");
|
||||
myFixture.configureFromExistingVirtualFile(foo.getVirtualFile());
|
||||
myFixture.doHighlighting();
|
||||
|
||||
assert !((PsiFileImpl)foo).stub
|
||||
assert ((PsiFileImpl)foo).treeElement
|
||||
assertNull(((PsiFileImpl)foo).getStub());
|
||||
assertNotNull(((PsiFileImpl)foo).getTreeElement());
|
||||
|
||||
LeakHunter.checkLeak(foo, MethodElement, { it.psi.containingFile == foo })
|
||||
LeakHunter.checkLeak(sup, MethodElement, { it.psi.containingFile == sup })
|
||||
LeakHunter.checkLeak(foo, MethodElement.class, it -> it.getPsi().getContainingFile().equals(foo));
|
||||
LeakHunter.checkLeak(sup, MethodElement.class, it -> it.getPsi().getContainingFile().equals(sup));
|
||||
}
|
||||
|
||||
void "test no hard refs to AST via class reference type"() {
|
||||
def cls = myFixture.addClass("class Foo { Object bar() {} }")
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
cls.node
|
||||
def type = cls.methods[0].returnType
|
||||
assert type instanceof PsiClassReferenceType
|
||||
public void test_no_hard_refs_to_AST_via_class_reference_type() {
|
||||
final PsiClass cls = myFixture.addClass("class Foo { Object bar() {} }");
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertNotNull(cls.getNode());
|
||||
PsiType type = cls.getMethods()[0].getReturnType();
|
||||
assertTrue(type instanceof PsiClassReferenceType);
|
||||
|
||||
LeakHunter.checkLeak(type, MethodElement, { MethodElement node ->
|
||||
node.psi == cls.methods[0]
|
||||
})
|
||||
LeakHunter.checkLeak(type, MethodElement.class, node -> node.getPsi().equals(cls.getMethods()[0]));
|
||||
|
||||
GCWatcher.tracking(cls.node).ensureCollected()
|
||||
assert !file.contentsLoaded
|
||||
GCWatcher.tracking(cls.getNode()).ensureCollected();
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert type.equalsToText(Object.name)
|
||||
assert !file.contentsLoaded
|
||||
assertTrue(type.equalsToText(Object.class.getName()));
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
@SuppressWarnings('CStyleArrayDeclaration')
|
||||
void "test no hard refs to AST via class reference type of c-style array"() {
|
||||
def cls = myFixture.addClass("class Foo { static void main(String args[]) {} }")
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
cls.node
|
||||
def type = cls.methods[0].parameterList.parameters[0].typeElement.type
|
||||
assert type instanceof PsiClassReferenceType
|
||||
@SuppressWarnings("CStyleArrayDeclaration")
|
||||
public void test_no_hard_refs_to_AST_via_class_reference_type_of_c_style_array() {
|
||||
final PsiClass cls = myFixture.addClass("class Foo { static void main(String args[]) {} }");
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertNotNull(cls.getNode());
|
||||
PsiType type = cls.getMethods()[0].getParameterList().getParameters()[0].getTypeElement().getType();
|
||||
assertTrue(type instanceof PsiClassReferenceType);
|
||||
|
||||
LeakHunter.checkLeak(type, ParameterElement, { ParameterElement node ->
|
||||
node.psi == cls.methods[0].parameterList.parameters[0]
|
||||
})
|
||||
LeakHunter.checkLeak(type, ParameterElement.class,
|
||||
node -> node.getPsi().equals(cls.getMethods()[0].getParameterList().getParameters()[0]));
|
||||
|
||||
GCWatcher.tracking(cls.node).ensureCollected()
|
||||
assert !file.contentsLoaded
|
||||
GCWatcher.tracking(cls.getNode()).ensureCollected();
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert type.equalsToText(String.name)
|
||||
assert !file.contentsLoaded
|
||||
assertTrue(type.equalsToText(String.class.getName()));
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test no hard refs to AST via array component type"() {
|
||||
def cls = myFixture.addClass("class Foo { Object[] bar() {} }")
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
cls.node
|
||||
def type = cls.methods[0].returnType
|
||||
assert type instanceof PsiArrayType
|
||||
def componentType = type.getComponentType()
|
||||
assert componentType instanceof PsiClassReferenceType
|
||||
public void test_no_hard_refs_to_AST_via_array_component_type() {
|
||||
final PsiClass cls = myFixture.addClass("class Foo { Object[] bar() {} }");
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertNotNull(cls.getNode());
|
||||
PsiType type = cls.getMethods()[0].getReturnType();
|
||||
assertTrue(type instanceof PsiArrayType);
|
||||
PsiType componentType = ((PsiArrayType)type).getComponentType();
|
||||
assertTrue(componentType instanceof PsiClassReferenceType);
|
||||
|
||||
LeakHunter.checkLeak(type, MethodElement, { MethodElement node ->
|
||||
node.psi == cls.methods[0]
|
||||
})
|
||||
LeakHunter.checkLeak(type, MethodElement.class, node -> node.getPsi().equals(cls.getMethods()[0]));
|
||||
|
||||
GCWatcher.tracking(cls.node).ensureCollected()
|
||||
assert !file.contentsLoaded
|
||||
GCWatcher.tracking(cls.getNode()).ensureCollected();
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert componentType.equalsToText(Object.name)
|
||||
assert !file.contentsLoaded
|
||||
assertTrue(componentType.equalsToText(Object.class.getName()));
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test no hard refs to AST via generic component type"() {
|
||||
def cls = myFixture.addClass("class Foo { java.util.Map<String[], ? extends CharSequence> bar() {} }")
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
cls.node
|
||||
def type = cls.methods[0].returnType
|
||||
assert type instanceof PsiClassReferenceType
|
||||
def parameters = (type as PsiClassReferenceType).getParameters()
|
||||
assert parameters.length == 2
|
||||
assert parameters[0] instanceof PsiArrayType
|
||||
def componentType = parameters[0].getDeepComponentType()
|
||||
assert componentType instanceof PsiClassReferenceType
|
||||
assert parameters[1] instanceof PsiWildcardType
|
||||
def bound = (parameters[1] as PsiWildcardType).getExtendsBound()
|
||||
assert bound instanceof PsiClassReferenceType
|
||||
public void test_no_hard_refs_to_AST_via_generic_component_type() {
|
||||
final PsiClass cls = myFixture.addClass("class Foo { java.util.Map<String[], ? extends CharSequence> bar() {} }");
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertNotNull(cls.getNode());
|
||||
PsiType type = cls.getMethods()[0].getReturnType();
|
||||
assertTrue(type instanceof PsiClassReferenceType);
|
||||
PsiType[] parameters = ((PsiClassReferenceType)type).getParameters();
|
||||
assertEquals(2, parameters.length);
|
||||
assertTrue(parameters[0] instanceof PsiArrayType);
|
||||
PsiType componentType = parameters[0].getDeepComponentType();
|
||||
assertTrue(componentType instanceof PsiClassReferenceType);
|
||||
assertTrue(parameters[1] instanceof PsiWildcardType);
|
||||
PsiType bound = ((PsiWildcardType)parameters[1]).getExtendsBound();
|
||||
assertTrue(bound instanceof PsiClassReferenceType);
|
||||
|
||||
LeakHunter.checkLeak(type, MethodElement, { MethodElement node ->
|
||||
node.psi == cls.methods[0]
|
||||
})
|
||||
LeakHunter.checkLeak(type, MethodElement.class, node -> node.getPsi().equals(cls.getMethods()[0]));
|
||||
|
||||
GCWatcher.tracking(cls.node).ensureCollected()
|
||||
assert !file.contentsLoaded
|
||||
GCWatcher.tracking(cls.getNode()).ensureCollected();
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert componentType.equalsToText(String.name)
|
||||
assert bound.equalsToText(CharSequence.name)
|
||||
assert !file.contentsLoaded
|
||||
assertTrue(componentType.equalsToText(String.class.getName()));
|
||||
assertTrue(bound.equalsToText(CharSequence.class.getName()));
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,518 +1,505 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.java.psi
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.psi;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil
|
||||
import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.PsiClassImpl
|
||||
import com.intellij.psi.impl.source.PsiFieldImpl
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.PsiShortNamesCache
|
||||
import com.intellij.psi.search.searches.AnnotatedElementsSearch
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import groovy.transform.CompileStatic
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil;
|
||||
import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiClassImpl;
|
||||
import com.intellij.psi.impl.source.PsiFieldImpl;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.psi.search.searches.AnnotatedElementsSearch;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@CompileStatic
|
||||
class JavaStubsTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public class JavaStubsTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public void test_resolve_from_annotation_method_default() {
|
||||
PsiClass cls = myFixture.addClass("""
|
||||
public @interface BrokenAnnotation {
|
||||
enum Foo {DEFAULT, OTHER}
|
||||
Foo value() default Foo.DEFAULT;
|
||||
}""");
|
||||
|
||||
void "test resolve from annotation method default"() {
|
||||
def cls = myFixture.addClass("""\
|
||||
public @interface BrokenAnnotation {
|
||||
enum Foo {DEFAULT, OTHER}
|
||||
Foo value() default Foo.DEFAULT;
|
||||
}
|
||||
""".stripIndent())
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertNotNull(file.getStub());
|
||||
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
assert file.stub
|
||||
PsiAnnotationMemberValue ref = (((PsiAnnotationMethod)cls.getMethods()[0])).getDefaultValue();
|
||||
assertNotNull(file.getStub());
|
||||
|
||||
def ref = (cls.methods[0] as PsiAnnotationMethod).defaultValue
|
||||
assert file.stub
|
||||
|
||||
assert ref instanceof PsiReferenceExpression
|
||||
assert ref.resolve() == cls.innerClasses[0].fields[0]
|
||||
assert file.stub
|
||||
assertTrue(ref instanceof PsiReferenceExpression);
|
||||
assertEquals(((PsiReferenceExpression)ref).resolve(), cls.getInnerClasses()[0].getFields()[0]);
|
||||
assertNotNull(file.getStub());
|
||||
}
|
||||
|
||||
void "test literal annotation value"() {
|
||||
def cls = myFixture.addClass("""\
|
||||
class Foo {
|
||||
@org.jetbrains.annotations.Contract(pure=true)
|
||||
native int foo();
|
||||
}
|
||||
""".stripIndent())
|
||||
public void test_literal_annotation_value() {
|
||||
PsiClass cls = myFixture.addClass("""
|
||||
class Foo {
|
||||
@org.jetbrains.annotations.Contract(pure=true)
|
||||
native int foo();
|
||||
}""");
|
||||
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
assert JavaMethodContractUtil.isPure(cls.methods[0])
|
||||
assert file.stub
|
||||
assert !file.contentsLoaded
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertTrue(JavaMethodContractUtil.isPure(cls.getMethods()[0]));
|
||||
assertNotNull(file.getStub());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test local variable annotation doesn't cause stub-ast switch"() {
|
||||
def cls = myFixture.addClass("""
|
||||
public void test_local_variable_annotation_doesn_t_cause_stub_ast_switch() {
|
||||
PsiClass cls = myFixture.addClass("""
|
||||
class Foo {
|
||||
@Anno int foo() {
|
||||
@Anno int var = 2;
|
||||
}
|
||||
}
|
||||
@interface Anno {}
|
||||
""")
|
||||
@interface Anno {}""");
|
||||
|
||||
def file = cls.containingFile as PsiFileImpl
|
||||
assert AnnotatedElementsSearch.searchPsiMethods(myFixture.findClass("Anno"), GlobalSearchScope.allScope(project)).size() == 1
|
||||
assert file.stub
|
||||
assert !file.contentsLoaded
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertEquals(1, AnnotatedElementsSearch.searchPsiMethods(myFixture.findClass("Anno"), GlobalSearchScope.allScope(getProject()))
|
||||
.findAll().size());
|
||||
assertNotNull(file.getStub());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test applying type annotations"() {
|
||||
def cls = myFixture.addClass("""\
|
||||
import java.lang.annotation.*;
|
||||
class Foo {
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface TA { String value(); }
|
||||
public void test_applying_type_annotations() {
|
||||
PsiClass cls = myFixture.addClass("""
|
||||
import java.lang.annotation.*;
|
||||
class Foo {
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface TA { String value(); }
|
||||
|
||||
private @TA String f1;
|
||||
private @TA String f1;
|
||||
|
||||
private static @TA int m1(@TA int p1) { return 0; }
|
||||
}
|
||||
""".stripIndent())
|
||||
private static @TA int m1(@TA int p1) { return 0; }
|
||||
}""");
|
||||
|
||||
def f1 = cls.fields[0].type
|
||||
def m1 = cls.methods[0].returnType
|
||||
def p1 = cls.methods[0].parameterList.parameters[0].type
|
||||
assert (cls as PsiClassImpl).stub
|
||||
PsiType f1 = cls.getFields()[0].getType();
|
||||
PsiType m1 = cls.getMethods()[0].getReturnType();
|
||||
PsiType p1 = cls.getMethods()[0].getParameterList().getParameters()[0].getType();
|
||||
assertNotNull(((PsiClassImpl)cls).getStub());
|
||||
|
||||
assert f1.getCanonicalText(true) == "java.lang.@Foo.TA String"
|
||||
assert m1.getCanonicalText(true) == "@Foo.TA int"
|
||||
assert p1.getCanonicalText(true) == "@Foo.TA int"
|
||||
assertEquals("java.lang.@Foo.TA String", f1.getCanonicalText(true));
|
||||
assertEquals("@Foo.TA int", m1.getCanonicalText(true));
|
||||
assertEquals("@Foo.TA int", p1.getCanonicalText(true));
|
||||
}
|
||||
|
||||
void "test containing class of a local class is null"() {
|
||||
def foo = myFixture.addClass("""\
|
||||
class Foo {
|
||||
static { class Bar extends Foo { } }
|
||||
}""".stripIndent())
|
||||
def bar = ClassInheritorsSearch.search(foo).findFirst()
|
||||
public void test_containing_class_of_a_local_class_is_null() {
|
||||
PsiClass foo = myFixture.addClass("""
|
||||
class Foo {
|
||||
static { class Bar extends Foo { } }
|
||||
}""");
|
||||
PsiClass bar = ClassInheritorsSearch.search(foo).findFirst();
|
||||
|
||||
def file = (PsiFileImpl)foo.containingFile
|
||||
assert !file.contentsLoaded
|
||||
PsiFileImpl file = (PsiFileImpl)foo.getContainingFile();
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert bar.containingClass == null
|
||||
assert !file.contentsLoaded
|
||||
assertNull(bar.getContainingClass());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
bar.node
|
||||
assert bar.containingClass == null
|
||||
assert file.contentsLoaded
|
||||
assertNotNull(bar.getNode());
|
||||
assertNull(bar.getContainingClass());
|
||||
assertTrue(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test stub-based super class type parameter resolve"() {
|
||||
public void test_stub_based_super_class_type_parameter_resolve() throws ExecutionException, InterruptedException {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
def foo = myFixture.addClass("class Foo$i<T> {}")
|
||||
def bar = myFixture.addClass("class Bar$i<T> extends Foo$i<T> {}")
|
||||
PsiClass foo = myFixture.addClass("class Foo" + i + "<T> {}");
|
||||
final PsiClass bar = myFixture.addClass("class Bar" + i + "<T> extends Foo" + i + "<T> {}");
|
||||
|
||||
def app = ApplicationManager.application
|
||||
app.executeOnPooledThread({ ReadAction.compute { bar.node } })
|
||||
def superType = app.executeOnPooledThread({ ReadAction.compute { bar.superTypes[0] }} as Callable<PsiClassType>).get()
|
||||
assert foo == superType.resolve()
|
||||
assert bar.typeParameters[0] == PsiUtil.resolveClassInClassTypeOnly(superType.parameters[0])
|
||||
Application app = ApplicationManager.getApplication();
|
||||
app.executeOnPooledThread(() -> ReadAction.compute(() -> bar.getNode()));
|
||||
PsiClassType superType = app.executeOnPooledThread(() -> ReadAction.compute(() -> bar.getSuperTypes()[0])).get();
|
||||
assertEquals(foo, superType.resolve());
|
||||
assertEquals(bar.getTypeParameters()[0], PsiUtil.resolveClassInClassTypeOnly(superType.getParameters()[0]));
|
||||
}
|
||||
}
|
||||
|
||||
void "test default annotation attribute name"() {
|
||||
def cls = myFixture.addClass('@Anno("foo") class Foo {}')
|
||||
def file = (PsiFileImpl)cls.containingFile
|
||||
assert !file.contentsLoaded
|
||||
public void test_default_annotation_attribute_name() {
|
||||
PsiClass cls = myFixture.addClass("@Anno(\"foo\") class Foo {}");
|
||||
PsiFileImpl file = (PsiFileImpl)cls.getContainingFile();
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
def attr = cls.modifierList.annotations[0].parameterList.attributes[0]
|
||||
assert attr.name == null
|
||||
assert !file.contentsLoaded
|
||||
PsiNameValuePair attr = cls.getModifierList().getAnnotations()[0].getParameterList().getAttributes()[0];
|
||||
assertNull(attr.getName());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
attr.node
|
||||
assert attr.name == null
|
||||
assertNotNull(attr.getNode());
|
||||
assertNull(attr.getName());
|
||||
}
|
||||
|
||||
void "test determine annotation target without AST"() {
|
||||
def cls = myFixture.addClass("""\
|
||||
import java.lang.annotation.*;
|
||||
@Anno class Some {}
|
||||
@Target(ElementType.METHOD) @interface Anno {}""".stripIndent())
|
||||
assert "Some" == cls.name
|
||||
assert !AnnotationTargetUtil.isTypeAnnotation(cls.modifierList.annotations[0])
|
||||
assert !((PsiFileImpl) cls.containingFile).contentsLoaded
|
||||
public void test_determine_annotation_target_without_AST() {
|
||||
PsiClass cls = myFixture.addClass("""
|
||||
import java.lang.annotation.*;
|
||||
@Anno class Some {}
|
||||
@Target(ElementType.METHOD) @interface Anno {}""");
|
||||
assertEquals("Some", cls.getName());
|
||||
assertFalse(AnnotationTargetUtil.isTypeAnnotation(cls.getModifierList().getAnnotations()[0]));
|
||||
assertFalse(((PsiFileImpl)cls.getContainingFile()).isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test parameter list count"() {
|
||||
myFixture.addFileToProject("a.java", "class Cls { void foo(a) {} }")
|
||||
def list = myFixture.findClass("Cls").methods[0].parameterList
|
||||
assert list.parametersCount == list.parameters.size()
|
||||
public void test_parameter_list_count() {
|
||||
myFixture.addFileToProject("a.java", "class Cls { void foo(a) {} }");
|
||||
PsiParameterList list = myFixture.findClass("Cls").getMethods()[0].getParameterList();
|
||||
assertEquals(list.getParametersCount(), list.getParameters().length);
|
||||
}
|
||||
|
||||
void "test deprecated enum constant"() {
|
||||
def cls = myFixture.addClass("enum Foo { c1, @Deprecated c2, /** @deprecated */ c3 }")
|
||||
assert !((PsiFileImpl) cls.containingFile).contentsLoaded
|
||||
public void test_deprecated_enum_constant() {
|
||||
PsiClass cls = myFixture.addClass("enum Foo { c1, @Deprecated c2, /** @deprecated */ c3 }");
|
||||
assertFalse(((PsiFileImpl)cls.getContainingFile()).isContentsLoaded());
|
||||
|
||||
assert !cls.fields[0].deprecated
|
||||
assert cls.fields[1].deprecated
|
||||
assert cls.fields[2].deprecated
|
||||
assertFalse(cls.getFields()[0].isDeprecated());
|
||||
assertTrue(cls.getFields()[1].isDeprecated());
|
||||
assertTrue(cls.getFields()[2].isDeprecated());
|
||||
|
||||
assert !((PsiFileImpl) cls.containingFile).contentsLoaded
|
||||
assertFalse(((PsiFileImpl)cls.getContainingFile()).isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test breaking and adding import does not cause stub AST mismatch"() {
|
||||
def file = myFixture.addFileToProject("a.java", "import foo.*; import bar.*; class Foo {}") as PsiJavaFile
|
||||
def another = myFixture.addClass("package zoo; public class Another {}")
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
file.viewProvider.document.insertString(file.text.indexOf("import"), "x")
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
file.importClass(another)
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
public void test_breaking_and_adding_import_does_not_cause_stub_AST_mismatch() {
|
||||
PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "import foo.*; import bar.*; class Foo {}");
|
||||
PsiClass another = myFixture.addClass("package zoo; public class Another {}");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), (Computable<Boolean>)() -> {
|
||||
file.getViewProvider().getDocument().insertString(file.getText().indexOf("import"), "x");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
return file.importClass(another);
|
||||
});
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
void "test removing import in broken code does not cause stub AST mismatch"() {
|
||||
def file = myFixture.addFileToProject("a.java", "import foo..module.SomeClass; class Foo {}") as PsiJavaFile
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
file.importList.importStatements[0].delete()
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
public void test_removing_import_in_broken_code_does_not_cause_stub_AST_mismatch() {
|
||||
PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "import foo..module.SomeClass; class Foo {}");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> file.getImportList().getImportStatements()[0].delete());
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
void "test adding type before method call does not cause stub AST mismatch"() {
|
||||
def file = myFixture.addFileToProject("a.java", """\
|
||||
public void test_adding_type_before_method_call_does_not_cause_stub_AST_mismatch() {
|
||||
final PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", """
|
||||
class Foo {
|
||||
void foo() {
|
||||
something();
|
||||
call();
|
||||
}
|
||||
}""".stripIndent()) as PsiJavaFile
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
file.viewProvider.document.insertString(file.text.indexOf("call"), "char ")
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
}
|
||||
}""");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
file.getViewProvider().getDocument().insertString(file.getText().indexOf("call"), "char ");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
});
|
||||
}
|
||||
|
||||
void "test inserting class keyword"() {
|
||||
String text = "class Foo { void foo() { return; } }"
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text)
|
||||
Document document = psiFile.getViewProvider().getDocument()
|
||||
public void test_inserting_class_keyword() {
|
||||
final String text = "class Foo { void foo() { return; } }";
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text);
|
||||
final Document document = psiFile.getViewProvider().getDocument();
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
document.insertString(text.indexOf("return"), "class ")
|
||||
}
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments()
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(), () -> document.insertString(text.indexOf("return"), "class "));
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
void "test inserting enum keyword"() {
|
||||
String text = "class Foo { void foo() { return; } }"
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text)
|
||||
Document document = psiFile.getViewProvider().getDocument()
|
||||
public void test_inserting_enum_keyword() {
|
||||
final String text = "class Foo { void foo() { return; } }";
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text);
|
||||
final Document document = psiFile.getViewProvider().getDocument();
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
document.insertString(text.indexOf("return"), "enum Foo")
|
||||
}
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments()
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(), () -> document.insertString(text.indexOf("return"), "enum Foo"));
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
void "test type arguments without type in a method"() {
|
||||
String text = "class Foo { { final Collection<String> contexts; f instanceof -> } }"
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text)
|
||||
public void test_type_arguments_without_type_in_a_method() {
|
||||
String text = "class Foo { { final Collection<String> contexts; f instanceof -> } }";
|
||||
final PsiFile psiFile = myFixture.addFileToProject("a.java", text);
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project) { deleteString(psiFile, "Collection") }
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments()
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> deleteString(psiFile, "Collection"));
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
private static void deleteString(PsiFile file, String fragment) {
|
||||
def document = file.viewProvider.document
|
||||
def index = document.text.indexOf(fragment)
|
||||
document.deleteString(index, index + fragment.size())
|
||||
Document document = file.getViewProvider().getDocument();
|
||||
int index = document.getText().indexOf(fragment);
|
||||
document.deleteString(index, index + fragment.length());
|
||||
}
|
||||
|
||||
void "test remove class literal qualifier"() {
|
||||
String text = "class Foo { { foo(String.class); } }"
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text)
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
psiFile.viewProvider.document.insertString(text.indexOf(");"), " x")
|
||||
WriteCommandAction.runWriteCommandAction(project) { deleteString(psiFile, "String") }
|
||||
}
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments()
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
public void test_remove_class_literal_qualifier() {
|
||||
final String text = "class Foo { { foo(String.class); } }";
|
||||
final PsiFile psiFile = myFixture.addFileToProject("a.java", text);
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(), () -> {
|
||||
psiFile.getViewProvider().getDocument().insertString(text.indexOf(");"), " x");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> deleteString(psiFile, "String"));
|
||||
});
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
void "test annotation stub without reference"() {
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", "@() class Foo { } }")
|
||||
assert ((PsiJavaFile) psiFile).classes[0].modifierList.annotations[0].nameReferenceElement == null
|
||||
assert !((PsiFileImpl) psiFile).contentsLoaded
|
||||
public void test_annotation_stub_without_reference() {
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", "@() class Foo { } }");
|
||||
assertNull(((PsiJavaFile)psiFile).getClasses()[0].getModifierList().getAnnotations()[0].getNameReferenceElement());
|
||||
assertFalse(((PsiFileImpl)psiFile).isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test anonymous class stubs see method type parameters"() {
|
||||
PsiFileImpl file = (PsiFileImpl) myFixture.addFileToProject("A.java", """\
|
||||
public void test_anonymous_class_stubs_see_method_type_parameters() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("A.java", """
|
||||
class A {
|
||||
<V> Object foo() {
|
||||
return new I<V>(){};
|
||||
}
|
||||
}
|
||||
interface I<T> {}
|
||||
""".stripIndent())
|
||||
interface I<T> {}""");
|
||||
|
||||
PsiClass a = ((PsiJavaFile) file).classes[0]
|
||||
PsiClass i = ((PsiJavaFile) file).classes[1]
|
||||
PsiAnonymousClass anon = assertOneElement(DirectClassInheritorsSearch.search(i).findAll()) as PsiAnonymousClass
|
||||
PsiClass a = ((PsiJavaFile)file).getClasses()[0];
|
||||
PsiClass i = ((PsiJavaFile)file).getClasses()[1];
|
||||
PsiAnonymousClass anon = (PsiAnonymousClass)UsefulTestCase.assertOneElement(DirectClassInheritorsSearch.search(i).findAll());
|
||||
|
||||
assert i == anon.baseClassType.resolve()
|
||||
assert a.methods[0].typeParameters[0] == PsiUtil.resolveClassInClassTypeOnly(anon.baseClassType.parameters[0])
|
||||
assertEquals(i, anon.getBaseClassType().resolve());
|
||||
assertEquals(a.getMethods()[0].getTypeParameters()[0], PsiUtil.resolveClassInClassTypeOnly(anon.getBaseClassType().getParameters()[0]));
|
||||
|
||||
assert !file.contentsLoaded
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test anonymous class stubs see local classes"() {
|
||||
PsiFileImpl file = (PsiFileImpl) myFixture.addFileToProject("A.java", """\
|
||||
public void test_anonymous_class_stubs_see_local_classes() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("A.java", """
|
||||
class A {
|
||||
void foo() {
|
||||
class Local {}
|
||||
new I<Local>(){};
|
||||
}
|
||||
}
|
||||
interface I<T> {}
|
||||
""".stripIndent())
|
||||
interface I<T> {}""");
|
||||
|
||||
PsiClass i = ((PsiJavaFile) file).classes[1]
|
||||
PsiAnonymousClass anon = assertOneElement(DirectClassInheritorsSearch.search(i).findAll()) as PsiAnonymousClass
|
||||
PsiClass i = ((PsiJavaFile)file).getClasses()[1];
|
||||
PsiAnonymousClass anon = (PsiAnonymousClass)UsefulTestCase.assertOneElement(DirectClassInheritorsSearch.search(i).findAll());
|
||||
|
||||
assert !file.contentsLoaded
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert i == anon.baseClassType.resolve()
|
||||
assert PsiUtil.resolveClassInClassTypeOnly(anon.baseClassType.parameters[0])?.name == "Local"
|
||||
assertEquals(i, anon.getBaseClassType().resolve());
|
||||
final PsiClass only = PsiUtil.resolveClassInClassTypeOnly(anon.getBaseClassType().getParameters()[0]);
|
||||
assertEquals("Local", (only == null ? null : only.getName()));
|
||||
}
|
||||
|
||||
void "test local class stubs see other local classes"() {
|
||||
PsiFileImpl file = (PsiFileImpl) myFixture.addFileToProject("A.java", """\
|
||||
public void test_local_class_stubs_see_other_local_classes() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("A.java", """
|
||||
class A {
|
||||
void foo() {
|
||||
class Local1 {}
|
||||
class Local2 extends Local1 {}
|
||||
}
|
||||
}
|
||||
""".stripIndent())
|
||||
}""");
|
||||
|
||||
def cache = PsiShortNamesCache.getInstance(project)
|
||||
def local1 = cache.getClassesByName("Local1", GlobalSearchScope.allScope(project))[0]
|
||||
def local2 = cache.getClassesByName("Local2", GlobalSearchScope.allScope(project))[0]
|
||||
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(getProject());
|
||||
PsiClass local1 = cache.getClassesByName("Local1", GlobalSearchScope.allScope(getProject()))[0];
|
||||
PsiClass local2 = cache.getClassesByName("Local2", GlobalSearchScope.allScope(getProject()))[0];
|
||||
|
||||
assert !file.contentsLoaded
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert local1 == local2.superClass
|
||||
assertEquals(local1, local2.getSuperClass());
|
||||
}
|
||||
|
||||
void "test local class stubs do not load AST for inheritance checking when possible"() {
|
||||
PsiFileImpl file = (PsiFileImpl) myFixture.addFileToProject("A.java", """\
|
||||
class A {
|
||||
void foo() {
|
||||
class UnrelatedLocal {}
|
||||
class Local extends A {}
|
||||
}
|
||||
}
|
||||
""".stripIndent())
|
||||
public void test_local_class_stubs_do_not_load_AST_for_inheritance_checking_when_possible() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("A.java", """
|
||||
class A {
|
||||
void foo() {
|
||||
class UnrelatedLocal {}
|
||||
class Local extends A {}
|
||||
}
|
||||
}""");
|
||||
|
||||
def local = PsiShortNamesCache.getInstance(project).getClassesByName("Local", GlobalSearchScope.allScope(project))[0]
|
||||
assert "A" == local.superClass.name
|
||||
assert !file.contentsLoaded
|
||||
PsiClass local = PsiShortNamesCache.getInstance(getProject()).getClassesByName("Local", GlobalSearchScope.allScope(getProject()))[0];
|
||||
assertEquals("A", local.getSuperClass().getName());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test broken anonymous"() {
|
||||
String text = """\
|
||||
public void test_broken_anonymous() {
|
||||
final String text = """
|
||||
class A {
|
||||
public GroupDescriptor[] getGroupDescriptors() {
|
||||
return new ThreadGroup(Descriptor[]{
|
||||
new GroupDescriptor(groupId, "test")
|
||||
};
|
||||
}
|
||||
}""".stripIndent()
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text)
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
psiFile.viewProvider.document.insertString(text.indexOf("]{"), "x")
|
||||
}
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments()
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
}""";
|
||||
final PsiFile psiFile = myFixture.addFileToProject("a.java", text);
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(), () -> psiFile.getViewProvider().getDocument().insertString(text.indexOf("]{"), "x"));
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
void "test broken nested anonymous"() {
|
||||
PsiTestUtil.checkStubsMatchText(myFixture.addFileToProject("a.java", "class A { { new A(new B[a]{b}); } }"))
|
||||
public void test_broken_nested_anonymous() {
|
||||
PsiTestUtil.checkStubsMatchText(myFixture.addFileToProject("a.java", "class A { { new A(new B[a]{b}); } }"));
|
||||
}
|
||||
|
||||
void "test lone angle brackets"() {
|
||||
String text = """\
|
||||
public void test_lone_angle_brackets() {
|
||||
String text = """
|
||||
class A {
|
||||
{
|
||||
PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(element, .class);
|
||||
final <PsiElement, TextRange> pair;
|
||||
}
|
||||
}""".stripIndent()
|
||||
PsiTestUtil.checkStubsMatchText(myFixture.addFileToProject("a.java", text))
|
||||
}
|
||||
|
||||
void "test incomplete static import does not cause CCE"() {
|
||||
def file = myFixture.addFileToProject("a.java", "import static foo.bar.") as PsiJavaFile
|
||||
assert ((PsiFileImpl)file).stub
|
||||
assert file.node
|
||||
def staticImport = ((PsiJavaFile)file).importList.importStaticStatements[0]
|
||||
assert staticImport.referenceName == null
|
||||
assert !staticImport.resolveTargetClass()
|
||||
}
|
||||
|
||||
void "test adding import to broken file with type parameters"() {
|
||||
def file = myFixture.addFileToProject("a.java", "A<B>") as PsiJavaFile
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
file.importClass(myFixture.findClass(CommonClassNames.JAVA_UTIL_LIST))
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
}
|
||||
|
||||
void "test remove extends reference before dot"() {
|
||||
def file = myFixture.addFileToProject("a.java", "class A extends B. { int a; }")
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
def javaFile = file as PsiJavaFile
|
||||
def clazz = (javaFile.classes[0] as PsiImplicitClass).innerClasses[0]
|
||||
clazz.extendsList.referenceElements[0].delete()
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
}
|
||||
|
||||
void "test remove type argument list after space"() {
|
||||
def file = myFixture.addFileToProject("a.java", "class A { A <B>a; }")
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
myFixture.findClass("A").fields[0].typeElement.innermostComponentReferenceElement.parameterList.delete()
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
PsiTestUtil.checkFileStructure(file)
|
||||
}
|
||||
|
||||
void "test remove modifier making a comment a class javadoc"() {
|
||||
def file = myFixture.addFileToProject("a.java", "import foo; final /** @deprecated */ public class A { }")
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
def clazz = myFixture.findClass("A")
|
||||
def children = clazz.modifierList.children
|
||||
assert children.length != 0 : clazz.containingFile.text + ";" + clazz.containingFile.virtualFile.path
|
||||
children[0].delete()
|
||||
}
|
||||
PsiTestUtil.checkFileStructure(file)
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
}
|
||||
|
||||
void "test add reference into broken extends list"() {
|
||||
def file = myFixture.addFileToProject("a.java", "class A extends.ends Foo { int a; }")
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
def javaFile = file as PsiJavaFile
|
||||
def clazz = (javaFile.classes[0] as PsiImplicitClass).innerClasses[0]
|
||||
clazz.extendsList.add(JavaPsiFacade.getElementFactory(project).createReferenceElementByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, file.resolveScope))
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
}
|
||||
|
||||
void "test identifier dot before class"() {
|
||||
def file = myFixture.addFileToProject("a.java", "class A {{ public id.class B {}}}")
|
||||
PsiTestUtil.checkStubsMatchText(file)
|
||||
}
|
||||
|
||||
void "test removing orphan annotation"() {
|
||||
String text = """\
|
||||
public class Foo {
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSteps {
|
||||
}
|
||||
}""".stripIndent()
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", text)
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
PsiTreeUtil.findChildOfType(psiFile, PsiAnnotation).delete()
|
||||
}
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
}""";
|
||||
PsiTestUtil.checkStubsMatchText(myFixture.addFileToProject("a.java", text));
|
||||
}
|
||||
|
||||
void "test local record"() {
|
||||
PsiTestUtil.checkStubsMatchText(myFixture.addFileToProject("a.java", """\
|
||||
class A {
|
||||
void test() {
|
||||
record A(String s) { }
|
||||
}
|
||||
}
|
||||
""".stripIndent()))
|
||||
public void test_incomplete_static_import_does_not_cause_CCE() {
|
||||
PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "import static foo.bar.");
|
||||
assertNotNull(((PsiFileImpl)file).getStub());
|
||||
assertNotNull(file.getNode());
|
||||
PsiImportStaticStatement staticImport = file.getImportList().getImportStaticStatements()[0];
|
||||
assertNull(staticImport.getReferenceName());
|
||||
assertNull(staticImport.resolveTargetClass());
|
||||
}
|
||||
|
||||
void "test field with missing initializer"() {
|
||||
def file = myFixture.addFileToProject("a.java", "class A { int a = ; } ")
|
||||
def clazz = myFixture.findClass("A")
|
||||
assert PsiFieldImpl.getDetachedInitializer(clazz.fields[0]) == null
|
||||
assert !(file as PsiFileImpl).contentsLoaded
|
||||
public void test_adding_import_to_broken_file_with_type_parameters() {
|
||||
final PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "A<B>");
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(), (Computable<Boolean>)() -> file.importClass(myFixture.findClass(CommonClassNames.JAVA_UTIL_LIST)));
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
void "test implicit class"() {
|
||||
public void test_remove_extends_reference_before_dot() {
|
||||
final PsiFile file = myFixture.addFileToProject("a.java", "class A extends B. { int a; }");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
PsiJavaFile javaFile = (PsiJavaFile)file;
|
||||
PsiClass clazz = javaFile.getClasses()[0].getInnerClasses()[0];
|
||||
clazz.getExtendsList().getReferenceElements()[0].delete();
|
||||
});
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
def psiFile = myFixture.addFileToProject("a.java", """\
|
||||
public void test_remove_type_argument_list_after_space() {
|
||||
PsiFile file = myFixture.addFileToProject("a.java", "class A { A <B>a; }");
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(),
|
||||
() -> myFixture.findClass("A").getFields()[0].getTypeElement().getInnermostComponentReferenceElement().getParameterList().delete());
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
PsiTestUtil.checkFileStructure(file);
|
||||
}
|
||||
|
||||
public void test_remove_modifier_making_a_comment_a_class_javadoc() {
|
||||
PsiFile file = myFixture.addFileToProject("a.java", "import foo; final /** @deprecated */ public class A { }");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
PsiClass clazz = myFixture.findClass("A");
|
||||
PsiElement[] children = clazz.getModifierList().getChildren();
|
||||
assertTrue(clazz.getContainingFile().getText() + ";" + clazz.getContainingFile().getVirtualFile().getPath(),
|
||||
children.length != 0);
|
||||
children[0].delete();
|
||||
});
|
||||
PsiTestUtil.checkFileStructure(file);
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
public void test_add_reference_into_broken_extends_list() {
|
||||
final PsiFile file = myFixture.addFileToProject("a.java", "class A extends.ends Foo { int a; }");
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), (Computable<PsiElement>)() -> {
|
||||
PsiJavaFile javaFile = (PsiJavaFile)file;
|
||||
PsiClass clazz = javaFile.getClasses()[0].getInnerClasses()[0];
|
||||
return clazz.getExtendsList().add(JavaPsiFacade.getElementFactory(getProject())
|
||||
.createReferenceElementByFQClassName(CommonClassNames.JAVA_LANG_OBJECT,
|
||||
file.getResolveScope()));
|
||||
});
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
public void test_identifier_dot_before_class() {
|
||||
PsiFile file = myFixture.addFileToProject("a.java", "class A {{ public id.class B {}}}");
|
||||
PsiTestUtil.checkStubsMatchText(file);
|
||||
}
|
||||
|
||||
public void test_removing_orphan_annotation() {
|
||||
String text = """
|
||||
public class Foo {
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSteps {
|
||||
}
|
||||
}""";
|
||||
final PsiFile psiFile = myFixture.addFileToProject("a.java", text);
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> PsiTreeUtil.findChildOfType(psiFile, PsiAnnotation.class).delete());
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
public void test_local_record() {
|
||||
PsiTestUtil.checkStubsMatchText(myFixture.addFileToProject("a.java", """
|
||||
class A {
|
||||
void test() {
|
||||
record A(String s) { }
|
||||
}
|
||||
}"""));
|
||||
}
|
||||
|
||||
public void test_field_with_missing_initializer() {
|
||||
PsiFile file = myFixture.addFileToProject("a.java", "class A { int a = ; } ");
|
||||
PsiClass clazz = myFixture.findClass("A");
|
||||
assertNull(PsiFieldImpl.getDetachedInitializer(clazz.getFields()[0]));
|
||||
assertFalse(((PsiFileImpl)file).isContentsLoaded());
|
||||
}
|
||||
|
||||
public void test_implicit_class() {
|
||||
PsiFile psiFile = myFixture.addFileToProject("a.java", """
|
||||
void test() {
|
||||
}
|
||||
|
||||
|
||||
String s = "foo";
|
||||
int i = 10;
|
||||
static {} // not allowed by spec, but we parse
|
||||
""".stripIndent())
|
||||
PsiTestUtil.checkStubsMatchText(psiFile)
|
||||
static {} // not allowed by spec, but we parse""");
|
||||
PsiTestUtil.checkStubsMatchText(psiFile);
|
||||
}
|
||||
|
||||
void "test array type use annotation stubbing"() {
|
||||
myFixture.addClass("""\
|
||||
import java.lang.annotation.*;
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface Anno { int value(); }""".stripIndent())
|
||||
public void test_array_type_use_annotation_stubbing() {
|
||||
myFixture.addClass("""
|
||||
import java.lang.annotation.*;
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface Anno { int value(); }""");
|
||||
|
||||
PsiClass clazz = myFixture.addClass("""\
|
||||
class Foo {
|
||||
<T> @Anno(0) String @Anno(1) [] @Anno(2) [] foo(@Anno(3) byte @Anno(4) [] data) {}
|
||||
List<String> @Anno(5) [] field;
|
||||
}""".stripIndent())
|
||||
PsiClass clazz = myFixture.addClass("""
|
||||
class Foo {
|
||||
<T> @Anno(0) String @Anno(1) [] @Anno(2) [] foo(@Anno(3) byte @Anno(4) [] data) {}
|
||||
List<String> @Anno(5) [] field;
|
||||
}""");
|
||||
|
||||
def method = clazz.methods[0]
|
||||
def field = clazz.fields[0]
|
||||
def parameter = method.parameterList.parameters[0]
|
||||
def parameterAnnotations = parameter.type.annotations
|
||||
def parameterComponentAnnotations = (parameter.type as PsiArrayType).componentType.annotations
|
||||
def methodAnnotations = method.returnType.annotations
|
||||
def methodComponentAnnotations = (method.returnType as PsiArrayType).componentType.annotations
|
||||
def methodDeepComponentAnnotations = method.returnType.deepComponentType.annotations
|
||||
def fieldAnnotations = field.type.annotations
|
||||
PsiMethod method = clazz.getMethods()[0];
|
||||
PsiField field = clazz.getFields()[0];
|
||||
PsiParameter parameter = method.getParameterList().getParameters()[0];
|
||||
PsiAnnotation[] parameterAnnotations = parameter.getType().getAnnotations();
|
||||
PsiAnnotation[] parameterComponentAnnotations = ((PsiArrayType)parameter.getType()).getComponentType().getAnnotations();
|
||||
PsiAnnotation[] methodAnnotations = method.getReturnType().getAnnotations();
|
||||
PsiAnnotation[] methodComponentAnnotations = ((PsiArrayType)method.getReturnType()).getComponentType().getAnnotations();
|
||||
PsiAnnotation[] methodDeepComponentAnnotations = method.getReturnType().getDeepComponentType().getAnnotations();
|
||||
PsiAnnotation[] fieldAnnotations = field.getType().getAnnotations();
|
||||
|
||||
assert !(clazz.containingFile as PsiFileImpl).contentsLoaded
|
||||
assertAnnotationValueText methodDeepComponentAnnotations, "0"
|
||||
assertAnnotationValueText methodAnnotations, "1"
|
||||
assertAnnotationValueText methodComponentAnnotations, "2"
|
||||
assertAnnotationValueText parameterComponentAnnotations, "3"
|
||||
assertAnnotationValueText parameterAnnotations, "4"
|
||||
assertAnnotationValueText fieldAnnotations, "5"
|
||||
assert !(clazz.containingFile as PsiFileImpl).contentsLoaded
|
||||
assertFalse(((PsiFileImpl)clazz.getContainingFile()).isContentsLoaded());
|
||||
assertAnnotationValueText(methodDeepComponentAnnotations, "0");
|
||||
assertAnnotationValueText(methodAnnotations, "1");
|
||||
assertAnnotationValueText(methodComponentAnnotations, "2");
|
||||
assertAnnotationValueText(parameterComponentAnnotations, "3");
|
||||
assertAnnotationValueText(parameterAnnotations, "4");
|
||||
assertAnnotationValueText(fieldAnnotations, "5");
|
||||
assertFalse(((PsiFileImpl)clazz.getContainingFile()).isContentsLoaded());
|
||||
|
||||
assert clazz.node // load AST
|
||||
assert parameter.type.annotations.size() == 1
|
||||
assertNotNull(clazz.getNode());// load AST
|
||||
assertEquals(1, parameter.getType().getAnnotations().length);
|
||||
}
|
||||
|
||||
private static void assertAnnotationValueText(PsiAnnotation[] annotations, String text) {
|
||||
assert annotations.size() == 1
|
||||
assert annotations[0].findAttributeValue("value").text == text
|
||||
assertEquals(1, annotations.length);
|
||||
assertEquals(annotations[0].findAttributeValue("value").getText(), text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,334 +1,354 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.psi
|
||||
package com.intellij.java.psi;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes
|
||||
import com.intellij.psi.impl.source.DummyHolder
|
||||
import com.intellij.psi.impl.source.PsiClassImpl
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.impl.source.PsiJavaFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubTree
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.LeakHunter
|
||||
import com.intellij.testFramework.SkipSlowTestLocally
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.intellij.util.ref.GCUtil
|
||||
import com.intellij.util.ref.GCWatcher
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.source.DummyHolder;
|
||||
import com.intellij.psi.impl.source.PsiClassImpl;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.impl.source.PsiJavaFileImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.stubs.StubTree;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.LeakHunter;
|
||||
import com.intellij.testFramework.SkipSlowTestLocally;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ref.GCUtil;
|
||||
import com.intellij.util.ref.GCWatcher;
|
||||
import junit.framework.TestCase;
|
||||
import one.util.streamex.IntStreamEx;
|
||||
|
||||
import java.lang.ref.SoftReference
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.Future
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
@SuppressWarnings("CallToSystemGC")
|
||||
@SkipSlowTestLocally
|
||||
class StubAstSwitchTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public class StubAstSwitchTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public void test_modifying_file_with_stubs_via_VFS() throws IOException {
|
||||
final PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("Foo.java", "class Foo {}");
|
||||
assertNotNull(file.getStub());
|
||||
PsiClass cls = ((PsiJavaFile)file).getClasses()[0];
|
||||
assertNotNull(file.getStub());
|
||||
|
||||
void "test modifying file with stubs via VFS"() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject('Foo.java', 'class Foo {}')
|
||||
assert file.stub
|
||||
def cls = ((PsiJavaFile)file).classes[0]
|
||||
assert file.stub
|
||||
long oldCount = getPsiManager().getModificationTracker().getModificationCount();
|
||||
|
||||
def oldCount = psiManager.modificationTracker.modificationCount
|
||||
WriteAction.run(() -> file.getVirtualFile().setBinaryContent(file.getVirtualFile().contentsToByteArray()));
|
||||
|
||||
ApplicationManager.application.runWriteAction { file.virtualFile.setBinaryContent(file.virtualFile.contentsToByteArray()) }
|
||||
assertTrue(getPsiManager().getModificationTracker().getModificationCount() != oldCount);
|
||||
|
||||
assert psiManager.modificationTracker.modificationCount != oldCount
|
||||
|
||||
assert !cls.valid
|
||||
assert file.stub
|
||||
assert cls != PsiTreeUtil.findElementOfClassAtOffset(file, 1, PsiClass, false)
|
||||
assert !file.stub
|
||||
assertFalse(cls.isValid());
|
||||
assertNotNull(file.getStub());
|
||||
assertNotEquals(cls, PsiTreeUtil.findElementOfClassAtOffset(file, 1, PsiClass.class, false));
|
||||
assertNull(file.getStub());
|
||||
}
|
||||
|
||||
void "test reachable psi classes remain valid when nothing changes"() {
|
||||
int count = 1000
|
||||
List<SoftReference<PsiClass>> classList = (0..<count).collect { new SoftReference<PsiClass>(myFixture.addClass("class Foo$it {}")) }
|
||||
System.gc()
|
||||
System.gc()
|
||||
System.gc()
|
||||
assert classList.every {
|
||||
def cls = it.get()
|
||||
if (!cls || cls.valid) return true
|
||||
cls.text //load AST
|
||||
return cls.valid
|
||||
}
|
||||
public void test_reachable_psi_classes_remain_valid_when_nothing_changes() {
|
||||
int count = 1000;
|
||||
List<SoftReference<PsiClass>> classList = IntStream.range(0, count)
|
||||
.mapToObj(n -> new SoftReference<>(myFixture.addClass("class Foo" + n + " {}"))).toList();
|
||||
System.gc();
|
||||
System.gc();
|
||||
System.gc();
|
||||
assertTrue(ContainerUtil.all(classList, ref -> {
|
||||
PsiClass cls = ref.get();
|
||||
if (cls == null || cls.isValid()) return true;
|
||||
assertNotNull(cls.getText());//load AST
|
||||
//noinspection ConstantValue
|
||||
return cls.isValid();
|
||||
}));
|
||||
}
|
||||
|
||||
void "test traversing PSI and switching concurrently"() {
|
||||
int count = 100
|
||||
List<PsiClass> classList = (0..<count).collect {
|
||||
myFixture.addClass("class Foo$it { " +
|
||||
"void foo$it(" +
|
||||
(0..250).collect { "int i$it"}.join(", ") +
|
||||
") {}" +
|
||||
" }")
|
||||
}
|
||||
CountDownLatch latch = new CountDownLatch(count)
|
||||
for (c in classList) {
|
||||
ApplicationManager.application.executeOnPooledThread {
|
||||
Thread.yield()
|
||||
ApplicationManager.application.runReadAction {
|
||||
c.text
|
||||
}
|
||||
latch.countDown()
|
||||
}
|
||||
for (m in c.methods) {
|
||||
def parameters = m.parameterList.parameters
|
||||
for (i in 0..<parameters.size()) {
|
||||
assert i == m.parameterList.getParameterIndex(parameters[i])
|
||||
public void test_traversing_PSI_and_switching_concurrently() throws InterruptedException {
|
||||
int count = 100;
|
||||
List<PsiClass> classList = IntStream.range(0, count)
|
||||
.mapToObj(num -> myFixture.addClass(
|
||||
"class Foo" + num + " {\n" +
|
||||
"void foo" + num + "(" + IntStreamEx.range(0, 250).mapToObj(parNum -> "int i" + parNum).joining(", ") + ") {}\n" +
|
||||
"}")).toList();
|
||||
final CountDownLatch latch = new CountDownLatch(count);
|
||||
for (PsiClass c : classList) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
Thread.yield();
|
||||
ReadAction.compute(() -> c.getText());
|
||||
latch.countDown();
|
||||
});
|
||||
for (PsiMethod m : c.getMethods()) {
|
||||
PsiParameter[] parameters = m.getParameterList().getParameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
assertEquals(i, m.getParameterList().getParameterIndex(parameters[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
latch.await()
|
||||
|
||||
latch.await();
|
||||
}
|
||||
|
||||
void "test smart pointer survives an external modification of a stubbed file"() {
|
||||
PsiFile file = myFixture.addFileToProject("A.java", "class A {}")
|
||||
def oldClass = JavaPsiFacade.getInstance(project).findClass("A", GlobalSearchScope.allScope(project))
|
||||
def pointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(oldClass)
|
||||
public void test_smart_pointer_survives_an_external_modification_of_a_stubbed_file() throws IOException {
|
||||
final PsiFile file = myFixture.addFileToProject("A.java", "class A {}");
|
||||
PsiClass oldClass = JavaPsiFacade.getInstance(getProject()).findClass("A", GlobalSearchScope.allScope(getProject()));
|
||||
SmartPsiElementPointer<PsiClass> pointer = SmartPointerManager.getInstance(getProject()).createSmartPsiElementPointer(oldClass);
|
||||
|
||||
def document = FileDocumentManager.instance.getDocument(file.virtualFile)
|
||||
assert document
|
||||
assert file == PsiDocumentManager.getInstance(project).getCachedPsiFile(document)
|
||||
assert document == PsiDocumentManager.getInstance(project).getCachedDocument(file)
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file.getVirtualFile());
|
||||
assertNotNull(document);
|
||||
assertEquals(file, PsiDocumentManager.getInstance(getProject()).getCachedPsiFile(document));
|
||||
assertEquals(document, PsiDocumentManager.getInstance(getProject()).getCachedDocument(file));
|
||||
|
||||
assert ((PsiFileImpl)file).stub
|
||||
assertNotNull(((PsiFileImpl)file).getStub());
|
||||
|
||||
ApplicationManager.application.runWriteAction { VfsUtil.saveText(file.virtualFile, "import java.util.*; class A {}; class B {}") }
|
||||
assert pointer.element == oldClass
|
||||
WriteAction.run(() -> VfsUtil.saveText(file.getVirtualFile(), "import java.util.*; class A {}; class B {}"));
|
||||
assertEquals(pointer.getElement(), oldClass);
|
||||
}
|
||||
|
||||
void "test do not parse when resolving references inside an anonymous class"() {
|
||||
PsiFileImpl file = (PsiFileImpl) myFixture.addFileToProject("A.java", """
|
||||
class A {
|
||||
Object field = new B() {
|
||||
void foo(Object o) {
|
||||
public void test_do_not_parse_when_resolving_references_inside_an_anonymous_class() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("A.java", """
|
||||
|
||||
class A {
|
||||
Object field = new B() {
|
||||
void foo(Object o) {
|
||||
}
|
||||
|
||||
class MyInner extends Inner {}
|
||||
};
|
||||
Runnable r = () -> { new B() {}; };
|
||||
Runnable r2 = (new B(){})::hashCode();
|
||||
}
|
||||
|
||||
class MyInner extends Inner {}
|
||||
};
|
||||
Runnable r = () -> { new B() {}; };
|
||||
Runnable r2 = (new B(){})::hashCode();
|
||||
}
|
||||
class B {
|
||||
void foo(Object o) {}
|
||||
static class Inner {}
|
||||
}
|
||||
""");
|
||||
assertFalse(file.isContentsLoaded());
|
||||
PsiClass bClass = ((PsiJavaFile)file).getClasses()[1];
|
||||
assertEquals(3, DirectClassInheritorsSearch.search(bClass).findAll().size());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
class B {
|
||||
void foo(Object o) {}
|
||||
static class Inner {}
|
||||
}
|
||||
""")
|
||||
assert !file.contentsLoaded
|
||||
PsiClass bClass = ((PsiJavaFile) file).classes[1]
|
||||
assert DirectClassInheritorsSearch.search(bClass).findAll().size() == 3
|
||||
assert !file.contentsLoaded
|
||||
PsiMethod fooMethod = bClass.getMethods()[0];
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
def fooMethod = bClass.methods[0]
|
||||
assert !file.contentsLoaded
|
||||
PsiMethod override = OverridingMethodsSearch.search(fooMethod).findFirst();
|
||||
assertNotNull(override);
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
def override = OverridingMethodsSearch.search(fooMethod).findAll().first()
|
||||
assert override
|
||||
assert !file.contentsLoaded
|
||||
assertTrue(override.getContainingClass() instanceof PsiAnonymousClass);
|
||||
assertFalse(file.isContentsLoaded());
|
||||
|
||||
assert override.containingClass instanceof PsiAnonymousClass
|
||||
assert !file.contentsLoaded
|
||||
|
||||
assert bClass == override.containingClass.superClass
|
||||
assert bClass.innerClasses[0] == override.containingClass.innerClasses[0].superClass
|
||||
assert !file.contentsLoaded
|
||||
assertEquals(bClass, override.getContainingClass().getSuperClass());
|
||||
assertEquals(bClass.getInnerClasses()[0], override.getContainingClass().getInnerClasses()[0].getSuperClass());
|
||||
assertFalse(file.isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test AST can be gc-ed and recreated"() {
|
||||
def psiClass = myFixture.addClass("class Foo {}")
|
||||
def file = psiClass.containingFile as PsiFileImpl
|
||||
assert file.stub
|
||||
public void test_AST_can_be_gc_ed_and_recreated() {
|
||||
PsiClass psiClass = myFixture.addClass("class Foo {}");
|
||||
PsiFileImpl file = (PsiFileImpl)psiClass.getContainingFile();
|
||||
assertNotNull(file.getStub());
|
||||
|
||||
assert psiClass.nameIdentifier
|
||||
assert !file.stub
|
||||
assert file.treeElement
|
||||
assertNotNull(psiClass.getNameIdentifier());
|
||||
assertNull(file.getStub());
|
||||
assertNotNull(file.getTreeElement());
|
||||
|
||||
GCUtil.tryGcSoftlyReachableObjects()
|
||||
assert !file.treeElement
|
||||
assert file.stub
|
||||
GCUtil.tryGcSoftlyReachableObjects();
|
||||
assertNull(file.getTreeElement());
|
||||
assertNotNull(file.getStub());
|
||||
|
||||
assert psiClass.nameIdentifier
|
||||
assert !file.stub
|
||||
assert file.treeElement
|
||||
assertNotNull(psiClass.getNameIdentifier());
|
||||
assertNull(file.getStub());
|
||||
assertNotNull(file.getTreeElement());
|
||||
}
|
||||
|
||||
void "test no AST loading on file rename"() {
|
||||
PsiJavaFile file = (PsiJavaFile) myFixture.addFileToProject('a.java', 'class Foo {}')
|
||||
assert file.classes.length == 1
|
||||
assert ((PsiFileImpl)file).stub
|
||||
public void test_no_AST_loading_on_file_rename() {
|
||||
final PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "class Foo {}");
|
||||
assertEquals(1, file.getClasses().length);
|
||||
assertNotNull(((PsiFileImpl)file).getStub());
|
||||
|
||||
WriteCommandAction.runWriteCommandAction project, { file.setName('b.java') }
|
||||
assert file.classes.length == 1
|
||||
assert ((PsiFileImpl)file).stub
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), (Computable<PsiElement>)() -> file.setName("b.java"));
|
||||
assertEquals(1, file.getClasses().length);
|
||||
assertNotNull(((PsiFileImpl)file).getStub());
|
||||
|
||||
assert file.classes[0].nameIdentifier.text == 'Foo'
|
||||
assert ((PsiFileImpl)file).contentsLoaded
|
||||
assertEquals("Foo", file.getClasses()[0].getNameIdentifier().getText());
|
||||
assertTrue(((PsiFileImpl)file).isContentsLoaded());
|
||||
}
|
||||
|
||||
void "test use green stub after AST loaded and gc-ed"() {
|
||||
PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "class A{public static void foo() { }}")
|
||||
//noinspection GroovyUnusedAssignment
|
||||
StubTree stubHardRef = ((PsiFileImpl)file).stubTree
|
||||
public void test_use_green_stub_after_AST_loaded_and_gc_ed() {
|
||||
PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "class A{public static void foo() { }}");
|
||||
assertNotNull(((PsiFileImpl)file).getStubTree());
|
||||
|
||||
assert file.classes[0].nameIdentifier
|
||||
loadAndGcAst(file)
|
||||
assertNoStubLoaded(file)
|
||||
assertNotNull(file.getClasses()[0].getNameIdentifier());
|
||||
loadAndGcAst(file);
|
||||
assertNoStubLoaded(file);
|
||||
|
||||
assert file.classes[0].methods[0].modifierList.hasExplicitModifier(PsiModifier.STATIC)
|
||||
assert !((PsiFileImpl)file).getTreeElement()
|
||||
assertTrue(file.getClasses()[0].getMethods()[0].getModifierList().hasExplicitModifier(PsiModifier.STATIC));
|
||||
assertNull(((PsiFileImpl)file).getTreeElement());
|
||||
}
|
||||
|
||||
void "test use green stub after building it from AST"() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("a.java", "class A<T>{}")
|
||||
PsiClass psiClass = ((PsiJavaFile)file).classes[0]
|
||||
assert psiClass.nameIdentifier
|
||||
public void test_use_green_stub_after_building_it_from_AST() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("a.java", "class A<T>{}");
|
||||
PsiClass psiClass = ((PsiJavaFile)file).getClasses()[0];
|
||||
assertNotNull(psiClass.getNameIdentifier());
|
||||
|
||||
loadAndGcAst(file)
|
||||
loadAndGcAst(file);
|
||||
|
||||
assertNoStubLoaded(file)
|
||||
StubElement hardRefToStub = file.greenStub
|
||||
assert hardRefToStub
|
||||
assert hardRefToStub == file.stub
|
||||
assertNoStubLoaded(file);
|
||||
StubElement<?> hardRefToStub = file.getGreenStub();
|
||||
assertNotNull(hardRefToStub);
|
||||
assertEquals(hardRefToStub, file.getStub());
|
||||
|
||||
loadAndGcAst(file)
|
||||
assert hardRefToStub.is(file.greenStub)
|
||||
loadAndGcAst(file);
|
||||
assertSame(hardRefToStub, file.getGreenStub());
|
||||
|
||||
assert psiClass.typeParameters.length == 1
|
||||
assert !file.treeElement
|
||||
assertEquals(1, psiClass.getTypeParameters().length);
|
||||
assertNull(file.getTreeElement());
|
||||
}
|
||||
|
||||
private static void loadAndGcAst(PsiFile file) {
|
||||
GCWatcher.tracking(file.node).ensureCollected()
|
||||
assert !((PsiFileImpl)file).treeElement
|
||||
GCWatcher.tracking(file.getNode()).ensureCollected();
|
||||
assertNull(((PsiFileImpl)file).getTreeElement());
|
||||
}
|
||||
|
||||
private static assertNoStubLoaded(PsiFile file) {
|
||||
LeakHunter.checkLeak(file, StubTree) { candidate -> candidate.root.psi == file }
|
||||
private static void assertNoStubLoaded(final PsiFile file) {
|
||||
LeakHunter.checkLeak(file, StubTree.class, candidate -> candidate.getRoot().getPsi().equals(file));
|
||||
}
|
||||
|
||||
void "test node has same PSI when loaded in green stub presence"() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("a.java", "class A<T>{}")
|
||||
def stubTree = file.stubTree
|
||||
PsiClass psiClass = ((PsiJavaFile)file).classes[0]
|
||||
assert psiClass.nameIdentifier
|
||||
GCUtil.tryGcSoftlyReachableObjects()
|
||||
public void test_node_has_same_PSI_when_loaded_in_green_stub_presence() {
|
||||
PsiFileImpl file = (PsiFileImpl)myFixture.addFileToProject("a.java", "class A<T>{}");
|
||||
StubTree stubTree = file.getStubTree();
|
||||
PsiClass psiClass = ((PsiJavaFile)file).getClasses()[0];
|
||||
assertNotNull(psiClass.getNameIdentifier());
|
||||
GCUtil.tryGcSoftlyReachableObjects();
|
||||
|
||||
assert stubTree.is(file.greenStubTree)
|
||||
assert file.node.lastChildNode.psi.is(psiClass)
|
||||
assertSame(stubTree, file.getGreenStubTree());
|
||||
assertSame(file.getNode().getLastChildNode().getPsi(), psiClass);
|
||||
}
|
||||
|
||||
void "test load stub from non-file PSI after AST is unloaded"() {
|
||||
PsiJavaFileImpl file = (PsiJavaFileImpl)myFixture.addFileToProject("a.java", "class A<T>{}")
|
||||
def cls = file.classes[0]
|
||||
assert cls.nameIdentifier
|
||||
public void test_load_stub_from_non_file_PSI_after_AST_is_unloaded() {
|
||||
PsiJavaFileImpl file = (PsiJavaFileImpl)myFixture.addFileToProject("a.java", "class A<T>{}");
|
||||
PsiClass cls = file.getClasses()[0];
|
||||
assertNotNull(cls.getNameIdentifier());
|
||||
|
||||
loadAndGcAst(file)
|
||||
loadAndGcAst(file);
|
||||
|
||||
assert ((PsiClassImpl) cls).stub
|
||||
assertNotNull(((PsiClassImpl)cls).getStub());
|
||||
}
|
||||
|
||||
void "test load PSI via stub when AST is gc-ed but PSI exists that was loaded via AST but knows its stub index"() {
|
||||
PsiJavaFileImpl file = (PsiJavaFileImpl)myFixture.addFileToProject("a.java", "class A{}")
|
||||
def cls = file.lastChild
|
||||
assert cls instanceof PsiClass
|
||||
public void test_load_PSI_via_stub_when_AST_is_gc_ed_but_PSI_exists_that_was_loaded_via_AST_but_knows_its_stub_index() {
|
||||
PsiJavaFileImpl file = (PsiJavaFileImpl)myFixture.addFileToProject("a.java", "class A{}");
|
||||
PsiElement cls = file.getLastChild();
|
||||
assertTrue(cls instanceof PsiClass);
|
||||
|
||||
GCUtil.tryGcSoftlyReachableObjects()
|
||||
assert file.treeElement // we still hold a strong reference to AST
|
||||
GCUtil.tryGcSoftlyReachableObjects();
|
||||
assertNotNull(file.getTreeElement());// we still hold a strong reference to AST
|
||||
|
||||
assertEquals(cls, myFixture.findClass("A"));
|
||||
|
||||
assert cls == myFixture.findClass('A')
|
||||
|
||||
// now we know stub index and can GC AST
|
||||
GCUtil.tryGcSoftlyReachableObjects()
|
||||
assert !file.treeElement
|
||||
|
||||
assert cls == myFixture.findClass('A')
|
||||
assert !file.treeElement
|
||||
GCUtil.tryGcSoftlyReachableObjects();
|
||||
assertNull(file.getTreeElement());
|
||||
assertEquals(cls, myFixture.findClass("A"));
|
||||
assertNull(file.getTreeElement());
|
||||
}
|
||||
|
||||
void "test bind stubs to AST after AST has been loaded and gc-ed"() {
|
||||
PsiJavaFileImpl file = (PsiJavaFileImpl)myFixture.addFileToProject("a.java", "class A{}")
|
||||
loadAndGcAst(file)
|
||||
public void test_bind_stubs_to_AST_after_AST_has_been_loaded_and_gc_ed() {
|
||||
PsiJavaFileImpl file = (PsiJavaFileImpl)myFixture.addFileToProject("a.java", "class A{}");
|
||||
loadAndGcAst(file);
|
||||
|
||||
def cls1 = file.classes[0]
|
||||
def cls2 = file.lastChild
|
||||
assert cls1 == cls2
|
||||
PsiClass cls1 = file.getClasses()[0];
|
||||
PsiElement cls2 = file.getLastChild();
|
||||
assertEquals(cls1, cls2);
|
||||
}
|
||||
|
||||
void "test concurrent stub and AST reloading"() {
|
||||
def fileNumbers = 0..<3
|
||||
List<PsiJavaFileImpl> files = fileNumbers.collect {
|
||||
(PsiJavaFileImpl)myFixture.addFileToProject("a${it}.java", "import foo.bar; class A{}")
|
||||
}
|
||||
for (iteration in 0..<3) {
|
||||
GCWatcher.tracking(files.collect { it.node }).ensureCollected()
|
||||
files.each { assert !it.treeElement }
|
||||
|
||||
List<Future<PsiImportList>> stubFutures = []
|
||||
List<Future<PsiImportList>> astFutures = []
|
||||
|
||||
for (i in fileNumbers) {
|
||||
def file = files[i]
|
||||
stubFutures << ApplicationManager.application.executeOnPooledThread({ ReadAction.compute {
|
||||
file.importList
|
||||
} } as Callable)
|
||||
astFutures << ApplicationManager.application.executeOnPooledThread({ ReadAction.compute {
|
||||
PsiTreeUtil.findElementOfClassAtOffset(file, 0, PsiImportList, false)
|
||||
} } as Callable)
|
||||
public void test_concurrent_stub_and_AST_reloading() throws ExecutionException, InterruptedException {
|
||||
int maxFile = 3;
|
||||
final List<PsiJavaFileImpl> files = IntStream.range(0, maxFile).mapToObj(
|
||||
num -> (PsiJavaFileImpl)myFixture.addFileToProject("a" + num + ".java", "import foo.bar; class A{}"))
|
||||
.toList();
|
||||
for (int iteration = 0; iteration <= 3; iteration++) {
|
||||
GCWatcher.tracking(ContainerUtil.map(files, PsiFileImpl::getNode)).ensureCollected();
|
||||
for (PsiJavaFileImpl file : files) {
|
||||
assertNull(file.getTreeElement());
|
||||
}
|
||||
GCUtil.tryGcSoftlyReachableObjects()
|
||||
|
||||
for (i in fileNumbers) {
|
||||
def stubImport = stubFutures[i].get()
|
||||
def astImport = astFutures[i].get()
|
||||
if (stubImport != astImport) {
|
||||
fail("Different import psi in ${files[i].name}: stub=$stubImport, ast=$astImport")
|
||||
List<Future<PsiImportList>> stubFutures = new ArrayList<>();
|
||||
List<Future<PsiImportList>> astFutures = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final PsiJavaFileImpl file = files.get(i);
|
||||
stubFutures.add(ApplicationManager.getApplication()
|
||||
.executeOnPooledThread(() -> ReadAction.compute(() -> file.getImportList())));
|
||||
astFutures.add(ApplicationManager.getApplication()
|
||||
.executeOnPooledThread(
|
||||
() -> ReadAction.compute(() -> PsiTreeUtil.findElementOfClassAtOffset(file, 0, PsiImportList.class, false))));
|
||||
}
|
||||
|
||||
GCUtil.tryGcSoftlyReachableObjects();
|
||||
|
||||
for (int i = 0; i < maxFile; i++) {
|
||||
PsiImportList stubImport = stubFutures.get(i).get();
|
||||
PsiImportList astImport = astFutures.get(i).get();
|
||||
if (!stubImport.equals(astImport)) {
|
||||
TestCase.fail("Different import psi in " +
|
||||
files.get(i).getName() +
|
||||
": stub=" +
|
||||
stubImport +
|
||||
", ast=" +
|
||||
astImport);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void "test DummyHolder calcStubTree does not fail"() {
|
||||
def text = "{ new Runnable() { public void run() {} }; }"
|
||||
def file = JavaPsiFacade.getElementFactory(project).createCodeBlockFromText(text, null).containingFile
|
||||
public void test_DummyHolder_calcStubTree_does_not_fail() {
|
||||
String text = "{ new Runnable() { public void run() {} }; }";
|
||||
PsiFile file = JavaPsiFacade.getElementFactory(getProject()).createCodeBlockFromText(text, null).getContainingFile();
|
||||
|
||||
// main thing is it doesn't fail; DummyHolder.calcStubTree can be changed to null in future if we decide we don't need it
|
||||
def stubTree = assertInstanceOf(file, DummyHolder).calcStubTree()
|
||||
// The main thing is it doesn't fail; DummyHolder.calcStubTree can be changed to null in future if we decide we don't need it
|
||||
StubTree stubTree = UsefulTestCase.assertInstanceOf(file, DummyHolder.class).calcStubTree();
|
||||
|
||||
assert stubTree.plainList.find { it.stubType == JavaStubElementTypes.ANONYMOUS_CLASS }
|
||||
assertTrue(ContainerUtil.exists(stubTree.getPlainList(),
|
||||
it -> JavaStubElementTypes.ANONYMOUS_CLASS.equals(it.getStubType())));
|
||||
}
|
||||
|
||||
void "test stub index is cleared on AST change"() {
|
||||
def clazz = myFixture.addClass("class Foo { int a; }")
|
||||
def field = clazz.fields[0]
|
||||
def file = clazz.containingFile as PsiFileImpl
|
||||
WriteCommandAction.runWriteCommandAction(project, {
|
||||
file.viewProvider.document.insertString(0, ' ')
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
})
|
||||
|
||||
assert file.calcStubTree()
|
||||
public void test_stub_index_is_cleared_on_AST_change() {
|
||||
PsiClass clazz = myFixture.addClass("class Foo { int a; }");
|
||||
PsiField field = clazz.getFields()[0];
|
||||
final PsiFileImpl file = (PsiFileImpl)clazz.getContainingFile();
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
file.getViewProvider().getDocument().insertString(0, " ");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
});
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project, {
|
||||
file.viewProvider.document.insertString(file.text.indexOf('int'), 'void foo();')
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
})
|
||||
|
||||
GCUtil.tryGcSoftlyReachableObjects()
|
||||
assertNotNull(file.calcStubTree());
|
||||
|
||||
assert file.calcStubTree()
|
||||
|
||||
assert field.valid
|
||||
assert field.name == 'a'
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
file.getViewProvider().getDocument().insertString(file.getText().indexOf("int"), "void foo();");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
});
|
||||
|
||||
GCUtil.tryGcSoftlyReachableObjects();
|
||||
|
||||
assertNotNull(file.calcStubTree());
|
||||
|
||||
assertTrue(field.isValid());
|
||||
assertEquals("a", field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.refactoring;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.run;
|
||||
|
||||
import com.intellij.application.options.PathMacrosCollector;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.unscramble;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.unscramble;
|
||||
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
|
||||
Reference in New Issue
Block a user