Github user mbeckerle commented on a diff in the pull request:
https://github.com/apache/incubator-daffodil/pull/5#discussion_r149837035
--- Diff:
daffodil-core/src/main/scala/edu/illinois/ncsa/daffodil/dsom/AnnotatedSchemaComponent.scala
---
@@ -41,23 +41,122 @@ import edu.illinois.ncsa.daffodil.equality._
import
edu.illinois.ncsa.daffodil.schema.annotation.props.PropertyLookupResult
import edu.illinois.ncsa.daffodil.schema.annotation.props.NotFound
import edu.illinois.ncsa.daffodil.schema.annotation.props.Found
+import edu.illinois.ncsa.daffodil.schema.annotation.props.FindPropertyMixin
+
+/**
+ * Only objects from which we generate processors (parsers/unparsers)
+ * can lookup property values.
+ *
+ * This avoids the possibility of a property being resolved incorrectly by
+ * not looking at the complete chain of schema components contributing to
the
+ * property resolution.
+ *
+ * The only objects that should resolve properties are
+ * ElementRef, Root, LocalElementDecl, Sequence, Choice, SequenceRef,
ChoiceRef
+ *
+ * These are all the "real" terms. Everything else is just contributing
+ * properties to the mix, but they are not points where properties are
+ * used to generate processors.
+ */
+trait ResolvesProperties
+ extends FindPropertyMixin { self: AnnotatedSchemaComponent =>
+
+ def term: Term
+
+ private def findNonDefaultProperty(pname: String): PropertyLookupResult
= {
+ val result = findDefaultOrNonDefaultProperty(pname,
nonDefaultPropertySources)
+ result match {
+ case f: Found => f
+ case NotFound(nd, d, _) =>
+ Assert.invariant(d.isEmpty)
+ }
+ result
+ }
+
+ private def findDefaultProperty(pname: String): PropertyLookupResult = {
+ val result = findDefaultOrNonDefaultProperty(pname,
defaultPropertySources)
+ val fixup = result match {
+ case Found(value, loc, pname, _) =>
+ // found as a default property.
+ // supply constructor's last arg is boolean indicating it's a
default property
+ Found(value, loc, pname, true)
+ case NotFound(nd, d, pn) =>
+ Assert.invariant(d.isEmpty)
+ NotFound(Seq(), nd, pn) // we want the places we searched shown as
default locations searched
+ }
+ fixup
+ }
+
+ override def findPropertyOption(pname: String): PropertyLookupResult = {
+ ExecutionMode.requireCompilerMode
+ // first try in regular properties
+ val regularResult = resolver.findNonDefaultProperty(pname)
+ regularResult match {
+ case f: Found => f
+ case NotFound(nonDefaultLocsTried1, defaultLocsTried1, _) => {
+ Assert.invariant(defaultLocsTried1.isEmpty)
+ val defaultResult = resolver.findDefaultProperty(pname)
+ defaultResult match {
+ case f: Found => f
+ case NotFound(nonDefaultLocsTried2, defaultLocsTried2, _) => {
+ Assert.invariant(nonDefaultLocsTried2.isEmpty)
+ // did not find it at all. Return a NotFound with all the
places we
+ // looked non-default and default.
+ val nonDefaultPlaces = nonDefaultLocsTried1
+ val defaultPlaces = defaultLocsTried2
+ NotFound(nonDefaultPlaces, defaultPlaces, pname)
+ }
+ }
+ }
+ }
+ }
+}
+
+abstract class AnnotatedSchemaComponentImpl( final override val xml: Node,
+ final override val parent: SchemaComponent)
+ extends AnnotatedSchemaComponent
/**
* Shared characteristics of any annotated schema component.
* Not all components can carry DFDL annotations.
*/
+trait AnnotatedSchemaComponent
+ extends SchemaComponent
+ with AnnotatedMixin
+ with OverlapCheckMixin {
-abstract class AnnotatedSchemaComponent(xml: Node, sc: SchemaComponent)
- extends SchemaComponent(xml, sc)
- with AnnotatedMixin {
+ final lazy val term: Term = this match {
+ case gr: GroupRef => gr.asModelGroup
+ // case mg: ModelGroup => mg.parent match {
+ // case ggd: GlobalGroupDef => {
+ // // this is the model group that is the definition of
+ // // a global group, so our term is the group reference
referring to this.
+ // ggd.groupRef.asModelGroup
+ // }
+ // case _ => mg
+ // }
+ case t: Term => t
+ case ged: GlobalElementDecl => ged.elementRef
+ case ty: SimpleTypeDefBase => ty.elementBase
+ case ty: ComplexTypeBase => ty.elementBase
+ case ggd: GlobalGroupDef => ggd.groupRef.asModelGroup
+ case sd: SchemaDocument =>
+ Assert.usageError("not to be called for schema documents")
+ }
+
+ final lazy val resolver: ResolvesProperties = {
+ val res = this match {
+ case sd: SchemaDocument => sd
+ case _ => term
+ }
+ res
+ }
requiredEvaluations(annotationObjs)
requiredEvaluations(shortFormPropertiesCorrect)
requiredEvaluations(nonDefaultPropertySources)
requiredEvaluations(defaultPropertySources)
- def term: Term
--- End diff --
Add scaladoc. What does term do if the annotated schema component is say, a
variable declaration?
---