stevedlawrence commented on a change in pull request #326: Daffodil 2280 
cleanup - removes backpointers and factory patterns no longer needed
URL: https://github.com/apache/incubator-daffodil/pull/326#discussion_r393672279
 
 

 ##########
 File path: daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
 ##########
 @@ -243,209 +247,120 @@ trait Term
 
   final val tID = UUID.randomUUID()
 
-  /** Overridden as false for elements with dfdl:inputValueCalc property. */
-  lazy val isRepresented = true
+  final lazy val isRepresented = this match {
+    case eb: ElementBase => {
+      val isRep = eb.inputValueCalcOption.isInstanceOf[NotFound]
+      if (!isRep) {
+        if (isOptional) {
+          SDE("inputValueCalc property can not appear on optional elements")
+        }
+        if (!isScalar) {
+          SDE("inputValueCalc property can not appear on array elements")
+        }
+      }
+      isRep
+    }
+    case _ => true
+  }
 
   /**
-   * nearestEnclosingSequence
+   * Answers whether this term appears anywhere inside an unordered sequence.
    *
-   * An attribute that looks upward to the surrounding
-   * context of the schema, and not just lexically surrounding context. It 
needs to see
-   * what declarations will physically surround the place. This is the dynamic 
scope,
-   * not just the lexical scope. So, a named global type still has to be able 
to
-   * ask what sequence is surrounding the element that references the global 
type.
-   *
-   * This is why we have to have the GlobalXYZDefFactory stuff. Because this 
kind of back
-   * pointer (contextual sensitivity) prevents sharing.
+   * A term can be in both ordered and unordered sequences if it appears in a 
global
+   * sequence def, which has refs to it that specify sequenceKind='ordered' on 
some
+   * and sequenceKind='unordered' on others of the group refs.
    */
