Add type conversion (still broken at this commit)

このコミットが含まれているのは:
Cory Slep 2018-12-09 11:40:59 +01:00
コミット fe8b4e7261
2個のファイルの変更156行の追加9行の削除

ファイルの表示

@ -5,6 +5,7 @@ import (
"github.com/cjslep/activity/tools/exp/props"
"github.com/cjslep/activity/tools/exp/rdf"
"github.com/cjslep/activity/tools/exp/types"
"github.com/dave/jennifer/jen"
"strings"
)
@ -27,8 +28,17 @@ func newVocabulary() vocabulary {
type PropertyPackagePolicy int
const (
FlatUnderRoot PropertyPackagePolicy = iota
IndividualUnderRoot
PropertyFlatUnderRoot PropertyPackagePolicy = iota
PropertyIndividualUnderRoot
PropertyFlatUnderVocabularyRoot
)
type TypePackagePolicy int
const (
TypeFlatUnderRoot TypePackagePolicy = iota
TypeIndividualUnderRoot
TypeFlatUnderVocabularyRoot
)
type Converter struct {
@ -36,9 +46,21 @@ type Converter struct {
VocabularyRoot string
PropertyPackagePolicy PropertyPackagePolicy
PropertyPackageRoot string
TypePackageRoot string
TypePackagePolicy TypePackagePolicy
}
func (c Converter) convert(p *rdf.ParsedVocabulary) (v vocabulary, e error) {
func (c Converter) Convert(p *rdf.ParsedVocabulary) (f []*jen.File, e error) {
var v vocabulary
v, e = c.convertVocabulary(p)
if e != nil {
return
}
// TODO
return
}
func (c Converter) convertVocabulary(p *rdf.ParsedVocabulary) (v vocabulary, e error) {
v = newVocabulary()
for k, val := range p.Vocab.Values {
v.Kinds[k] = c.convertValue(val)
@ -53,7 +75,93 @@ func (c Converter) convert(p *rdf.ParsedVocabulary) (v vocabulary, e error) {
return
}
}
// TODO: Types in dependency order.
// Instead of building a dependency tree, naively keep iterating through
// 'allTypes' until it is empty (good) or we get stuck (return error).
allTypes := make([]rdf.VocabularyType, 0, len(p.Vocab.Types))
for _, t := range p.Vocab.Types {
allTypes = append(allTypes, t)
}
for {
if len(allTypes) == 0 {
break
}
stuck := true
for _, t := range allTypes {
var tg *types.TypeGenerator
tg, e = c.convertType(t, p.Vocab, v.FProps, v.NFProps, v.Types)
if e != nil {
return
}
v.Types[t.Name] = tg
}
if stuck {
e = fmt.Errorf("converting types got stuck in dependency cycle")
return
}
}
return
}
func (c Converter) convertType(t rdf.VocabularyType,
v rdf.Vocabulary,
existingFProps map[string]*props.FunctionalPropertyGenerator,
existingNFProps map[string]*props.NonFunctionalPropertyGenerator,
existingTypes map[string]*types.TypeGenerator) (tg *types.TypeGenerator, e error) {
// Determine the types package name
var pkg string
pkg, e = c.typePackageName(t)
if e != nil {
return
}
// Determine the properties for this type
var p []types.Property
for k, prop := range v.Properties {
for _, ref := range prop.Domain {
if len(ref.Vocab) != 0 {
e = fmt.Errorf("unhandled use case: property domain outside its vocabulary")
return
} else if ref.Name == t.Name {
if prop.Functional {
p = append(p, existingFProps[prop.Name])
} else {
p = append(p, existingNFProps[prop.Name])
}
break
}
}
}
// Determine what this type extends
var ext []*types.TypeGenerator
for _, ex := range t.Extends {
if len(ex.Vocab) != 0 {
// TODO: This should be fixed
e = fmt.Errorf("unhandled use case: type extends another type outside its vocabulary")
return
} else {
ext = append(ext, existingTypes[ex.Name])
}
}
tg, e = types.NewTypeGenerator(
pkg,
strings.Title(t.Name), // Must be same in convertTypeToKind
t.Notes,
p,
ext,
nil)
if e != nil {
return
}
// Apply disjoint if both sides are available.
for _, disj := range t.DisjointWith {
if len(disj.Vocab) != 0 {
// TODO: This should be fixed
e = fmt.Errorf("unhandled use case: type is disjoint with another type outside its vocabulary")
return
} else if disjointType, ok := existingTypes[disj.Name]; ok {
disjointType.AddDisjoint(tg)
tg.AddDisjoint(disjointType)
}
}
return
}
@ -116,7 +224,7 @@ func (c Converter) convertValue(v rdf.VocabularyValue) (k *props.Kind) {
func (c Converter) convertTypeToKind(v rdf.VocabularyType) (k *props.Kind) {
k = &props.Kind{
Name: c.toIdentifier(v),
ConcreteKind: strings.Title(v.Name),
ConcreteKind: strings.Title(v.Name), // Must be same in convertType
Nilable: true,
// TODO
SerializeFn: types.SerializeFn,
@ -172,25 +280,58 @@ func (c Converter) propertyKinds(v rdf.VocabularyProperty,
return
}
func (c Converter) typePackageName(v rdf.VocabularyType) (pkg string, e error) {
switch c.TypePackagePolicy {
case TypeFlatUnderRoot:
pkg = c.TypePackageRoot
case TypeIndividualUnderRoot:
pkg = v.Name
case TypeFlatUnderVocabularyRoot:
pkg = c.VocabularyRoot
default:
e = fmt.Errorf("unrecognized TypePackagePolicy: %v", c.TypePackagePolicy)
}
return
}
func (c Converter) propertyPackageName(v rdf.VocabularyProperty) (pkg string, e error) {
switch c.PropertyPackagePolicy {
case FlatUnderRoot:
case PropertyFlatUnderRoot:
pkg = c.PropertyPackageRoot
case IndividualUnderRoot:
case PropertyIndividualUnderRoot:
pkg = v.Name
case PropertyFlatUnderVocabularyRoot:
pkg = c.VocabularyRoot
default:
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
}
return
}
// TODO: Use this?
func (c Converter) typePackageFile(v rdf.VocabularyType) (pkg string, e error) {
switch c.TypePackagePolicy {
case TypeFlatUnderRoot:
pkg = fmt.Sprintf("%s/%s", c.VocabularyRoot, c.TypePackageRoot)
case TypeIndividualUnderRoot:
pkg = fmt.Sprintf("%s/%s/%s", c.VocabularyRoot, c.TypePackageRoot, v.Name)
case TypeFlatUnderVocabularyRoot:
pkg = c.VocabularyRoot
default:
e = fmt.Errorf("unrecognized TypePackagePolicy: %v", c.TypePackagePolicy)
}
return
}
// TODO: Use this?
func (c Converter) propertyPackageFile(v rdf.VocabularyProperty) (pkg string, e error) {
switch c.PropertyPackagePolicy {
case FlatUnderRoot:
case PropertyFlatUnderRoot:
pkg = fmt.Sprintf("%s/%s", c.VocabularyRoot, c.PropertyPackageRoot)
case IndividualUnderRoot:
case PropertyIndividualUnderRoot:
pkg = fmt.Sprintf("%s/%s/%s", c.VocabularyRoot, c.PropertyPackageRoot, v.Name)
case PropertyFlatUnderVocabularyRoot:
pkg = c.VocabularyRoot
default:
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
}

ファイルの表示

@ -83,6 +83,11 @@ func NewTypeGenerator(packageName, typeName, comment string,
return t, nil
}
// AddDisjoint adds another TypeGenerator that is disjoint to this one.
func (t *TypeGenerator) AddDisjoint(o *TypeGenerator) {
t.disjoint = append(t.disjoint, o)
}
// Comment returns the comment for this type.
func (t *TypeGenerator) Comment() string {
return t.comment
@ -134,6 +139,7 @@ func (t *TypeGenerator) Definition() *codegen.Struct {
t.cacheOnce.Do(func() {
members := make([]jen.Code, 0, len(t.properties))
for name, property := range t.properties {
// TODO: Properties of parents that are extended, minus DoesNotApplyTo
members = append(members, jen.Id(name).Id(property.StructName()))
}
t.cachedStruct = codegen.NewStruct(