Skip to content

Commit

Permalink
porting #208 workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Jul 28, 2013
1 parent da1980e commit 4d3ae66
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 34 deletions.
Expand Up @@ -17,7 +17,7 @@ trait ContextProcessor extends ScalaNames { self: Namer with Lookup =>
tagged.tag.toString + "??"
}

def getTraitName(tagged: Tagged[XComplexType]): String =
def getTraitName(tagged: TaggedType[XComplexType]): String =
context.traitNames.get(tagged) getOrElse {
error(tagged.tag.toString + "??")
}
Expand Down
40 changes: 24 additions & 16 deletions cli/src/main/scala/scalaxb/compiler/xsd2/Generator.scala
Expand Up @@ -48,7 +48,7 @@ class Generator(val schema: ReferenceSchema,
case _ => Vector()
}): _*)

def processComplexType(decl: Tagged[XComplexType]): Seq[Trippet] =
def processComplexType(decl: TaggedType[XComplexType]): Seq[Trippet] =
if (context.baseToSubs.contains(decl)) {
generateBaseComplexTypeTrait(buildTraitSymbol(decl), decl) +:
(if (decl.abstractValue) Vector()
Expand All @@ -58,7 +58,7 @@ class Generator(val schema: ReferenceSchema,

/** recursively return compositors.
*/
private def compositorsR(decl: Tagged[XComplexType]): Seq[TaggedParticle[KeyedGroup]] = {
private def compositorsR(decl: TaggedType[XComplexType]): Seq[TaggedParticle[KeyedGroup]] = {
val ps = decl.primarySequence
val singleps = ps map { tagged => Occurrence(tagged).isSingle } getOrElse {false}

Expand All @@ -82,7 +82,7 @@ class Generator(val schema: ReferenceSchema,
else ps.toSeq ++ nonps
}

def generateComplexTypeEntity(sym: ClassSymbol, decl: Tagged[XComplexType]): Trippet = {
def generateComplexTypeEntity(sym: ClassSymbol, decl: TaggedType[XComplexType]): Trippet = {
logger.debug("generateComplexTypeEntity: emitting %s" format sym.toString)

lazy val attributeSeqRef: Tagged[AttributeSeqParam] = TaggedAttributeSeqParam(AttributeSeqParam(), decl.tag)
Expand Down Expand Up @@ -132,7 +132,7 @@ class Generator(val schema: ReferenceSchema,
compositorCodes: _*)
}

private def generateDefaultFormat(sym: ClassSymbol, decl: Tagged[XComplexType],
private def generateDefaultFormat(sym: ClassSymbol, decl: TaggedType[XComplexType],
hasAttributes: Boolean, hasSequenceParam: Boolean, longAll: Boolean): Tree = {
val particles = decl.splitNonEmptyParticles
val unmixedParserList = particles map { buildParticleParser(_, decl.effectiveMixed, decl.effectiveMixed) }
Expand Down Expand Up @@ -242,7 +242,7 @@ class Generator(val schema: ReferenceSchema,
).flatten)
}

private def generateBaseComplexTypeTrait(sym: ClassSymbol, decl: Tagged[XComplexType]): Trippet = {
private def generateBaseComplexTypeTrait(sym: ClassSymbol, decl: TaggedType[XComplexType]): Trippet = {
logger.debug("generateBaseComplexTypeTrait: emitting %s" format sym.toString)

lazy val attributeSeqRef: Tagged[AttributeSeqParam] = TaggedAttributeSeqParam(AttributeSeqParam(), decl.tag)
Expand Down Expand Up @@ -270,7 +270,7 @@ class Generator(val schema: ReferenceSchema,
makeImplicitValue(sym))
}

private def generateBaseComplexTypeFormat(sym: ClassSymbol, decl: Tagged[XComplexType]): Tree = {
private def generateBaseComplexTypeFormat(sym: ClassSymbol, decl: TaggedType[XComplexType]): Tree = {
logger.debug("generateBaseComplexTypeFormat - ", sym)

val dfmt = defaultFormatterSymbol(sym)
Expand Down Expand Up @@ -323,7 +323,7 @@ class Generator(val schema: ReferenceSchema,
NEW(ANONDEF(dfmt.decodedName) := BLOCK())
}

def complexTypeSuperTypes(decl: Tagged[XComplexType]): Seq[Type] = {
def complexTypeSuperTypes(decl: TaggedType[XComplexType]): Seq[Type] = {
def choices: List[TaggedKeyedGroup] =
(for {
sch <- context.schemas
Expand Down Expand Up @@ -409,37 +409,45 @@ class Generator(val schema: ReferenceSchema,
Trippet(TRAITDEF(sym))
}

def processSimpleType(decl: Tagged[XSimpleType]): Seq[Trippet] =
def processSimpleType(decl: TaggedType[XSimpleType]): Seq[Trippet] =
Seq(generateSimpleType(userDefinedClassSymbol(decl), decl))

private def generateSimpleType(sym: ClassSymbol, decl: Tagged[XSimpleType]) = {
private def generateSimpleType(sym: ClassSymbol, decl: TaggedType[XSimpleType]) = {
val enums = filterEnumeration(decl)
val enumValues = enums map { enum =>
CASEOBJECTDEF(userDefinedClassSymbol(enum)) withParents(sym) := BLOCK(
DEF(Any_toString) withFlags(Flags.OVERRIDE) := LIT(enum.value.value)
DEF(Any_toString) withFlags(Flags.OVERRIDE) := LIT(decl.enumValue(enum).toString)
)
}
val valueTree: Tree =
if (decl.qnameBased) PAREN(BLOCK(
VAL(TUPLE(ID("ns"), ID("localPart"))) := (HelperClass DOT "splitQName") APPLY(REF("value"), REF("scope")),
NEW(QNameClass, REF("ns") DOT "orNull", REF("localPart")) TOSTRING
))
else REF("value")
val companionTree: Tree =
if (enums.isEmpty) OBJECTDEF(sym) := BLOCK(
DEF("fromString", sym) withParams(PARAM("value", StringClass)) := REF(sym) APPLY()
DEF("fromString", sym) withParams(PARAM("value", StringClass), PARAM("scope", NamespaceBindingClass)) := REF(sym) APPLY()
)
else OBJECTDEF(sym) := BLOCK(
DEF("fromString", sym) withParams(PARAM("value", StringClass)) := REF("value") MATCH(
enums map { enum => CASE (LIT(enum.value.value)) ==> REF(userDefinedClassSymbol(enum)) }
DEF("fromString", sym) withParams(PARAM("value", StringClass), PARAM("scope", NamespaceBindingClass)) := valueTree MATCH(
enums map { enum => CASE (LIT(decl.enumValue(enum).toString)) ==> REF(userDefinedClassSymbol(enum)) }
))
Trippet(TRAITDEF(sym).tree :: companionTree ::
enumValues.toList, Nil,
generateSimpleTypeFormat(sym, decl) :: Nil,
makeImplicitValue(sym) :: Nil)
}

private def generateSimpleTypeFormat(sym: ClassSymbol, decl: Tagged[XSimpleType]): Tree = {
private def generateSimpleTypeFormat(sym: ClassSymbol, decl: TaggedType[XSimpleType]): Tree = {
val dfmt = defaultFormatterSymbol(sym)

TRAITDEF(dfmt.decodedName) withParents(XMLFormatClass TYPE_OF sym) := BLOCK(List(
DEF("reads", eitherType(StringClass, sym)) withParams(
PARAM("seq", NodeSeqClass), PARAM("stack", TYPE_LIST(ElemNameClass))) :=
RIGHT((sym DOT "fromString")(REF("seq") DOT "text")),
PARAM("seq", NodeSeqClass), PARAM("stack", TYPE_LIST(ElemNameClass))) := REF("seq") MATCH(
CASE(ID("elem") withType(ElemClass)) ==> RIGHT((sym DOT "fromString")(REF("elem") DOT "text", REF("elem") DOT "scope")),
CASE(WILDCARD) ==> RIGHT((sym DOT "fromString")(REF("seq") DOT "text", REF(TopScopeModule)))
),
DEF("writes", NodeSeqClass) withParams(PARAM("__obj", sym),
PARAM("__namespace", optionType(StringClass)),
PARAM("__elementLabel", optionType(StringClass)),
Expand Down
4 changes: 2 additions & 2 deletions cli/src/main/scala/scalaxb/compiler/xsd2/Lookup.scala
Expand Up @@ -114,10 +114,10 @@ trait Lookup extends ContextProcessor { self: Namer with Splitter with Symbols =
tagged.value.ref map { ref => buildAttributeGroupTypeSymbol(resolveAttributeGroup(ref)) } getOrElse {
userDefinedClassSymbol(tagged) }

def buildComplexTypeSymbol(tagged: Tagged[XComplexType]): ClassSymbol =
def buildComplexTypeSymbol(tagged: TaggedType[XComplexType]): ClassSymbol =
userDefinedClassSymbol(tagged.tag.namespace, getName(tagged))

def buildTraitSymbol(tagged: Tagged[XComplexType]): ClassSymbol =
def buildTraitSymbol(tagged: TaggedType[XComplexType]): ClassSymbol =
userDefinedClassSymbol(tagged.tag.namespace, getTraitName(tagged))

def buildNamedGroupSymbol(tagged: Tagged[XNamedGroup]): ClassSymbol =
Expand Down
4 changes: 2 additions & 2 deletions cli/src/main/scala/scalaxb/compiler/xsd2/SchemaContext.scala
Expand Up @@ -28,7 +28,7 @@ import java.net.URI

case class SchemaContext(schemas: mutable.ListBuffer[ReferenceSchema] = mutable.ListBuffer(),
names: mutable.ListMap[Tagged[_], String] = mutable.ListMap(),
traitNames: mutable.ListMap[Tagged[XComplexType], String] = mutable.ListMap(),
traitNames: mutable.ListMap[TaggedType[XComplexType], String] = mutable.ListMap(),
packageNames: mutable.ListMap[Option[String], Option[String]] = mutable.ListMap(),
baseToSubs: mutable.ListMap[Tagged[XComplexType], List[Tagged[XComplexType]]] = mutable.ListMap(),
baseToSubs: mutable.ListMap[TaggedType[XComplexType], List[TaggedType[XComplexType]]] = mutable.ListMap(),
prefixes: mutable.ListMap[URI, String] = mutable.ListMap())
25 changes: 25 additions & 0 deletions cli/src/main/scala/scalaxb/compiler/xsd2/SchemaOps.scala
Expand Up @@ -180,6 +180,31 @@ case class SimpleTypeOps(decl: TaggedType[XSimpleType]) {
case _ => sys.error("baseType#: Unsupported content " + decl.xSimpleDerivationOption3.value.toString)
}
}
/** this decl is a decendant of QName. */
def qnameBased(implicit lookup: Lookup): Boolean = {
import Defs._
import lookup.{BuiltInType, SimpleType}
import scalaxb.compiler.xsd.XsQName
decl.value.xSimpleDerivationOption3.value match {
case XRestriction(_, _, _, Some(base), _) =>
QualifiedName(base) match {
case BuiltInType(TaggedSymbol(XsQName, _)) => true
case SimpleType(tagged) => SimpleTypeOps(tagged).qnameBased
case _ => false
}
case XRestriction(_, XSimpleRestrictionModelSequence(Some(simpleType), _), _, _, _) =>
SimpleTypeOps(Tagged(simpleType, decl.tag)).qnameBased
case _ => false
}
}

def enumValue(enum: Tagged[XNoFixedFacet])(implicit lookup: Lookup): Any =
if (qnameBased) {
import scalaxb.compiler.Module.splitTypeName
val (ns, localPart) = splitTypeName(enum.value.value, lookup.scopeEv)
QualifiedName(ns map {new URI(_)}, localPart)
}
else enum.value.value
}

/** represents attributes param */
Expand Down
20 changes: 10 additions & 10 deletions cli/src/main/scala/scalaxb/compiler/xsd2/namer.scala
Expand Up @@ -45,7 +45,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}}
}

def nameSimpleTypes(decl: Tagged[XSimpleType]) {
def nameSimpleTypes(decl: TaggedType[XSimpleType]) {
if (containsEnumeration(decl)) {
val name = makeProtectedSimpleTypeName(decl)
logger.debug("nameSimpleTypes: named %s", name)
Expand All @@ -54,7 +54,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}
}

def nameTrait(decl: Tagged[XComplexType]) {
def nameTrait(decl: TaggedType[XComplexType]) {
val rawName = decl.name.get
val initialName = if (rawName.last == 'e') rawName.dropRight(1) + "able"
else rawName + "able"
Expand All @@ -63,7 +63,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
traitNames(decl) = name
}

def nameComplexTypes(decl: Tagged[XComplexType]) {
def nameComplexTypes(decl: TaggedType[XComplexType]) {
val name = makeProtectedComplexTypeName(decl)
logger.debug("nameComplexTypes: named %s", name)
names(decl) = name
Expand All @@ -83,7 +83,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}
}

def nameComplexTypeCompositors(decl: Tagged[XComplexType]) {
def nameComplexTypeCompositors(decl: TaggedType[XComplexType]) {
val primarySequence = decl.primarySequence
implicit val s = schema.unbound
val cs: Seq[TaggedParticle[KeyedGroup]] = decl.toSeq collect {
Expand Down Expand Up @@ -127,9 +127,9 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}
}

def nameEnumValues(decl: Tagged[XSimpleType]) {
def nameEnumValues(decl: TaggedType[XSimpleType]) {
filterEnumeration(decl) map { enum =>
names(enum) = makeProtectedEnumTypeName(enum)
names(enum) = makeProtectedEnumTypeName(enum, decl)
}
}

Expand All @@ -140,14 +140,14 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
def makeProtectedElementTypeName(elem: Tagged[XElement]): String =
makeProtectedTypeName(elem.name, "", elem.tag, true)

def makeProtectedComplexTypeName(decl: Tagged[XComplexType]): String =
def makeProtectedComplexTypeName(decl: TaggedType[XComplexType]): String =
makeProtectedTypeName(decl.name, "Type", decl.tag, true)

def makeProtectedSimpleTypeName(decl: Tagged[XSimpleType]): String =
def makeProtectedSimpleTypeName(decl: TaggedType[XSimpleType]): String =
makeProtectedTypeName(decl.name, "Type", decl.tag, true)

def makeProtectedEnumTypeName(enum: Tagged[XNoFixedFacet]): String =
makeProtectedTypeName(enum.value.value, "Value", enum.tag, true)
def makeProtectedEnumTypeName(enum: Tagged[XNoFixedFacet], decl: TaggedType[XSimpleType]): String =
makeProtectedTypeName(decl.enumValue(enum).toString, "Value", enum.tag, true)

def makeProtectedNamedGroup(tagged: Tagged[XNamedGroup]): String =
makeProtectedTypeName(tagged.name.get + "Group", "", tagged.tag, true)
Expand Down
3 changes: 0 additions & 3 deletions cli/src/main/scala/scalaxb/compiler/xsd2/symbols.scala
Expand Up @@ -34,9 +34,6 @@ trait Symbols {
lazy val JavaxXmlNamespacePackage = JavaxXmlPackageClass.newPackage("namespace")
lazy val JavaxXmlNamespacePackageClass = JavaxXmlNamespacePackage.moduleClass
lazy val QNameClass = JavaxXmlNamespacePackageClass.newClass("QName")

// workaround treehugger 0.2.0 bug
lazy val NamespaceBindingClass = definitions.getClass("scala.xml.NamespaceBinding")

def xmlFormatType(arg: Type): Type = appliedType(XMLFormatClass.typeConstructor, List(arg))
def parserType(arg: Type): Type = appliedType(ParserClass.typeConstructor, List(arg))
Expand Down
18 changes: 18 additions & 0 deletions cli/src/test/scala/EntitySpec.scala
Expand Up @@ -17,6 +17,7 @@ object EntitySpec extends Specification { def is = sequential ^
"each enumerations represented as case object" ! enum2^
"be referenced as the trait" ! enum3^
"generate a companion object named similarly" ! enum4^
"generate a fromString method using underlying value if it derives from QName" !enum5^
end^
"top-level complex types should" ^
"generate a case class named similarly" ! complexType1^
Expand Down Expand Up @@ -85,6 +86,11 @@ object EntitySpec extends Specification { def is = sequential ^
<xs:enumeration value="SKIM"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="QNameEnum">
<xs:restriction base="xs:QName">
<xs:enumeration value="tns:Receiver"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="SimpleTypeTest">
<xs:sequence>
<xs:element name="milk1" type="tns:MilkType"/>
Expand All @@ -109,6 +115,18 @@ object EntitySpec extends Specification { def is = sequential ^
enumEntitySource must contain("""object MilkType {""")
}

def enum5 = {
enumEntitySource must contain("""object QNameEnum {
def fromString(value: String, scope: scala.xml.NamespaceBinding): example.QNameEnum =
({
val (ns, localPart) = scalaxb.Helper.splitQName(value, scope)
new javax.xml.namespace.QName(ns.orNull, localPart).toString
}) match {
case "{http://www.example.com/}Receiver" => example.U123httpu58u47u47wwwu46exampleu46comu47u125Receiver
}
}""")
}

lazy val complexTypeEntitySource = module.processNode(complexTypeCardinalityXML, "example")(0)

lazy val expectedComplexTypeTest =
Expand Down

0 comments on commit 4d3ae66

Please sign in to comment.