Allow to shorten class member references
This commit is contained in:
@@ -16,6 +16,10 @@ import java.util.HashSet;
|
|||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.util.containers.HashMap
|
import com.intellij.util.containers.HashMap
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPropertyDescriptor
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyPackageFragmentForJavaClass
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor
|
||||||
|
|
||||||
public object ShortenReferences {
|
public object ShortenReferences {
|
||||||
public fun process(element: JetElement) {
|
public fun process(element: JetElement) {
|
||||||
@@ -101,16 +105,18 @@ public object ShortenReferences {
|
|||||||
val referenceExpression = userType.getReferenceExpression()
|
val referenceExpression = userType.getReferenceExpression()
|
||||||
if (referenceExpression == null) return false
|
if (referenceExpression == null) return false
|
||||||
|
|
||||||
val target = bindingContext(referenceExpression).get(BindingContext.REFERENCE_TARGET, referenceExpression)
|
val target = bindingContext(referenceExpression).get(BindingContext.REFERENCE_TARGET, referenceExpression)?.let { desc ->
|
||||||
|
if (desc is ConstructorDescriptor) desc.getContainingDeclaration() else desc
|
||||||
|
}
|
||||||
if (target == null) return false
|
if (target == null) return false
|
||||||
// references to nested classes should be shortened when visiting qualifier
|
|
||||||
if (target.getContainingDeclaration() is ClassDescriptor) return false
|
|
||||||
|
|
||||||
val typeReference = PsiTreeUtil.getParentOfType(userType, javaClass<JetTypeReference>())!!
|
val typeReference = PsiTreeUtil.getParentOfType(userType, javaClass<JetTypeReference>())!!
|
||||||
val scope = resolveSession.resolveToElement(typeReference).get(BindingContext.TYPE_RESOLUTION_SCOPE, typeReference)!!
|
val scope = resolveSession.resolveToElement(typeReference).get(BindingContext.TYPE_RESOLUTION_SCOPE, typeReference)!!
|
||||||
val name = target.getName()
|
val name = target.getName()
|
||||||
val targetByName = scope.getClassifier(name)
|
val targetByName = scope.getClassifier(name)
|
||||||
if (targetByName == null) {
|
if (targetByName == null) {
|
||||||
|
if (target.getContainingDeclaration() is ClassDescriptor) return false
|
||||||
|
|
||||||
addImportIfNeeded(target, file)
|
addImportIfNeeded(target, file)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -147,21 +153,41 @@ public object ShortenReferences {
|
|||||||
|
|
||||||
private fun processDotQualifiedExpression(qualifiedExpression: JetDotQualifiedExpression): PsiElement {
|
private fun processDotQualifiedExpression(qualifiedExpression: JetDotQualifiedExpression): PsiElement {
|
||||||
val selectorExpression = qualifiedExpression.getSelectorExpression()
|
val selectorExpression = qualifiedExpression.getSelectorExpression()
|
||||||
|
|
||||||
if (selectorExpression is JetCallExpression) {
|
if (selectorExpression is JetCallExpression) {
|
||||||
val calleeExpression = selectorExpression.getCalleeExpression()
|
val calleeExpression = selectorExpression.getCalleeExpression()
|
||||||
if (calleeExpression is JetReferenceExpression) {
|
if (calleeExpression is JetReferenceExpression) {
|
||||||
|
val bindingContext = bindingContext(calleeExpression)
|
||||||
|
|
||||||
val targetClass = instantiatedClass(calleeExpression)
|
val targetClass = instantiatedClass(calleeExpression)
|
||||||
if (targetClass != null) {
|
if (targetClass != null) return shortenIfPossibleByDescriptor(qualifiedExpression, targetClass, bindingContext)
|
||||||
return shortenIfPossible(qualifiedExpression, targetClass, bindingContext(calleeExpression))
|
|
||||||
}
|
return shortenIfPossible(qualifiedExpression, calleeExpression, bindingContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (selectorExpression is JetReferenceExpression) {
|
else if (selectorExpression is JetReferenceExpression) {
|
||||||
val bindingContext = bindingContext(selectorExpression)
|
return shortenIfPossible(qualifiedExpression, selectorExpression, bindingContext(selectorExpression))
|
||||||
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, selectorExpression)
|
}
|
||||||
if (target is ClassDescriptor || target is PackageViewDescriptor) { //TODO: should we ever add imports to real packages?
|
|
||||||
return shortenIfPossible(qualifiedExpression, target, bindingContext)
|
return qualifiedExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shortenIfPossible(
|
||||||
|
qualifiedExpression: JetDotQualifiedExpression,
|
||||||
|
refExpression: JetReferenceExpression,
|
||||||
|
bindingContext: BindingContext
|
||||||
|
): PsiElement {
|
||||||
|
val receiverExpression = qualifiedExpression.getReceiverExpression()
|
||||||
|
val target = bindingContext.get(BindingContext.REFERENCE_TARGET, refExpression)
|
||||||
|
if (target != null) {
|
||||||
|
if ((target is JavaPropertyDescriptor || target is JavaMethodDescriptor) && receiverExpression is JetDotQualifiedExpression) {
|
||||||
|
val containingDescriptor = target.getContainingDeclaration()
|
||||||
|
if (containingDescriptor is LazyPackageFragmentForJavaClass) {
|
||||||
|
return shortenIfPossibleByDescriptor(receiverExpression, containingDescriptor.getCorrespondingClass(), bindingContext)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return shortenIfPossibleByDescriptor(qualifiedExpression, target, bindingContext)
|
||||||
}
|
}
|
||||||
return qualifiedExpression
|
return qualifiedExpression
|
||||||
}
|
}
|
||||||
@@ -194,9 +220,10 @@ public object ShortenReferences {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shortenIfPossible(qualifiedExpression: JetDotQualifiedExpression, targetClassOrPackage: DeclarationDescriptor, bindingContext: BindingContext): PsiElement {
|
private fun shortenIfPossibleByDescriptor(qualifiedExpression: JetDotQualifiedExpression, targetDescriptor: DeclarationDescriptor, bindingContext: BindingContext): PsiElement {
|
||||||
// references to nested classes should be shortened when visiting qualifier
|
val isClassMember = targetDescriptor.getContainingDeclaration() is ClassDescriptor
|
||||||
if (targetClassOrPackage.getContainingDeclaration() is ClassDescriptor) return qualifiedExpression
|
val isUsageInImport = qualifiedExpression.getParentByType(javaClass<JetImportDirective>()) != null
|
||||||
|
val isClassOrPackage = targetDescriptor is ClassDescriptor || targetDescriptor is PackageViewDescriptor
|
||||||
|
|
||||||
val referenceExpression = referenceExpression(qualifiedExpression.getSelectorExpression())!!
|
val referenceExpression = referenceExpression(qualifiedExpression.getSelectorExpression())!!
|
||||||
val resolveBefore = resolveState(referenceExpression, bindingContext)
|
val resolveBefore = resolveState(referenceExpression, bindingContext)
|
||||||
@@ -214,7 +241,9 @@ public object ShortenReferences {
|
|||||||
return newExpression.replace(copy) // revert shortening
|
return newExpression.replace(copy) // revert shortening
|
||||||
}
|
}
|
||||||
|
|
||||||
addImportIfNeeded(targetClassOrPackage, file)
|
if (isUsageInImport || isClassMember || !isClassOrPackage) return newExpression.replace(copy) // revert shortening
|
||||||
|
|
||||||
|
addImportIfNeeded(targetDescriptor, file)
|
||||||
return newExpression
|
return newExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A {
|
||||||
|
static class B {
|
||||||
|
static void foo() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
<selection>A.B.foo()</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
B.foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A {
|
||||||
|
public class B {
|
||||||
|
public B(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar(s: String) {
|
||||||
|
<selection>val t: A.B = A().B(s)</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar(s: String) {
|
||||||
|
val t: A.B = A().B(s)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A {
|
||||||
|
public class B {
|
||||||
|
public B(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar(s: String) {
|
||||||
|
<selection>val t: A.B = A().B(s)</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar(s: String) {
|
||||||
|
val t: B = A().B(s)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A {
|
||||||
|
public static class B {
|
||||||
|
public B(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar(s: String) {
|
||||||
|
<selection>val t: A.B = A.B(s)</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar(s: String) {
|
||||||
|
val t: A.B = A.B(s)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A {
|
||||||
|
public static class B {
|
||||||
|
public B(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar(s: String) {
|
||||||
|
<selection>val t: A.B = A.B(s)</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar(s: String) {
|
||||||
|
val t: B = B(s)
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class A {
|
||||||
|
public static int X = 10;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar() {
|
||||||
|
<selection>A.X = 100</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar() {
|
||||||
|
A.X = 100
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class A {
|
||||||
|
public static int X = 10;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
<selection>A.X = 100</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
X = 100
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class A {
|
||||||
|
public static void foo(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar(s: String) {
|
||||||
|
<selection>A.foo(s)</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar(s: String) {
|
||||||
|
A.foo(s)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class A {
|
||||||
|
public static void foo(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar(s: String) {
|
||||||
|
<selection>A.foo(s)</selection>
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import A.*
|
||||||
|
|
||||||
|
fun bar(s: String) {
|
||||||
|
foo(s)
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
class A : <selection>java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock</selection>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
|
|
||||||
|
class A : ReentrantReadWriteLock.WriteLock
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: <selection>test.A()</selection> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -36,6 +36,10 @@ abstract class AbstractShortenRefsTest : LightCodeInsightFixtureTestCase() {
|
|||||||
if (File(dependencyPath).exists()) {
|
if (File(dependencyPath).exists()) {
|
||||||
fixture.configureByFile(dependencyPath)
|
fixture.configureByFile(dependencyPath)
|
||||||
}
|
}
|
||||||
|
val javaDependencyPath = testPath.replace(".kt", ".dependency.java")
|
||||||
|
if (File(javaDependencyPath).exists()) {
|
||||||
|
fixture.configureByFile(javaDependencyPath)
|
||||||
|
}
|
||||||
|
|
||||||
fixture.configureByFile(testPath)
|
fixture.configureByFile(testPath)
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import org.jetbrains.jet.shortenRefs.AbstractShortenRefsTest;
|
|||||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("idea/testData/shortenRefs")
|
@TestMetadata("idea/testData/shortenRefs")
|
||||||
@InnerTestClasses({ShortenRefsTestGenerated.Constructor.class, ShortenRefsTestGenerated.Type.class})
|
@InnerTestClasses({ShortenRefsTestGenerated.Constructor.class, ShortenRefsTestGenerated.Java.class, ShortenRefsTestGenerated.Type.class})
|
||||||
public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
||||||
public void testAllFilesPresentInShortenRefs() throws Exception {
|
public void testAllFilesPresentInShortenRefs() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/shortenRefs"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/shortenRefs"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
||||||
@@ -88,6 +88,11 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
|||||||
doTest("idea/testData/shortenRefs/constructor/NestedClass.kt");
|
doTest("idea/testData/shortenRefs/constructor/NestedClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NestedClassWithImport.kt")
|
||||||
|
public void testNestedClassWithImport() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/constructor/NestedClassWithImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NoImportNeeded.kt")
|
@TestMetadata("NoImportNeeded.kt")
|
||||||
public void testNoImportNeeded() throws Exception {
|
public void testNoImportNeeded() throws Exception {
|
||||||
doTest("idea/testData/shortenRefs/constructor/NoImportNeeded.kt");
|
doTest("idea/testData/shortenRefs/constructor/NoImportNeeded.kt");
|
||||||
@@ -105,6 +110,54 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/shortenRefs/java")
|
||||||
|
public static class Java extends AbstractShortenRefsTest {
|
||||||
|
public void testAllFilesPresentInJava() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/shortenRefs/java"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerClassNoImports.kt")
|
||||||
|
public void testInnerClassNoImports() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/innerClassNoImports.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerClassOnDemandImport.kt")
|
||||||
|
public void testInnerClassOnDemandImport() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/innerClassOnDemandImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("staticClassNoImports.kt")
|
||||||
|
public void testStaticClassNoImports() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/staticClassNoImports.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("staticClassOnDemandImport.kt")
|
||||||
|
public void testStaticClassOnDemandImport() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/staticClassOnDemandImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("staticFieldNoImports.kt")
|
||||||
|
public void testStaticFieldNoImports() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/staticFieldNoImports.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("staticFieldOnDemandImport.kt")
|
||||||
|
public void testStaticFieldOnDemandImport() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/staticFieldOnDemandImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("staticMethodNoImports.kt")
|
||||||
|
public void testStaticMethodNoImports() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/staticMethodNoImports.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("staticMethodOnDemandImport.kt")
|
||||||
|
public void testStaticMethodOnDemandImport() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/java/staticMethodOnDemandImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/shortenRefs/type")
|
@TestMetadata("idea/testData/shortenRefs/type")
|
||||||
public static class Type extends AbstractShortenRefsTest {
|
public static class Type extends AbstractShortenRefsTest {
|
||||||
public void testAllFilesPresentInType() throws Exception {
|
public void testAllFilesPresentInType() throws Exception {
|
||||||
@@ -116,6 +169,11 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
|||||||
doTest("idea/testData/shortenRefs/type/ClassSameNameAsPackage.kt");
|
doTest("idea/testData/shortenRefs/type/ClassSameNameAsPackage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("delegationSpecifier.kt")
|
||||||
|
public void testDelegationSpecifier() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/type/delegationSpecifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("FunctionType.kt")
|
@TestMetadata("FunctionType.kt")
|
||||||
public void testFunctionType() throws Exception {
|
public void testFunctionType() throws Exception {
|
||||||
doTest("idea/testData/shortenRefs/type/FunctionType.kt");
|
doTest("idea/testData/shortenRefs/type/FunctionType.kt");
|
||||||
@@ -146,6 +204,11 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
|||||||
doTest("idea/testData/shortenRefs/type/NestedClass.kt");
|
doTest("idea/testData/shortenRefs/type/NestedClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NestedClassRefInImport.kt")
|
||||||
|
public void testNestedClassRefInImport() throws Exception {
|
||||||
|
doTest("idea/testData/shortenRefs/type/NestedClassRefInImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NoImportNeeded.kt")
|
@TestMetadata("NoImportNeeded.kt")
|
||||||
public void testNoImportNeeded() throws Exception {
|
public void testNoImportNeeded() throws Exception {
|
||||||
doTest("idea/testData/shortenRefs/type/NoImportNeeded.kt");
|
doTest("idea/testData/shortenRefs/type/NoImportNeeded.kt");
|
||||||
@@ -182,6 +245,7 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
|||||||
TestSuite suite = new TestSuite("ShortenRefsTestGenerated");
|
TestSuite suite = new TestSuite("ShortenRefsTestGenerated");
|
||||||
suite.addTestSuite(ShortenRefsTestGenerated.class);
|
suite.addTestSuite(ShortenRefsTestGenerated.class);
|
||||||
suite.addTestSuite(Constructor.class);
|
suite.addTestSuite(Constructor.class);
|
||||||
|
suite.addTestSuite(Java.class);
|
||||||
suite.addTestSuite(Type.class);
|
suite.addTestSuite(Type.class);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user