system/src/sc/lang/sc/ModifyDeclaration.java
public boolean transformModifyInherited(ILanguageModel.RuntimeType runtime, boolean finishTransform) {
      String nextType = typeName;
      String rest;
      ClassDeclaration subClass;
      BodyTypeDeclaration nextParent = getEnclosingType(), theRoot = null;
      BodyTypeDeclaration currentModType;
      BodyTypeDeclaration subType;
      boolean replaceNode = true;
      boolean newType;

      // Any special init-time code that the tag type needs to add.  This could be done with a mixin but we already have the element dependency
      if (element != null)
         element.addMixinProperties(this);

      do {
         // Need to handle the "a.b" types here - we create class a extends modType.a {  class b extends modType.a.b here }
         int dotIx = nextType.indexOf(".");
         if (dotIx != -1) {
            rest = nextType.substring(dotIx+1);
            nextType = nextType.substring(0, dotIx);
            int startIx = 0;
            int upCt;
            // Count number of "."s in the current name, including the one we stripped off
            for (upCt = 1; (startIx = nextType.indexOf('.', startIx)) != -1; upCt++)
               ;
            currentModType = getModifyTypeForTransform();
            for (int up = 0; up < upCt; up++) {
               if (currentModType == null) {
                  // Should not get here
                  System.err.println("*** Unable to resolve parent type for complex modify: " + typeName);
                  break;
               }
               currentModType = currentModType.getEnclosingType();
            }
         }
         else {
            rest = null;
            currentModType = getModifyTypeForTransform();
         }
         if (currentModType == null) {
            System.err.println("*** Can't find mod type for type transform: " + typeName);
            return true;
         }

         subType = null;
         Object innerTypeObj = nextParent.getInnerType(nextType, null, false, false, false, false);
         if (innerTypeObj != this && innerTypeObj instanceof BodyTypeDeclaration) {
            subType = (BodyTypeDeclaration) innerTypeObj;
            if (theRoot == null)
               replaceNode = false;
         }

         // Did not find an existing subType so create a new one
         if (subType == null) {
            newType = true;
            subClass = new ClassDeclaration();
            subClass.typeName = nextType;
            subClass.setProperty("extendsType", ClassType.create(ModelUtil.getTypeName(currentModType)));
            subClass.operator = currentModType.getDeclarationType() == DeclarationType.OBJECT ? "object" : "class";
            if (ModelUtil.hasModifier(currentModType, "public"))
               subClass.addModifier("public");

            if (theRoot == null) {
               theRoot = subClass;
            }
            else {
               nextParent.addBodyStatement(subClass);
            }
            subType = subClass;
         }
         else {
            newType = false;
            if (theRoot == null)
               theRoot = subType;
         }
         nextParent = subType;

         nextType = rest;
      } while (rest != null);

      ISemanticNode toTransform = null;
      if (replaceNode) {
         transformedType = theRoot;
         // Need to set the parent before we start it
         parentNode.replaceChild(this, theRoot);
      }
      else {
         int ix = parentNode.removeChild(this);
         if (ix == -1) {
            System.err.println("*** Cannot find child to remove in transform");
         }
         // If we remove a node in a list which is being transformed, we need to transform the next guy in the list
         // since the SemanticNodeList's loop will skip this node in this case.
         else if (parentNode instanceof SemanticNodeList) {
            SemanticNodeList list = ((SemanticNodeList) parentNode);
            if (list.size() > ix) {
               Object nextNode = list.get(ix);
               if (nextNode instanceof ISemanticNode) {
                  toTransform = (ISemanticNode) nextNode;
               }
            }
         }
      }

      // move over the body for the last guy
      if (newType) {
         subType.setProperty("body", body);

         mergeModifiersInto(subType);
      }
      else
         mergeDefinitionsInto(subType, true);

      if (finishTransform) {
         if (replaceNode)
            theRoot.transform(runtime);
         if (toTransform != null)
            toTransform.transform(runtime);
      }
      return true;
   }
/**
    * When the modify is part of an inner type, it can modify a type inherited from the extended type of the outer type.
    * This turns out not to need a true modify at all, but instead is the traditional extends operation, but where you use the
    * same name in the new type.  If this is an object definition, we use the same getX method so it effectively changes
    * the type of the object.
    *
    * This method gets called in two contexts.  For compiled types, when we transform the type we need to do this
    * conversion.   For dynamic types, we do not do the transform, but we still need this transform to be applied
    * to the model before we can run it.
    */
