NTA double cache check

Create issue
Issue #182 resolved
Jesper Öqvist created an issue

Found this in some generated code for the class AnyType:

 * @attribute syn nta
 * @aspect Multiplicities
 * @declaredat /home/jesper/git/multiplicities/src/main/jastadd/Multiplicities.jrag:6
public Modifiers getModifiers() {
  if(getModifiers_computed) {
    return (Modifiers) getChild(getModifiersChildPosition());
  if(getModifiers_computed) {
    return getModifiers_value;

Abstract grammar for AnyType:

abstract MultiplicityType : TypeDecl ::= /Modifiers/ /BodyDecl*/;
AnyType : MultiplicityType ::= ContainerType:Access /Modifiers/ /BodyDecl*/;

Attribute declarations:

    syn nta Modifiers MultiplicityType.getModifiers() =
            new Modifiers();
    syn nta List<BodyDecl> MultiplicityType.getBodyDeclList() =
            new List<BodyDecl>();
    syn nta Modifiers AnyType.getModifiers() =
            new Modifiers();
    syn nta List<BodyDecl> AnyType.getBodyDeclList() =
            new List<BodyDecl>();

Comments (6)

  1. Jesper Öqvist reporter

    In version 2.1.10 the double cache check is still present, and what's worse is that the second cache check seems to be the correct one because NTA attributes do not cache their value with setChild. Either the NTA should cache using setChild, or the first cache check should be removed. In either case one of the cache checks should not be generated.

  2. Jesper Öqvist reporter

    An example from JModelica:

        public Opt getFDynamicResolverOpt() {
            if(getFDynamicResolverOpt_computed) {
                return (Opt) getChild(getFDynamicResolverOptChildPosition());
            if(getFDynamicResolverOpt_computed) {                                                                                 
                return getFDynamicResolverOpt_value;                                                                              
            ASTNode$State state = state();                                                                                        
            boolean intermediate = state.INTERMEDIATE_VALUE;                                                                      
            state.INTERMEDIATE_VALUE = false;                                                                                     
            int num = state.boundariesCrossed;                                                                                    
            boolean isFinal = this.is$Final();                                                                                    
            getFDynamicResolverOpt_value = new DynamicOpt();                                                                      
            getFDynamicResolverOpt_value.is$Final = true;                                                                         
            if (true) {                                                                                                           
                getFDynamicResolverOpt_computed = true;                                                                           
            } else {                                                                                                              
            state.INTERMEDIATE_VALUE |= intermediate;                                                                             
             Opt node = (Opt) this.getChild(getFDynamicResolverOptChildPosition());                                                
             return node;                                                                                                          
  3. Jesper Öqvist reporter

    The Optional NTA caching is a separate issue. Th getChild cache access is needed to trigger rewrites, so it should be preserved. The second cache check should not happen.

  4. Log in to comment