Add DataMap on Node
This commit is contained in:
pmd-core/src/main/java/net/sourceforge/pmd
@ -26,6 +26,9 @@ import net.sourceforge.pmd.lang.ast.xpath.Attribute;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.AttributeAxisIterator;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.DocumentNavigator;
|
||||
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
|
||||
import net.sourceforge.pmd.util.DataMap;
|
||||
import net.sourceforge.pmd.util.DataMap.DataKey;
|
||||
import net.sourceforge.pmd.util.DataMap.SimpleDataKey;
|
||||
|
||||
|
||||
/**
|
||||
@ -42,6 +45,10 @@ public abstract class AbstractNode implements Node {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(AbstractNode.class.getName());
|
||||
|
||||
private static final SimpleDataKey<Object> LEGACY_USER_DATA = DataMap.simpleDataKey("legacy user data");
|
||||
|
||||
private final DataMap<DataKey<?, ?>> userData = DataMap.newDataMap();
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getParent()}
|
||||
*/
|
||||
@ -73,7 +80,6 @@ public abstract class AbstractNode implements Node {
|
||||
@Deprecated
|
||||
protected GenericToken lastToken;
|
||||
private DataFlowNode dataFlowNode;
|
||||
private Object userData;
|
||||
// @Deprecated?
|
||||
private String image;
|
||||
|
||||
@ -522,12 +528,17 @@ public abstract class AbstractNode implements Node {
|
||||
|
||||
@Override
|
||||
public Object getUserData() {
|
||||
return userData;
|
||||
return userData.get(LEGACY_USER_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserData(final Object userData) {
|
||||
this.userData = userData;
|
||||
this.userData.set(LEGACY_USER_DATA, userData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataMap<DataKey<?, ?>> getUserMap() {
|
||||
return userData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,6 +14,8 @@ import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
|
||||
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
|
||||
import net.sourceforge.pmd.util.DataMap;
|
||||
import net.sourceforge.pmd.util.DataMap.DataKey;
|
||||
|
||||
/**
|
||||
* Root interface for all AST nodes. This interface provides only the API
|
||||
@ -413,6 +415,14 @@ public interface Node {
|
||||
void removeChildAtIndex(int childIndex);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a data map used to store additional information on this node.
|
||||
* This replaces the legacy {@link #getUserData()}/{@link #setUserData(Object)}.
|
||||
*
|
||||
* @return The user data map of this node
|
||||
*/
|
||||
DataMap<DataKey<?, ?>> getUserMap();
|
||||
|
||||
/**
|
||||
* Returns the parent of this node, or null if this is the {@linkplain RootNode root}
|
||||
* of the tree.
|
||||
|
94
pmd-core/src/main/java/net/sourceforge/pmd/util/DataMap.java
Normal file
94
pmd-core/src/main/java/net/sourceforge/pmd/util/DataMap.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An opaque, strongly typed heterogeneous data container.
|
||||
*
|
||||
* @param <K> Type of keys in this map
|
||||
*/
|
||||
public class DataMap<K> {
|
||||
|
||||
private final Map<DataKey<? extends K, ?>, Object> map = new IdentityHashMap<>();
|
||||
|
||||
private DataMap() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mapping to the given data.
|
||||
*
|
||||
* @param key Key
|
||||
* @param data Data mapped to the key
|
||||
* @param <T> Type of the data
|
||||
*
|
||||
* @return Previous value associated with the key (nullable)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T set(DataKey<? extends K, ? super T> key, T data) {
|
||||
return (T) map.put(key, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data currently mapped to the key.
|
||||
*
|
||||
* @param key Key
|
||||
* @param <T> Type of the data
|
||||
*
|
||||
* @return Value associated with the key (nullable)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(DataKey<? extends K, ? super T> key) {
|
||||
return (T) map.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given key has a non-null value in the map.
|
||||
*
|
||||
* @param key Key
|
||||
*
|
||||
* @return True if some value is set
|
||||
*/
|
||||
public boolean isSet(DataKey<? extends K, ?> key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public static <K> DataMap<K> newDataMap() {
|
||||
return new DataMap<>();
|
||||
}
|
||||
|
||||
public static <T> SimpleDataKey<T> simpleDataKey(final String name) {
|
||||
return new SimpleDataKey<>(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* A key for type-safe access into a {@link DataMap}. Data keys use
|
||||
* reference identity and are only compared by reference within
|
||||
* {@link DataMap}.
|
||||
*
|
||||
* @param <K> Type of the family of keys this is a part of
|
||||
* @param <T> Type of the addressed data
|
||||
*/
|
||||
public interface DataKey<K extends DataKey<K, T>, T> {
|
||||
|
||||
}
|
||||
|
||||
public static class SimpleDataKey<T> implements DataKey<SimpleDataKey<T>, T> {
|
||||
|
||||
private final String name;
|
||||
|
||||
SimpleDataKey(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user