1 /******************************************************************************* 2 * Copyright (c) 2000, 2020 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.ui.tests.refactoring.typeconstraints; 15 16 import static org.junit.Assert.assertEquals; 17 import static org.junit.Assert.assertTrue; 18 19 import java.util.ArrayList; 20 import java.util.Arrays; 21 import java.util.List; 22 23 import org.junit.Rule; 24 import org.junit.Test; 25 26 import org.eclipse.jdt.core.ICompilationUnit; 27 import org.eclipse.jdt.core.IPackageFragment; 28 import org.eclipse.jdt.core.dom.CompilationUnit; 29 30 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ASTCreator; 31 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ConstraintCollector; 32 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ConstraintOperator; 33 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ConstraintVariable; 34 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ConstraintVariableFactory; 35 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.FullConstraintCreator; 36 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ITypeConstraint; 37 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.TypeConstraintFactory; 38 39 import org.eclipse.jdt.ui.tests.refactoring.GenericRefactoringTest; 40 import org.eclipse.jdt.ui.tests.refactoring.rules.RefactoringTestSetup; 41 42 public class TypeConstraintTests extends GenericRefactoringTest { 43 private static final String PATH= "TypeConstraints/"; 44 45 @Override getRefactoringPath()46 protected String getRefactoringPath() { 47 return PATH; 48 } 49 50 @Rule 51 public RefactoringTestSetup rts= new RefactoringTestSetup(); 52 getSimpleTestFileName()53 private String getSimpleTestFileName(){ 54 return "A_" + tn.getMethodName() + ".java"; 55 } 56 getTestFileName()57 private String getTestFileName(){ 58 return TEST_PATH_PREFIX + getRefactoringPath() + getSimpleTestFileName(); 59 } 60 createCUfromTestFile(IPackageFragment pack)61 private ICompilationUnit createCUfromTestFile(IPackageFragment pack) throws Exception { 62 return createCU(pack, getSimpleTestFileName(), getFileContents(getTestFileName())); 63 } 64 getCuNode()65 private CompilationUnit getCuNode() throws Exception { 66 ICompilationUnit cu= createCUfromTestFile(getPackageP()); 67 return ASTCreator.createAST(cu, null); 68 } 69 numberHelper(int number)70 private void numberHelper(int number) throws Exception { 71 CompilationUnit cuNode= getCuNode(); 72 ConstraintCollector collector= getCollector(); 73 cuNode.accept(collector); 74 ITypeConstraint[] constraints= collector.getConstraints(); 75 assertEquals(Arrays.asList(constraints).toString(), number, constraints.length); 76 } 77 78 @Test testNumber0()79 public void testNumber0() throws Exception{ 80 numberHelper(2); 81 } 82 83 @Test testNumber1()84 public void testNumber1() throws Exception{ 85 numberHelper(3); 86 } 87 88 @Test testNumber2()89 public void testNumber2() throws Exception{ 90 numberHelper(10); 91 } 92 getCollector()93 private ConstraintCollector getCollector() { 94 TypeConstraintFactory factory = new TypeConstraintFactory(){ 95 @Override 96 public boolean filter(ConstraintVariable v1, ConstraintVariable v2, ConstraintOperator o){ 97 return false; 98 } 99 }; 100 ConstraintCollector collector= new ConstraintCollector(new FullConstraintCreator(new ConstraintVariableFactory(), factory)); 101 return collector; 102 } 103 allToStrings(Object[] elements)104 private static List<String> allToStrings(Object[] elements) { 105 String[] strings= new String[elements.length]; 106 for (int i= 0; i < elements.length; i++) { 107 strings[i]= elements[i].toString(); 108 } 109 return new ArrayList<>(Arrays.asList(strings));//want to be able to remove stuff from it 110 } 111 testConstraints(String[] constraintStrings)112 private void testConstraints(String[] constraintStrings) throws Exception{ 113 CompilationUnit cuNode= getCuNode(); 114 ConstraintCollector collector= getCollector(); 115 cuNode.accept(collector); 116 ITypeConstraint[] constraints= collector.getConstraints(); 117 118 List<String> externals= allToStrings(constraints); 119 assertEquals("length", constraintStrings.length, constraints.length); 120 for (String constraintString : constraintStrings) { 121 assertTrue("missing constraint:" + constraintString, externals.remove(constraintString)); 122 } 123 } 124 125 @Test testConstraints0()126 public void testConstraints0() throws Exception{ 127 String[] strings= {"[null] <= [a0]", "[a0] <= [a1]", "[a0] =^= A", "[a1] =^= A", "Decl(A:f()) =^= p.A"}; 128 testConstraints(strings); 129 } 130 131 @Test testConstraints1()132 public void testConstraints1() throws Exception{ 133 String[] strings= {"[null] <= [a0]", "[a0] == [a1]", "[a0] =^= A", "[a1] =^= A", "Decl(A:a0) =^= p.A", "Decl(A:a1) =^= p.A"}; 134 testConstraints(strings); 135 } 136 137 @Test testConstraints2()138 public void testConstraints2() throws Exception{ 139 String[] strings= {"[null] <= [a0]", "[(A)a0] =^= A", "[(A)a0] <= [a1]", "[a0] <= [(A)a0] or [(A)a0] <= [a0]", "[a0] =^= A", "[a1] =^= A", "Decl(A:f()) =^= p.A"}; 140 testConstraints(strings); 141 } 142 143 @Test testConstraints3()144 public void testConstraints3() throws Exception{ 145 String[] strings= {"[null] <= [a]", "[null] <= [b]", "[a] == [b]", "[a] =^= A", "[b] =^= A", "Decl(A:f()) =^= p.A"}; 146 testConstraints(strings); 147 } 148 149 @Test testConstraints4()150 public void testConstraints4() throws Exception{ 151 String[] strings= {"[as0] =^= A[]", "[a0] <= A", "[{a0}] <= [as0]", "Decl(A:f()) =^= p.A", "[null] <= [a0]", "[a0] =^= A"}; 152 testConstraints(strings); 153 } 154 155 @Test testConstraints5()156 public void testConstraints5() throws Exception{ 157 String[] strings= {"[as0] =^= A[]", "Decl(A:f()) =^= p.A", "[a0] <= A", "[a0] =^= A", "[null] <= [a0]", "[new A[]{a0}] <= [as0]"}; 158 testConstraints(strings); 159 } 160 161 @Test testConstraints6()162 public void testConstraints6() throws Exception{ 163 String[] strings= {"Decl(A:f()) =^= p.A", "Decl(A:A(A)) =^= p.A", "[new A(a0)] =^= p.A", "[a0] <= [Parameter(0,A:A(A))]", "[a1] =^= A", "[a] =^= A", "[a0] =^= A", "[null] <= [a0]", "[new A(a0)] <= [a1]", "[Parameter(0,A:A(A))] =^= [a]"}; 164 testConstraints(strings); 165 } 166 167 @Test testConstraints7()168 public void testConstraints7() throws Exception{ 169 String[] strings= {"Decl(A:A()) =^= p.A", "Decl(A:A(A)) =^= p.A", "[null] <= [Parameter(0,A:A(A))]", "[Parameter(0,A:A(A))] =^= [a]", "[a] =^= A"}; 170 testConstraints(strings); 171 } 172 173 @Test testConstraints8()174 public void testConstraints8() throws Exception{ 175 String[] strings= {"Decl(A:x) =^= p.A", "Decl(A:f()) =^= p.A", "[x] =^= java.lang.Object", "Decl(A:aField) =^= p.A", "[this] <= [x]", "[aField] =^= A", "[x] =^= Object", "[this] =^= p.A", "[aField] <= Decl(A:x)"}; 176 testConstraints(strings); 177 } 178 179 @Test testConstraints9()180 public void testConstraints9() throws Exception{ 181 String[] strings= {"Decl(A:f()) =^= p.A", "[a] =^= A", "[x] =^= boolean", "[a instanceof A] <= [x]", "[null] <= [a]", "[a] <= A or A <= [a]"}; 182 testConstraints(strings); 183 } 184 185 @Test testConstraints10()186 public void testConstraints10() throws Exception{ 187 String[] strings= {"[null] <= [A:f1()]_returnType", "Decl(A:f1()) =^= p.A", "[A:f1()]_returnType =^= A[]"}; 188 testConstraints(strings); 189 } 190 191 @Test testConstraints11()192 public void testConstraints11() throws Exception{ 193 String[] strings= {"[null] <= [A:f(A, Object)]_returnType", "[Parameter(1,B:f(A, Object))] =^= [a4]", 194 "[B:f(A, Object)]_returnType =^= A", "Decl(B:f(A, Object)) < Decl(A:f(A, Object))", 195 "[Parameter(1,A:f(A, Object))] == [Parameter(1,B:f(A, Object))]", 196 "[Parameter(0,A:f(A, Object))] == [Parameter(0,B:f(A, Object))]", 197 "[A:f(A, Object)]_returnType == [B:f(A, Object)]_returnType", 198 "[Parameter(0,B:f(A, Object))] =^= [a3]", 199 "[Parameter(0,A:f(A, Object))] =^= [a0]", "Decl(A:f(A, Object)) =^= p.A", 200 "[null] <= [B:f(A, Object)]_returnType", "[Parameter(1,A:f(A, Object))] =^= [a1]", 201 "[A:f(A, Object)]_returnType =^= A", "Decl(B:f(A, Object)) =^= p.B", 202 "[a3] =^= A", "[a0] =^= A", "[a1] =^= Object", "[a4] =^= Object"}; 203 testConstraints(strings); 204 } 205 206 @Test testConstraints12()207 public void testConstraints12() throws Exception{ 208 String[] strings= { "Decl(B:f(A, Object)) =^= p.B", "[Parameter(1,B:f(A, Object))] =^= [a4]", "[B:f(A, Object)]_returnType =^= A", "[null] <= [B:f(A, Object)]_returnType", "[A:f(A, Object)]_returnType =^= A", "[Parameter(1,A:f(A, Object))] =^= [a1]", "Decl(A:f(A, Object)) =^= p.A", "[Parameter(0,B:f(A, Object))] =^= [a3]", "[null] <= [A:f(A, Object)]_returnType", "[Parameter(0,A:f(A, Object))] =^= [a0]", "[a3] =^= A", "[a0] =^= A", "[a1] =^= Object", "[a4] =^= Object" }; 209 testConstraints(strings); 210 } 211 212 @Test testConstraints13()213 public void testConstraints13() throws Exception{ 214 String[] strings= {"Decl(B:f(A, Object)) =^= p.B", "[Parameter(1,B:f(A, Object))] =^= [a4]", "[B:f(A, Object)]_returnType =^= A", "[null] <= [B:f(A, Object)]_returnType", "[A:f(A, Object)]_returnType =^= A", "[Parameter(1,A:f(A, Object))] =^= [a1]", "Decl(A:f(A, Object)) =^= p.A", "[Parameter(0,B:f(A, Object))] =^= [a3]", "[null] <= [A:f(A, Object)]_returnType", "[Parameter(0,A:f(A, Object))] =^= [a0]", "[a3] =^= A", "[a0] =^= A", "[a1] =^= Object", "[a4] =^= Object"}; 215 testConstraints(strings); 216 } 217 218 @Test testConstraints14()219 public void testConstraints14() throws Exception{ 220 String[] strings= {"[A:f(A)]_returnType == [B:f(A)]_returnType", "[Parameter(0,A:f(A))] == [Parameter(0,B:f(A))]", "[B:f(A)]_returnType =^= A", "Decl(B:f(A)) < Decl(A:f(A))", "[A:f(A)]_returnType =^= A", "Decl(B:f(A)) < Decl(I:f(A))", "[null] <= [A:f(A)]_returnType", "[Parameter(0,A:f(A))] =^= [a0]", "[I:f(A)]_returnType =^= A", "Decl(A:f(A)) =^= p.A", "[ax] =^= B", "[Parameter(0,B:f(A))] =^= [a3]", "[null] <= [B:f(A)]_returnType", "[a3] <= [Parameter(0,B:f(A))]", "[ax.f(a3)] =^= [B:f(A)]_returnType", "[ax] <= Decl(I:f(A)) or [ax] <= Decl(A:f(A))", "Decl(B:f(A)) =^= p.B", "[I:f(A)]_returnType == [B:f(A)]_returnType", "[Parameter(0,I:f(A))] == [Parameter(0,B:f(A))]", "[null] <= [ax]", "[Parameter(0,I:f(A))] =^= [ai]", "Decl(I:f(A)) =^= p.I", "[a3] =^= A", "[a0] =^= A", "[ai] =^= A"}; 221 testConstraints(strings); 222 } 223 224 @Test testConstraints15()225 public void testConstraints15() throws Exception{ 226 String[] strings= {"[Parameter(0,A:f(A))] =^= [a0]", "[I:f(A)]_returnType == [B:f(A)]_returnType", "[Parameter(0,I:f(A))] == [Parameter(0,B:f(A))]", "[null] <= [A:f(A)]_returnType", "[A:f(A)]_returnType == [B:f(A)]_returnType", "[Parameter(0,A:f(A))] == [Parameter(0,B:f(A))]", "Decl(B:f(A)) < Decl(A:f(A))", "[super.f(a3)] =^= [A:f(A)]_returnType", "Decl(A:f(A)) =^= p.A", "[null] <= [B:f(A)]_returnType", "[Parameter(0,I:f(A))] =^= [ai]", "[Parameter(0,B:f(A))] =^= [a3]", "[A:f(A)]_returnType =^= A", "Decl(B:f(A)) =^= p.B", "Decl(I:f(A)) =^= p.I", "Decl(B:f(A)) < Decl(I:f(A))", "[a3] <= [Parameter(0,A:f(A))]", "[I:f(A)]_returnType =^= A", "[B:f(A)]_returnType =^= A", "[a3] =^= A", "[a0] =^= A", "[ai] =^= A"}; 227 testConstraints(strings); 228 } 229 230 @Test testConstraints16()231 public void testConstraints16() throws Exception{ 232 String[] strings= {"Decl(A:aField) =^= p.A", "Decl(A:f()) =^= p.A", "[this] =^= p.A", "[this] =^= p.A", "[this] <= [aTemp]", "[this] <= [aField]", "[this] <= [a]", "[a] =^= A", "[aField] =^= A", "[aTemp] =^= A", "[this] =^= p.A"}; 233 testConstraints(strings); 234 } 235 236 @Test testConstraints17()237 public void testConstraints17() throws Exception{ 238 String[] strings= {"Decl(A:f()) =^= p.A", "[null] <= [a]", "[A:f()]_returnType =^= A", "[a] =^= A", "[a] <= [A:f()]_returnType"}; 239 testConstraints(strings); 240 } 241 242 @Test testConstraints18()243 public void testConstraints18() throws Exception{ 244 String[] strings= {"[Parameter(0,B:B(A))] =^= [a1]", "Decl(B:B(A)) =^= p.B", "[Parameter(0,A:A(A))] =^= [a0]", "Decl(A:A(A)) =^= p.A", "[a1] <= [Parameter(0,A:A(A))]", "[a1] =^= A", "[a0] =^= A"}; 245 testConstraints(strings); 246 } 247 248 @Test testConstraints19()249 public void testConstraints19() throws Exception{ 250 String[] strings= {"[aField] =^= p.A", "[a] =^= A", "Decl(B:f()) =^= p.B", "[a] <= [aField]", "[null] <= [a]", "Decl(A:aField) =^= p.A", "[aField] =^= A"}; 251 testConstraints(strings); 252 } 253 254 @Test testConstraints20()255 public void testConstraints20() throws Exception{ 256 String[] strings= {"Decl(B:aField) =^= p.B", "Decl(A:aField) =^= p.A", "Decl(B:aField) < Decl(A:aField)", "[aField] =^= A", "[aField] =^= A"}; 257 testConstraints(strings); 258 } 259 260 @Test testConstraints21()261 public void testConstraints21() throws Exception{ 262 String[] strings= {"Decl(A:f2(A[])) =^= p.A", "[Parameter(0,A:f2(A[]))] =^= [as]", "[as] =^= A[]"}; 263 testConstraints(strings); 264 } 265 266 @Test testConstraints22()267 public void testConstraints22() throws Exception{ 268 String[] strings= {"[null] <= [A:f(A, Object)]_returnType", "[Parameter(0,A:f(A, Object))] =^= [a0]", "[Parameter(1,A:f(A, Object))] =^= [a1]", "[A:f(A, Object)]_returnType =^= A", "Decl(A:f(A, Object)) =^= p.A", "[a1] =^= Object", "[a0] =^= A"}; 269 testConstraints(strings); 270 } 271 272 @Test testConstraints23()273 public void testConstraints23() throws Exception{ 274 //test for bug 41271 NullPointerException dumping set of ITypeConstraints to System.out 275 String[] strings= {"[args.length] =^= int", "[0] <= [i]", "[i] =^= int", "[args] <= Decl((array type):length)", "[args] =^= String[]", "[Parameter(0,Test1:main(String[]))] =^= [args]", "Decl(Test1:main(String[])) =^= p.Test1"}; 276 testConstraints(strings); 277 } 278 } 279