When the modify is part of an inner type, it can modify a type inherited from the extended type of the outer type.
This turns out not to need a true modify at all, but instead is the traditional extends operation, but where you use the
same name in the new type.  If this is an object definition, we use the same getX method so it effectively changes
the type of the object.

This method gets called in two contexts.  For compiled types, when we transform the type we need to do this
conversion.   For dynamic types, we do not do the transform, but we still need this transform to be applied
to the model before we can run it.
When the modify is part of an inner type it can modify a type inherited from the extended type of the outer type . This turns out not to need a true modify at all but instead is the traditional extends operation but where you use the same name in the new type . If this is an object definition we use the same getX method so it effectively changes the type of the object . This method gets called in two contexts . For compiled types when we transform the type we need to do this conversion . For dynamic types we do not do the transform but we still need this transform to be applied to the model before we can run it .
public boolean transformModifyInherited(ILanguageModel.RuntimeType runtime, boolean finishTransform) {
      String nextType = typeName;
      String rest;
      ClassDeclaration subClass;
      BodyTypeDeclaration nextParent = getEnclosingType(), theRoot = null;
      BodyTypeDeclaration currentModType;
      BodyTypeDeclaration subType;
      boolean replaceNode = true;
      boolean newType;
      if (element != null)
         element.addMixinProperties(this);
      do {
         int dotIx = nextType.indexOf(".");
         if (dotIx != -1) {
            rest = nextType.substring(dotIx+1);
            nextType = nextType.substring(0, dotIx);
            int startIx = 0;
            int upCt;
            for (upCt = 1; (startIx = nextType.indexOf('.', startIx)) != -1; upCt++)
               ;
            currentModType = getModifyTypeForTransform();
            for (int up = 0; up < upCt; up++) {
               if (currentModType == null) {
                  System.err.println("*** Unable to resolve parent type for complex modify: " + typeName);
                  break;
               }
               currentModType = currentModType.getEnclosingType();
            }
         }
         else {
            rest = null;
            currentModType = getModifyTypeForTransform();
         }
         if (currentModType == null) {
            System.err.println("*** Can't find mod type for type transform: " + typeName);
            return true;
         }
         subType = null;
         Object innerTypeObj = nextParent.getInnerType(nextType, null, false, false, false, false);
         if (innerTypeObj != this && innerTypeObj instanceof BodyTypeDeclaration) {
            subType = (BodyTypeDeclaration) innerTypeObj;
            if (theRoot == null)
               replaceNode = false;
         }
         if (subType == null) {
            newType = true;
            subClass = new ClassDeclaration();
            subClass.typeName = nextType;
            subClass.setProperty("extendsType", ClassType.create(ModelUtil.getTypeName(currentModType)));
            subClass.operator = currentModType.getDeclarationType() == DeclarationType.OBJECT ? "object" : "class";
            if (ModelUtil.hasModifier(currentModType, "public"))
               subClass.addModifier("public");
            if (theRoot == null) {
               theRoot = subClass;
            }
            else {
               nextParent.addBodyStatement(subClass);
            }
            subType = subClass;
         }
         else {
            newType = false;
            if (theRoot == null)
               theRoot = subType;
         }
         nextParent = subType;
         nextType = rest;
      } while (rest != null);
      ISemanticNode toTransform = null;
      if (replaceNode) {
         transformedType = theRoot;
         parentNode.replaceChild(this, theRoot);
      }
      else {
         int ix = parentNode.removeChild(this);
         if (ix == -1) {
            System.err.println("*** Cannot find child to remove in transform");
         }
         else if (parentNode instanceof SemanticNodeList) {
            SemanticNodeList list = ((SemanticNodeList) parentNode);
            if (list.size() > ix) {
               Object nextNode = list.get(ix);
               if (nextNode instanceof ISemanticNode) {
                  toTransform = (ISemanticNode) nextNode;
               }
            }
         }
      }
      if (newType) {
         subType.setProperty("body", body);
         mergeModifiersInto(subType);
      }
      else
         mergeDefinitionsInto(subType, true);
      if (finishTransform) {
         if (replaceNode)
            theRoot.transform(runtime);
         if (toTransform != null)
            toTransform.transform(runtime);
      }
      return true;
   }