-  final lazy val nearestEnclosingSequence: Option[SequenceTermBase] = 
enclosingTerm match {
-    case None => None
-    //
-    // We want to recurse outward, and don't care about these implied sequence 
terms
-    // that choices wrap around branch elements.
-    //
-    case Some(cs: ChoiceBranchImpliedSequence) => 
enclosingTerm.get.nearestEnclosingSequence
-    case Some(s: SequenceTermBase) => Some(s)
-    case Some(_) => enclosingTerm.get.nearestEnclosingSequence
-  }
-
-  final lazy val nearestEnclosingChoiceBeforeSequence: Option[ChoiceTermBase] 
= enclosingTerm match {
-    case None => None
-    //
-    // We want to recurse outward, and don't care about these implied sequence 
terms
-    // that choices wrap around branch elements.
-    //
-    case Some(cs: ChoiceBranchImpliedSequence) => 
enclosingTerm.get.nearestEnclosingChoiceBeforeSequence
-    case Some(s: SequenceTermBase) => None
-    case Some(c: ChoiceTermBase) => Some(c)
-    case Some(_) => enclosingTerm.get.nearestEnclosingChoiceBeforeSequence
-  }
-
-  final lazy val nearestEnclosingUnorderedSequence: Option[SequenceTermBase] = 
enclosingTerm match {
-    case None => None
-    case Some(s: SequenceTermBase) if !s.isOrdered => Some(s)
-    case Some(_) => enclosingTerm.get.nearestEnclosingUnorderedSequence
-  }
-
-  final lazy val isInUnorderedSequence: Boolean = 
!nearestEnclosingUnorderedSequence.isEmpty
-
-  final lazy val nearestEnclosingUnorderedSequenceBeforeSequence: 
Option[SequenceTermBase] = enclosingTerm match {
-    case None => None
-    case Some(s: SequenceTermBase) if !s.isOrdered => Some(s)
-    case Some(s: SequenceTermBase) => None
-    case Some(_) => enclosingTerm.get.nearestEnclosingUnorderedSequence
-  }
-
-  final lazy val inChoiceBeforeNearestEnclosingSequence: Boolean = 
enclosingTerm match {
-    case None => false
-    case Some(s: SequenceTermBase) => false
-    case Some(c: ChoiceTermBase) => true
-    case Some(_) => enclosingTerm.get.inChoiceBeforeNearestEnclosingSequence
-  }
-
-  final lazy val nearestEnclosingElement: Option[ElementBase] = enclosingTerm 
match {
-    case None => None
-    case Some(eb: ElementBase) => Some(eb)
-    case Some(_) => enclosingTerm.get.nearestEnclosingElement
+  final lazy val isEverInUnorderedSequence: Boolean = {
+    optLexicalParent.map {
+      case s: SequenceTermBase => !s.isOrdered
+      case gsd: GlobalSequenceGroupDef => {
+        gsd.schemaSet.root.groupRefsTo(gsd).exists {
+          case sgr: SequenceGroupRef => !sgr.isOrdered
+        }
+      }
+      case c: ChoiceDefMixin => false
+      case ct: ComplexTypeBase => false
+      case x => Assert.invariantFailed("Unexpected lexical parent: " + x)
+    }.getOrElse(false)
   }
 
-  final lazy val immediatelyEnclosingModelGroup: Option[ModelGroup] = {
+  final lazy val immediatelyEnclosingGroupDef: Option[GroupDefLike] = {
     optLexicalParent.flatMap { lexicalParent =>
-      val res = lexicalParent match {
-        case c: ChoiceTermBase => Some(c)
+      val res: Option[GroupDefLike] = lexicalParent match {
+        case c: Choice => Some(c)
         //
         // skip past the implied sequence that is wrapped around choice 
branches
         // to the actual choice
         //
-        case c: ChoiceBranchImpliedSequence => c.immediatelyEnclosingModelGroup
-        case s: SequenceTermBase => Some(s)
+        case c: ChoiceBranchImpliedSequence => c.immediatelyEnclosingGroupDef
+        case s: Sequence => Some(s)
         case d: SchemaDocument => {
           // we must be the Root elementRef or a quasi node
           Assert.invariant(this.isInstanceOf[Root] || 
this.isInstanceOf[QuasiElementDeclBase])
           None
         }
-        case gr: GroupRef => gr.asModelGroup.immediatelyEnclosingModelGroup
-        case gdd: GlobalGroupDef => Some(gdd.groupRef.asModelGroup)
-        case ged: GlobalElementDecl => 
ged.elementRef.immediatelyEnclosingModelGroup
-        case ct: ComplexTypeBase => {
-          None
-          // The above formerly was ct.element.immediatelyEnclosingModelGroup,
-          // but if we have a CT as our parent, the group around the element 
whose type
-          // that is, isn't "immediately enclosing".
-        }
-        case qe: QuasiElementDeclBase => {
-          //
-          // If your lexical parent is a Quasi-element, then your model group 
is
-          // the one surrounding the quasi-element.
-          //
-          qe.immediatelyEnclosingModelGroup
-        }
+        case gdd: GlobalGroupDef => Some(gdd)
+        case ctd: ComplexTypeBase => None
+        case rt: RepTypeQuasiElementDecl => rt.immediatelyEnclosingGroupDef
+        case std: SimpleTypeBase => None
         case _ => Assert.invariantFailed("immediatelyEnclosingModelGroup 
called on " + this + " with lexical parent " + lexicalParent)
       }
       res
     }
   }
 
+  lazy val immediatelyEnclosingModelGroup: Option[ModelGroup] =
+    immediatelyEnclosingGroupDef.flatMap {
+      _ match {
+        case mg: ModelGroup => Some(mg)
+        case _ => None
+      }
+    }
+
   /**
-   * One-based position in the nearest enclosing sequence.
-   * Follows backpointers from group defs to group refs until it
-   * finds a sequence.
+   * Prior using one-based position in the enclosing lexical sequence.
+   *
+   * Nil if enclosed by a choice def, or this is the root.
    */
-  final lazy val positionInNearestEnclosingSequence: Int = {
-    // FIXME:Classic example of a method that creates a pointless
-    // need for the backpointers to parent that make structure
-    // sharing of the DSOM objects impossible. This should be a value
-    // passed down to a SequenceChild constructor, and the algorithms
-    // that use this should be on SequenceTermBase or child classes thereof.
-    val optET = enclosingTerm
-    val optNES = nearestEnclosingSequence
-    val res =
-      (optET, optNES) match {
-        case (Some(et), Some(nes)) if (et == nes) =>
-          position
-        case _ => {
-          if (this.isInstanceOf[Root]) 1
-          else {
-            optET match {
-              case Some(term: Term) => term.positionInNearestEnclosingSequence
-              case x => Assert.invariantFailed("For " + this + " unable to 
compute position in nearest enclosing sequence. The enclosingComponent was " + 
x)
-            }
-          }
-        }
-      }
-    res
+  final lazy val priorSiblings = {
+    optLexicalParent match {
+      case Some(stb: SequenceTermBase) => stb.groupMembers.take(position - 1)
+      case Some(gsgd: GlobalSequenceGroupDef) => 
gsgd.groupMembers.take(position - 1)
+      case _ => Nil
+    }
   }
 
-  final lazy val allSiblings: Seq[Term] = {
-    val res = nearestEnclosingSequence.map { enc =>
-      val allSiblings = enc.groupMembers
-      allSiblings
+  /**
+   * Siblings after this in the lexically enclosing group.
+   *
+   * Nil if enclosed by a choice def, or this is the root.
+   */
+  final lazy val laterSiblings = {
+    optLexicalParent match {
+      case Some(stb: SequenceTermBase) => stb.groupMembers.drop(position)
+      case Some(gsgd: GlobalSequenceGroupDef) => 
gsgd.groupMembers.drop(position)
+      case _ => Nil
     }
-    res.getOrElse(Nil)
   }
 
-  final lazy val priorSiblings = ListUtils.preceding(allSiblings, this)
-  final lazy val laterSiblings = ListUtils.tailAfter(allSiblings, this)
-  final lazy val laterElementSiblings = laterSiblings.collect { case elt: 
ElementBase => elt }
+  /**
+   * Siblings (including self) in the lexically enclosing sequence def.
+   *
+   * Nil if enclosed by a choice def, or this is the root.
+   */
+  final lazy val allSiblings = {
+    optLexicalParent match {
+      case Some(stb: SequenceTermBase) => stb.groupMembers
+      case Some(gsgd: GlobalSequenceGroupDef) => gsgd.groupMembers
+      case _ => Nil
+    }
+  }
+
+  // final lazy val laterElementSiblings = laterSiblings.collect { case elt: 
ElementBase => elt }
 
 Review comment:
   Remove comment.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to