public final class AstKey
extends java.lang.Object
implements java.io.Externalizable
equals()
and
hashCode
to provide implementations of these methods whose
behavior is customizable, based upon criteria passed to the constructor.
Equality and hashing functionality is delegated to this separate class,
rather than being hardcoded directly in the annotated AST implementation,
because it is intended to operate on AST branches whose purpose and general
structure is well known to the user. AnnotatedAst
, on the other
hand, is intended to be a very general purpose implementation.
Only those AST characteristics which are explicitly defined at
instantiation are included in equality tests and hash code calculations.
Characteristics which may be considered are token type, and optionally,
within a specific token type, token text (either case sensitive or case
insensitive), and zero or more annotation types. These are specified as
a map that is passed to the constructor. The map's keys are token types.
Each value is a collection containing zero or more annotation keys
(Strings), and optionally, either a true
or false
value indicating the token's text (case insensitively or case sensitively,
respectively) should be considered. The boolean values are mutually
exclusive; only one may be included in the collection.
During processing of equals()
, only those nodes whose token
types appear in the map are tested for equality with the corresponding
node in the comparison target. Other nodes are ignored completely, as if
they did not exist. Likewise, annotations (and text) which are not
included in the criteria are ignored. Thus, two ASTs that differ only in
ignored token types, or text, or annotations, will be considered equal to
one another. AST IDs are never considered, as these are required to be
unique globally and would only match if an object were being compared with
itself.
Likewise, hashCode
considers only nodes, text, and annotations
which are included in the criteria map when calculating its result.
Alternatively, a wildcard token type entry can be added to the map, such
that the associated set of criteria are used when no more specific token
type entry is found. This is done using the KEY_WILDCARD
key to store criteria properties in the criteria map passed to this class'
constructor. In this mode, no nodes in either of the compared trees is
ever ignored. Thus, at a minimum, the token type structure of the two
trees (plus any comparison properties specified) must be identical for two
trees to be considered equal, or to have them generate the same hash code.
Modifier and Type | Field and Description |
---|---|
private Aast |
ast
AST whose data backs this key
|
private java.util.Map<java.lang.Integer,java.util.Collection<?>> |
criteria
Map of token types to AST properties to consider
|
private int |
hash
Cached value of hash.
|
static java.lang.Object |
KEY_WILDCARD
Key which indicates the wildcard token type
|
static java.lang.Boolean |
TEXT_KEY_CASE_SENS
Constant indicating that case sensitive text is a criterion
|
static java.lang.Boolean |
TEXT_KEY_IGNORE_CASE
Constant indicating that case insensitive text is a criterion
|
Constructor and Description |
---|
AstKey()
Default c'tor, used for (de)serialization.
|
AstKey(Aast ast,
java.util.Map<java.lang.Integer,java.util.Collection<?>> criteria)
Constructor which stores a backing AST and defines how this AST will be
tested for equality with others, and how this key's hash code will be
calculated.
|
Modifier and Type | Method and Description |
---|---|
private int |
annotationsHashCode(Aast node,
java.lang.String key)
Calculate the hash code for a particular annotation on the given AST
node.
|
private boolean |
compareAnnotations(Aast x,
Aast y,
java.lang.String key)
Determine whether the given nodes have the same value for an annotation.
|
private boolean |
compareNodes(Aast x,
Aast y,
java.util.Set<?> props)
Determine whether two nodes are considered equal to one another based
upon a comparison of only the specified subset of their common
properties.
|
private int |
computeHash()
Calculates a hash code for this key, which is consistent with this
class' implementation of
equals(java.lang.Object) . |
boolean |
equals(java.lang.Object o)
A specialized equality test which checks only the subset of AST
properties which were specified as criteria when this key was created.
|
int |
hashCode()
Calculates a hash code for this key, which is consistent with this
class' implementation of
equals(java.lang.Object) . |
private int |
hashCode(Aast node,
java.util.Set<?> props)
Calculate a hash code for the given node, which considers only those
properties specified in
props . |
private void |
initialize(Aast ast,
java.util.Map<java.lang.Integer,java.util.Collection<?>> criteria)
Initialize this instance using the backing AST.
|
private boolean |
isIgnoreNode(Aast node,
java.lang.Long ignoreID)
Determine whether the specified node should be ignored.
|
static void |
main(java.lang.String[] args)
Test harness.
|
void |
readExternal(java.io.ObjectInput in)
Restore this instance by re-loading the AST with the given ID and
initialize(com.goldencode.ast.Aast, java.util.Map<java.lang.Integer, java.util.Collection<?>>) it. |
void |
writeExternal(java.io.ObjectOutput out)
Write this instance to stream.
|
public static final java.lang.Boolean TEXT_KEY_IGNORE_CASE
public static final java.lang.Boolean TEXT_KEY_CASE_SENS
public static final java.lang.Object KEY_WILDCARD
private Aast ast
private java.util.Map<java.lang.Integer,java.util.Collection<?>> criteria
private int hash
FrameAstKey
is imutabil so once computed in constructor it
remains unchanged during the lifetime of the container.public AstKey()
public AstKey(Aast ast, java.util.Map<java.lang.Integer,java.util.Collection<?>> criteria)
ast
- Backing data; may not be null
criteria
- Map of token types to AST properties to consider for equals(java.lang.Object)
and hashCode()
; may not be null
.public final boolean equals(java.lang.Object o)
equals
in class java.lang.Object
o
- Another object (presumably another instance of this class with
identical test criteria) to test for equality with this one.true
if o
is considered equal to
this object; else false
.public final int hashCode()
equals(java.lang.Object)
. That is, two objects
considered equal according to the equals
method will
always produce identical hash codes by this method.hashCode
in class java.lang.Object
private boolean isIgnoreNode(Aast node, java.lang.Long ignoreID)
ignoreID
is not null
AND
ignoreID
matches its ID or any of its parents' IDs.node
- Node under test.ignoreID
- ID which demarcates an ignored branch of nodes.true
if node
should be ignored;
else false
.private boolean compareNodes(Aast x, Aast y, java.util.Set<?> props)
x
- First node.y
- Second node.props
- Set of properties to test for equality.true
if nodes test as equal, else
false
private boolean compareAnnotations(Aast x, Aast y, java.lang.String key)
x
- First node.y
- Second node.key
- Annotation key.false
if the annotation is not present in either
(but not both) nodes, or if its value differs between nodes;
else true
.private int hashCode(Aast node, java.util.Set<?> props)
props
.node
- Node whose properties are used to calculate the hash code.props
- A set of annotation keys and/or one of the special text keys.node
.private int annotationsHashCode(Aast node, java.lang.String key)
node
- Target AST.key
- Annotation key.public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException
writeExternal
in interface java.io.Externalizable
out
- The object output stream.java.io.IOException
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, java.lang.ClassNotFoundException
initialize(com.goldencode.ast.Aast, java.util.Map<java.lang.Integer, java.util.Collection<?>>)
it.readExternal
in interface java.io.Externalizable
in
- The object input stream.java.io.IOException
java.lang.ClassNotFoundException
private int computeHash()
equals(java.lang.Object)
. That is, two objects
considered equal according to the equals
method will
always produce identical hash codes by this method.private void initialize(Aast ast, java.util.Map<java.lang.Integer,java.util.Collection<?>> criteria)
ast
- Backing data; may not be null
criteria
- Map of token types to AST properties to consider for equals(java.lang.Object)
and hashCode()
; may not be null
.public static void main(java.lang.String[] args)
equals
and hashCode
methods against two P2O ASTs.args
- Two filenames are expected (the persisted ASTs to be loaded).