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