Skip to content
Snippets Groups Projects
Select Git revision
  • f90f4d2a5c95e65a7fabc7b4834a58c15d060fd8
  • dev default protected
  • trace-incremental
3 results

Notification.tt

Blame
  • user avatar
    Emma Söderberg authored
    f90f4d2a
    History
    Notification.tt 14.39 KiB
    # Copyright (c) 2013, The JastAdd Team
    # All rights reserved.
    #
    # Redistribution and use in source and binary forms, with or without
    # modification, are permitted provided that the following conditions are met:
    #
    #     * Redistributions of source code must retain the above copyright notice,
    #       this list of conditions and the following disclaimer.
    #     * Redistributions in binary form must reproduce the above copyright
    #       notice, this list of conditions and the following disclaimer in the
    #       documentation and/or other materials provided with the distribution.
    #     * Neither the name of the Lund University nor the names of its
    #       contributors may be used to endorse or promote products derived from
    #       this software without specific prior written permission.
    #
    # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    # POSSIBILITY OF SUCH DAMAGE.
    
    ASTDecl.incValueAffectedMethod = [[
    $if(IncrementalEnabled)
    
    $if(IncrementalLevelParam)
    $if(IncrementalPropLimit)
      /** @apilevel internal */
      public boolean #name.inc_valueAffected(String attrID, Object _parameters) {
        $AttrAffectedChecks
        $if(#isASTNodeDecl)
        return true;
        $else
        return super.inc_valueAffected(attrID, _parameters);
        $endif
      }
    $endif
    $endif
    
    $endif
    ]]
    
    # TODO: Add support for more than one parameter
    ASTDecl.checkAttrValueAffected = [[
    $if(IsNTA)
    // NTAs are always considered affected
    $if(IsParameterized)
    if (attrID.equals("$AttrSign") && $(AttrSign)_values != null && $(AttrSign)_values.containsKey(_parameters)) {
    $else
    if (attrID.equals("$AttrSign") && $(AttrSign)_computed) {
    $endif
      return true;
    }
    $else
    // non-NTAs
    $if(IsParameterized)
    if (attrID.equals("$AttrSign") && $(AttrSign)_values != null && $(AttrSign)_values.containsKey(_parameters)) {
      $if(IsPrimitiveAttr)
      // store old value
      $AttrType oldValue = $AttrObjectType.valueOf(($AttrObjectType)$(AttrSign)_values.get(_parameters));
      // flush value
      $(AttrSign)_values.remove(_parameters);
      // clear dependencies in handler
      $DDGNodeName handler = ($DDGNodeName)$(AttrSign)_handler.get(_parameters);
      // compute new value
      $if(IsAttrWithOneParam)
      $(AttrType) newValue = $AttrName(($ParamTypeSignature)_parameters);
      $else
      throw new Error("No support for more than one parameter in affected value check");
      $endif
      $else
      // store old value
      $AttrType oldValue = ($AttrType)$(AttrSign)_values.get(_parameters);
      // flush value
      $(AttrSign)_values.remove(_parameters);
      // clear dependencies in handler
      $DDGNodeName handler = ($DDGNodeName)$(AttrSign)_handler.get(_parameters);
      // compute new value
      $if(IsAttrWithOneParam)
      $AttrType newValue = $(AttrName)(($ParamTypeSignature)_parameters);
      $else
      throw new Error("No support for more than one parameter in affected value check");
      $endif
      $endif
    
    $else
    if (attrID.equals("$AttrSign") && $(AttrSign)_computed) {
      // store old value + flush value
      $AttrType oldValue = $(AttrSign)_value;
      $AttrResetVisit
      $AttrResetCache
      // clear dependencies in handler
      // compute new value
      $AttrType newValue = $AttrName();
    $endif
    
      // compare old and new value
      $if(IsPrimitiveAttr)
      if (oldValue == newValue) {
      $else
      Object obj = (Object)oldValue;
      if ((obj instanceof $ASTNode && (oldValue == newValue)) ||
          (oldValue == null && newValue == null) ||
          (oldValue != null && oldValue.equals(newValue))) {
      $endif
        return false;
      }
      return true;
    }
    $endif
    ]]
    
    ASTDecl.incReactToDepChangeMethod = [[
    $if(IncrementalEnabled)
    
    $if(IncrementalLevelParam)
      /** @apilevel internal */
      public void #name.reactToDependencyChange(String attrID, Object _parameters) {
        $if(IncrementalChangeFlush)
        $include(ASTDecl.incChangeFlush)
        $endif
        $if(!#isASTNodeDecl)
        super.reactToDependencyChange(attrID, _parameters);
        $endif
      }
    $endif
    
    $if(IncrementalLevelAttr)
      /** @apilevel internal */
      public void #name.reactToDependencyChange(String attrID) {
        $if(IncrementalChangeFlush)
        $include(ASTDecl.incChangeFlush)
        $endif
        $if(!#isASTNodeDecl)
        super.reactToDependencyChange(attrID);
        $endif
      }
    $endif
    
    $if(IncrementalLevelNode)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public void #name.reactToDependencyChange() {
        $if(IncrementalChangeFlush)
        $include(ASTDecl.incChangeFlush)
        $endif
      }
    $endif
    $endif
    
    $if(IncrementalLevelRegion)
    $if(#isRegionRoot)
      /** @apilevel internal */
      public void #name.reactToDependencyChange() {
        $if(IncrementalChangeFlush)
        $include(ASTDecl.incChangeFlush)
        $endif
      }
    $else
      $if(#isASTNodeDecl)
      /** @apilevel internal */
      public void #name.reactToDependencyChange() {
      }
      $endif
    $endif
    $endif
    
    $endif
    ]]
    
    ASTDecl.incChangeFlush = [[
    $if(IncrementalChangeFlush)
    
    $if(IncrementalLevelParam)
    $if(#isASTNodeDecl)
    // flush children
    if (attrID.equals("getChild")) {
      int i = (Integer)_parameters;
      getChild_handler[i].notifyDependencies();
    }
    $endif
    $endif
    
    $if(IncrementalLevelAttr)
    $if(#isASTNodeDecl)
    if (attrID.equals("getChild")) {
      if (inc_checkRegionForInnerRewrite()) {
        $ASTNode enclosingNode = inc_locateEnclosingRewrittenNode();
        enclosingNode.getChild_handler.flushRegion();
        return;
      } else {
        inc_flushRegion_rewrites();
        getChild_handler.notifyDependencies();
        return;
      }
    }
    $endif
    $endif
    
    $if(IncrementalLevelNode)
    inc_flushRegionRoot();
    handler.notifyDependencies();
    $endif
    
    $if(IncrementalLevelRegion)
    $if(#isRegionRoot)
    inc_flushRegion();
    handler.notifyDependencies();
    $endif
    $endif
    $endif
    ]]
    
    AttrDecl.reactToDepChange = [[
    $if(IncrementalLevelParam)
    $if(#isParameterized)
    if (#(signature)_values != null && #(signature)_values.containsKey(fParams)) {
      #(signature)_values.remove(fParams);
      $DDGNodeName handler = ($DDGNodeName) #(signature)_handler.remove(fParams);
      handler.throwAway();
      handler.notifyDependencies();
    }
    $else
    $if(#isCircular)
    if (#(signature)_computed) {
    $else
    {
    $endif
      #resetVisit
      #resetCache
      #(signature)_handler.notifyDependencies();
      $include(AttrDecl.traceFlushIncAttr)
    }
    $endif
    $endif
    
    $if(IncrementalLevelAttr)
    $if(#isParameterized)
    if (#(signature)_values != null && !#(signature)_values.isEmpty()) {
      #resetVisit
      #resetCache
      #(signature)_handler.notifyDependencies();
    }
    $else
    $if(#isCircular)
    if (#(signature)_computed) {
    $else
    {
    $endif
      #resetVisit
      #resetCache
      #(signature)_handler.notifyDependencies();
    }
    $endif
    $endif
    ]]
    
    ASTDecl.incFlushMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    $if(IncrementalLevelNode)
      /** @apilevel internal */
      public void #name.inc_flush() {
        $FlushAttrs
    $if(!#isASTNodeDecl)
        super.inc_flush();
    $endif
      }
    $endif
    $if(IncrementalLevelRegion)
      /** @apilevel internal */
      public void #name.inc_flush() {
        $FlushAttrs
    $if(!#isASTNodeDecl)
        super.inc_flush();
    $endif
      }
    $endif
    $endif
    $endif
    ]]
    
    ASTDecl.attrFlush = [[
    $if(IsNTA)
    $if(IncrementalLevelRegion)
    // TODO: Add a flush of non-region root NTA children
    $endif
    $else
    $if(IsParameterized)
    if ($(AttrSign)_values != null && !$(AttrSign)_values.isEmpty()) {
      $AttrResetVisit
      $AttrResetCache
    }
    $else
    $AttrResetVisit
    $AttrResetCache
    $endif
    $endif
    ]]
    
    ASTNode.incFlushChildMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    $if(#isASTNodeDecl)
    
    $if(IncrementalLevelNode)
      /** @apilevel internal */
      public boolean $ASTNode.inc_flush_child($ASTNode node) {
        for (int i = 0; node.mayHaveRewrite() && i < children.length; i++) {
          if (children[i] == node) {
            return inc_restoreInitialForIndex(i, node.handler());
          }
        }
        return true;
      }
    $endif
    
    $endif
    $endif
    $endif
    ]]
    
    ASTDecl.incFlushNTAMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    
    $if(IncrementalLevelNode)
      /** @apilevel internal */
      public boolean #name.inc_flush_NTA($ASTNode node) {
      $if(#isListDecl)
        if (inc_internalNTAList) {
          state().enterConstruction();
          int childIndex = getIndexOfChild(node);
          removeChild(childIndex);
          state().exitConstruction();
          if (inc_internalNTAList_map.containsValue(node)) {
            for (java.util.Iterator itr = inc_internalNTAList_map.keySet().iterator(); itr.hasNext();) {
              Object key = itr.next();
              if (inc_internalNTAList_map.get(key) == node) {
                inc_internalNTAList_map.remove(key);
                break;
              }
            }
          }
          return true;
        }
        if (parent != null) {
          int index = parent.getIndexOfChild(this);
          if (index >= 0 && parent.childIsNTA(index)) {
            state().enterConstruction();
            int childIndex = getIndexOfChild(node);
            removeChild(childIndex);
            state().exitConstruction();
            return true;
          }
          return false;
        }
      $else
        $if(#isListDecl)
        if (parent != null) {
          int index = parent.getIndexOfChild(this);
          if (index >= 0 && parent.childIsNTA(index)) {
            state().enterConstruction();
            node.setParent(null);
            state().exitConstruction();
            return true;
          }
          return false;
        }
        $else
        $FlushNTAs
        $endif
      $endif
        return false;
      }
    $endif
    
    $if(IncrementalLevelRegion)
      /** @apilevel internal */
      public boolean #name.inc_flush_NTA($ASTNode node) {
      $if(#isListDecl)
      $else
        $FlushNTAs
      $endif
        return false;
      }
    $endif
    
    $endif
    $endif
    ]]
    
    ASTDecl.ntaFlush = [[
    if ($(AttrSign)_value == node) {
      state().enterConstruction();
      $(AttrSign)_value.setParent(null);
      state().exitConstruction();
      $AttrResetVisit
      $AttrResetCache
    }
    ]]
    
    ASTDecl.incFlushRegionRootMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    
    $if(IncrementalLevelNode)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public boolean $ASTNode.inc_flushRegionRoot() {
        inc_flush();
        boolean rewriteFlushed = true;
        if (parent != null) {
          rewriteFlushed = parent.inc_flush_child(this);
          // region root had an outer rewrite which was flushed (parent == null) -> done
          if (rewriteFlushed && parent == null) {
            return true;
          }
        }
        if (!rewriteFlushed) {
          $ASTNode enclosingNode = inc_locateEnclosingRewrittenNode();
          enclosingNode.handler().flushRegion();
          return false;
        }
        if (parent != null) {
          parent.inc_flush_NTA(this);     // check NTA
        }
        return true;
      }
    $endif
    $endif
    
    $endif
    $endif
    ]]
    
    ASTNode.incCheckRegionForInnerRewriteMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    
    $if(IncrementalLevelNode)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public boolean $ASTNode.inc_checkRegionForInnerRewrite() {
        for (int i = 0; children != null && children_computed != null && i < children.length && i < children_computed.length; i++) {
          $ASTNode child = children[i];
          if (child != null && !child.isRegionRoot()) {
            if (children_computed[i]) {
              if (init_children != null && i < init_children.length && init_children[i] == null) {
                return true;
              }
            } else {
              if (child.inc_checkRegionForInnerRewrite()) {
                return true;
              }
            }
          }
        }
        return false;
      }
    $endif
    $endif
    
    $if(IncrementalLevelAttr)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public boolean $ASTNode.inc_checkRegionForInnerRewrite() {
        for (int i = 0; children != null && children_computed != null && i < children.length && i < children_computed.length; i++) {
          $ASTNode child = children[i];
          if (child != null) {
            if (children_computed[i]) {
              if (init_children != null && i < init_children.length && init_children[i] == null) {
                return true;
              }
            }
          }
        }
        return false;
      }
    $endif
    $endif
    
    $endif
    $endif
    ]]
    
    ASTDecl.incFlushRegionMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    $if(IncrementalLevelRegion)
      /** @apilevel internal */
      public void #name.inc_flushRegion() {
      $if(#isASTNodeDecl)
        inc_flush();
        for (int i = 0; children != null && i < children.length; i++) {
          $ASTNode child = children[i];
          if (child != null && !child.isRegionRoot()) {
            child.inc_flushRegion();
          }
        }
      $else
        super.inc_flushRegion();
      $endif
        $FlushNTAsInRegion
      }
    $endif
    $endif
    $endif
    ]]
    
    ASTDecl.flushNTAsInRegion = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    
    $if(IsNTA)
    $if(IsParameterized)
    if ($(AttrSign)_proxy != null) {
      $(AttrSign)_values.clear();
    }
    $else
    $if(IsNtaWithTree)
    if ($(AttrSign)_value != null) {
      state().enterConstruction();
      $(AttrSign)_value.setParent(null);
      state().exitConstruction();
      $AttrResetVisit
      $AttrResetCache
    }
    $endif
    $endif
    $endif
    
    $endif
    $endif
    ]]
    
    ASTNode.incFlushRegionRewritesMethod = [[
    $if(IncrementalEnabled)
    $if(IncrementalChangeFlush)
    
    $if(IncrementalLevelAttr)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public boolean $ASTNode.inc_flushRegion_rewrites() {
        for (int i = 0; children != null && i < children.length; i++) {
          $ASTNode child = children[i];
          if (child == null) {
            continue;
          }
          // rewritten child
          if (children_computed != null && i < children_computed.length && children_computed[i]) {
            if (!inc_restoreInitialForIndex(i, getChild_handler)) {
              return false;
            }
          }
        }
        return true;
      }
    $endif
    $endif
    
    $endif
    $endif
    ]]
    
    ASTNode.incNotifyForRemoveMethod = [[
    $if(IncrementalEnabled)
    
    $if(IncrementalLevelRegion)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public void $ASTNode.inc_notifyForRemove() {
        handler().flushRegion();
      }
    $endif
    $endif
    
    $if(IncrementalLevelNode)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public void $ASTNode.inc_notifyForRemove() {
        handler.flushRegion();
      }
    $endif
    $endif
    
    $if(IncrementalLevelAttr)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public void $ASTNode.inc_notifyForRemove() {
        getParent_handler.notifyDependencies();
      }
    $endif
    $endif
    
    $if(IncrementalLevelParam)
    $if(#isASTNodeDecl)
      /** @apilevel internal */
      public void $ASTNode.inc_notifyForRemove() {
        getParent_handler.notifyDependencies();
      }
    $endif
    $endif
    $endif
    ]]