| /******************************************************************************* |
| * Copyright (c) 2004, 2015 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 |
| * Technical University Berlin - adapted for Object Teams |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.core.tests.dom; |
| |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import junit.framework.Test; |
| |
| import org.eclipse.jdt.core.dom.*; |
| |
| @SuppressWarnings({"rawtypes", "unchecked"}) |
| public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase { |
| |
| /** @deprecated using deprecated code */ |
| public static Test suite() { |
| // TODO (frederic) use buildList + setAstLevel(init) instead... |
| junit.framework.TestSuite suite = new junit.framework.TestSuite(ASTStructuralPropertyTest.class.getName()); |
| |
| Class c = ASTStructuralPropertyTest.class; |
| Method[] methods = c.getMethods(); |
| for (int i = 0, max = methods.length; i < max; i++) { |
| if (methods[i].getName().startsWith("test")) { //$NON-NLS-1$ |
| suite.addTest(new ASTStructuralPropertyTest(methods[i].getName(), AST.JLS2)); |
| suite.addTest(new ASTStructuralPropertyTest(methods[i].getName(), AST.JLS3)); |
| suite.addTest(new ASTStructuralPropertyTest(methods[i].getName(), AST.JLS4)); |
| suite.addTest(new ASTStructuralPropertyTest(methods[i].getName(), AST.JLS8)); |
| } |
| } |
| return suite; |
| } |
| |
| AST ast; |
| ASTParser parser; |
| int API_LEVEL; |
| |
| public ASTStructuralPropertyTest(String name) { |
| super(name.substring(0, name.indexOf(" - JLS"))); |
| name.indexOf(" - JLS"); |
| this.API_LEVEL = Integer.parseInt(name.substring(name.indexOf(" - JLS") + 6)); |
| } |
| |
| public ASTStructuralPropertyTest(String name, int apiLevel) { |
| super(name); |
| this.API_LEVEL = apiLevel; |
| } |
| |
| protected void setUp() throws Exception { |
| super.setUp(); |
| this.ast = AST.newAST(this.API_LEVEL); |
| this.parser = ASTParser.newParser(this.API_LEVEL); |
| } |
| |
| protected void tearDown() throws Exception { |
| this.ast = null; |
| super.tearDown(); |
| } |
| |
| public String getName() { |
| String name = super.getName() + " - JLS" + this.API_LEVEL; |
| return name; |
| } |
| |
| public void testLocationInParent() { |
| final ASTNode root = SampleASTs.oneOfEach(this.ast); |
| ASTVisitor v = new ASTVisitor(true) { |
| public void postVisit(ASTNode node) { |
| StructuralPropertyDescriptor me = node.getLocationInParent(); |
| assertTrue(me != null || (node == root)); |
| ASTNode p = node.getParent(); |
| if (p != null) { |
| List parentProperties = p.structuralPropertiesForType(); |
| boolean foundMe = false; |
| for (Iterator it = parentProperties.iterator(); it |
| .hasNext();) { |
| StructuralPropertyDescriptor prop = |
| (StructuralPropertyDescriptor) it.next(); |
| if (me == prop || prop.getId().equals(me.getId())) { |
| foundMe = true; |
| break; |
| } |
| } |
| assertTrue(foundMe); |
| } |
| } |
| }; |
| root.accept(v); |
| } |
| |
| /** |
| * @deprecated since using deprecated constant |
| */ |
| public void testStructuralProperties() { |
| final ASTNode root = SampleASTs.oneOfEach(this.ast); |
| |
| final Set simpleProperties = new LinkedHashSet(400); |
| final Set childProperties = new LinkedHashSet(400); |
| final Set childListProperties = new LinkedHashSet(400); |
| final Set visitedProperties = new LinkedHashSet(400); |
| final Set nodeClasses = new LinkedHashSet(100); |
| |
| ASTVisitor v = new ASTVisitor(true) { |
| public void postVisit(ASTNode node) { |
| StructuralPropertyDescriptor me = node.getLocationInParent(); |
| if (me != null) { |
| visitedProperties.add(me); |
| } |
| nodeClasses.add(node.getClass()); |
| List ps = node.structuralPropertiesForType(); |
| for (Iterator it = ps.iterator(); it.hasNext(); ) { |
| StructuralPropertyDescriptor p = (StructuralPropertyDescriptor) it.next(); |
| Object o = node.getStructuralProperty(p); |
| if (p.isSimpleProperty()) { |
| simpleProperties.add(p); |
| // slam simple properties |
| node.setStructuralProperty(p, o); |
| } else if (p.isChildProperty()) { |
| childProperties.add(p); |
| // replace child with a copy |
| ASTNode copy = ASTNode.copySubtree(ASTStructuralPropertyTest.this.ast, (ASTNode) o); |
| node.setStructuralProperty(p, copy); |
| } else if (p.isChildListProperty()) { |
| childListProperties.add(p); |
| // replace child list with copies |
| List list = (List) o; |
| List copy = ASTNode.copySubtrees(ASTStructuralPropertyTest.this.ast, list); |
| list.clear(); |
| list.addAll(copy); |
| } |
| } |
| } |
| }; |
| root.accept(v); |
| switch(this.API_LEVEL) { |
| case AST.JLS2 : |
| assertEquals("Wrong number of visited node classes", 67, nodeClasses.size()); |
| assertEquals("Wrong number of visited properties", 81, visitedProperties.size()); |
| //{ObjectTeams: 2 new simple properties in TypeDeclaration: TEAM_PROPERTY and ROLE_PROPERTY: |
| /* orig: |
| assertEquals("Wrong number of simple properties", 26, simpleProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of simple properties", 28, simpleProperties.size()); |
| // 2 new child properties: GUARD_PROPERTY (in TypeDeclaration and MethodDeclaration) |
| /* orig: |
| assertEquals("Wrong number of child properties", 90, childProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child properties", 92, childProperties.size()); |
| |
| // 1 new child list property: PRECEDENCES_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of child list properties", 26, childListProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child list properties", 27, childListProperties.size()); |
| // SH} |
| break; |
| case AST.JLS3 : |
| assertEquals("Wrong number of visited node classes", 80, nodeClasses.size()); |
| assertEquals("Wrong number of visited properties", 103, visitedProperties.size()); |
| //{ObjectTeams: 2 new simple properties in TypeDeclaration: TEAM_PROPERTY and ROLE_PROPERTY: |
| // 1 new property in ImportDeclaration: BASE_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of simple properties", 23, simpleProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of simple properties", 26, simpleProperties.size()); |
| // 2 new child properties: GUARD_PROPERTY (in TypeDeclaration and MethodDeclaration) |
| /* orig: |
| assertEquals("Wrong number of child properties", 115, childProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child properties", 117, childProperties.size()); |
| |
| // 2 new child list properties: TypeDeclaration.PRECEDENCES_PROPERTY, PackageDeclaration.MODIFIERS_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of child list properties", 52, childListProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child list properties", 54, childListProperties.size()); |
| // SH} |
| break; |
| case AST.JLS4 : |
| assertEquals("Wrong number of visited node classes", 81, nodeClasses.size()); |
| assertEquals("Wrong number of visited properties", 103, visitedProperties.size()); |
| //{ObjectTeams: 2 new simple properties in TypeDeclaration: TEAM_PROPERTY and ROLE_PROPERTY: |
| // 1 new property in ImportDeclaration: BASE_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of simple properties", 23, simpleProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of simple properties", 26, simpleProperties.size()); |
| // 2 new child properties: GUARD_PROPERTY (in TypeDeclaration and MethodDeclaration) |
| /* orig: |
| assertEquals("Wrong number of child properties", 115, childProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child properties", 117, childProperties.size()); |
| |
| // 2 new child list properties: TypeDeclaration.PRECEDENCES_PROPERTY, PackageDeclaration.MODIFIERS_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of child list properties", 54, childListProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child list properties", 56, childListProperties.size()); |
| // SH} |
| break; |
| case AST.JLS8 : |
| assertEquals("Wrong number of visited node classes", 84, nodeClasses.size()); |
| assertEquals("Wrong number of visited properties", 106, visitedProperties.size()); |
| //{ObjectTeams: 2 new simple properties in TypeDeclaration: TEAM_PROPERTY and ROLE_PROPERTY: |
| // 1 new property in ImportDeclaration: BASE_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of simple properties", 21, simpleProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of simple properties", 24, simpleProperties.size()); |
| // 2 new child properties: GUARD_PROPERTY (in TypeDeclaration and MethodDeclaration) |
| /* orig: |
| assertEquals("Wrong number of child properties", 118, childProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child properties", 120, childProperties.size()); |
| |
| // 2 new child list properties: TypeDeclaration.PRECEDENCES_PROPERTY, PackageDeclaration.MODIFIERS_PROPERTY |
| /* orig: |
| assertEquals("Wrong number of child list properties", 66, childListProperties.size()); |
| :giro */ |
| assertEquals("Wrong number of child list properties", 68, childListProperties.size()); |
| // SH} |
| break; |
| default : |
| fail(); |
| } |
| // visit should rebuild tree |
| ASTNode newRoot = SampleASTs.oneOfEach(this.ast); |
| assertTrue(root.subtreeMatch(new ASTMatcher(), newRoot)); |
| } |
| |
| public void testProtect() { |
| final ASTNode root = SampleASTs.oneOfEach(this.ast); |
| |
| // check that all properties are again modifiable |
| class Slammer extends ASTVisitor { |
| boolean shouldBeProtected; |
| Slammer(boolean shouldBeProtected){ |
| super(true); // visit doc |
| this.shouldBeProtected = shouldBeProtected; |
| } |
| public void postVisit(ASTNode node) { |
| try { |
| node.setSourceRange(1, 1); |
| assertTrue(!this.shouldBeProtected); |
| } catch (RuntimeException e) { |
| assertTrue(this.shouldBeProtected); |
| } |
| List ps = node.structuralPropertiesForType(); |
| for (Iterator it = ps.iterator(); it.hasNext(); ) { |
| StructuralPropertyDescriptor p = (StructuralPropertyDescriptor) it.next(); |
| Object o = node.getStructuralProperty(p); |
| if (p.isSimpleProperty()) { |
| // slam simple properties |
| try { |
| node.setStructuralProperty(p, o); |
| assertTrue(!this.shouldBeProtected); |
| } catch (RuntimeException e) { |
| assertTrue(this.shouldBeProtected); |
| } |
| } else if (p.isChildProperty()) { |
| // replace child with a copy |
| ASTNode copy = ASTNode.copySubtree(ASTStructuralPropertyTest.this.ast, (ASTNode) o); |
| try { |
| node.setStructuralProperty(p, copy); |
| assertTrue(!this.shouldBeProtected); |
| } catch (RuntimeException e) { |
| assertTrue(this.shouldBeProtected); |
| } |
| } else if (p.isChildListProperty()) { |
| // replace child list with copies |
| List list = (List) o; |
| List copy = ASTNode.copySubtrees(ASTStructuralPropertyTest.this.ast, list); |
| if (!list.isEmpty()) { |
| try { |
| list.clear(); |
| assertTrue(!this.shouldBeProtected); |
| } catch (RuntimeException e) { |
| assertTrue(this.shouldBeProtected); |
| } |
| try { |
| list.addAll(copy); |
| assertTrue(!this.shouldBeProtected); |
| } catch (RuntimeException e) { |
| assertTrue(this.shouldBeProtected); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| class Protector extends ASTVisitor { |
| boolean shouldBeProtected; |
| Protector(boolean shouldBeProtected){ |
| super(true); // visit doc |
| this.shouldBeProtected = shouldBeProtected; |
| } |
| public void preVisit(ASTNode node) { |
| int f = node.getFlags(); |
| if (this.shouldBeProtected) { |
| f |= ASTNode.PROTECT; |
| } else { |
| f &= ~ASTNode.PROTECT; |
| } |
| node.setFlags(f); |
| } |
| } |
| |
| |
| // mark all nodes as protected |
| root.accept(new Protector(true)); |
| root.accept(new Slammer(true)); |
| |
| // mark all nodes as unprotected |
| root.accept(new Protector(false)); |
| root.accept(new Slammer(false)); |
| } |
| |
| public void testDelete() { |
| final ASTNode root = SampleASTs.oneOfEach(this.ast); |
| |
| // check that nodes can be deleted unless mandatory |
| root.accept(new ASTVisitor(true) { |
| public void postVisit(ASTNode node) { |
| List ps = node.structuralPropertiesForType(); |
| for (Iterator it = ps.iterator(); it.hasNext(); ) { |
| StructuralPropertyDescriptor p = (StructuralPropertyDescriptor) it.next(); |
| if (p.isChildProperty()) { |
| ChildPropertyDescriptor c = (ChildPropertyDescriptor) p; |
| ASTNode child = (ASTNode) node.getStructuralProperty(c); |
| if (!c.isMandatory() && child != null) { |
| try { |
| child.delete(); |
| assertTrue(node.getStructuralProperty(c) == null); |
| } catch (RuntimeException e) { |
| assertTrue(false); |
| } |
| } |
| } else if (p.isChildListProperty()) { |
| // replace child list with copies |
| List list = (List) node.getStructuralProperty(p); |
| // iterate over a copy and try removing all members |
| List copy = new ArrayList(); |
| copy.addAll(list); |
| for (Iterator it2 = copy.iterator(); it2.hasNext(); ) { |
| ASTNode n = (ASTNode) it2.next(); |
| try { |
| n.delete(); |
| assertTrue(!list.contains(n)); |
| } catch (RuntimeException e) { |
| assertTrue(false); |
| } |
| } |
| } |
| } |
| } |
| }); |
| } |
| |
| /** @deprecated using deprecated code */ |
| public void testCreateInstance() { |
| int maxNodeType; |
| switch (this.ast.apiLevel()) { |
| case AST.JLS2: |
| maxNodeType = 69; |
| break; |
| case AST.JLS3: |
| maxNodeType = 83; |
| break; |
| case AST.JLS4: |
| maxNodeType = 84; |
| break; |
| case AST.JLS8: |
| maxNodeType = 92; |
| break; |
| default: |
| fail(); |
| return; |
| } |
| for (int nodeType = 0; nodeType < 100; nodeType++) { |
| Class nodeClass = null; |
| try { |
| nodeClass = ASTNode.nodeClassForType(nodeType); |
| } catch (IllegalArgumentException e) { |
| // oops - guess that's not valid |
| } |
| if (nodeClass != null) { |
| try { |
| ASTNode node = this.ast.createInstance(nodeClass); |
| //{ObjectTeams: adpated for new OT-specific ASTNodes |
| if ((nodeType >= 85) && (nodeType <= 100)) { |
| // good: OT node |
| } else |
| // SH} |
| assertTrue(nodeType <= maxNodeType); |
| assertTrue(node.getNodeType() == nodeType); |
| //ASTNode node2 = ast.createInstance(nodeType); |
| //assertTrue(node2.getNodeType() == nodeType); |
| } catch (RuntimeException e) { |
| assertTrue((nodeType < 1) || (nodeType > maxNodeType)); |
| } |
| } |
| } |
| } |
| |
| public void testNodeClassForType() { |
| //{ObjectTeams: larger range: |
| /* orig: |
| Set classes = new HashSet(100); |
| // make sure node types are contiguous starting at 0 |
| int hi = 0; |
| for (int nodeType = 1; nodeType < 100; nodeType++) { |
| :giro */ |
| Set classes = new HashSet(120); |
| // make sure node types are contiguous starting at 0 |
| int hi = 0; |
| for (int nodeType = 1; nodeType < 120; nodeType++) { |
| // SH} |
| try { |
| Class nodeClass = ASTNode.nodeClassForType(nodeType); |
| assertTrue(ASTNode.class.isAssignableFrom(nodeClass)); |
| classes.add(nodeClass); |
| if (nodeType > 1) { |
| assertTrue(hi == nodeType - 1); |
| } |
| hi = nodeType; |
| } catch (IllegalArgumentException e) { |
| // oops - guess that's not valid |
| } |
| } |
| // {ObjectTeams: adapted for OT specific ASTNodes |
| /* orig: |
| assertEquals("Wrong last known type", 92, hi); // last known one |
| :giro */ |
| assertEquals("Wrong last known type", 108, hi); // last known one |
| // jwl} |
| assertEquals("Wrong number of distinct types", hi, classes.size()); // all classes are distinct |
| } |
| } |