### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java,v retrieving revision 1.44 diff -u -r1.44 ASTRewrite.java --- dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java 25 Jun 2010 14:58:37 -0000 1.44 +++ dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java 27 Sep 2010 10:33:29 -0000 @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.jdt.core.dom.rewrite; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -103,6 +104,27 @@ * @since 3.1 */ private TargetSourceRangeComputer targetSourceRangeComputer = null; + + /** + * Primary field used in representing rewrite properties efficiently. + * If null, this rewrite has no properties. + * If a String, this is the name of this rewrite's sole property, + * and property2 contains its value. + * If a HashMap, this is the table of property name-value + * mappings; property2, if non-null is its unmodifiable + * equivalent. + * Initially null. + * + * @see #property2 + */ + private Object property1 = null; + + /** + * Auxillary field used in representing rewrite properties efficiently. + * + * @see #property1 + */ + private Object property2 = null; /** * Creates a new instance for describing manipulations of @@ -702,4 +724,115 @@ } return buf.toString(); } + + /** + * Returns the named property of this rewrite, or null if none. + * + * @param propertyName the property name + * @return the property value, or null if none + * @see #setProperty(String,Object) + * @since 3.7 + */ + public final Object getProperty(String propertyName) { + if (propertyName == null) { + throw new IllegalArgumentException(); + } + if (this.property1 == null) { + // rewrite has no properties at all + return null; + } + if (this.property1 instanceof String) { + // rewrite has only a single property + if (propertyName.equals(this.property1)) { + return this.property2; + } else { + return null; + } + } + // otherwise rewrite has table of properties + Map m = (Map) this.property1; + return m.get(propertyName); + } + + /** + * Sets the named property of this rewrite to the given value, + * or to null to clear it. + *

+ * Clients should employ property names that are sufficiently unique + * to avoid inadvertent conflicts with other clients that might also be + * setting properties on the same rewrite. + *

+ *

+ * Note that modifying a property is not considered a modification to the + * AST itself. This is to allow clients to decorate existing rewrites with + * their own properties without jeopardizing certain things (like the + * validity of bindings), which rely on the underlying tree remaining static. + *

+ * + * @param propertyName the property name + * @param data the new property value, or null if none + * @see #getProperty(String) + * @since 3.7 + */ + public final void setProperty(String propertyName, Object data) { + if (propertyName == null) { + throw new IllegalArgumentException(); + } + + if (this.property1 == null) { + // rewrite has no properties at all + if (data == null) { + // rewrite already knows this + return; + } + // rewrite gets its fist property + this.property1 = propertyName; + this.property2 = data; + return; + } + + if (this.property1 instanceof String) { + // rewrite has only a single property + if (propertyName.equals(this.property1)) { + // we're in luck + this.property2 = data; + if (data == null) { + // just delete last property + this.property1 = null; + this.property2 = null; + } + return; + } + if (data == null) { + // we already know this + return; + } + // rewrite already has one property - getting its second + // convert to more flexible representation + HashMap m = new HashMap(2); + m.put(this.property1, this.property2); + m.put(propertyName, data); + this.property1 = m; + this.property2 = null; + return; + } + + // rewrite has two or more properties + HashMap m = (HashMap) this.property1; + if (data == null) { + m.remove(propertyName); + // check for just one property left + if (m.size() == 1) { + // convert to more efficient representation + Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]); + this.property1 = entries[0].getKey(); + this.property2 = entries[0].getValue(); + } + return; + } else { + m.put(propertyName, data); + // still has two or more properties + return; + } + } }