public boolean transformModifyInherited ( ILanguageModel . RuntimeType runtime , boolean finishTransform ) { String nextType = typeName ; String rest ; ClassDeclaration subClass ; BodyTypeDeclaration nextParent = getEnclosingType ( ) , theRoot = null ; BodyTypeDeclaration currentModType ; BodyTypeDeclaration subType ; boolean replaceNode = true ; boolean newType ; if ( element != null ) element . addMixinProperties ( this ) ; do { int dotIx = nextType . indexOf ( "." ) ; if ( dotIx != - 1 ) { rest = nextType . substring ( dotIx + 1 ) ; nextType = nextType . substring ( 0 , dotIx ) ; int startIx = 0 ; int upCt ; for ( upCt = 1 ; ( startIx = nextType . indexOf ( '.' , startIx ) ) != - 1 ; upCt ++ ) ; currentModType = getModifyTypeForTransform ( ) ; for ( int up = 0 ; up < upCt ; up ++ ) { if ( currentModType == null ) { System . err . println ( "*** Unable to resolve parent type for complex modify: " + typeName ) ; break ; } currentModType = currentModType . getEnclosingType ( ) ; } } else { rest = null ; currentModType = getModifyTypeForTransform ( ) ; } if ( currentModType == null ) { System . err . println ( "*** Can't find mod type for type transform: " + typeName ) ; return true ; } subType = null ; Object innerTypeObj = nextParent . getInnerType ( nextType , null , false , false , false , false ) ; if ( innerTypeObj != this && innerTypeObj instanceof BodyTypeDeclaration ) { subType = ( BodyTypeDeclaration ) innerTypeObj ; if ( theRoot == null ) replaceNode = false ; } if ( subType == null ) { newType = true ; subClass = new ClassDeclaration ( ) ; subClass . typeName = nextType ; subClass . setProperty ( "extendsType" , ClassType . create ( ModelUtil . getTypeName ( currentModType ) ) ) ; subClass . operator = currentModType . getDeclarationType ( ) == DeclarationType . OBJECT ? "object" : "class" ; if ( ModelUtil . hasModifier ( currentModType , "public" ) ) subClass . addModifier ( "public" ) ; if ( theRoot == null ) { theRoot = subClass ; } else { nextParent . addBodyStatement ( subClass ) ; } subType = subClass ; } else { newType = false ; if ( theRoot == null ) theRoot = subType ; } nextParent = subType ; nextType = rest ; } while ( rest != null ) ; ISemanticNode toTransform = null ; if ( replaceNode ) { transformedType = theRoot ; parentNode . replaceChild ( this , theRoot ) ; } else { int ix = parentNode . removeChild ( this ) ; if ( ix == - 1 ) { System . err . println ( "*** Cannot find child to remove in transform" ) ; } else if ( parentNode instanceof SemanticNodeList ) { SemanticNodeList list = ( ( SemanticNodeList ) parentNode ) ; if ( list . size ( ) > ix ) { Object nextNode = list . get ( ix ) ; if ( nextNode instanceof ISemanticNode ) { toTransform = ( ISemanticNode ) nextNode ; } } } } if ( newType ) { subType . setProperty ( "body" , body ) ; mergeModifiersInto ( subType ) ; } else mergeDefinitionsInto ( subType , true ) ; if ( finishTransform ) { if ( replaceNode ) theRoot . transform ( runtime ) ; if ( toTransform != null ) toTransform . transform ( runtime ) ; } return true ; }
When the modify is part of an inner type, it can modify a type inherited from the extended type of the outer type.
When the modify is part of an inner type it can modify a type inherited from the extended type of the outer type .
// Any special init-time code that the tag type needs to add.  This could be done with a mixin but we already have the element dependency // Need to handle the "a.b" types here - we create class a extends modType.a {  class b extends modType.a.b here } // Count number of "."s in the current name, including the one we stripped off // Should not get here // Did not find an existing subType so create a new one // Need to set the parent before we start it // If we remove a node in a list which is being transformed, we need to transform the next guy in the list // since the SemanticNodeList's loop will skip this node in this case. // move over the body for the last guy