1 19 package org.netbeans.api.java.source.gen; 20 21 import com.sun.source.tree.AssignmentTree; 22 import com.sun.source.tree.BlockTree; 23 import com.sun.source.tree.ClassTree; 24 import com.sun.source.tree.CompilationUnitTree; 25 import com.sun.source.tree.ExpressionTree; 26 import com.sun.source.tree.StatementTree; 27 import com.sun.source.tree.Tree; 28 import com.sun.source.tree.TypeParameterTree; 29 import com.sun.source.tree.VariableTree; 30 import com.sun.source.util.TreePath; 31 import com.sun.source.util.TreeScanner; 32 import java.io.File ; 33 import java.io.FileInputStream ; 34 import java.io.FileOutputStream ; 35 import java.io.IOException ; 36 import java.io.InputStream ; 37 import java.io.OutputStream ; 38 import java.util.ArrayList ; 39 import java.util.Collections ; 40 import java.util.EnumSet ; 41 import java.util.List ; 42 import java.util.Set ; 43 import javax.lang.model.element.Element; 44 import javax.lang.model.element.ElementKind; 45 import javax.lang.model.element.Modifier; 46 import javax.lang.model.element.PackageElement; 47 import javax.lang.model.element.TypeElement; 48 import javax.lang.model.element.VariableElement; 49 import javax.lang.model.type.TypeKind; 50 import javax.swing.text.Document ; 51 import org.netbeans.api.java.source.CancellableTask; 52 import org.netbeans.api.java.source.CompilationInfo; 53 import org.netbeans.api.java.source.JavaSource; 54 import org.netbeans.api.java.source.JavaSource.Phase; 55 import org.netbeans.api.java.source.SourceUtilsTestUtil; 56 import org.netbeans.api.java.source.SourceUtilsTestUtil2; 57 import org.netbeans.api.java.source.WorkingCopy; 58 import org.netbeans.api.java.source.transform.Transformer; 59 import org.netbeans.junit.NbTestCase; 60 import org.netbeans.modules.java.source.JavaSourceAccessor; 61 import org.openide.cookies.EditorCookie; 62 import org.openide.filesystems.FileObject; 63 import org.openide.filesystems.FileUtil; 64 import org.openide.loaders.DataObject; 65 66 70 public class MemberAdditionTest extends NbTestCase { 71 72 73 public MemberAdditionTest(String name) { 74 super(name); 75 } 76 77 public void testSynteticDefaultConstructor() throws Exception { 78 performTest("SynteticDefaultConstructor"); 79 80 source.runModificationTask(new CancellableTask<WorkingCopy>() { 81 public void cancel() { 82 } 83 public void run(WorkingCopy copy) { 84 ClassTree topLevel = findTopLevelClass(copy); 85 SourceUtilsTestUtil2.run(copy, new AddSimpleField(), topLevel); 86 } 87 }).commit(); 88 89 JavaSourceAccessor.INSTANCE.revalidate(source); 90 91 CompilationInfo check = SourceUtilsTestUtil.getCompilationInfo(source, Phase.RESOLVED); 92 CompilationUnitTree cu = check.getCompilationUnit(); 93 94 assertEquals(check.getDiagnostics().toString(), 0, check.getDiagnostics().size()); 95 96 ClassTree newTopLevel = findTopLevelClass(check); 97 Element clazz = check.getTrees().getElement(TreePath.getPath(cu, newTopLevel)); 98 Element pack = clazz.getEnclosingElement(); 99 100 assertEquals(ElementKind.PACKAGE, pack.getKind()); 101 assertEquals("test", ((PackageElement) pack).getQualifiedName().toString()); 102 assertEquals(clazz.getEnclosedElements().toString(), 2 + 1, clazz.getEnclosedElements().size()); 103 } 104 105 public void testEmptyClass() throws Exception { 106 performTest("EmptyClass"); 107 108 source.runModificationTask(new CancellableTask<WorkingCopy>() { 109 public void cancel() { 110 } 111 public void run(WorkingCopy copy) { 112 ClassTree topLevel = findTopLevelClass(copy); 113 SourceUtilsTestUtil2.run(copy, new AddSimpleField(), topLevel); 114 } 115 }).commit(); 116 117 JavaSourceAccessor.INSTANCE.revalidate(source); 118 119 CompilationInfo check = SourceUtilsTestUtil.getCompilationInfo(source, Phase.RESOLVED); 120 CompilationUnitTree cu = check.getCompilationUnit(); 121 122 assertEquals(check.getDiagnostics().toString(), 0, check.getDiagnostics().size()); 123 124 ClassTree newTopLevel = findTopLevelClass(check); 125 Element clazz = check.getTrees().getElement(TreePath.getPath(cu, newTopLevel)); 126 Element pack = clazz.getEnclosingElement(); 127 128 assertEquals(ElementKind.PACKAGE, pack.getKind()); 129 assertEquals("test", ((PackageElement) pack).getQualifiedName().toString()); 130 assertEquals(clazz.getEnclosedElements().toString(), 1 + 1, clazz.getEnclosedElements().size()); 131 } 132 133 public void testClassImplementingList() throws Exception { 134 performTest("ClassImplementingList"); 135 136 source.runModificationTask(new CancellableTask<WorkingCopy>() { 137 public void cancel() { 138 } 139 public void run(WorkingCopy copy) { 140 ClassTree topLevel = findTopLevelClass(copy); 141 SourceUtilsTestUtil2.run(copy, new AddSimpleField(), topLevel); 142 } 143 }).commit(); 144 145 JavaSourceAccessor.INSTANCE.revalidate(source); 146 147 CompilationInfo check = SourceUtilsTestUtil.getCompilationInfo(source, Phase.RESOLVED); 148 CompilationUnitTree cu = check.getCompilationUnit(); 149 150 assertEquals(check.getDiagnostics().toString(), 1, check.getDiagnostics().size()); 151 assertEquals("compiler.err.does.not.override.abstract", check.getDiagnostics().get(0).getCode()); 152 153 ClassTree newTopLevel = findTopLevelClass(check); 154 Element clazz = check.getTrees().getElement(TreePath.getPath(cu, newTopLevel)); 155 Element pack = clazz.getEnclosingElement(); 156 157 assertEquals(ElementKind.PACKAGE, pack.getKind()); 158 assertEquals("test", ((PackageElement) pack).getQualifiedName().toString()); 159 assertEquals(clazz.getEnclosedElements().toString(), 1 + 1, clazz.getEnclosedElements().size()); 160 } 161 162 public void testClassWithInnerClass() throws Exception { 163 performTest("ClassWithInnerClass"); 164 165 source.runModificationTask(new CancellableTask<WorkingCopy>() { 166 public void cancel() { 167 } 168 public void run(WorkingCopy copy) { 169 ClassTree topLevel = findTopLevelClass(copy); 170 171 FindVariableDeclaration d = new FindVariableDeclaration(); 172 173 CompilationUnitTree cu = copy.getCompilationUnit(); 174 d.scan(cu, true); 175 176 VariableTree var = d.var; 177 178 SourceUtilsTestUtil2.run(copy, new CreateConstructor(Collections.singletonList((VariableElement) copy.getTrees().getElement(TreePath.getPath(cu, var))), (TypeElement) copy.getTrees().getElement(TreePath.getPath(cu, topLevel)), var), topLevel); 179 } 180 }).commit(); 181 182 JavaSourceAccessor.INSTANCE.revalidate(source); 183 184 CompilationInfo check = SourceUtilsTestUtil.getCompilationInfo(source, Phase.RESOLVED); 185 CompilationUnitTree cu = check.getCompilationUnit(); 186 187 assertEquals(check.getDiagnostics().toString(), 0, check.getDiagnostics().size()); 188 189 ClassTree newTopLevel = findTopLevelClass(check); 190 Element clazz = check.getTrees().getElement(TreePath.getPath(cu, newTopLevel)); 191 Element pack = clazz.getEnclosingElement(); 192 193 assertEquals(ElementKind.PACKAGE, pack.getKind()); 194 assertEquals("test", ((PackageElement) pack).getQualifiedName().toString()); 195 assertEquals(clazz.getEnclosedElements().toString(), 3, clazz.getEnclosedElements().size()); 196 } 197 198 private ClassTree findTopLevelClass(CompilationInfo info) { 199 TopLevelClassInfo i = new TopLevelClassInfo(); 200 201 i.scan(info.getCompilationUnit(), null); 202 203 return i.topLevel; 204 } 205 206 private static class TopLevelClassInfo extends TreeScanner<Void , Boolean > { 207 208 private ClassTree topLevel; 209 210 public Void visitClass(ClassTree node, Boolean p) { 211 topLevel = node; 212 return null; 213 } 214 215 } 216 217 private static class FindVariableDeclaration extends TreeScanner<Void , Boolean > { 218 219 private VariableTree var; 220 221 public Void visitVariable(VariableTree node, Boolean p) { 222 var = node; 223 return null; 224 } 225 226 } 227 228 private static class AddSimpleField extends Transformer<Void , Boolean > { 229 230 public Void visitClass(ClassTree node, Boolean p) { 231 TypeElement te = (TypeElement)model.getElement(node); 232 if (te != null) { 233 List <Tree> members = new ArrayList <Tree>(); 234 for(Tree m : node.getMembers()) 235 members.add(m); 236 members.add(make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), "test", make.PrimitiveType(TypeKind.INT), null)); 237 ClassTree decl = make.Class(node.getModifiers(), node.getSimpleName(), node.getTypeParameters(), node.getExtendsClause(), (List <ExpressionTree>)node.getImplementsClause(), members); 238 model.setElement(decl, te); 239 model.setType(decl, model.getType(node)); 240 model.setPos(decl, model.getPos(node)); 241 changes.rewrite(node, decl); 242 } 243 244 return null; 245 } 246 247 } 248 249 public static class CreateConstructor extends Transformer<Void , Object > { 250 251 private List <VariableElement> fields; 252 private TypeElement parent; 253 private Tree putBefore; 254 255 public CreateConstructor(List <VariableElement> fields, TypeElement parent, Tree putBefore) { 256 this.fields = fields; 257 this.parent = parent; 258 this.putBefore = putBefore; 259 } 260 261 public Void visitClass(ClassTree node, Object p) { 262 TypeElement te = (TypeElement)model.getElement(node); 263 if (te != null) { 264 List <Tree> members = new ArrayList <Tree>(node.getMembers()); 265 int pos = putBefore != null ? members.indexOf(putBefore) + 1: members.size(); 266 267 Set <Modifier> mods = EnumSet.of(Modifier.PUBLIC); 268 269 List <StatementTree> statements = new ArrayList (); 271 List <VariableTree> arguments = new ArrayList (); 272 273 for (VariableElement ve : fields) { 274 AssignmentTree a = make.Assignment(make.MemberSelect(make.Identifier("this"), ve.getSimpleName()), make.Identifier(ve.getSimpleName())); 275 276 statements.add(make.ExpressionStatement(a)); 277 arguments.add(make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), ve.getSimpleName(), make.Type(ve.asType()), null)); 278 } 279 280 BlockTree body = make.Block(statements, false); 281 282 members.add(pos, make.Method(make.Modifiers(mods), "<init>", null, Collections.<TypeParameterTree> emptyList(), arguments, Collections.<ExpressionTree>emptyList(), body, null)); 283 ClassTree decl = make.Class(node.getModifiers(), node.getSimpleName(), node.getTypeParameters(), node.getExtendsClause(), (List <ExpressionTree>)node.getImplementsClause(), members); 284 model.setElement(decl, te); 285 model.setType(decl, model.getType(node)); 286 model.setPos(decl, model.getPos(node)); 287 changes.rewrite(node, decl); 288 } 289 return null; 290 } 291 292 } 293 294 private FileObject testSourceFO; 295 private JavaSource source; 296 private Document doc; 297 298 private void copyToWorkDir(File resource, File toFile) throws IOException { 299 InputStream is = new FileInputStream (resource); 301 OutputStream outs = new FileOutputStream (toFile); 302 303 int read; 304 305 while ((read = is.read()) != (-1)) { 306 outs.write(read); 307 } 308 309 outs.close(); 310 311 is.close(); 312 } 313 314 private void performTest(String fileName) throws Exception { 315 SourceUtilsTestUtil.prepareTest(new String [0], new Object [0]); 316 317 FileObject scratch = SourceUtilsTestUtil.makeScratchDir(this); 318 FileObject cache = scratch.createFolder("cache"); 319 320 File wd = getWorkDir(); 321 File testSource = new File (wd, "test/" + fileName + ".java"); 322 323 testSource.getParentFile().mkdirs(); 324 325 File dataFolder = new File (getDataDir(), "org/netbeans/test/codegen/"); 326 327 for (File f : dataFolder.listFiles()) { 328 copyToWorkDir(f, new File (wd, "test/" + f.getName())); 329 } 330 331 testSourceFO = FileUtil.toFileObject(testSource); 332 333 assertNotNull(testSourceFO); 334 335 File testBuildTo = new File (wd, "test-build"); 336 337 testBuildTo.mkdirs(); 338 339 SourceUtilsTestUtil.prepareTest(FileUtil.toFileObject(dataFolder), FileUtil.toFileObject(testBuildTo), cache); 340 SourceUtilsTestUtil.compileRecursively(FileUtil.toFileObject(dataFolder)); 341 342 source = JavaSource.forFileObject(testSourceFO); 343 344 DataObject d = DataObject.find(testSourceFO); 345 EditorCookie ec = (EditorCookie) d.getCookie(EditorCookie.class); 346 347 doc = ec.openDocument(); 348 } 349 350 } 351 | Popular Tags |