| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.ui.tests.core.source; |
| |
| import java.lang.reflect.Modifier; |
| |
| import junit.framework.Assert; |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IField; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.IMethodBinding; |
| import org.eclipse.jdt.core.dom.ITypeBinding; |
| import org.eclipse.jdt.core.dom.IVariableBinding; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.VariableDeclarationFragment; |
| |
| import org.eclipse.jdt.internal.corext.codemanipulation.AddCustomConstructorOperation; |
| import org.eclipse.jdt.internal.corext.dom.Bindings; |
| import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil; |
| import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; |
| import org.eclipse.jdt.internal.corext.util.JavaModelUtil; |
| |
| import org.eclipse.jdt.ui.tests.core.ProjectTestSetup; |
| |
| /** |
| * Tests generation of constructors using fields |
| * |
| * @see org.eclipse.jdt.internal.corext.codemanipulation.AddCustomConstructorOperation |
| * |
| */ |
| public class GenerateConstructorUsingFieldsTest extends SourceTestCase { |
| |
| static final Class THIS= GenerateConstructorUsingFieldsTest.class; |
| |
| public GenerateConstructorUsingFieldsTest(String name) { |
| super(name); |
| } |
| |
| public static Test allTests() { |
| return new ProjectTestSetup(new TestSuite(THIS)); |
| } |
| |
| public static Test suite() { |
| return allTests(); |
| } |
| |
| public void runOperation(IType type, IField[] fields, IMethod superConstructor, IJavaElement insertBefore, boolean createComments, boolean omitSuper, int visibility) throws CoreException { |
| |
| RefactoringASTParser parser= new RefactoringASTParser(AST.JLS3); |
| CompilationUnit unit= parser.parse(type.getCompilationUnit(), true); |
| |
| IVariableBinding[] bindings= new IVariableBinding[fields.length]; |
| for (int i= 0; i < fields.length; i++) { |
| Assert.assertTrue(fields[i].exists()); |
| VariableDeclarationFragment frag= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(fields[i], unit); |
| bindings[i]= frag.resolveBinding(); |
| } |
| |
| IMethodBinding constructorToInvoke; |
| if (superConstructor!=null) { |
| CompilationUnit mUnit= parser.parse(superConstructor.getCompilationUnit(), true); |
| MethodDeclaration mdl= ASTNodeSearchUtil.getMethodDeclarationNode(superConstructor, mUnit); |
| constructorToInvoke= mdl.resolveBinding(); |
| } else |
| constructorToInvoke= getObjectConstructor(unit); |
| |
| fSettings.createComments= createComments; |
| |
| AddCustomConstructorOperation op= new AddCustomConstructorOperation(type, insertBefore, unit, bindings, constructorToInvoke, fSettings, true, true); |
| op.setOmitSuper(omitSuper); |
| op.setVisibility(visibility); |
| |
| op.run(new NullProgressMonitor()); |
| JavaModelUtil.reconcile(type.getCompilationUnit()); |
| } |
| |
| public void runOperation(IType type, IField[] fields, IMethod superConstructor) throws CoreException { |
| runOperation(type, fields, superConstructor, null, true, false, Modifier.PUBLIC); |
| } |
| |
| private IMethodBinding getObjectConstructor(CompilationUnit compilationUnit) { |
| final ITypeBinding binding= compilationUnit.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ |
| return Bindings.findMethodInType(binding, "Object", new ITypeBinding[0]); //$NON-NLS-1$ |
| } |
| |
| private void runIt(String topLevelTypeName, String[] fieldNames, IMethod superConstructor, String source, String destination) throws Exception { |
| |
| ICompilationUnit a= fPackageP.createCompilationUnit(topLevelTypeName + ".java", source, true, null); |
| IType type= a.getType(topLevelTypeName); |
| IField[] fields= new IField[fieldNames.length]; |
| for (int i= 0; i < fieldNames.length; i++) |
| fields[i]= type.getField(fieldNames[i]); |
| |
| runOperation(type, fields, superConstructor); |
| |
| compareSource(destination, a.getSource()); |
| } |
| |
| private void runIt(String topLevelTypeName, String[] fieldNames, String source, String destination) throws Exception { |
| runIt(topLevelTypeName, fieldNames, null, source, destination); |
| } |
| |
| |
| // ----------------------- actual tests -------------------------- |
| |
| /** |
| * Tests simple constructor generation with one field |
| * |
| * @throws Exception |
| */ |
| public void test01() throws Exception { |
| |
| runIt("A", |
| new String[] { "field1" }, |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field1;\r\n" + |
| "\r\n" + |
| "}", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field1;\r\n" + |
| "\r\n" + |
| " /**\r\n" + |
| " * @param field1\r\n" + |
| " */\r\n" + |
| " public A(String field1) {\r\n" + |
| " super();\r\n" + |
| " this.field1 = field1;\r\n" + |
| " }\r\n" + |
| "\r\n" + |
| "}"); |
| } |
| |
| /** |
| * Tests adding two fields with identically named classes from different packages |
| * |
| * @throws Exception |
| */ |
| public void test02() throws Exception { |
| |
| printTestDisabledMessage("see bug 113052 (import issue)"); |
| |
| // ICompilationUnit pB= fPackageP.createCompilationUnit("B.java", "package p;\r\n" + |
| // "\r\n" + |
| // "public class B {\r\n" + |
| // "\r\n" + |
| // "}\r\n" + |
| // "", true, null); |
| // |
| // IPackageFragment packageQ= fRoot.createPackageFragment("q", true, null); |
| // packageQ.createCompilationUnit("B.java", "package p;\r\n" + |
| // "\r\n" + |
| // "public class B {\r\n" + |
| // "\r\n" + |
| // "}\r\n" + |
| // "", true, null); |
| // |
| // ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| // "\r\n" + |
| // "public class A {\r\n" + |
| // " q.B field1;\r\n" + |
| // " B field2;\r\n" + |
| // "}\r\n" + |
| // "", true, null); |
| // |
| // IField f1= a.getType("A").getField("field1"); |
| // IField f2= a.getType("A").getField("field2"); |
| // |
| // runOperation(a.getType("A"), new IField[] { f1, f2 }, null); |
| // |
| // compareSource("package p;\r\n" + |
| // "\r\n" + |
| // "public class A {\r\n" + |
| // " q.B field1;\r\n" + |
| // " B field2;\r\n" + |
| // " /**\r\n" + |
| // " * @param field1\r\n" + |
| // " * @param field2\r\n" + |
| // " */\r\n" + |
| // " public A(q.B field1, B field2) {\r\n" + |
| // " super();\r\n" + |
| // " // TODO Auto-generated constructor stub\r\n" + |
| // " this.field1 = field1;\r\n" + |
| // " this.field2 = field2;\r\n" + |
| // " }\r\n" + |
| // "}\r\n" + |
| // "", a.getSource()); |
| } |
| |
| /** |
| * Ensure field ordering stays constant |
| * |
| * @throws Exception |
| */ |
| public void test03() throws Exception { |
| |
| runIt("A", new String[] { "firstField", "secondField", "beforeHandThirdField" }, |
| "package p;\r\n" + |
| "\r\n" + |
| "import java.util.List;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String firstField;\r\n" + |
| " List secondField;\r\n" + |
| " A beforeHandThirdField;\r\n" + |
| "}", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "import java.util.List;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String firstField;\r\n" + |
| " List secondField;\r\n" + |
| " A beforeHandThirdField;\r\n" + |
| " /**\r\n" + |
| " * @param firstField\r\n" + |
| " * @param secondField\r\n" + |
| " * @param beforeHandThirdField\r\n" + |
| " */\r\n" + |
| " public A(String firstField, List secondField, A beforeHandThirdField) {\r\n" + |
| " super();\r\n" + |
| " this.firstField = firstField;\r\n" + |
| " this.secondField = secondField;\r\n" + |
| " this.beforeHandThirdField = beforeHandThirdField;\r\n" + |
| " }\r\n" + |
| "}\r\n" + |
| ""); |
| } |
| |
| /** |
| * Test insertion between two methods |
| * |
| * @throws Exception |
| */ |
| public void test04() throws Exception { |
| |
| ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "\r\n" + |
| " public void method1() {}\r\n" + |
| " public void method2() {}\r\n" + |
| "}", true, null); |
| IType typeA= a.getType("A"); |
| IField firstField= typeA.getField("field"); |
| IMethod method= typeA.getMethod("method2", new String[0]); |
| |
| runOperation(typeA, new IField[] { firstField }, null, method, true, false, Modifier.PUBLIC); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "\r\n" + |
| " public void method1() {}\r\n" + |
| " /**\r\n" + |
| " * @param field\r\n" + |
| " */\r\n" + |
| " public A(String field) {\r\n" + |
| " super();\r\n" + |
| " this.field = field;\r\n" + |
| " }\r\n" + |
| " public void method2() {}\r\n" + |
| "}", a.getSource()); |
| } |
| |
| /** |
| * Without comments |
| * |
| * @throws Exception |
| */ |
| public void test05() throws Exception { |
| |
| ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "}", true, null); |
| IType typeA= a.getType("A"); |
| IField field= typeA.getField("field"); |
| |
| runOperation(typeA, new IField[] { field }, null, null, false, false, Modifier.PUBLIC); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "\r\n" + |
| " public A(String field) {\r\n" + |
| " super();\r\n" + |
| " this.field = field;\r\n" + |
| " }\r\n" + |
| "}", a.getSource()); |
| } |
| |
| /** |
| * With a different modifier |
| * |
| * @throws Exception |
| */ |
| public void test06() throws Exception { |
| |
| ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "}", true, null); |
| IType typeA= a.getType("A"); |
| IField field= typeA.getField("field"); |
| |
| runOperation(typeA, new IField[] { field }, null, null, false, false, Modifier.PROTECTED); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "\r\n" + |
| " protected A(String field) {\r\n" + |
| " super();\r\n" + |
| " this.field = field;\r\n" + |
| " }\r\n" + |
| "}", a.getSource()); |
| } |
| |
| /** |
| * Omitting the super constructor |
| * |
| * @throws Exception |
| */ |
| public void test07() throws Exception { |
| |
| ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "}", true, null); |
| IType typeA= a.getType("A"); |
| IField field= typeA.getField("field"); |
| |
| runOperation(typeA, new IField[] { field }, null, null, false, true, Modifier.PUBLIC); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " String field;\r\n" + |
| "\r\n" + |
| " public A(String field) {\r\n" + |
| " this.field = field;\r\n" + |
| " }\r\n" + |
| "}", a.getSource()); |
| } |
| |
| /** |
| * Type variables; generic types in fields |
| * |
| * @throws Exception |
| */ |
| public void test08() throws Exception { |
| |
| fPackageP.createCompilationUnit("B.java", "package p;\r\n" + |
| "\r\n" + |
| "public class B {\r\n" + |
| "\r\n" + |
| "}\r\n" + |
| "", true, null); |
| |
| ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "import java.util.Map;\r\n" + |
| "\r\n" + |
| "public class A<E> {\r\n" + |
| " Map<String, B> field1;\r\n" + |
| " E field2;\r\n" + |
| "}", true, null); |
| |
| IType typeA= a.getType("A"); |
| IField field1= typeA.getField("field1"); |
| IField field2= typeA.getField("field2"); |
| |
| runOperation(typeA, new IField[] { field1, field2 }, null); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "import java.util.Map;\r\n" + |
| "\r\n" + |
| "public class A<E> {\r\n" + |
| " Map<String, B> field1;\r\n" + |
| " E field2;\r\n" + |
| " /**\r\n" + |
| " * @param field1\r\n" + |
| " * @param field2\r\n" + |
| " */\r\n" + |
| " public A(Map<String, B> field1, E field2) {\r\n" + |
| " super();\r\n" + |
| " this.field1 = field1;\r\n" + |
| " this.field2 = field2;\r\n" + |
| " }\r\n" + |
| "}", a.getSource()); |
| } |
| |
| /** |
| * Enums |
| * |
| * @throws Exception |
| */ |
| public void test09() throws Exception { |
| |
| runIt("A", new String[] { "field1" }, |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " public enum B { C, D };\r\n" + |
| " B field1;\r\n" + |
| "}", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " public enum B { C, D };\r\n" + |
| " B field1;\r\n" + |
| " /**\r\n" + |
| " * @param field1\r\n" + |
| " */\r\n" + |
| " public A(B field1) {\r\n" + |
| " super();\r\n" + |
| " this.field1 = field1;\r\n" + |
| " }\r\n" + |
| "}"); |
| } |
| |
| /** |
| * Final uninitialized fields |
| * |
| * @throws Exception |
| */ |
| public void test10() throws Exception { |
| |
| runIt("A", new String[] { "field1" }, |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " final A field1;\r\n" + |
| "}", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " final A field1;\r\n" + |
| "\r\n" + |
| " /**\r\n" + |
| " * @param field1\r\n" + |
| " */\r\n" + |
| " public A(final A field1) {\r\n" + |
| " super();\r\n" + |
| " this.field1 = field1;\r\n" + |
| " }\r\n" + |
| "}"); |
| } |
| |
| /** |
| * Verify JDT code conventions are followed, see bug 111801 |
| * |
| * @throws Exception |
| */ |
| public void test11() throws Exception { |
| |
| runIt("A", new String[] { "startDate", "endDate" }, |
| "package p;\r\n" + |
| "\r\n" + |
| "import java.util.Date;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " private Date startDate;\r\n" + |
| " private Date endDate;\r\n" + |
| "}", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "import java.util.Date;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " private Date startDate;\r\n" + |
| " private Date endDate;\r\n" + |
| " /**\r\n" + |
| " * @param startDate\r\n" + |
| " * @param endDate\r\n" + |
| " */\r\n" + |
| " public A(Date startDate, Date endDate) {\r\n" + |
| " super();\r\n" + |
| " this.startDate = startDate;\r\n" + |
| " this.endDate = endDate;\r\n" + |
| " }\r\n" + |
| "}"); |
| } |
| |
| |
| /** |
| * Name clashing fun with super constructors |
| * |
| */ |
| public void test12() throws Exception { |
| |
| ICompilationUnit unit= fPackageP.createCompilationUnit("SuperA.java", "package p;\r\n" + |
| "\r\n" + |
| "public class SuperA {\r\n" + |
| " \r\n" + |
| " public SuperA() {};\r\n" + |
| " public SuperA(String a, String b) {}\r\n" + |
| "\r\n" + |
| "}\r\n" + |
| "", true, null); |
| |
| IMethod superConstructor= unit.getType("SuperA").getMethod("SuperA", new String[] { "QString;", "QString;" }); |
| |
| runIt("A", new String[] { "a", "b" }, superConstructor, |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A extends SuperA {\r\n" + |
| " \r\n" + |
| " String a;\r\n" + |
| " String b;\r\n" + |
| "}\r\n" + |
| "", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A extends SuperA {\r\n" + |
| " \r\n" + |
| " String a;\r\n" + |
| " String b;\r\n" + |
| " /**\r\n" + |
| " * @param a\r\n" + |
| " * @param b\r\n" + |
| " * @param a2\r\n" + |
| " * @param b2\r\n" + |
| " */\r\n" + |
| " public A(String a, String b, String a2, String b2) {\r\n" + |
| " super(a, b);\r\n" + |
| " a = a2;\r\n" + |
| " b = b2;\r\n" + |
| " }\r\n" + |
| "}"); |
| } |
| |
| /** |
| * Generic types in parameters of super constructor |
| * |
| * @throws Exception |
| */ |
| public void test13() throws Exception { |
| |
| ICompilationUnit unit= fPackageP.createCompilationUnit("SuperA.java", "package p;\r\n" + |
| "\r\n" + |
| "import java.util.Map;\r\n" + |
| "\r\n" + |
| "public class SuperA {\r\n" + |
| " \r\n" + |
| " private Map<String, A> someMap;\r\n" + |
| "\r\n" + |
| " public SuperA() {}\r\n" + |
| "\r\n" + |
| " public SuperA(Map<String, A> someMap) {\r\n" + |
| " this.someMap = someMap;\r\n" + |
| " };\r\n" + |
| "}\r\n" + |
| "", true, null); |
| |
| IMethod superConstructor= unit.getType("SuperA").getMethod("SuperA", new String[] { "QMap<QString;QA;>;" }); |
| |
| runIt("A", new String[] { "field" }, superConstructor, |
| "package p;\r\n" + |
| "\r\n" + |
| "public class A extends SuperA {\r\n" + |
| " String field;\r\n" + |
| "}\r\n" + |
| "", |
| |
| "package p;\r\n" + |
| "\r\n" + |
| "import java.util.Map;\r\n" + |
| "\r\n" + |
| "public class A extends SuperA {\r\n" + |
| " String field;\r\n" + |
| "\r\n" + |
| " /**\r\n" + |
| " * @param someMap\r\n" + |
| " * @param field\r\n" + |
| " */\r\n" + |
| " public A(Map<String, A> someMap, String field) {\r\n" + |
| " super(someMap);\r\n" + |
| " this.field = field;\r\n" + |
| " }\r\n" + |
| "}"); |
| } |
| |
| /** |
| * Inner types |
| * @throws Exception |
| */ |
| public void test14() throws Exception { |
| |
| ICompilationUnit unit= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " \r\n" + |
| " class B {\r\n" + |
| " A b;\r\n" + |
| " }\r\n" + |
| "}\r\n" + |
| "", true, null); |
| |
| IType innerType= unit.getType("A").getType("B"); |
| IField field= innerType.getField("b"); |
| |
| runOperation(innerType, new IField[] { field }, null); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| " \r\n" + |
| " class B {\r\n" + |
| " A b;\r\n" + |
| "\r\n" + |
| " /**\r\n" + |
| " * @param b\r\n" + |
| " */\r\n" + |
| " public B(A b) {\r\n" + |
| " super();\r\n" + |
| " this.b = b;\r\n" + |
| " }\r\n" + |
| " }\r\n" + |
| "}", unit.getSource()); |
| } |
| |
| public void test15() throws Exception { |
| |
| ICompilationUnit unit= fPackageP.createCompilationUnit("A.java", "package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| "}\r\n" + |
| "\r\n" + |
| "class B {\r\n" + |
| " A foo;\r\n" + |
| "}", true, null); |
| |
| IType secondary= (IType)unit.getElementAt(40); // get secondary type |
| IField foo= secondary.getField("foo"); |
| |
| runOperation(secondary, new IField[] { foo }, null); |
| |
| compareSource("package p;\r\n" + |
| "\r\n" + |
| "public class A {\r\n" + |
| "}\r\n" + |
| "\r\n" + |
| "class B {\r\n" + |
| " A foo;\r\n" + |
| "\r\n" + |
| " /**\r\n" + |
| " * @param foo\r\n" + |
| " */\r\n" + |
| " public B(A foo) {\r\n" + |
| " super();\r\n" + |
| " this.foo = foo;\r\n" + |
| " }\r\n" + |
| "}\r\n" + |
| "", unit.getSource()); |
| } |
| } |