Changeset 13921


Ignore:
Timestamp:
Oct 31, 2019 2:02:20 PM (12 days ago)
Author:
jwedin
Message:

GenericAnnotationNodes can now be immutable. Changed so static singleton annotations are immutable. Added and updated Javadoc for some annotation node classes. Updated the state in GenericAnnotationNode to no longer be volatile. #5865

Location:
branches/dev-jw-2590/Compiler
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/dev-jw-2590/Compiler/ModelicaFlatTree/src/jastadd/FlatAnnotations.jrag

    r13294 r13921  
    2828    public class FlatAnnotation extends GenericAnnotationNode<FlatAnnotation, FlatAnnotationProvider, FExp> {
    2929
    30         public static final FlatAnnotation AMBIGUOUS_ANNOTATION =  new FlatAnnotation(null, null, null);
    31 
     30        public static final FlatAnnotation AMBIGUOUS_ANNOTATION =  new FlatAnnotation(null, null, null, Mutability.IMMUTABLE);
     31
     32        /** Creates a mutable flat annotation.
     33         * See {@link GenericAnnotationNode#GenericAnnotationNode(String, AnnotationProvider, GenericAnnotationNode)}
     34         */
    3235        protected FlatAnnotation(String name, FlatAnnotationProvider node, FlatAnnotation parent) {
    3336            super(name, node, parent);
     37        }
     38
     39        /** Creates a flat annotation.
     40         * See {@link GenericAnnotationNode#GenericAnnotationNode(String, AnnotationProvider, GenericAnnotationNode, Mutability)}
     41         */
     42        protected FlatAnnotation(String name, FlatAnnotationProvider node, FlatAnnotation parent, Mutability mutability) {
     43            super(name, node, parent, mutability);
    3444        }
    3545
  • branches/dev-jw-2590/Compiler/ModelicaFrontEnd/src/jastadd/util/SrcAnnotations.jrag

    r13294 r13921  
    106106    public class SrcAnnotationNode extends GenericAnnotationNode<SrcAnnotationNode, SrcAnnotationProvider, SrcExp> {
    107107       
    108         public static final SrcAnnotationNode AMBIGUOUS_ANNOTATION =  new SrcAnnotationNode(null, null, null,
    109                 SrcAnnotationNode.defaultEvaluator());
     108        public static final SrcAnnotationNode AMBIGUOUS_ANNOTATION =  new SrcAnnotationNode(null, null, null, SrcAnnotationNode.defaultEvaluator(), Mutability.IMMUTABLE);
    110109       
    111110        private Evaluator<SrcExp> evaluator;
    112        
     111
     112        /** Creates a mutable source annotation.
     113         * See {@link GenericAnnotationNode#GenericAnnotationNode(String, AnnotationProvider, GenericAnnotationNode)}
     114         */
    113115        protected SrcAnnotationNode(String name, SrcAnnotationProvider node, SrcAnnotationNode parent,
    114116                Evaluator<SrcExp> evaluator) {
    115117            super(name, node, parent);
     118            this.evaluator = evaluator;
     119        }
     120
     121        /** Creates a source annotation.
     122         * See {@link GenericAnnotationNode#GenericAnnotationNode(String, AnnotationProvider, GenericAnnotationNode, Mutability)}
     123         */
     124        protected SrcAnnotationNode(String name, SrcAnnotationProvider node, SrcAnnotationNode parent, Evaluator<SrcExp> evaluator, Mutability mutability) {
     125            super(name, node, parent, mutability);
    116126            this.evaluator = evaluator;
    117127        }
  • branches/dev-jw-2590/Compiler/ModelicaFrontEnd/src/java/org/jmodelica/util/annotations/GenericAnnotationNode.java

    r13009 r13921  
    5151        N extends AnnotationProvider<N, V>, V extends Evaluable> {
    5252
     53    public enum Mutability {
     54        MUTABLE, IMMUTABLE,
     55    }
    5356    /**
    5457     * Vendor name.
     
    6063    private final T parent;
    6164
    62     private volatile Collection<T> subNodes_cache;
    63     private volatile Map<String, T> subNodesNameMap_cache;
    64     private volatile boolean nodeWasSet = false;
    65     private volatile boolean subNodeNodeWasSet = false;
    66     private volatile T valueAnnotation_cache;
    67     private volatile boolean valueAnnotation_cacheComputed = false;
    68 
    69     /**
    70      * Constructor. <code>name</code> may be null, some nodes simply do not have a name.
     65    private final Collection<T> subNodes_cache;
     66    private final Map<String, T> subNodesNameMap_cache;
     67    private boolean nodeWasSet = false;
     68    private boolean subNodeNodeWasSet = false;
     69    private T valueAnnotation_cache;
     70    private boolean valueAnnotation_cacheComputed;
     71    private Mutability mutability;
     72
     73    /**
     74     * Constructor to create a mutable annotation node.<br>
     75     * <code>name</code> may be null, some nodes simply do not have a name.<br>
    7176     * <code>node</code> may only be null for the instances returned by
    7277     * {@link #ambiguousNode()} and nodes which don't exist yet.
     
    7479     * @param name Name of the node, optionally null.
    7580     * @param node The node that this annotation node represent.
     81     * @param parent The parent of the node
    7682     */
    7783    protected GenericAnnotationNode(String name, N node, T parent) {
     84        this(name, node, parent, Mutability.MUTABLE);
     85    }
     86
     87    /**
     88     * Constructor to create an annotation node.<br>
     89     * <code>name</code> may be null, some nodes simply do not have a name.<br>
     90     * <code>node</code> may only be null for the instances returned by
     91     * {@link #ambiguousNode()} and nodes which don't exist yet.
     92     *
     93     * @param name Name of the node, optionally null.
     94     * @param node The node that this annotation node represent.
     95     * @param parent The parent of the node
     96     * @param mutability The mutability of the node, i.e., if it is mutable or immutable.
     97     */
     98    protected GenericAnnotationNode(String name, N node, T parent, Mutability mutability) {
     99        this.mutability = mutability;
    78100        this.parent = parent;
    79         setNode(name, node);
    80     }
    81 
    82    
    83     /**
     101        valueAnnotation_cacheComputed = isImmutable();
     102        subNodes_cache = isImmutable() ? Collections.emptyList() : new ArrayList<>();
     103        subNodesNameMap_cache = isImmutable() ? Collections.emptyMap() : new HashMap<>();
     104        List<String> l = Collections.emptyList();
     105        List<String> a = new ArrayList<>();
     106        if (!isImmutable()) {
     107            setNode(name, node);
     108        }
     109    }
     110
     111    private boolean isImmutable() {
     112        return mutability == Mutability.IMMUTABLE;
     113    }
     114
     115    /**
    84116     * This is an internal method, do not call it.
    85117     */
     
    87119        if (isSubNodesCacheFresh()) {
    88120            return;
    89         }
    90         if (subNodes_cache == null) {
    91             subNodes_cache = Collections.emptyList();
    92         }
    93         if (subNodesNameMap_cache == null) {
    94             subNodesNameMap_cache = Collections.emptyMap();
    95121        }
    96122
     
    119145        for(List<T> oldNodes : oldNodesMap.values()) {
    120146            for(T oldNode: oldNodes) {
    121                 //TODO move the setting of the node field in the subnode to null to an explicit step
     147                //TODO move the setting of the node field in the sub node to null to an explicit step
    122148                createOrSetSubNodeAndAddToCaches(oldNode, oldNode.name(), null, subNodes, subNodesNameMap);
    123149            }
    124150        }
    125         subNodes_cache = subNodes;
    126         subNodesNameMap_cache = subNodesNameMap;
     151
     152        subNodes_cache.clear();
     153        subNodes_cache.addAll(subNodes);
     154        subNodesNameMap_cache.clear();
     155        subNodesNameMap_cache.putAll(subNodesNameMap);
    127156        clearNodeWasSetFlags();
    128157    }
     
    238267        T subNode = subNodesNameMap_cache.get(paths[currentIndex]);
    239268        if (subNode == null) {
    240             makeEmptySubNodesCacheMutable();
    241269            subNode = createOrSetSubNodeAndAddToCaches(subNode, paths[currentIndex], null, subNodes_cache,
    242270                    subNodesNameMap_cache);
     
    245273    }
    246274
    247     private void makeEmptySubNodesCacheMutable() {
    248         if (subNodesNameMap_cache.isEmpty()) {
    249             subNodesNameMap_cache = new HashMap<String, T>();
    250         }
    251         if (subNodes_cache.isEmpty()) {
    252             subNodes_cache = new ArrayList<T>();
    253         }
    254     }
    255    
    256275    /**
    257276     * Returns reference to it self, but with correct type! This pattern
     
    300319     * @return true if this node has sub nodes, otherwise false.
    301320     */
    302     public boolean hasSubNodes() {
     321    private boolean hasSubNodes() {
    303322        computeSubNodesCache();
    304323        return !subNodes_cache.isEmpty();
     
    378397        return name;
    379398    }
    380    
     399
     400    /**
     401     * Ensures that this node is mutable.
     402     * @throws UnsupportedOperationException if this node is immutable
     403     */
     404    private void verifyMutability() {
     405        if (isImmutable()) {
     406            throw new UnsupportedOperationException();
     407        }
     408    }
     409
    381410    /**
    382411     * Updates the name and node of this GenericAnnotationNode.
     
    386415    @SuppressWarnings("unchecked")
    387416    protected void updateNode(String newName, N node) {
     417        verifyMutability();
    388418        if (parent() != null && !name().equals(newName)) {
    389419            asGeneric(parent()).updateSubNode(newName, node, (T) this);
     
    392422        }
    393423    }
     424
    394425    /**
    395426     * Sets the name and node of this GenericAnnotationNode. This is an internal method,
     
    399430     */
    400431    private void setNode(String newName, N node) {
     432        verifyMutability();
    401433        // This is an internal method because it does not update the caches in the parent node.
    402434        // it needs to be protected to be accessible from the parent node.
     
    451483    public T valueAsAnnotation() {
    452484        if (!valueAnnotation_cacheComputed) {
     485            verifyMutability();
    453486            valueAnnotation_cacheComputed = true;
    454487            if (isAmbiguous()) {
     
    473506     * annotation node.
    474507     *
    475      * @param value Value which can be an annotation node
    476508     * @return Provider which reflects the value as annotation node
    477509     */
     
    524556
    525557    /**
    526      * This is an internal method, call {{@link #exists()} instead.
     558     * This is an internal method, call {{@link #nodeExists()} instead.
    527559     * @return true if this node is available.
    528560     */
     
    885917     */
    886918    protected void disconnectFromNode() {
     919        verifyMutability();
    887920        if (parent != null) {
    888921            node = null;
     
    897930
    898931    private void setNodeWasSetFlags() {
     932        verifyMutability();
    899933        nodeWasSet = true;
    900934        if (parent() != null) {
     
    904938
    905939    private void setSubNodeNodeWasSet() {
     940        verifyMutability();
    906941        subNodeNodeWasSet = true;
    907942    }
    908943
    909944    private void clearNodeWasSetFlags() {
     945        verifyMutability();
    910946        nodeWasSet = false;
    911947        subNodeNodeWasSet = false;
  • branches/dev-jw-2590/Compiler/ModelicaFrontEnd/test/junit/org/jmodelica/util/annotations/mock/DummyAnnotationNode.java

    r13009 r13921  
    11package org.jmodelica.util.annotations.mock;
    22
     3import org.jmodelica.util.annotations.AnnotationProvider;
    34import org.jmodelica.util.annotations.GenericAnnotationNode;
    45import org.jmodelica.util.values.Evaluable;
     
    67public class DummyAnnotationNode extends GenericAnnotationNode<DummyAnnotationNode, DummyAnnotProvider, Evaluable> {
    78
    8     private static DummyAnnotationNode ambiguousNode = new DummyAnnotationNode("Ambiguous", null, null);
     9    private static DummyAnnotationNode ambiguousNode = new DummyAnnotationNode(null, null, null, Mutability.IMMUTABLE);
     10
     11    /** Creates a mutable dummy annotation.
     12     * See {@link GenericAnnotationNode#GenericAnnotationNode(String, AnnotationProvider, GenericAnnotationNode)}
     13     */
    914    public DummyAnnotationNode(String name, DummyAnnotProvider node, DummyAnnotationNode parent) {
    1015        super(name, node, parent);
     16    }
     17
     18    /** Creates a dummy annotation.
     19     * See {@link GenericAnnotationNode#GenericAnnotationNode(String, AnnotationProvider, GenericAnnotationNode, Mutability)}
     20     */
     21    public DummyAnnotationNode(String name, DummyAnnotProvider node, DummyAnnotationNode parent, Mutability mutability) {
     22        super(name, node, parent, mutability);
    1123    }
    1224
Note: See TracChangeset for help on using the changeset viewer.