From db77eb54d7f7d701a4e19a2cda4c2e6a0ab1947d Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 12 Dec 2013 22:32:53 +0400 Subject: [PATCH] Smart completion: java static members, enum members and class object members added --- .../codeInsight/lookup/annotations.xml | 12 ++++ .../jet/lang/descriptors/ClassDescriptor.java | 2 +- .../impl/AbstractClassDescriptor.java | 2 +- .../impl/LazySubstitutingClassDescriptor.java | 2 +- .../jet/plugin/completion/SmartCompletion.kt | 60 +++++++++++++++++++ .../handlers/smart/ClassObjectMethod1.kt | 11 ++++ .../smart/ClassObjectMethod1.kt.after | 11 ++++ .../handlers/smart/ClassObjectMethod2.kt | 11 ++++ .../smart/ClassObjectMethod2.kt.after | 11 ++++ .../smart/JavaStaticFieldInsertImport.kt | 3 + .../JavaStaticFieldInsertImport.kt.after | 5 ++ .../handlers/smart/JavaStaticMethod.kt | 3 + .../handlers/smart/JavaStaticMethod.kt.after | 3 + .../completion/smart/ClassObjectMembers.kt | 21 +++++++ .../smart/ClassObjectMembersForNullable.kt | 19 ++++++ idea/testData/completion/smart/EnumMembers.kt | 13 ++++ .../completion/smart/JavaEnumMembers.kt | 8 +++ .../smart/JavaEnumMembersForNullable.kt | 8 +++ .../completion/smart/JavaStaticFields.kt | 6 ++ .../smart/JavaStaticFieldsForNullable.kt | 6 ++ .../completion/smart/JavaStaticMethods.kt | 5 ++ .../JetSmartCompletionTestGenerated.java | 40 +++++++++++++ .../handlers/SmartCompletionHandlerTest.kt | 4 ++ 23 files changed, 263 insertions(+), 3 deletions(-) create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod1.kt create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod1.kt.after create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod2.kt create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod2.kt.after create mode 100644 idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt create mode 100644 idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt.after create mode 100644 idea/testData/completion/handlers/smart/JavaStaticMethod.kt create mode 100644 idea/testData/completion/handlers/smart/JavaStaticMethod.kt.after create mode 100644 idea/testData/completion/smart/ClassObjectMembers.kt create mode 100644 idea/testData/completion/smart/ClassObjectMembersForNullable.kt create mode 100644 idea/testData/completion/smart/EnumMembers.kt create mode 100644 idea/testData/completion/smart/JavaEnumMembers.kt create mode 100644 idea/testData/completion/smart/JavaEnumMembersForNullable.kt create mode 100644 idea/testData/completion/smart/JavaStaticFields.kt create mode 100644 idea/testData/completion/smart/JavaStaticFieldsForNullable.kt create mode 100644 idea/testData/completion/smart/JavaStaticMethods.kt diff --git a/annotations/com/intellij/codeInsight/lookup/annotations.xml b/annotations/com/intellij/codeInsight/lookup/annotations.xml index ad8a832f1e4..2c3b30ff6ac 100644 --- a/annotations/com/intellij/codeInsight/lookup/annotations.xml +++ b/annotations/com/intellij/codeInsight/lookup/annotations.xml @@ -26,14 +26,26 @@ name='com.intellij.codeInsight.lookup.LookupElementBuilder com.intellij.codeInsight.lookup.LookupElementBuilder setTypeText(java.lang.String, boolean)'> + + + + + + + + + diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java index ff2e14dcaf4..18a42860061 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java @@ -30,7 +30,7 @@ import java.util.List; public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor, ClassOrNamespaceDescriptor { @NotNull - JetScope getMemberScope(List typeArguments); + JetScope getMemberScope(@NotNull List typeArguments); @NotNull JetScope getUnsubstitutedInnerClassesScope(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java index eb1dd61723b..16792c9af7c 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/AbstractClassDescriptor.java @@ -107,7 +107,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { @NotNull @Override - public JetScope getMemberScope(List typeArguments) { + public JetScope getMemberScope(@NotNull List typeArguments) { assert typeArguments.size() == getTypeConstructor().getParameters().size() : "Illegal number of type arguments: expected " + getTypeConstructor().getParameters().size() + " but was " + typeArguments.size() + " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java index cc549a47621..47e1f8d93d0 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java @@ -87,7 +87,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { @NotNull @Override - public JetScope getMemberScope(List typeArguments) { + public JetScope getMemberScope(@NotNull List typeArguments) { JetScope memberScope = original.getMemberScope(typeArguments); if (originalSubstitutor.isEmpty()) { return memberScope; diff --git a/idea/src/org/jetbrains/jet/plugin/completion/SmartCompletion.kt b/idea/src/org/jetbrains/jet/plugin/completion/SmartCompletion.kt index 625ff538c96..51eba98d146 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/SmartCompletion.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/SmartCompletion.kt @@ -19,6 +19,12 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration import org.jetbrains.jet.lang.resolve.name.Name +import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPropertyDescriptor +import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiModifier +import com.intellij.psi.util.PsiTreeUtil trait SmartCompletionData{ fun accepts(descriptor: DeclarationDescriptor): Boolean @@ -49,6 +55,7 @@ fun buildSmartCompletionData(expression: JetSimpleNameExpression, resolveSession if (receiver == null) { typeInstantiationItems(expectedType, resolveSession, bindingContext).toCollection(additionalElements) thisItems(expressionWithType, expectedType, bindingContext).toCollection(additionalElements) + staticMembers(expressionWithType, expectedType, resolveSession, bindingContext).toCollection(additionalElements) } val dataFlowInfo = bindingContext.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expressionWithType) @@ -231,6 +238,59 @@ private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo?, receiver: JetExpres return ProcessDataFlowInfoResult() } +// adds java static members, enum members and members from class object +private fun staticMembers(context: JetExpression, expectedType: JetType, resolveSession: CancelableResolveSession, bindingContext: BindingContext): Iterable { + val classDescriptor = TypeUtils.getClassDescriptor(expectedType) + if (classDescriptor == null) return listOf() + if (classDescriptor.getName().isSpecial()) return listOf() + val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, context) + if (scope == null) return listOf() + + val descriptors = ArrayList() + + val isSuitableCallable: (DeclarationDescriptor) -> Boolean = { it is CallableDescriptor && it.getReturnType()?.let { JetTypeChecker.INSTANCE.isSubtypeOf(it, expectedType) } ?: false } + + if (classDescriptor is JavaClassDescriptor) { + //TODO: shouldn't we have special util to obtain this pseudo package? + val container = classDescriptor.getContainingDeclaration() //TODO: nested classes! + if (container is NamespaceDescriptor) { + val pseudoPackage: NamespaceDescriptor? = container.getMemberScope().getNamespace(classDescriptor.getName()) + if (pseudoPackage != null) { + pseudoPackage.getMemberScope().getAllDescriptors().filterTo(descriptors, isSuitableCallable) + } + } + } + + val classObject = classDescriptor.getClassObjectDescriptor() + if (classObject != null) { + classObject.getDefaultType().getMemberScope().getAllDescriptors().filterTo(descriptors, isSuitableCallable) + } + + if (classDescriptor.getKind() == ClassKind.ENUM_CLASS) { + classDescriptor.getDefaultType().getMemberScope().getAllDescriptors() + .filterTo(descriptors) { it is ClassDescriptor && it.getKind() == ClassKind.ENUM_ENTRY && JetTypeChecker.INSTANCE.isSubtypeOf(it.getDefaultType(), expectedType) } + } + + return descriptors + .filter { !(it is DeclarationDescriptorWithVisibility) || Visibilities.isVisible(it, scope.getContainingDeclaration()) } + .map { + val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, it) + val presentation = LookupElementPresentation() + lookupElement.renderElement(presentation) + var builder = LookupElementBuilder.create(lookupElement.getObject(), classDescriptor.getName().asString() + "." + lookupElement.getLookupString()) + .withIcon(presentation.getIcon()) + .withStrikeoutness(presentation.isStrikeout()) + .withTailText(" (" + DescriptorUtils.getFQName(classDescriptor.getContainingDeclaration()) + ")") + .withTypeText(if (presentation.getTypeText() != "") presentation.getTypeText() else DescriptorRenderer.TEXT.renderType(classDescriptor.getDefaultType())) + if (it is FunctionDescriptor) { + builder = builder.withPresentableText(builder.getLookupString() + "()") + val caretPosition = if (it.getValueParameters().empty) CaretPosition.AFTER_BRACKETS else CaretPosition.IN_BRACKETS + builder = builder.withInsertHandler(JetFunctionInsertHandler(caretPosition, BracketType.PARENTHESIS)) + } + builder + } +} + private fun T?.toList(): List = if (this != null) listOf(this) else listOf() private fun MutableCollection.addAll(iterator: Iterator) { diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod1.kt b/idea/testData/completion/handlers/smart/ClassObjectMethod1.kt new file mode 100644 index 00000000000..dfc201ce219 --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod1.kt @@ -0,0 +1,11 @@ +package sample + +class K { + class object { + fun bar(): K = K() + } +} + +fun foo(){ + val k : K = +} diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod1.kt.after b/idea/testData/completion/handlers/smart/ClassObjectMethod1.kt.after new file mode 100644 index 00000000000..fa8dd4357dd --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod1.kt.after @@ -0,0 +1,11 @@ +package sample + +class K { + class object { + fun bar(): K = K() + } +} + +fun foo(){ + val k : K = K.bar() +} diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod2.kt b/idea/testData/completion/handlers/smart/ClassObjectMethod2.kt new file mode 100644 index 00000000000..c6dd96c5070 --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod2.kt @@ -0,0 +1,11 @@ +package sample + +class K { + class object { + fun bar(p: Int): K = K() + } +} + +fun foo(){ + val k : K = +} diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod2.kt.after b/idea/testData/completion/handlers/smart/ClassObjectMethod2.kt.after new file mode 100644 index 00000000000..369ec744e06 --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod2.kt.after @@ -0,0 +1,11 @@ +package sample + +class K { + class object { + fun bar(p: Int): K = K() + } +} + +fun foo(){ + val k : K = K.bar() +} diff --git a/idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt b/idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt new file mode 100644 index 00000000000..37592e3e6bb --- /dev/null +++ b/idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt @@ -0,0 +1,3 @@ +fun foo(){ + var l : java.util.Locale = +} diff --git a/idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt.after b/idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt.after new file mode 100644 index 00000000000..9b67d7c879c --- /dev/null +++ b/idea/testData/completion/handlers/smart/JavaStaticFieldInsertImport.kt.after @@ -0,0 +1,5 @@ +import java.util.Locale + +fun foo(){ + var l : java.util.Locale = Locale.ENGLISH +} diff --git a/idea/testData/completion/handlers/smart/JavaStaticMethod.kt b/idea/testData/completion/handlers/smart/JavaStaticMethod.kt new file mode 100644 index 00000000000..52ce3361f82 --- /dev/null +++ b/idea/testData/completion/handlers/smart/JavaStaticMethod.kt @@ -0,0 +1,3 @@ +fun foo(){ + val l : java.lang.Thread = +} diff --git a/idea/testData/completion/handlers/smart/JavaStaticMethod.kt.after b/idea/testData/completion/handlers/smart/JavaStaticMethod.kt.after new file mode 100644 index 00000000000..a5741b81458 --- /dev/null +++ b/idea/testData/completion/handlers/smart/JavaStaticMethod.kt.after @@ -0,0 +1,3 @@ +fun foo(){ + val l : java.lang.Thread = Thread.currentThread() +} diff --git a/idea/testData/completion/smart/ClassObjectMembers.kt b/idea/testData/completion/smart/ClassObjectMembers.kt new file mode 100644 index 00000000000..760623bc32a --- /dev/null +++ b/idea/testData/completion/smart/ClassObjectMembers.kt @@ -0,0 +1,21 @@ +package sample + +class K { + class object { + val foo: K = K() + fun bar(): K = K() + val x: String = "" + var kk: K? = null + private val privateVal: K = K() + } +} + +fun foo(){ + val k : K = +} + +// EXIST: { lookupString:"K.foo", itemText:"K.foo", tailText:" (sample)", typeText:"sample.K" } +// EXIST: { lookupString:"K.bar", itemText:"K.bar()", tailText:" (sample)", typeText:"sample.K" } +// ABSENT: K.x +// ABSENT: K.kk +// ABSENT: K.privateVal diff --git a/idea/testData/completion/smart/ClassObjectMembersForNullable.kt b/idea/testData/completion/smart/ClassObjectMembersForNullable.kt new file mode 100644 index 00000000000..05759289160 --- /dev/null +++ b/idea/testData/completion/smart/ClassObjectMembersForNullable.kt @@ -0,0 +1,19 @@ +package sample + +class K { + class object { + val foo: K = K() + fun bar(): K = K() + val x: String = "" + var kk: K? = null + } +} + +fun foo(){ + val k : K? = +} + +// EXIST: { lookupString:"K.foo", itemText:"K.foo", tailText:" (sample)", typeText:"sample.K" } +// EXIST: { lookupString:"K.bar", itemText:"K.bar()", tailText:" (sample)", typeText:"sample.K" } +// ABSENT: K.x +// EXIST: { lookupString:"K.kk", itemText:"K.kk", tailText:" (sample)", typeText:"sample.K?" } diff --git a/idea/testData/completion/smart/EnumMembers.kt b/idea/testData/completion/smart/EnumMembers.kt new file mode 100644 index 00000000000..564a6226a87 --- /dev/null +++ b/idea/testData/completion/smart/EnumMembers.kt @@ -0,0 +1,13 @@ +package sample + +enum class Foo { + X + Y +} + +fun foo(){ + val f : Foo = +} + +// EXIST: { lookupString:"Foo.X", itemText:"Foo.X", tailText:" (sample)", typeText:"sample.Foo" } +// EXIST: { lookupString:"Foo.Y", itemText:"Foo.Y", tailText:" (sample)", typeText:"sample.Foo" } diff --git a/idea/testData/completion/smart/JavaEnumMembers.kt b/idea/testData/completion/smart/JavaEnumMembers.kt new file mode 100644 index 00000000000..c81cc4c1e77 --- /dev/null +++ b/idea/testData/completion/smart/JavaEnumMembers.kt @@ -0,0 +1,8 @@ +import java.lang.annotation.ElementType + +fun foo(){ + val e : ElementType = +} + +// EXIST: { lookupString:"ElementType.TYPE", itemText:"ElementType.TYPE", tailText:" (java.lang.annotation)", typeText:"java.lang.annotation.ElementType" } +// EXIST: { lookupString:"ElementType.FIELD", itemText:"ElementType.FIELD", tailText:" (java.lang.annotation)", typeText:"java.lang.annotation.ElementType" } diff --git a/idea/testData/completion/smart/JavaEnumMembersForNullable.kt b/idea/testData/completion/smart/JavaEnumMembersForNullable.kt new file mode 100644 index 00000000000..a4a5fdd10f0 --- /dev/null +++ b/idea/testData/completion/smart/JavaEnumMembersForNullable.kt @@ -0,0 +1,8 @@ +import java.lang.annotation.ElementType + +fun foo(){ + var e : ElementType? = +} + +// EXIST: { lookupString:"ElementType.TYPE", itemText:"ElementType.TYPE", tailText:" (java.lang.annotation)", typeText:"java.lang.annotation.ElementType" } +// EXIST: { lookupString:"ElementType.FIELD", itemText:"ElementType.FIELD", tailText:" (java.lang.annotation)", typeText:"java.lang.annotation.ElementType" } diff --git a/idea/testData/completion/smart/JavaStaticFields.kt b/idea/testData/completion/smart/JavaStaticFields.kt new file mode 100644 index 00000000000..4d6d8c2e03c --- /dev/null +++ b/idea/testData/completion/smart/JavaStaticFields.kt @@ -0,0 +1,6 @@ +fun foo(){ + var l : java.util.Locale = +} + +// EXIST: { lookupString:"Locale.ENGLISH", itemText:"Locale.ENGLISH", tailText:" (java.util)", typeText:"Locale" } +// EXIST: { lookupString:"Locale.FRENCH", itemText:"Locale.FRENCH", tailText:" (java.util)", typeText:"Locale" } diff --git a/idea/testData/completion/smart/JavaStaticFieldsForNullable.kt b/idea/testData/completion/smart/JavaStaticFieldsForNullable.kt new file mode 100644 index 00000000000..e0bf222b8e0 --- /dev/null +++ b/idea/testData/completion/smart/JavaStaticFieldsForNullable.kt @@ -0,0 +1,6 @@ +fun foo(){ + var l : java.util.Locale? = +} + +// EXIST: { lookupString:"Locale.ENGLISH", itemText:"Locale.ENGLISH", tailText:" (java.util)", typeText:"Locale" } +// EXIST: { lookupString:"Locale.FRENCH", itemText:"Locale.FRENCH", tailText:" (java.util)", typeText:"Locale" } diff --git a/idea/testData/completion/smart/JavaStaticMethods.kt b/idea/testData/completion/smart/JavaStaticMethods.kt new file mode 100644 index 00000000000..907d4ac16ff --- /dev/null +++ b/idea/testData/completion/smart/JavaStaticMethods.kt @@ -0,0 +1,5 @@ +fun foo(){ + val l : java.lang.Thread = +} + +// EXIST: { lookupString:"Thread.currentThread", itemText:"Thread.currentThread()", tailText:" (java.lang)", typeText:"Thread" } diff --git a/idea/tests/org/jetbrains/jet/completion/JetSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JetSmartCompletionTestGenerated.java index 2c23bf587ba..6518c69d089 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetSmartCompletionTestGenerated.java @@ -61,6 +61,16 @@ public class JetSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest("idea/testData/completion/smart/ChainedCall.kt"); } + @TestMetadata("ClassObjectMembers.kt") + public void testClassObjectMembers() throws Exception { + doTest("idea/testData/completion/smart/ClassObjectMembers.kt"); + } + + @TestMetadata("ClassObjectMembersForNullable.kt") + public void testClassObjectMembersForNullable() throws Exception { + doTest("idea/testData/completion/smart/ClassObjectMembersForNullable.kt"); + } + @TestMetadata("Constructor.kt") public void testConstructor() throws Exception { doTest("idea/testData/completion/smart/Constructor.kt"); @@ -81,11 +91,41 @@ public class JetSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest("idea/testData/completion/smart/EmptyPrefix.kt"); } + @TestMetadata("EnumMembers.kt") + public void testEnumMembers() throws Exception { + doTest("idea/testData/completion/smart/EnumMembers.kt"); + } + @TestMetadata("InsideIdentifier.kt") public void testInsideIdentifier() throws Exception { doTest("idea/testData/completion/smart/InsideIdentifier.kt"); } + @TestMetadata("JavaEnumMembers.kt") + public void testJavaEnumMembers() throws Exception { + doTest("idea/testData/completion/smart/JavaEnumMembers.kt"); + } + + @TestMetadata("JavaEnumMembersForNullable.kt") + public void testJavaEnumMembersForNullable() throws Exception { + doTest("idea/testData/completion/smart/JavaEnumMembersForNullable.kt"); + } + + @TestMetadata("JavaStaticFields.kt") + public void testJavaStaticFields() throws Exception { + doTest("idea/testData/completion/smart/JavaStaticFields.kt"); + } + + @TestMetadata("JavaStaticFieldsForNullable.kt") + public void testJavaStaticFieldsForNullable() throws Exception { + doTest("idea/testData/completion/smart/JavaStaticFieldsForNullable.kt"); + } + + @TestMetadata("JavaStaticMethods.kt") + public void testJavaStaticMethods() throws Exception { + doTest("idea/testData/completion/smart/JavaStaticMethods.kt"); + } + @TestMetadata("MethodCallArgument.kt") public void testMethodCallArgument() throws Exception { doTest("idea/testData/completion/smart/MethodCallArgument.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTest.kt b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTest.kt index 9efd3d36dd7..79ec10c8eca 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTest.kt +++ b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTest.kt @@ -42,4 +42,8 @@ public class SmartCompletionHandlerTest() : CompletionHandlerTestBase() { fun testConstructorForNullable() = doTest() fun testConstructorForJavaClass() = doTest() //fun testConstructorInsertsImport() = doTest() //TODO + fun testJavaStaticMethod() = doTest(1, "Thread.currentThread", null, '\n') + fun testClassObjectMethod1() = doTest(1, "K.bar", null, '\n') + fun testClassObjectMethod2() = doTest(1, "K.bar", null, '\n') + //fun testJavaStaticFieldInsertImport() = doTest(1, "Locale.ENGLISH", null, '\n') //TODO }