git.iko.soy/typeable/xsd-isogen
on 909baa9 help sign in
34 files changed+462−1584
since splitsnapshots
unifiedsplit
cabal.project+2−2 golden/README−3 golden/ambig.xsd−20 golden/ambig.xsd.hs−39 golden/ambig1.xsd−16 golden/ambig1.xsd.hs−39 golden/enum.xsd−12 golden/enum.xsd.hs−25 golden/extension.xsd−36 golden/extension.xsd.hs−83 golden/extension_dep.xsd−31 golden/extension_dep.xsd.hs−101 golden/import.xsd−16 golden/import.xsd.hs−33 golden/import_ambig.xsd−26 golden/import_ambig.xsd.hs−50 golden/imported.xsd−9 golden/imported.xsd.hs−27 golden/include.xsd−5 golden/include.xsd.hs−27 golden/included.xsd−6 golden/included.xsd.hs−27 golden/seq.xsd−14 golden/seq.xsd.hs−34 golden/simple.xsd−25 golden/simple.xsd.hs−40 golden/test.sh−5 src/BuiltInTypes.hs−67 src/Gen.hs−213 src/Main.hs+440−436 src/Options.hs+6−10 src/References.hs−80 stack.yaml−12 xsd-isogen.cabal+14−15
cabal.project+2−2
@@ -2,5 +2,5 @@ packages: .
22
33source-repository-package
44 type: git
5− location: https://github.com/typeable/xsd-parser.git
6− tag: e08a37cf08674a492407b9b7f4a61e8faedb1590
5+ location: https://github.com/dredozubov/xsd-parser.git
6+ tag: f9cbe65a9b9c37e9015a73707f1cd4f00e79c96e
golden/READMEdeleted−3
@@ -1,3 +0,0 @@
1−To use the golden tests, cd to this folder and run test.sh. It will run
2−xsd-isogen on each xsd file here. Then use git diff to check the
3−difference.
golden/ambig.xsddeleted−20
@@ -1,20 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:simpleType name="stringtype">
4− <xs:restriction base="xs:string"/>
5− </xs:simpleType>
6− <xs:element name="Aa">
7− <xs:complexType>
8− <xs:sequence>
9− <xs:element name="firstName" type="stringtype"/>
10− </xs:sequence>
11− </xs:complexType>
12− </xs:element>
13− <xs:element name="Ab">
14− <xs:complexType>
15− <xs:sequence>
16− <xs:element name="firstName" type="stringtype"/>
17− </xs:sequence>
18− </xs:complexType>
19− </xs:element>
20−</xs:schema>
golden/ambig.xsd.hsdeleted−39
@@ -1,39 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−{-|
28−Generated from: Aa
29−-}
30−"Aa" =:= record ParserAndGenerator
31− ! "firstName" [t|XmlStringtype|]
32−
33−{-|
34−Generated from: Ab
35−-}
36−"Ab1" =:= record ParserAndGenerator
37− ! "firstName" [t|XmlStringtype|]
38−
39−
golden/ambig1.xsddeleted−16
@@ -1,16 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:simpleType name="stringtype">
4− <xs:restriction base="xs:string"/>
5− </xs:simpleType>
6− <xs:complexType name="Aa">
7− <xs:sequence>
8− <xs:element name="firstName" type="stringtype"/>
9− </xs:sequence>
10− </xs:complexType>
11− <xs:complexType name="Ab">
12− <xs:sequence>
13− <xs:element name="firstName" type="stringtype"/>
14− </xs:sequence>
15− </xs:complexType>
16−</xs:schema>
golden/ambig1.xsd.hsdeleted−39
@@ -1,39 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−{-|
28−Generated from: Aa
29−-}
30−"Aa" =:= record ParserAndGenerator
31− ! "firstName" [t|XmlStringtype|]
32−
33−{-|
34−Generated from: Ab
35−-}
36−"Ab1" =:= record ParserAndGenerator
37− ! "firstName" [t|XmlStringtype|]
38−
39−
golden/enum.xsddeleted−12
@@ -1,12 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:simpleType name="stringtype">
4− <xs:annotation>
5− <xs:documentation>Blah</xs:documentation>
6− </xs:annotation>
7− <xs:restriction base="xs:string">
8− <xs:enumeration value="day"/>
9− <xs:enumeration value="night"/>
10− </xs:restriction>
11− </xs:simpleType>
12−</xs:schema>
golden/enum.xsd.hsdeleted−25
@@ -1,25 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: stringtype
18−
19−Blah
20−-}
21−"Stringtype" Exhaustive =:= enum ParserAndGenerator
22− & "Day"
23− & "Night"
24−
25−
golden/extension.xsddeleted−36
@@ -1,36 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:complexType name="some">
4− <xs:sequence>
5− <xs:element name="a" type="xs:string"/>
6− </xs:sequence>
7− </xs:complexType>
8− <xs:complexType name="basetype">
9− <xs:sequence>
10− <xs:element name="a" type="xs:string"/>
11− </xs:sequence>
12− </xs:complexType>
13− <xs:complexType name="ext1">
14− <xs:complexContent>
15− <xs:extension base="basetype">
16− <xs:sequence>
17− <xs:element name="b" type="xs:int"/>
18− </xs:sequence>
19− </xs:extension>
20− </xs:complexContent>
21− </xs:complexType>
22− <xs:complexType name="ext2">
23− <xs:complexContent>
24− <xs:extension base="basetype">
25− <xs:sequence>
26− <xs:element name="c" type="xs:int"/>
27− </xs:sequence>
28− </xs:extension>
29− </xs:complexContent>
30− </xs:complexType>
31− <xs:complexType name="other">
32− <xs:sequence>
33− <xs:element name="a" type="basetype"/>
34− </xs:sequence>
35− </xs:complexType>
36−</xs:schema>
golden/extension.xsd.hsdeleted−83
@@ -1,83 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: basetype
18−-}
19−"Basetype" =:= record ParserAndGenerator
20− ! "a" [t|Text|]
21−
22−{-|
23−Generated from: ext2
24−-}
25−"Ext2" =:= record ParserAndGenerator
26− ! "a" [t|Text|]
27− ! "c" [t|Integer|]
28−
29−{-|
30−Generated from: ext1
31−-}
32−"Ext1" =:= record ParserAndGenerator
33− ! "a" [t|Text|]
34− ! "b" [t|Integer|]
35−
36−data AnyXmlBasetype
37− = TheXmlBasetype !XmlBasetype
38− | TheXmlExt2 !XmlExt2
39− | TheXmlExt1 !XmlExt1
40− deriving (Eq, Show)
41−
42−instance NFData AnyXmlBasetype where
43− rnf = rwhnf
44−
45−instance FromDom AnyXmlBasetype where
46− fromDom = do
47− tp <- parseAttribute
48− (matchName "{http://www.w3.org/2001/XMLSchema-instance}type")
49− Right
50− case tp of
51− "Basetype" -> TheXmlBasetype <$> fromDom
52− "Ext2" -> TheXmlExt2 <$> fromDom
53− "Ext1" -> TheXmlExt1 <$> fromDom
54− _ -> throwParserError (PEOther "Unexpected type")
55−
56−instance ToXML AnyXmlBasetype where
57− toXML (TheXmlBasetype a) = toXML a
58− toXML (TheXmlExt2 a) = toXML a
59− toXML (TheXmlExt1 a) = toXML a
60−
61−instance ToXmlParentAttributes AnyXmlBasetype where
62− toXmlParentAttributes (TheXmlBasetype a) =
63− ("{http://www.w3.org/2001/XMLSchema-instance}type", "Basetype")
64− : toXmlParentAttributes a
65− toXmlParentAttributes (TheXmlExt2 a) =
66− ("{http://www.w3.org/2001/XMLSchema-instance}type", "Ext2")
67− : toXmlParentAttributes a
68− toXmlParentAttributes (TheXmlExt1 a) =
69− ("{http://www.w3.org/2001/XMLSchema-instance}type", "Ext1")
70− : toXmlParentAttributes a
71−{-|
72−Generated from: other
73−-}
74−"Other" =:= record ParserAndGenerator
75− ! "a" [t|AnyXmlBasetype|]
76−
77−{-|
78−Generated from: some
79−-}
80−"Some" =:= record ParserAndGenerator
81− ! "a" [t|Text|]
82−
83−
golden/extension_dep.xsddeleted−31
@@ -1,31 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:complexType name="X">
4− <xs:sequence>
5− <xs:element name="s" type="xs:string"/>
6− </xs:sequence>
7− </xs:complexType>
8− <xs:complexType name="B">
9− <xs:sequence>
10− <xs:element name="s" type="xs:string"/>
11− </xs:sequence>
12− </xs:complexType>
13− <xs:complexType name="C">
14− <xs:complexContent>
15− <xs:extension base="B">
16− <xs:sequence>
17− <xs:element name="x" type="X"/>
18− </xs:sequence>
19− </xs:extension>
20− </xs:complexContent>
21− </xs:complexType>
22− <xs:complexType name="A">
23− <xs:complexContent>
24− <xs:extension base="C">
25− <xs:sequence>
26− <xs:element name="i" type="xs:int"/>
27− </xs:sequence>
28− </xs:extension>
29− </xs:complexContent>
30− </xs:complexType>
31−</xs:schema>
golden/extension_dep.xsd.hsdeleted−101
@@ -1,101 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: X
18−-}
19−"X" =:= record ParserAndGenerator
20− ! "s" [t|Text|]
21−
22−{-|
23−Generated from: A
24−-}
25−"A" =:= record ParserAndGenerator
26− ! "s" [t|Text|]
27− ! "x" [t|XmlX|]
28− ! "i" [t|Integer|]
29−
30−{-|
31−Generated from: B
32−-}
33−"B" =:= record ParserAndGenerator
34− ! "s" [t|Text|]
35−
36−{-|
37−Generated from: C
38−-}
39−"C" =:= record ParserAndGenerator
40− ! "s" [t|Text|]
41− ! "x" [t|XmlX|]
42−
43−data AnyXmlC
44− = TheXmlC !XmlC
45− | TheXmlA !XmlA
46− deriving (Eq, Show)
47−
48−instance NFData AnyXmlC where
49− rnf = rwhnf
50−
51−instance FromDom AnyXmlC where
52− fromDom = do
53− tp <- parseAttribute
54− (matchName "{http://www.w3.org/2001/XMLSchema-instance}type")
55− Right
56− case tp of
57− "C" -> TheXmlC <$> fromDom
58− "A" -> TheXmlA <$> fromDom
59− _ -> throwParserError (PEOther "Unexpected type")
60−
61−instance ToXML AnyXmlC where
62− toXML (TheXmlC a) = toXML a
63− toXML (TheXmlA a) = toXML a
64−
65−instance ToXmlParentAttributes AnyXmlC where
66− toXmlParentAttributes (TheXmlC a) =
67− ("{http://www.w3.org/2001/XMLSchema-instance}type", "C")
68− : toXmlParentAttributes a
69− toXmlParentAttributes (TheXmlA a) =
70− ("{http://www.w3.org/2001/XMLSchema-instance}type", "A")
71− : toXmlParentAttributes a
72−data AnyXmlB
73− = TheXmlB !XmlB
74− | TheAnyXmlC !AnyXmlC
75− deriving (Eq, Show)
76−
77−instance NFData AnyXmlB where
78− rnf = rwhnf
79−
80−instance FromDom AnyXmlB where
81− fromDom = do
82− tp <- parseAttribute
83− (matchName "{http://www.w3.org/2001/XMLSchema-instance}type")
84− Right
85− case tp of
86− "B" -> TheXmlB <$> fromDom
87− "C" -> TheAnyXmlC <$> fromDom
88− _ -> throwParserError (PEOther "Unexpected type")
89−
90−instance ToXML AnyXmlB where
91− toXML (TheXmlB a) = toXML a
92− toXML (TheAnyXmlC a) = toXML a
93−
94−instance ToXmlParentAttributes AnyXmlB where
95− toXmlParentAttributes (TheXmlB a) =
96− ("{http://www.w3.org/2001/XMLSchema-instance}type", "B")
97− : toXmlParentAttributes a
98− toXmlParentAttributes (TheAnyXmlC a) =
99− ("{http://www.w3.org/2001/XMLSchema-instance}type", "C")
100− : toXmlParentAttributes a
101−
golden/import.xsddeleted−16
@@ -1,16 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema
3− xmlns:xs="http://www.w3.org/2001/XMLSchema"
4− xmlns:my="uri:my"
5− xmlns:my1="uri:my1"
6− targetNamespace="uri:my1"
7− >
8− <xs:import schemaLocation="imported.xsd" namespace="uri:my"/>
9− <xs:element name="person">
10− <xs:complexType>
11− <xs:sequence>
12− <xs:element name="name" type="my:stringtype"/>
13− </xs:sequence>
14− </xs:complexType>
15− </xs:element>
16−</xs:schema>
golden/import.xsd.hsdeleted−33
@@ -1,33 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: uri:my:stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−{-|
28−Generated from: uri:my1:person
29−-}
30−"Person" =:= record ParserAndGenerator
31− ! "{uri:my1}name" [t|XmlStringtype|]
32−
33−
golden/import_ambig.xsddeleted−26
@@ -1,26 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema
3− xmlns:xs="http://www.w3.org/2001/XMLSchema"
4− xmlns:my="uri:my"
5− xmlns:my1="uri:my1"
6− targetNamespace="uri:my1"
7− >
8− <xs:import schemaLocation="imported.xsd" namespace="uri:my"/>
9− <xs:simpleType name="stringtype">
10− <xs:restriction base="xs:string"/>
11− </xs:simpleType>
12− <xs:element name="AaBb">
13− <xs:complexType>
14− <xs:sequence>
15− <xs:element name="name" type="my:stringtype"/>
16− </xs:sequence>
17− </xs:complexType>
18− </xs:element>
19− <xs:element name="AaBc">
20− <xs:complexType>
21− <xs:sequence>
22− <xs:element name="name" type="my1:stringtype"/>
23− </xs:sequence>
24− </xs:complexType>
25− </xs:element>
26−</xs:schema>
golden/import_ambig.xsd.hsdeleted−50
@@ -1,50 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: uri:my:stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−{-|
28−Generated from: uri:my1:AaBb
29−-}
30−"AaBb" =:= record ParserAndGenerator
31− ! "{uri:my1}name" [t|XmlStringtype|]
32−
33−{-|
34−Generated from: uri:my1:stringtype
35−-}
36−newtype XmlStringtype1
37− = XmlStringtype1
38− { unXmlStringtype1 :: Text
39− } deriving (Show, Eq, NFData, ToXML)
40−
41−instance FromDom XmlStringtype1 where
42− fromDom = XmlStringtype1 <$> fromDom
43−
44−{-|
45−Generated from: uri:my1:AaBc
46−-}
47−"AaBc1" =:= record ParserAndGenerator
48− ! "{uri:my1}name" [t|XmlStringtype1|]
49−
50−
golden/imported.xsddeleted−9
@@ -1,9 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema
3− xmlns:xs="http://www.w3.org/2001/XMLSchema"
4− targetNamespace="uri:my"
5− >
6− <xs:simpleType name="stringtype">
7− <xs:restriction base="xs:string"/>
8− </xs:simpleType>
9−</xs:schema>
golden/imported.xsd.hsdeleted−27
@@ -1,27 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: uri:my:stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−
golden/include.xsddeleted−5
@@ -1,5 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:include schemaLocation="included.xsd"/>
4− <xs:element name="name" type="stringtype"/>
5−</xs:schema>
golden/include.xsd.hsdeleted−27
@@ -1,27 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−
golden/included.xsddeleted−6
@@ -1,6 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:simpleType name="stringtype">
4− <xs:restriction base="xs:string"/>
5− </xs:simpleType>
6−</xs:schema>
golden/included.xsd.hsdeleted−27
@@ -1,27 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: stringtype
18−-}
19−newtype XmlStringtype
20− = XmlStringtype
21− { unXmlStringtype :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStringtype where
25− fromDom = XmlStringtype <$> fromDom
26−
27−
golden/seq.xsddeleted−14
@@ -1,14 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:simpleType name="str">
4− <xs:restriction base="xs:string"/>
5− </xs:simpleType>
6− <xs:element name="customer">
7− <xs:complexType>
8− <xs:sequence>
9− <xs:element name="firstName" type="str"/>
10− <xs:element name="lastName" type="str"/>
11− </xs:sequence>
12− </xs:complexType>
13− </xs:element>
14−</xs:schema>
golden/seq.xsd.hsdeleted−34
@@ -1,34 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: str
18−-}
19−newtype XmlStr
20− = XmlStr
21− { unXmlStr :: Text
22− } deriving (Show, Eq, NFData, ToXML)
23−
24−instance FromDom XmlStr where
25− fromDom = XmlStr <$> fromDom
26−
27−{-|
28−Generated from: customer
29−-}
30−"Customer" =:= record ParserAndGenerator
31− ! "firstName" [t|XmlStr|]
32− ! "lastName" [t|XmlStr|]
33−
34−
golden/simple.xsddeleted−25
@@ -1,25 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3− <xs:simpleType name="stringtype">
4− <xs:annotation>
5− <xs:documentation>Blah</xs:documentation>
6− </xs:annotation>
7− <xs:restriction base="xs:string"/>
8− </xs:simpleType>
9− <xs:element name="name" type="stringtype"/>
10− <xs:element name="a">
11− <xs:annotation>
12− <xs:documentation>A blah</xs:documentation>
13− </xs:annotation>
14− <xs:complexType>
15− <xs:sequence>
16− <xs:element name="a" type="stringtype"/>
17− <xs:element name="b" minOccurs="1" type="stringtype"/>
18− <xs:element name="c" minOccurs="0" maxOccurs="1" type="stringtype"/>
19− <xs:element name="d" minOccurs="1" maxOccurs="2" type="stringtype"/>
20− <xs:element name="e" minOccurs="1" maxOccurs="unbounded" type="stringtype"/>
21− <xs:element name="f" type="xs:decimal"/>
22− </xs:sequence>
23− </xs:complexType>
24− </xs:element>
25−</xs:schema>
golden/simple.xsd.hsdeleted−40
@@ -1,40 +0,0 @@
1−-- This file was generated by xsd-isogen version 0.1.0.0
2−-- https://github.com/dredozubov/xsd-isogen
3−
4−{-# OPTIONS_GHC -Wno-unused-imports #-}
5−module Dummy where
6−
7−import Control.DeepSeq
8−import Data.Scientific
9−import Data.THGen.XML
10−import Text.XML.DOM.Parser
11−import Text.XML.Writer
12−import Text.XML.ParentAttributes
13−import Prelude hiding ((*), (+))
14−
15−
16−{-|
17−Generated from: stringtype
18−
19−Blah
20−-}
21−newtype XmlStringtype
22− = XmlStringtype
23− { unXmlStringtype :: Text
24− } deriving (Show, Eq, NFData, ToXML)
25−
26−instance FromDom XmlStringtype where
27− fromDom = XmlStringtype <$> fromDom
28−
29−{-|
30−Generated from: a
31−-}
32−"A" =:= record ParserAndGenerator
33− ! "a" [t|XmlStringtype|]
34− ! "b" [t|XmlStringtype|]
35− ? "c" [t|XmlStringtype|]
36− + "d" [t|XmlStringtype|]
37− + "e" [t|XmlStringtype|]
38− ! "f" [t|Scientific|]
39−
40−
golden/test.shdeleted−5
@@ -1,5 +0,0 @@
1−#!/bin/bash
2−
3−for file in *.xsd; do
4− cabal run -v0 xsd-isogen -- -i $file > $file.hs
5−done
src/BuiltInTypes.hsdeleted−67
@@ -1,67 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−
3−module BuiltInTypes
4−( builtInTypes
5−)
6−where
7−
8−import Data.Map (Map)
9−import qualified Data.Map as Map
10−
11−import qualified Xsd
12−
13−import Gen
14−
15−builtInTypes :: Map Xsd.QName TypeName
16−builtInTypes = Map.fromList . map qualify $
17− [ ("anyURI", "Text")
18− , ("base64Binary", "ByteString")
19− , ("boolean", "Bool")
20− , ("date", "Date")
21− , ("dateTime", "Text")
22− , ("dateTimeStamp", "Text")
23− , ("decimal", "Scientific")
24− , ("integer", "Integer")
25− , ("long", "Integer")
26− , ("int", "Integer")
27− , ("short", "Integer")
28− , ("byte", "Integer")
29− , ("nonNegativeInteger", "Integer")
30− , ("positiveInteger", "Integer")
31− , ("unsignedLong", "Integer")
32− , ("unsignedInt", "Integer")
33− , ("unsignedByte", "Integer")
34− , ("nonPositiveInteger", "Integer")
35− , ("negativeInteger", "Integer")
36− , ("float", "Float")
37− , ("double", "Scientific")
38− , ("gDay", "Day")
39− , ("gMonth", "Text")
40− , ("gMonthDay", "Text")
41− , ("gYear", "Text")
42− , ("gYearMonth", "Text")
43− , ("hexBinary", "Text")
44− , ("NOTATION", "Text")
45− , ("QName", "Text")
46− , ("string", "Text")
47− , ("normalizedString", "Text")
48− , ("token", "Text")
49− , ("language", "Text")
50− , ("NCName", "Text")
51− , ("Entity", "Text")
52− , ("ID", "Text")
53− , ("IDREF", "Text")
54− , ("NMToken", "Text")
55− , ("time", "Text")
56− , ("duration", "Text")
57− ]
58− where
59− qualify (n, t) =
60− let
61− tn = TypeName
62− { tnName = t
63− , tnPrefixed = t
64− , tnQName = qname
65− }
66− qname = Xsd.QName (Just (Xsd.Namespace Xsd.schemaNamespace)) n
67− in (qname, tn)
src/Gen.hsdeleted−213
@@ -1,213 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−
4−module Gen
5−( GenState(..)
6−, Gen
7−, runGen
8−, TypeName(..)
9−, getMode
10−, writeCode
11−, warn
12−, genError
13−, resolveType
14−, resolveTypeName
15−, knownTypeName
16−, extensions
17−, makeTypeName
18−, makeFieldName
19−, makeEnumName
20−)
21−where
22−
23−import qualified Data.Char as Char
24−import Data.Text (Text)
25−import qualified Data.Text as Text
26−import Data.Maybe
27−import Data.Set (Set)
28−import qualified Data.Set as Set
29−import Data.Map (Map)
30−import qualified Data.Map as Map
31−import Control.Monad
32−import Control.Monad.Trans
33−import Control.Monad.Trans.State
34−import Control.Monad.Trans.Except
35−import qualified Xsd
36−
37−import Options (GenType(..))
38−
39−-- | Generator state
40−data GenState = GenState
41− { gsTypes :: Map Xsd.QName Xsd.Type
42− -- ^ All global types
43− , gsExtensions :: Map Xsd.QName [(Xsd.QName, Xsd.Type)]
44− -- ^ Lift of extension of the specified type
45− , gsKnownTypes :: Map Xsd.QName TypeName
46− -- ^ Global types that were already processed and their generated names
47− , gsBoundTypeName :: Set Text
48− -- ^ prefixed names that were already used
49− , gsBoundFields :: Set Text
50− -- ^ field names that were already used
51− , gsMode :: GenType
52− , gsCode :: [Text]
53− , gsWarnings :: [Text]
54− }
55−
56−-- | Generator monad
57−newtype Gen a = Gen
58− { fromGen :: StateT GenState (Except String) a
59− }
60− deriving (Functor, Applicative, Monad)
61−
62−-- | Run generator
63−runGen :: GenState -> Gen a -> Either String GenState
64−runGen s m = runExcept $ execStateT (fromGen m) s
65−
66−getMode :: Gen GenType
67−getMode = Gen $ gets gsMode
68−
69−-- | Add lines to the output
70−writeCode :: [Text] -> Gen ()
71−writeCode code = Gen $ modify' $ \s -> s
72− { gsCode = reverse code ++ gsCode s
73− }
74−
75−-- | Emit warning
76−warn :: Text -> Gen ()
77−warn msg = Gen $ modify' $ \s -> s
78− { gsWarnings = ("WARNING: " <> msg) : gsWarnings s
79− }
80−
81−-- | Usually we prefix types with "Xml", but for records we need plain name
82−--
83−-- Note that built-in types doesn't have prefix, so prefixed name is
84−-- the same as the plain one.
85−data TypeName = TypeName
86− { tnName :: Text
87− -- ^ plain name
88− , tnPrefixed :: Text
89− -- ^ name with "Xml" prefix
90− , tnQName :: Xsd.QName
91− -- ^ the original name
92− }
93−
94−-- | Allocate new type name for given qualified name
95−--
96−-- It checks for ambiguous type names and fields
97−makeTypeName :: Xsd.QName -> Xsd.Type -> Gen TypeName
98−makeTypeName name tp = go Nothing
99− where
100− go suffix = do
101− let
102− typeName = capitalize (Xsd.qnName name)
103− <> maybe "" (Text.pack . show) suffix
104− prefixed = "Xml" <> typeName
105− next = case suffix of
106− Nothing -> Just (1 :: Int)
107− Just i -> Just (succ i)
108− bound <- Gen $ gets (Set.member prefixed . gsBoundTypeName)
109− duplicateFields <- hasDuplicateFields typeName tp
110− if bound || duplicateFields
111− then go next
112− else do
113− let
114− tn = TypeName
115− { tnName = typeName
116− , tnPrefixed = prefixed
117− , tnQName = name
118− }
119− Gen $ modify' $ \s -> s
120− { gsKnownTypes = Map.insert name tn (gsKnownTypes s)
121− , gsBoundTypeName = Set.insert prefixed (gsBoundTypeName s)
122− }
123− return tn
124−
125−makeFieldName :: TypeName -> Xsd.QName -> Gen Text
126−makeFieldName typeName name = do
127− -- here we remember that the field name is bound, so that
128− -- hasDuplicateFields can check for ambiguous fields
129− let prefixed = makePrefixedField (tnName typeName) name
130− Gen $ modify' $ \s -> s
131− { gsBoundFields = Set.insert prefixed (gsBoundFields s)
132− }
133− return (qualifier <> Xsd.qnName name)
134− where
135− qualifier = maybe ""
136− (\(Xsd.Namespace ns) -> "{" <> ns <> "}")
137− (Xsd.qnNamespace name)
138−
139−-- | Make value for enum
140−--
141−-- We may need to handle duplicate enum values here
142−makeEnumName :: Text -> Gen Text
143−makeEnumName = return . capitalize
144−
145−-- | Check whether field name is ambiguous
146−hasDuplicateFields :: Text -> Xsd.Type -> Gen Bool
147−hasDuplicateFields typeName tp = do
148− bound <- forM (allFields tp) $ \f -> do
149− let prefixed = makePrefixedField typeName f
150− Gen $ gets (Set.member prefixed . gsBoundFields)
151− return (or bound)
152−
153−-- | Get all fields from the type
154−allFields :: Xsd.Type -> [Xsd.QName]
155−allFields (Xsd.TypeSimple _) = []
156−allFields (Xsd.TypeComplex t) =
157− case Xsd.complexContent t of
158− Xsd.ContentPlain c ->
159− case Xsd.plainContentModel c of
160− Just (Xsd.Sequence es) -> mapMaybe elementName es
161− _ -> []
162− Xsd.ContentSimple _ -> []
163− Xsd.ContentComplex (Xsd.ComplexContentExtension e) ->
164− case Xsd.complexExtensionModel e of
165− Just (Xsd.Sequence es) -> mapMaybe elementName es
166− _ -> []
167− Xsd.ContentComplex (Xsd.ComplexContentRestriction _) -> []
168− where
169− elementName = Xsd.refOr
170− (const Nothing)
171− (Just . Xsd.elementName)
172−
173−-- | Prefix field name with based on the type name
174−makePrefixedField :: Text -> Xsd.QName -> Text
175−makePrefixedField typeName field = prefix <> Xsd.qnName field
176− where
177− prefix
178− = Text.map Char.toLower
179− . Text.filter (\c -> Char.isUpper c || Char.isDigit c)
180− $ typeName
181−
182−-- | Get generated name for the type name
183−--
184−-- Returns Nothing if the type was not generated yet
185−knownTypeName :: Xsd.QName -> Gen (Maybe TypeName)
186−knownTypeName name = Gen $ gets (Map.lookup name . gsKnownTypes)
187−
188−extensions :: Xsd.QName -> Gen [(Xsd.QName, Xsd.Type)]
189−extensions base = Gen $ gets (Map.findWithDefault [] base . gsExtensions)
190−
191−-- | Returns type for the reference
192−resolveType :: Xsd.QName -> Gen Xsd.Type
193−resolveType name = do
194− mt <- Gen $ gets (Map.lookup name . gsTypes)
195− case mt of
196− Just t -> return t
197− Nothing -> genError ("unknown reference to " <> show name)
198−
199−-- | Returns type type for the reference
200−--
201−-- It should already be generated
202−resolveTypeName :: Xsd.QName -> Gen TypeName
203−resolveTypeName name = knownTypeName name
204− >>= maybe (genError ("unresolved type: " <> show name)) return
205−
206−-- | Fail the generator
207−genError :: String -> Gen a
208−genError = Gen . lift . throwE
209−
210−capitalize :: Text -> Text
211−capitalize t
212− | Text.null t = t
213− | otherwise = Text.singleton (Char.toUpper (Text.head t)) <> Text.tail t
src/Main.hs+440−436
@@ -1,450 +1,454 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE LambdaCase #-}
13{-# LANGUAGE OverloadedStrings #-}
4+{-# LANGUAGE TupleSections #-}
25
36module Main
4−( main
5−)
6−where
7−
8−import Data.Text (Text)
9−import qualified Data.Text as Text
10−import qualified Data.Text.IO as Text
7+ ( main
8+ ) where
9+
10+import Control.Monad.RWS.CPS (RWS, execRWS)
11+import Control.Monad.Reader
12+import Control.Monad.State.Strict
13+import Control.Monad.Writer.CPS (Writer, tell, execWriter)
14+import Data.ByteString.Lazy as BL
15+import Data.Char as C
16+import Data.Default
17+import Data.Foldable as F
18+import Data.List as L
19+import Data.Map.Strict as M
20+import Data.Set as S
21+import Data.Text as T
22+import Data.Text.IO as T
23+import Data.Traversable
24+import Debug.Trace
25+import System.Environment
26+import System.IO
27+import Text.XSD
28+import Options
1129import Data.Maybe
12−import qualified Data.List as List
13−import qualified Data.Set as Set
14−import Data.Map (Map)
15−import qualified Data.Map as Map
16−import Control.Monad
17−import qualified System.IO as IO
18−import qualified Xsd
1930
20−import Options
21−import Gen
22−import References
23−import BuiltInTypes
2431
25−main :: IO ()
26−main = do
27− opts <- getOptions
28− schema <- Xsd.getSchema (oInput opts)
29− res <- either fail return
30− (generate opts schema)
31− mapM_ (Text.hPutStrLn IO.stderr) (resultWarnings res)
32− Text.putStrLn (resultCode res)
33−
34−data Result = Result
35− { resultCode :: Text
36− , resultWarnings :: [Text]
37− }
38−
39−generate :: Options -> Xsd.Schema -> Either String Result
40−generate opts schema = do
41− let
42− types = Map.union (Xsd.schemaTypes schema)
43− (elementsToTypes (Xsd.schemaElements schema))
44− s <- runGen (initialGenState opts types) $ do
45− genHeader opts
46− genTypes types
47− Right Result
48− { resultCode = Text.unlines (reverse (gsCode s))
49− , resultWarnings = reverse (gsWarnings s)
50− }
51−
52−elementsToTypes :: Map Xsd.QName Xsd.Element -> Map Xsd.QName Xsd.Type
53−elementsToTypes = List.foldl' step Map.empty . Map.toList
32+makeNamePrefix :: Text -> Text
33+makeNamePrefix = T.map C.toLower . T.filter (\c -> C.isUpper c || C.isDigit c)
34+
35+type GenMonad = ReaderT DatatypeMap (Writer Text)
36+
37+class Fields a where
38+ fields :: a -> [Text]
39+
40+instance Fields Datatype where
41+ fields (TypeComplex ty) = fields ty
42+ fields (TypeSimple ty) = fields ty
43+
44+instance Fields SimpleType where
45+ fields ty@(STAtomic tyName _ _ restrictions) = if shouldBeNewtype ty
46+ then [getNewtypeUnconsName tyName]
47+ else getEnumeratedCode restrictions
48+
49+instance Fields ComplexType where
50+ fields (ComplexType _ _ _ (Just g)) = fields g
51+ fields (ComplexType _ _ _ Nothing) = []
52+
53+instance Fields ModelGroupSchema where
54+ fields (CTSequence els) = snd . name <$> els
55+ fields (CTChoice els) = snd . name <$> els
56+ fields (CTAll els) = snd . name <$> els
57+
58+class References a where
59+ references :: a -> [Text]
60+
61+instance References Datatype where
62+ references (TypeComplex (ComplexType _ _ _ mmgs)) =
63+ case mmgs of
64+ Just mgs -> case mgs of
65+ CTSequence els -> F.concatMap references els
66+ CTChoice els -> F.concatMap references els
67+ CTAll els -> F.concatMap references els
68+ Nothing -> []
69+ references (TypeSimple _) = []
70+
71+instance References Element where
72+ references (Element _ t _ _ _) = references t
73+
74+instance References DatatypeRef where
75+ references (DatatypeRef ty) = [ty]
76+ references (InlineComplex dt) = references dt
77+
78+instance References a => References [a] where
79+ references = F.concatMap references
80+
81+-- | 'DatatypeMap' are the types left to process
82+-- 'S.Set Text' are the types already processed.
83+type PreMonad = StateT (DatatypeMap, S.Set Text) (Writer [(Text, Datatype)])
84+
85+type PreElemMonad = RWS DatatypeMap [Element] [Element]
86+
87+-- | Marks the given type as processed.
88+proceed :: Text -> Datatype -> PreMonad ()
89+proceed t dt = do
90+ tell [(t, dt)]
91+ modify $ \(f,s) -> (M.delete t f, S.insert t s)
92+
93+-- | Marks element as processed.
94+proceed' :: Element -> PreElemMonad ()
95+proceed' el = do
96+ tell [el]
97+ modify $ L.delete el
98+
99+untwistDeps :: [Element] -> DatatypeMap -> ([(Text, Datatype)], [Element])
100+untwistDeps e dm = (dList, e')
54101 where
55− step types (_, e) = case Xsd.elementType e of
56− Xsd.Ref _ -> types
57− Xsd.Inline t -> Map.insert (Xsd.elementName e) t types
58−
59−genTypes :: Map Xsd.QName Xsd.Type -> Gen ()
60−genTypes types = mapM_ (uncurry genTopType) . Map.toList $ types
61−
62−genTopType :: Xsd.QName -> Xsd.Type -> Gen ()
63−genTopType = genType []
64−
65−genType :: [Xsd.Annotation] -> Xsd.QName -> Xsd.Type -> Gen ()
66−genType annotations name tp = do
67− known <- knownTypeName name
68− case known of
69− Just _ -> return () -- already generated
70− Nothing -> do
71− -- we should generate dependencies before the type itself to make
72− -- sure they are in scope when xml-isogen quotes them
73− -- (stage restriction in TH)
74− genDependencies tp
75− typeName <- makeTypeName name tp
76− case tp of
77− Xsd.TypeSimple t -> genSimpleType typeName t annotations
78− Xsd.TypeComplex t -> genComplexType typeName t annotations
79− genExtension name
80−
81−genExtension :: Xsd.QName -> Gen ()
82−genExtension base = do
83− exts <- extensions base
84− case exts of
85− [] -> return ()
86− types -> do
87− mapM_ (uncurry genTopType) types
88− baseTypeName <- tnPrefixed <$> resolveTypeName base
89− writeCode
90− [ "data Any" <> baseTypeName
91− , " = The" <> baseTypeName <> " !" <> baseTypeName
92− ]
93− let
94− mkConstructor (n, _) = do
95− tn <- tnPrefixed <$> resolveTypeName n
96− exts' <- extensions n
102+ dList = disambiguateNames . nub . execWriter $ do
103+ (a, _) <- runStateT sortDatatypesByDeps (dm, S.empty)
104+ return a
105+ (_, e') = execRWS sortElemsByDeps (M.fromList dList) e
106+
107+type Abbreviation = Text
108+type Subelement = Text
109+type DisambiguaterMonad = State (M.Map Abbreviation (S.Set Subelement))
110+
111+-- | If any two datatypes with the same name abbreviation ('makeNamePrefix')
112+-- have any fields in common, then one of them gets a \"2\" appended to it
113+-- (\"_2\" if the last character of the name was a digit).
114+-- Repeat the same process until there are no conflicts.
115+-- If we have already appended a \"2\" to a datatype and it still has conflicts,
116+-- we change the 2 to a 3, a 3 to a 4 and so on.
117+disambiguateNames :: [(Text, Datatype)] -> [(Text, Datatype)]
118+disambiguateNames = flip evalState mempty . mapM disambiguateName
119+ where
120+ disambiguateName :: (Text, Datatype) -> DisambiguaterMonad (Text, Datatype)
121+ disambiguateName (tyName', dt) = do
122+ let rNames = S.fromList $ fields dt
123+ (, dt) <$> attempt tyName' rNames 1
124+ where
125+ attempt :: Abbreviation -> S.Set Subelement -> Int -> DisambiguaterMonad Text
126+ attempt tyName fieldNames n = do
127+ processedTypes <- get
97128 let
98− n' = case exts' of
99− [] -> tn
100− _ -> "Any" <> tn
101− return (" | The" <> n' <> " !" <> n')
102− constructors <- mapM mkConstructor types
103− writeCode constructors
104− writeCode
105− [ " deriving (Eq, Show)"
106− , ""
107− ]
108− writeCode
109− [ "instance NFData Any" <> baseTypeName <> " where"
110− , " rnf = rwhnf"
111− , " "
112− ]
113− mode <- getMode
114− unless (mode == Generator) $ do
115− writeCode
116− [ "instance FromDom Any" <> baseTypeName <> " where"
117− , " fromDom = do"
118− , " tp <- parseAttribute"
119− , " (matchName " <>
120− "\"{http://www.w3.org/2001/XMLSchema-instance}type\")"
121− , " Right"
122− , " case tp of"
123− ]
124− let
125− mkClause n = do
126− tn <- resolveTypeName n
127− exts' <- extensions n
128− n' <- case exts' of
129− [] -> return (tnPrefixed tn)
130− _ | n == base -> return (tnPrefixed tn)
131− _ -> return ("Any" <> tnPrefixed tn)
132− return $ mconcat
133− [ " \""
134− , tnName tn
135− , "\" -> The"
136− , n'
137− , " <$> fromDom"
138− ]
139− clauses <- mapM mkClause (base : map fst types)
140− writeCode clauses
141− writeCode
142− [ " _ -> throwParserError (PEOther \"Unexpected type\")"
143− , ""
144− ]
145− unless (mode == Parser) $ do
146− writeCode
147− [ "instance ToXML Any" <> baseTypeName <> " where"
148− , " toXML (The" <> baseTypeName <> " a) = toXML a"
149− ]
150− let
151− mkClause (n, _) = do
152− tn <- tnPrefixed <$> resolveTypeName n
153− exts' <- extensions n
154− let
155− n' = case exts' of
156− [] -> tn
157− _ -> "Any" <> tn
158− return (" toXML (The" <> n' <> " a) = toXML a")
159− clauses <- mapM mkClause types
160− writeCode clauses
161− writeCode [""]
162− writeCode
163− [ "instance ToXmlParentAttributes Any" <> baseTypeName <> " where"
164− ]
165− let
166− toAttrLine n = do
167− tn <- resolveTypeName n
168− exts' <- extensions n
169− n' <- case exts' of
170− [] -> return (tnPrefixed tn)
171− _ | n == base -> return (tnPrefixed tn)
172− _ -> return ("Any" <> tnPrefixed tn)
173− return
174− [ " toXmlParentAttributes (The" <> n' <> " a) ="
175− , " (\"{http://www.w3.org/2001/XMLSchema-instance}type\", \""
176− <> tnName tn <> "\")"
177− , " : toXmlParentAttributes a"
178− ]
179− attrLines <- mapM toAttrLine (base : map fst types)
180− writeCode (concat attrLines)
181−
182−genDependencies :: References a => a -> Gen ()
183−genDependencies a = forM_ (references a) $ \name -> do
184− known <- knownTypeName name
185− case known of
186− Just _ -> return () -- already generated
187− Nothing -> do
188− tp <- resolveType name
189− genTopType name tp
190−
191−genSimpleType :: TypeName -> Xsd.SimpleType -> [Xsd.Annotation]-> Gen ()
192−genSimpleType tn (Xsd.AtomicType restriction ann) parentAnn = do
193− let
194− baseName r = case Xsd.simpleRestrictionBase r of
195− Xsd.Ref n -> Just n
196− Xsd.Inline (Xsd.AtomicType r' _) -> baseName r'
197− Xsd.Inline (Xsd.ListType _ _) -> Nothing
198− Xsd.Inline (Xsd.UnionType _ _) -> Nothing
199− case baseName restriction of
200− Just _
201− | isEnum restriction
202− -> genEnum tn
203− (Xsd.simpleRestrictionConstraints restriction)
204− (parentAnn <> ann)
205− Just base ->
206− genNewtype tn base (parentAnn <> ann)
207− _ -> genUnsupported tn
208−genSimpleType typeName (Xsd.ListType _ _) _ = genUnsupported typeName
209−genSimpleType typeName (Xsd.UnionType _ _) _ = genUnsupported typeName
210−
211−genNewtype :: TypeName -> Xsd.QName -> [Xsd.Annotation] -> Gen ()
212−genNewtype tn base annots = do
213− fieldTypeName <- tnPrefixed <$> resolveTypeName base
214− mode <- getMode
215− let
216− typeName = tnPrefixed tn
217− fieldName = "un" <> typeName
218− toxml = case mode of
219− Parser -> ""
220− _ -> ", ToXML"
221− writeCode $ makeComments tn annots
222− writeCode
223− [ "newtype " <> typeName
224− , " = " <> typeName
225− , " { " <> fieldName <> " :: " <> fieldTypeName
226− , " } deriving (Show, Eq, NFData" <> toxml <> ")"
227− , ""
228− ]
229− unless (mode == Generator) $ writeCode
230− [ "instance FromDom " <> typeName <> " where"
231− , " fromDom = " <> typeName <> " <$> fromDom"
232− , ""
233− ]
234−
235−genEnum :: TypeName -> [Xsd.Constraint] -> [Xsd.Annotation] -> Gen ()
236−genEnum tn constraints annots = do
237− mode <- getMode
238− let
239− values = map toValue constraints
240− toValue (Xsd.Enumeration v) = v
241− enumLines <- forM values $ \v -> do
242− enumName <- makeEnumName v
243− return (" & \"" <> enumName <> "\"")
244− writeCode $ makeComments tn annots
245− writeCode $ "\"" <> tnName tn <> "\" Exhaustive =:= enum "
246− <> genTypeToText mode : enumLines
247− writeCode [""]
248−
249−isEnum :: Xsd.SimpleRestriction -> Bool
250−isEnum = any isEnumConstraint . Xsd.simpleRestrictionConstraints
129+ newTyName
130+ | n == 1 = tyName
131+ | shouldSeparateNumber = tyName <> "_" <> T.pack (show n)
132+ | otherwise = tyName <> T.pack (show n)
133+ abr = makeNamePrefix newTyName
134+ case M.lookup abr processedTypes of
135+ Just usedNames ->
136+ if S.null $ S.intersection fieldNames usedNames
137+ then modify (M.adjust (S.union fieldNames) abr) >> return newTyName
138+ else attempt tyName fieldNames (n + 1)
139+ Nothing -> modify (M.insert abr fieldNames) >> return newTyName
140+ shouldSeparateNumber = isDigit $ T.last tyName'
141+
142+sortElemsByDeps :: PreElemMonad ()
143+sortElemsByDeps = do
144+ els <- get
145+ if Prelude.null els then pure () else do
146+ let first = Prelude.head els
147+ -- traceM $ "sortElemsByDeps: " <> show first
148+ case references first of
149+ [] -> proceed' first >> sortElemsByDeps
150+ xs -> do
151+ results <- traverse memberDatatype xs
152+ if L.and results
153+ then proceed' first >> sortElemsByDeps
154+ else do
155+ let failed = fmap snd $ L.filter (not . fst) $ L.zip results xs
156+ error $ "impossible to lookup types: " <> show failed
157+
158+memberDatatype :: Text -> PreElemMonad Bool
159+memberDatatype ty = do
160+ -- traceM $ "memberDatatype: " <> show ty
161+ dm <- ask
162+ case M.lookup ty dm of
163+ Just _ -> return True
164+ Nothing -> return False
165+
166+sortDatatypesByDeps :: PreMonad ()
167+sortDatatypesByDeps = do
168+ (dm, _) <- get
169+ if M.null dm then pure () else do
170+ let first = Prelude.head (M.toList dm)
171+ traceM $ "sortDatatypesByDeps: " <> show first
172+ case references $ snd first of
173+ [] -> uncurry proceed first >> sortDatatypesByDeps
174+ xs -> do
175+ traverse_ lookupDatatype xs
176+ uncurry proceed first
177+ sortDatatypesByDeps
178+
179+lookupDatatype :: Text -> PreMonad ()
180+lookupDatatype ty = do
181+ traceM $ "lookupDatatype: " <> show ty
182+ (dm, s) <- get
183+ case M.lookup ty dm of
184+ Nothing -> if S.member ty s then pure () else
185+ error $ "can't look up datatype: " <> show ty
186+ Just typ -> case references typ of
187+ [] -> proceed ty typ
188+ xs -> traverse_ lookupDatatype xs >> proceed ty typ
189+
190+class Capitalizable t where
191+ capitalize :: t -> t
192+
193+instance Capitalizable String where
194+ capitalize [] = []
195+ capitalize (a:as) = C.toUpper a : as
196+
197+instance Capitalizable Text where
198+ capitalize t
199+ | T.null t = t
200+ | otherwise = T.singleton (C.toUpper (T.head t)) <> T.tail t
201+
202+data DataFlavour = QQ | Plain
203+
204+-- TODO: improve after moving some XML types to xml-isogen
205+simpleTypeToIsoType :: DataFlavour -> SimpleAtomicType -> Text
206+simpleTypeToIsoType fl = \case
207+ STAnyURI -> wrap fl "Text"
208+ STBase64Binary -> wrap fl "ByteString"
209+ STBoolean -> wrap fl "Bool"
210+ STDate -> wrap fl "Date \"%YYYYj\""
211+ STDateTime -> wrap fl "Text"
212+ STDateTimeStamp -> wrap fl "Text"
213+ STDecimal DTDecimal -> wrap fl "Double"
214+ (STDecimal _) -> wrap fl "Integer"
215+ STDouble -> wrap fl "Double"
216+ (STDuration _) -> wrap fl "Integer"
217+ STFloat -> wrap fl "Float"
218+ STGDay -> wrap fl "Day"
219+ STGMonth -> wrap fl "Text"
220+ STGMonthDay -> wrap fl "Text"
221+ STGYear -> wrap fl "Text"
222+ STGYearMonth -> wrap fl "Text"
223+ STHexBinary -> wrap fl "Text"
224+ STNOTATION -> wrap fl "Text"
225+ STQName -> wrap fl "Text"
226+ (STString _) -> wrap fl "Text"
227+ STTime -> wrap fl "Text"
251228 where
252− isEnumConstraint (Xsd.Enumeration _) = True
229+ wrap QQ t = "[t|" <> t <> "|]"
230+ wrap Plain t = t
253231
254−genComplexType :: TypeName -> Xsd.ComplexType -> [Xsd.Annotation] -> Gen ()
255−genComplexType typeName t parentAnn = do
256− mode <- getMode
257− let
258− header = "\"" <> tnName typeName <> "\" =:= record "
259− <> genTypeToText mode
260− fields <- genFields typeName (Xsd.complexContent t)
261− writeCode $ makeComments typeName
262− (parentAnn <> Xsd.complexAnnotations t)
263− writeCode [header]
264− writeCode fields
265− writeCode [""]
266−
267−makeComments :: TypeName -> [Xsd.Annotation] -> [Text]
268−makeComments typeName annotations = if null annotations
269− then
270− [ "{-|"
271− , generated
272− , "-}"
273− ]
274− else
275− [ "{-|"
276− , generated
277− , ""
278− ] <> map makeDoc annotations <>
279− [ "-}"
280− ]
281− where
282− generated = "Generated from: " <> prefix <> name
283− qname = tnQName typeName
284− name = Xsd.qnName qname
285− prefix = maybe "" ((<> ":") . Xsd.fromNamespace) (Xsd.qnNamespace qname)
286− makeDoc (Xsd.Documentation docs) = docs
287−
288−-- | Generate code for record fields
289−--
290−-- The first argument - record name
291−genFields :: TypeName -> Xsd.Content -> Gen [Text]
292−genFields typeName (Xsd.ContentPlain c) =
293− maybe (return []) (genFieldsForModel typeName) (Xsd.plainContentModel c)
294−genFields _ (Xsd.ContentSimple _) = return []
295−genFields typeName (Xsd.ContentComplex (Xsd.ComplexContentExtension e)) = do
296− base <- resolveType (Xsd.complexExtensionBase e)
297− genDependencies base
298− baseFields <- case base of
299− Xsd.TypeComplex t -> genFields typeName (Xsd.complexContent t)
300− _ -> return []
301− fields <- maybe (return []) (genFieldsForModel typeName)
302− (Xsd.complexExtensionModel e)
303− return (baseFields ++ fields)
304−genFields _ (Xsd.ContentComplex (Xsd.ComplexContentRestriction _)) =
305− return []
306−
307−genFieldsForModel :: TypeName -> Xsd.ModelGroup -> Gen [Text]
308−genFieldsForModel typeName (Xsd.Sequence elements) =
309− catMaybes <$> mapM (genField typeName) elements
310−genFieldsForModel _ (Xsd.Choice _) = do
311− warn "choice: not implemented"
312− return []
313−genFieldsForModel _ (Xsd.All _) = do
314− warn "all: not implemented"
315− return []
316−
317−genField :: TypeName -> Xsd.RefOr Xsd.Element -> Gen (Maybe Text)
318−genField _ (Xsd.Ref _) = return Nothing
319−genField typeName (Xsd.Inline e) = do
320− fieldName <- makeFieldName typeName (Xsd.elementName e)
321−
322− fieldTypeName <- case Xsd.elementType e of
323− Xsd.Ref name -> do
324− tn <- tnPrefixed <$> resolveTypeName name
325− exts <- extensions name
326− case exts of
327− [] -> return tn
328− _ -> return ("Any" <> tn)
329− Xsd.Inline t -> do
330− genType (Xsd.elementAnnotations e) (Xsd.elementName e) t
331− tnPrefixed <$> resolveTypeName (Xsd.elementName e)
332−
333− qualifier <- makeQualifier (Xsd.elementOccurs e)
232+tellGen
233+ :: [Text] -- generated code
234+ -> Text -- comment
235+ -> GenMonad ()
236+tellGen code comment =
237+ tell $ "\n" <> comment <> T.unlines code
334238
239+runGen :: DatatypeMap -> GenMonad a -> Text
240+runGen dm act = execWriter $ runReaderT act dm
241+
242+generateIsoXml :: Maybe Header -> ModuleName -> GenType -> XSD -> Text
243+generateIsoXml mHeader name genType xsd@(XSD (e,dm)) =
335244 let
336− fieldType = if Xsd.elementNillable e
337− then "Nillable " <> fieldTypeName
338− else fieldTypeName
339−
340− return $ Just $ mconcat
341− [ " "
342− , qualifier
343− , " \""
344− , fieldName
345− , "\" [t|"
346− , fieldType
347− , "|]"
348− ]
349−
350−makeQualifier :: (Int, Xsd.MaxOccurs) -> Gen Text
351−makeQualifier (minOcc, maxOcc) = case maxOcc of
352− Xsd.MaxOccursUnbound -> toQualifier minOcc maxBound
353− Xsd.MaxOccurs v -> toQualifier minOcc v
354−
355−toQualifier :: Int -> Int -> Gen Text
356−toQualifier 1 1 = return "!"
357−toQualifier 0 1 = return "?"
358−toQualifier 1 maxOcc
359− | maxOcc < 1
360− = genError "maxOccurs < minOccurs"
361−toQualifier 1 maxOcc
362− | maxOcc > 1
363− = return "+"
364−toQualifier _ _ = return "*"
365−
366−genUnsupported :: TypeName -> Gen ()
367−genUnsupported tn = do
368− let typeName = tnPrefixed tn
369− warn $ "generating stub for unsupported construct in " <> typeName
370− mode <- getMode
371− writeCode (makeComments tn [])
372− writeCode
373− [ "data " <> typeName <> " = " <> typeName
374− , " deriving (Eq, Show)"
375− , ""
376− , "instance NFData " <> typeName <> " where"
377− , " rnf _ = ()"
378− , ""
379− ]
380−
381− unless (mode == Parser) $ writeCode
382− [ "instance ToXML " <> typeName <> " where"
383− , " toXML _ = comment \"" <> typeName <> "\""
384− , ""
385− ]
386−
387− unless (mode == Generator) $ writeCode
388− [ "instance FromDom " <> typeName <> " where"
389− , " fromDom = undefined"
390− , ""
391− ]
392−
393−genHeader :: Options -> Gen ()
394−genHeader opts = do
395− case oHeader opts of
396− Nothing -> return ()
397− Just h -> do
398− writeCode . fmap ("-- " <>) . Text.lines $ h
399− writeCode [""]
400−
401− writeCode
402− [ "{-# OPTIONS_GHC -Wno-unused-imports #-}"
403− , "module " <> oModule opts <> " where"
404− , ""
405− , "import Control.DeepSeq"
406− , "import Data.Scientific"
407− , "import Data.THGen.XML"
408− ]
409− writeCode imports
410− writeCode
411− [ "import Prelude hiding ((*), (+))"
412− , ""
413− , ""
414− ]
245+ (dList, el) = untwistDeps e dm
246+ in (header mHeader name genType <>) . runGen dm $ do
247+ for_ dList $ \(t,dt) -> do
248+ generateIsoDatatype genType (Just t) dt []
249+ for_ el (generateIsoRecord genType)
250+
251+toQualifier :: Int -> Int -> Text
252+toQualifier minOc maxOc
253+ | minOc == 1 && maxOc == 1 = "!"
254+ | minOc == 0 && maxOc == 1 = "?"
255+ | minOc == 1 && maxOc > minOc = "+"
256+ | minOc == 1 && maxOc < minOc = error "maxOccurs < minOccurs"
257+ | otherwise = "*"
258+
259+header :: Maybe Header -> ModuleName -> GenType -> Text
260+header mHeader name genType = T.unlines $
261+ maybeToList (T.unlines . fmap ("-- " <>) . T.lines <$> mHeader) <>
262+ [ "module " <> name <> " where"
263+ , ""
264+ , "import Control.DeepSeq"
265+ , "import Data.THGen.XML"
266+ ] <> specImports <>
267+ [ "import Prelude hiding ((*), (+))"
268+ , "" ]
269+ where
270+ specImports = case genType of
271+ Generator -> [ xmlWriter ]
272+ Parser -> [ domParser ]
273+ Both -> [ domParser, xmlWriter ]
274+ xmlWriter, domParser :: Text
275+ xmlWriter = "import Text.XML.Writer"
276+ domParser = "import Text.XML.DOM.Parser.FromDom"
277+
278+quote :: Text -> Text
279+quote t = "\"" <> t <> "\""
280+
281+generateIsoRecord :: GenType -> Element -> GenMonad ()
282+generateIsoRecord
283+ genType
284+ (Element (_, laxName) elXtype _ _ elAnnotations) = do
285+ written <- ask
286+ case elXtype of
287+ InlineComplex dt ->
288+ generateIsoDatatype genType laxName dt elAnnotations
289+ DatatypeRef nam -> if M.member nam written
290+ then pure ()
291+ else error $ "Implementation failure: "
292+ <> show nam <> " type never encountered before"
293+
294+data CommentType = Haddock | Regular
295+
296+toComment :: CommentType -> [Annotation] -> Text
297+toComment ct ann = case texts of
298+ [] -> ""
299+ (h:tl) -> T.unlines ((prefix <> h) : fmap ("-- "<>) tl)
415300 where
416− imports = case oMode opts of
417− Generator -> [ xmlWriter, parentAttr ]
418− Parser -> [ domParser ]
419− ParserAndGenerator -> [ domParser, xmlWriter, parentAttr ]
420− xmlWriter = "import Text.XML.Writer"
421− parentAttr = "import Text.XML.ParentAttributes"
422− domParser = "import Text.XML.DOM.Parser"
423−
424−-- | We populate the initial state with all built-in types to make sure
425−-- they will be correctly resolved
426−initialGenState :: Options -> Map Xsd.QName Xsd.Type -> GenState
427−initialGenState opts types = GenState
428− { gsTypes = types
429− , gsExtensions = collectExtensions types
430− , gsKnownTypes = builtInTypes
431− , gsBoundTypeName = Set.empty
432− , gsBoundFields = Set.empty
433− , gsMode = oMode opts
434− , gsCode = []
435− , gsWarnings = []
436− }
437−
438−collectExtensions
439− :: Map Xsd.QName Xsd.Type
440− -> Map Xsd.QName [(Xsd.QName, Xsd.Type)]
441−collectExtensions = List.foldl' step Map.empty . Map.toList
301+ texts = stripTexts $ F.concatMap (wrap80 . fromDocumentation) ann
302+ stripTexts = \case
303+ [] -> []
304+ l@(h:tl) -> if T.all (\x -> x == ' ' || x == '\n') h then stripTexts tl else l
305+ prefix = case ct of
306+ Haddock -> "-- | "
307+ Regular -> "-- "
308+
309+fromDocumentation :: Annotation -> Text
310+fromDocumentation (Documentation t) = t
311+
312+wrap80 :: Text -> [Text]
313+wrap80 = L.foldl' go [] . T.split (==' ')
442314 where
443− step exts (n, t) = case baseOf t of
444− Nothing -> exts
445− Just base -> Map.insertWith (++) base [(n, t)] exts
446− baseOf (Xsd.TypeSimple _) = Nothing
447− baseOf (Xsd.TypeComplex t) = case Xsd.complexContent t of
448− Xsd.ContentComplex (Xsd.ComplexContentExtension e) ->
449− Just (Xsd.complexExtensionBase e)
450− _ -> Nothing
315+ go [] e = [e]
316+ go l e =
317+ let last' = L.last l
318+ in if T.length last' + T.length e >= 73 -- 80 minus "-- | " and ' '
319+ then l <> pure e
320+ else L.init l <> [L.last l <> " " <> e]
321+
322+generateIsoDatatype
323+ :: GenType
324+ -> Text
325+ -> Datatype
326+ -> [Annotation]
327+ -> GenMonad ()
328+ -- ^ (type name for lookups, generated code)
329+generateIsoDatatype
330+ genType
331+ eName
332+ (TypeComplex (ComplexType _ _ tyAnnotations mGroupSchema))
333+ annotationsRec = do
334+ case mGroupSchema of
335+ Just groupSchema -> case groupSchema of
336+ CTSequence elements -> do
337+ tyFields <- for elements (generateIsoField genType)
338+ let
339+ comment = toComment Haddock $ annotationsRec
340+ <> [Documentation ""]
341+ <> tyAnnotations
342+ tyHeader =
343+ quote (capitalize eName)
344+ <> " =:= record "
345+ <> genTypeToText genType
346+ tellGen (tyHeader : tyFields) comment
347+ CTChoice _ -> error "'Choice' group not supported yet"
348+ CTAll _ -> error "'All' group not supported yet"
349+ Nothing -> error $ "No group schema provided for type: " <> T.unpack eName
350+generateIsoDatatype
351+ genType
352+ eName
353+ (TypeSimple ty@(STAtomic iName sat tyAnnotations restrictions))
354+ annotationsRec = do
355+ let eName = eName
356+ let
357+ comment =
358+ toComment Haddock $ annotationsRec
359+ <> [Documentation ""]
360+ <> tyAnnotations
361+ if not (shouldBeNewtype ty)
362+ then tellGen
363+ (generateEnum
364+ (quote $ capitalize eName)
365+ (getEnumeratedCode restrictions))
366+ comment
367+ else
368+ tellGen (generateNewtype genType iName sat) comment
369+
370+getEnumeratedCode :: [Restriction] -> [Text]
371+getEnumeratedCode = F.concatMap fromEnumeration . Prelude.filter isEnumeration
372+ where
373+ fromEnumeration (Enumeration x) = x
374+
375+isEnumeration :: Restriction -> Bool
376+isEnumeration (Enumeration _) = True
377+
378+shouldBeNewtype :: SimpleType -> Bool
379+shouldBeNewtype (STAtomic _ _ _ restrictions) =
380+ not . Prelude.any isEnumeration $ restrictions
381+
382+getNewtypeConsName :: Text -> Text
383+getNewtypeConsName = ("Xml" <>) . capitalize
384+
385+getNewtypeUnconsName :: Text -> Text
386+getNewtypeUnconsName = ("un" <>) . getNewtypeConsName
387+
388+generateNewtype :: GenType -> Text -> SimpleAtomicType -> [Text]
389+generateNewtype genType n sat =
390+ let
391+ constructor = getNewtypeConsName n
392+ decons = getNewtypeUnconsName n
393+ parser =
394+ [ ""
395+ , "instance FromDom " <> constructor <> " where"
396+ , " fromDom = " <> constructor <> " <$> fromDom"
397+ ]
398+ in
399+ [ "newtype " <> constructor
400+ , " = " <> constructor
401+ , " { " <> decons <> " :: " <> simpleTypeToIsoType Plain sat
402+ , " } deriving (Show, Eq, NFData" <> case genType of
403+ Parser -> ")"
404+ _ -> ", ToXML)"
405+ ] <> case genType of
406+ Generator -> []
407+ _ -> parser
408+
409+generateEnum
410+ :: Text -- type name
411+ -> [Text] -- enums
412+ -> [Text] -- generated code
413+generateEnum enumName enums =
414+ let
415+ enumHeader = enumName <> " Exhaustive =:= enum Both"
416+ eFields = ("& "<>) <$> enums
417+ in pure enumHeader <> eFields
418+
419+lookupSimpleType
420+ :: DatatypeRef
421+ -> GenMonad (Maybe Text)
422+lookupSimpleType (InlineComplex _) = pure Nothing
423+lookupSimpleType (DatatypeRef tyName) =
424+ asks (M.lookup tyName) >>= \case
425+ Just (TypeComplex _) -> pure Nothing
426+ Just (TypeSimple (STAtomic nam _ _ _)) -> pure $ Just nam
427+ Nothing -> error $ "can't look up type: " <> show tyName
428+
429+generateIsoField :: GenType -> Element -> GenMonad Text
430+generateIsoField
431+ genType
432+ (Element (_, fieldName) fieldXtype minOc maxOc fieldAnnotations) = do
433+ let
434+ qualifier = toQualifier minOc maxOc
435+ line <- lookupSimpleType fieldXtype >>= \case
436+ Just tyName ->
437+ pure $ quote fieldName <> " [t|Xml" <> tyName <> "|]"
438+ Nothing -> case fieldXtype of
439+ InlineComplex dt -> do
440+ generateIsoDatatype genType (capitalize fieldName) dt fieldAnnotations
441+ pure $ quote fieldName
442+ DatatypeRef ref ->
443+ pure $ quote fieldName <> " [t|Xml" <> capitalize ref <> "|]"
444+ pure $ " " <> qualifier <> " " <> line
445+
446+main :: IO ()
447+main = do
448+ Options{..} <- getOptions
449+ xml <- BL.readFile oInput
450+ let
451+ xsd = case parseXSD def xml of
452+ Right xsd' -> xsd'
453+ Left e -> error $ show e
454+ T.hPutStrLn stdout $ generateIsoXml oHeader oModule oMode xsd
src/Options.hs+6−10
@@ -1,6 +1,3 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE TypeApplications #-}
3−
41module Options
52 ( Options(..)
63 , optionsParser
@@ -19,13 +16,13 @@ import Paths_xsd_isogen (version)
1916import Data.List
2017
2118
22−data GenType = Parser | Generator | ParserAndGenerator
23− deriving (Read, Show, Eq, Bounded, Enum)
19+data GenType = Parser | Generator | Both
20+ deriving (Read, Show, Bounded, Enum)
2421
2522genTypeToText :: GenType -> Text
26−genTypeToText Parser = "Parser"
27−genTypeToText Generator = "Generator"
28−genTypeToText ParserAndGenerator = "ParserAndGenerator"
23+genTypeToText Parser = "Parser"
24+genTypeToText Generator = "Generator"
25+genTypeToText Both = "Both"
2926
3027type ModuleName = Text
3128type Header = Text
@@ -36,7 +33,6 @@ data Options = Options
3633 , oInput :: FilePath
3734 , oModule :: ModuleName
3835 }
39− deriving (Show)
4036
4137optionsParser :: Parser Options
4238optionsParser = Options
@@ -54,7 +50,7 @@ optionsParser = Options
5450 <*> option auto
5551 ( long "mode"
5652 <> short 'm'
57− <> value ParserAndGenerator
53+ <> value Both
5854 <> help ("Whether to generate both parsers and generators. One of: "
5955 <> (mconcat . intersperse ", " . fmap show
6056 $ [minBound @GenType .. maxBound]) <> ".")
src/References.hsdeleted−80
@@ -1,80 +0,0 @@
1−
2−module References
3−( References(..)
4−)
5−where
6−
7−import qualified Xsd
8−
9−class References a where
10− references :: a -> [Xsd.QName]
11− referencesList :: [a] -> [Xsd.QName]
12− referencesList = concatMap references
13−
14−instance References t => References (Maybe t) where
15− references Nothing = []
16− references (Just t) = references t
17−
18−instance References Xsd.Type where
19− references (Xsd.TypeSimple t) = references t
20− references (Xsd.TypeComplex t) = references t
21−
22−instance References Xsd.SimpleType where
23− references (Xsd.AtomicType r _) = references r
24− references (Xsd.ListType r _) = references r
25− references (Xsd.UnionType rs _) = referencesList rs
26−
27−instance References Xsd.SimpleRestriction where
28− references r = references (Xsd.simpleRestrictionBase r)
29−
30−instance References Xsd.ComplexRestriction where
31− references r = [Xsd.complexRestrictionBase r]
32−
33−instance References t => References (Xsd.RefOr t) where
34− references (Xsd.Ref r) = [r]
35− references (Xsd.Inline t) = references t
36−
37−instance References Xsd.ComplexType where
38− references t = references (Xsd.complexContent t)
39−
40−instance References Xsd.Content where
41− references (Xsd.ContentComplex c) = references c
42− references (Xsd.ContentSimple c) = references c
43− references (Xsd.ContentPlain c) = references c
44−
45−instance References Xsd.PlainContent where
46− references t = referencesList (Xsd.plainContentAttributes t)
47− ++ references (Xsd.plainContentModel t)
48−
49−instance References Xsd.SimpleContent where
50− references _ = []
51−
52−instance References Xsd.ComplexContent where
53− references (Xsd.ComplexContentExtension e) = references e
54− references (Xsd.ComplexContentRestriction r) = references r
55−
56−instance References Xsd.ComplexExtension where
57− -- Note that we don't include extension base here
58− -- becase we don't depend on it. And actaully we generate extensions before
59− -- the base because we need to generate the ADT with all the extensions
60− -- at this point.
61− references e = referencesList (Xsd.complexExtensionAttributes e)
62− ++ references (Xsd.complexExtensionModel e)
63−
64−instance References Xsd.Attribute where
65− references (Xsd.RefAttribute a) = references a
66− references (Xsd.InlineAttribute a) = references a
67−
68−instance References Xsd.AttributeRef where
69− references a = [Xsd.attributeRefRef a]
70−
71−instance References Xsd.AttributeInline where
72− references = references . Xsd.attributeInlineType
73−
74−instance References Xsd.ModelGroup where
75− references (Xsd.Sequence elements) = referencesList elements
76− references (Xsd.Choice elements) = referencesList elements
77− references (Xsd.All elements) = referencesList elements
78−
79−instance References Xsd.Element where
80− references = references . Xsd.elementType
stack.yamldeleted−12
@@ -1,12 +0,0 @@
1−#resolver: nightly-2022-01-24
2−resolver: lts-18.23
3−
4−packages:
5−- .
6−
7−extra-deps:
8−- git: https://github.com/typeable/xsd-parser
9− commit: 648877d94d03a58dc9114f68d4e99c674e353fca
10−
11−nix:
12− packages: [zlib]
xsd-isogen.cabal+14−15
@@ -20,16 +20,12 @@ extra-source-files: CHANGELOG.md
2020executable xsd-isogen
2121 main-is: Main.hs
2222 other-modules: Options
23− , Gen
24− , BuiltInTypes
25− , References
2623 , Paths_xsd_isogen
2724 -- other-extensions:
28− build-depends: base >=4.12 && < 5.0
25+ build-depends: base ^>=4.12.0.0
2926 , bytestring
3027 , containers
3128 , data-default
32− , transformers
3329 , mtl
3430 , optparse-applicative
3531 , text
@@ -39,13 +35,16 @@ executable xsd-isogen
3935 hs-source-dirs: src
4036 default-language: Haskell2010
4137 ghc-options: -fwarn-unused-binds
42− -fwarn-unused-imports
43− -Wall
44− -Wincomplete-uni-patterns
45− -Wincomplete-record-updates
46− -Wpartial-fields
47− -- -Werror=missing-home-modules
48− -Wmissing-home-modules
49− -Widentities
50− -Wredundant-constraints
51− -Wmissing-export-lists
38+ , -fwarn-unused-imports
39+ , -Wall
40+ , -Wincomplete-uni-patterns
41+ , -Wincomplete-record-updates
42+ , -Wpartial-fields
43+ , -Werror=missing-home-modules
44+ , -Wmissing-home-modules
45+ , -Widentities
46+ , -Wredundant-constraints
47+ , -Wmissing-export-lists
48+ default-extensions: TypeApplications
49+ , OverloadedStrings
50+ , RecordWildCards