From d1a6fbe0c75d5c33116ba70190c9613fefd4fe49 Mon Sep 17 00:00:00 2001 From: Erik Arvidsson Date: Mon, 4 Apr 2016 11:54:34 -0700 Subject: [PATCH] Codegen for flow struct types. This generates the a flow interface for structs defined in noms files Issue #1157 Issue #1081 --- nomdl/codegen/code/generate.go | 34 +++++++++++++++++++ nomdl/codegen/codegen.go | 19 ++++++----- nomdl/codegen/js/list.tmpl | 2 +- nomdl/codegen/js/map.tmpl | 2 +- nomdl/codegen/js/ref.tmpl | 2 +- nomdl/codegen/js/set.tmpl | 2 +- nomdl/codegen/js/struct.tmpl | 8 ++++- nomdl/codegen/test/gen/enum_struct.noms.js | 6 +++- nomdl/codegen/test/gen/list_int64.noms.js | 2 +- nomdl/codegen/test/gen/map.noms.js | 4 +-- nomdl/codegen/test/gen/ref.noms.js | 18 ++++++---- nomdl/codegen/test/gen/set.noms.js | 2 +- nomdl/codegen/test/gen/sha1_1c216c6.js | 8 ++++- nomdl/codegen/test/gen/sha1_b3ecb0f.js | 10 ++++-- nomdl/codegen/test/gen/sha1_eda4273.js | 14 ++++++-- nomdl/codegen/test/gen/struct.noms.js | 10 ++++-- .../codegen/test/gen/struct_optional.noms.js | 8 ++++- .../test/gen/struct_primitives.noms.js | 32 ++++++++++++++++- .../codegen/test/gen/struct_recursive.noms.js | 8 +++-- .../test/gen/struct_with_dup_list.noms.js | 8 +++-- .../test/gen/struct_with_imports.noms.js | 10 ++++-- .../codegen/test/gen/struct_with_list.noms.js | 12 ++++++- .../test/gen/struct_with_union_field.noms.js | 18 ++++++++-- .../test/gen/struct_with_unions.noms.js | 24 +++++++++++-- .../codegen/testDeps/leafDep/leafDep.noms.js | 8 ++++- 25 files changed, 222 insertions(+), 49 deletions(-) diff --git a/nomdl/codegen/code/generate.go b/nomdl/codegen/code/generate.go index 0babe1ad51..7c76c130f6 100644 --- a/nomdl/codegen/code/generate.go +++ b/nomdl/codegen/code/generate.go @@ -75,6 +75,40 @@ func (gen Generator) UserType(t types.Type) string { panic("unreachable") } +// UserTypeJS returns a string containing the JS type that should be used when the Noms type described by t needs to be returned by a generated getter or taken as a parameter to a generated setter. +func (gen Generator) UserTypeJS(t types.Type, nomsName string) string { + rt := gen.R.Resolve(t) + k := rt.Kind() + switch k { + case types.BlobKind: + return fmt.Sprintf("%s.Blob", nomsName) + case types.BoolKind: + return "boolean" + case types.StringKind: + return "string" + case types.Float32Kind, types.Float64Kind, types.Int16Kind, types.Int32Kind, types.Int64Kind, types.Int8Kind, types.Uint16Kind, types.Uint32Kind, types.Uint64Kind, types.Uint8Kind: + return fmt.Sprintf("%s.%s", nomsName, strings.ToLower(kindToString(k))) + case types.EnumKind, types.StructKind: + return gen.UserName(t) + case types.ListKind: + return fmt.Sprintf("%s.List<%s>", nomsName, gen.UserTypeJS(t.Desc.(types.CompoundDesc).ElemTypes[0], nomsName)) + case types.SetKind: + return fmt.Sprintf("%s.NomsSet<%s>", nomsName, gen.UserTypeJS(t.Desc.(types.CompoundDesc).ElemTypes[0], nomsName)) + case types.RefKind: + return fmt.Sprintf("%s.RefValue<%s>", nomsName, gen.UserTypeJS(t.Desc.(types.CompoundDesc).ElemTypes[0], nomsName)) + case types.MapKind: + elemTypes := t.Desc.(types.CompoundDesc).ElemTypes + return fmt.Sprintf("%s.NomsMap<%s, %s>", nomsName, gen.UserTypeJS(elemTypes[0], nomsName), gen.UserTypeJS(elemTypes[1], nomsName)) + case types.PackageKind: + return fmt.Sprintf("%s.Package", nomsName) + case types.ValueKind: + return fmt.Sprintf("%s.Value", nomsName) + case types.TypeKind: + return fmt.Sprintf("%s.Type", nomsName) + } + panic("unreachable") +} + // DefToValue returns a string containing Go code to convert an instance of a Def type (named val) to a Noms types.Value of the type described by t. func (gen Generator) DefToValue(val string, t types.Type) string { rt := gen.R.Resolve(t) diff --git a/nomdl/codegen/codegen.go b/nomdl/codegen/codegen.go index 8debb36780..b0feb739da 100644 --- a/nomdl/codegen/codegen.go +++ b/nomdl/codegen/codegen.go @@ -265,20 +265,21 @@ func (gen *codeGen) readTemplates() *template.Template { glob := path.Join(path.Dir(thisfile), gen.lang, "*.tmpl") return template.Must(template.New("").Funcs( template.FuncMap{ - "defType": gen.generator.DefType, - "defToValue": gen.generator.DefToValue, "defToUser": gen.generator.DefToUser, + "defToValue": gen.generator.DefToValue, + "defType": gen.generator.DefType, "mayHaveChunks": gen.generator.MayHaveChunks, - "valueToDef": gen.generator.ValueToDef, - "userType": gen.generator.UserType, - "userToValue": gen.generator.UserToValue, - "userToDef": gen.generator.UserToDef, - "valueToUser": gen.generator.ValueToUser, - "userZero": gen.generator.UserZero, - "valueZero": gen.generator.ValueZero, "title": strings.Title, "toTypesType": gen.generator.ToType, "toTypesTypeJS": gen.generator.ToTypeJS, + "userToDef": gen.generator.UserToDef, + "userToValue": gen.generator.UserToValue, + "userType": gen.generator.UserType, + "userTypeJS": gen.generator.UserTypeJS, + "userZero": gen.generator.UserZero, + "valueToDef": gen.generator.ValueToDef, + "valueToUser": gen.generator.ValueToUser, + "valueZero": gen.generator.ValueZero, }).ParseGlob(glob)) } diff --git a/nomdl/codegen/js/list.tmpl b/nomdl/codegen/js/list.tmpl index 68a9fdfef6..830a39c254 100644 --- a/nomdl/codegen/js/list.tmpl +++ b/nomdl/codegen/js/list.tmpl @@ -1 +1 @@ -// list.tmpl +{{/* Lists in JS needs no codegen */}} diff --git a/nomdl/codegen/js/map.tmpl b/nomdl/codegen/js/map.tmpl index 307bf9528d..ec61431d6d 100644 --- a/nomdl/codegen/js/map.tmpl +++ b/nomdl/codegen/js/map.tmpl @@ -1 +1 @@ -// map.tmpl +{{/* Maps in JS needs no codegen */}} diff --git a/nomdl/codegen/js/ref.tmpl b/nomdl/codegen/js/ref.tmpl index 4af3797979..352a8d827d 100644 --- a/nomdl/codegen/js/ref.tmpl +++ b/nomdl/codegen/js/ref.tmpl @@ -1 +1 @@ -// ref.tmpl +{{/* Refs in JS needs no codegen */}} diff --git a/nomdl/codegen/js/set.tmpl b/nomdl/codegen/js/set.tmpl index f8ae3c6b66..6289ddb303 100644 --- a/nomdl/codegen/js/set.tmpl +++ b/nomdl/codegen/js/set.tmpl @@ -1 +1 @@ -// set.tmpl +{{/* Sets in JS needs no codegen */}} diff --git a/nomdl/codegen/js/struct.tmpl b/nomdl/codegen/js/struct.tmpl index 9d14d034d4..cbe3f9cf17 100644 --- a/nomdl/codegen/js/struct.tmpl +++ b/nomdl/codegen/js/struct.tmpl @@ -1 +1,7 @@ -// struct.tmpl +{{$name := .Name}} +export interface {{.Name}} extends _noms.Struct {{"{"}}{{range $field := .Fields}} + {{.Name}}: {{if .Optional}}?{{end}}{{userTypeJS .T "_noms"}}; // readonly + set{{title .Name}}(value: {{if .Optional}}?{{end}}{{userTypeJS .T "_noms"}}): {{$name}};{{end}}{{range $field := .Choices}} + {{.Name}}: ?{{userTypeJS .T "_noms"}}; // readonly + set{{title .Name}}(value: {{userTypeJS .T "_noms"}}): {{$name}};{{end}} +} diff --git a/nomdl/codegen/test/gen/enum_struct.noms.js b/nomdl/codegen/test/gen/enum_struct.noms.js index 61dbb4c24a..b0495ea5c5 100644 --- a/nomdl/codegen/test/gen/enum_struct.noms.js +++ b/nomdl/codegen/test/gen/enum_struct.noms.js @@ -21,4 +21,8 @@ import * as _noms from '@attic/noms'; } // enum.tmpl -// struct.tmpl + +export interface EnumStruct extends _noms.Struct { + hand: Handedness; // readonly + setHand(value: Handedness): EnumStruct; +} diff --git a/nomdl/codegen/test/gen/list_int64.noms.js b/nomdl/codegen/test/gen/list_int64.noms.js index 2389dc300a..a99f10ffac 100644 --- a/nomdl/codegen/test/gen/list_int64.noms.js +++ b/nomdl/codegen/test/gen/list_int64.noms.js @@ -2,4 +2,4 @@ // @flow // eslint-disable max-len -// list.tmpl + diff --git a/nomdl/codegen/test/gen/map.noms.js b/nomdl/codegen/test/gen/map.noms.js index 9bb4d7b439..459dd0bebe 100644 --- a/nomdl/codegen/test/gen/map.noms.js +++ b/nomdl/codegen/test/gen/map.noms.js @@ -2,5 +2,5 @@ // @flow // eslint-disable max-len -// map.tmpl -// map.tmpl + + diff --git a/nomdl/codegen/test/gen/ref.noms.js b/nomdl/codegen/test/gen/ref.noms.js index 3d6f67102c..b5aa20e3b8 100644 --- a/nomdl/codegen/test/gen/ref.noms.js +++ b/nomdl/codegen/test/gen/ref.noms.js @@ -19,10 +19,14 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// ref.tmpl -// list.tmpl -// ref.tmpl -// list.tmpl -// ref.tmpl -// set.tmpl + +export interface StructWithRef extends _noms.Struct { + r: _noms.RefValue<_noms.NomsSet<_noms.float32>>; // readonly + setR(value: _noms.RefValue<_noms.NomsSet<_noms.float32>>): StructWithRef; +} + + + + + + diff --git a/nomdl/codegen/test/gen/set.noms.js b/nomdl/codegen/test/gen/set.noms.js index f93127d36c..a99f10ffac 100644 --- a/nomdl/codegen/test/gen/set.noms.js +++ b/nomdl/codegen/test/gen/set.noms.js @@ -2,4 +2,4 @@ // @flow // eslint-disable max-len -// set.tmpl + diff --git a/nomdl/codegen/test/gen/sha1_1c216c6.js b/nomdl/codegen/test/gen/sha1_1c216c6.js index 074ee88483..c0e679e5da 100644 --- a/nomdl/codegen/test/gen/sha1_1c216c6.js +++ b/nomdl/codegen/test/gen/sha1_1c216c6.js @@ -21,5 +21,11 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl + +export interface S extends _noms.Struct { + s: string; // readonly + setS(value: string): S; + b: boolean; // readonly + setB(value: boolean): S; +} // enum.tmpl diff --git a/nomdl/codegen/test/gen/sha1_b3ecb0f.js b/nomdl/codegen/test/gen/sha1_b3ecb0f.js index 0e04fd037e..0afe832d81 100644 --- a/nomdl/codegen/test/gen/sha1_b3ecb0f.js +++ b/nomdl/codegen/test/gen/sha1_b3ecb0f.js @@ -19,6 +19,10 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// list.tmpl -// list.tmpl + +export interface A extends _noms.Struct { + A: _noms.List<_noms.List<_noms.Blob>>; // readonly + setA(value: _noms.List<_noms.List<_noms.Blob>>): A; +} + + diff --git a/nomdl/codegen/test/gen/sha1_eda4273.js b/nomdl/codegen/test/gen/sha1_eda4273.js index f0d06a6434..d6bc5f3978 100644 --- a/nomdl/codegen/test/gen/sha1_eda4273.js +++ b/nomdl/codegen/test/gen/sha1_eda4273.js @@ -29,5 +29,15 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// struct.tmpl + +export interface D extends _noms.Struct { + structField: S; // readonly + setStructField(value: S): D; + enumField: E; // readonly + setEnumField(value: E): D; +} + +export interface DUser extends _noms.Struct { + Dfield: D; // readonly + setDfield(value: D): DUser; +} diff --git a/nomdl/codegen/test/gen/struct.noms.js b/nomdl/codegen/test/gen/struct.noms.js index ce51d82d91..53aece284a 100644 --- a/nomdl/codegen/test/gen/struct.noms.js +++ b/nomdl/codegen/test/gen/struct.noms.js @@ -20,5 +20,11 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// list.tmpl + +export interface Struct extends _noms.Struct { + s: string; // readonly + setS(value: string): Struct; + b: boolean; // readonly + setB(value: boolean): Struct; +} + diff --git a/nomdl/codegen/test/gen/struct_optional.noms.js b/nomdl/codegen/test/gen/struct_optional.noms.js index f2f03a97c5..32573a91b1 100644 --- a/nomdl/codegen/test/gen/struct_optional.noms.js +++ b/nomdl/codegen/test/gen/struct_optional.noms.js @@ -20,4 +20,10 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl + +export interface OptionalStruct extends _noms.Struct { + s: ?string; // readonly + setS(value: ?string): OptionalStruct; + b: ?boolean; // readonly + setB(value: ?boolean): OptionalStruct; +} diff --git a/nomdl/codegen/test/gen/struct_primitives.noms.js b/nomdl/codegen/test/gen/struct_primitives.noms.js index 0754c83f21..af51d28c0f 100644 --- a/nomdl/codegen/test/gen/struct_primitives.noms.js +++ b/nomdl/codegen/test/gen/struct_primitives.noms.js @@ -32,4 +32,34 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl + +export interface StructPrimitives extends _noms.Struct { + uint64: _noms.uint64; // readonly + setUint64(value: _noms.uint64): StructPrimitives; + uint32: _noms.uint32; // readonly + setUint32(value: _noms.uint32): StructPrimitives; + uint16: _noms.uint16; // readonly + setUint16(value: _noms.uint16): StructPrimitives; + uint8: _noms.uint8; // readonly + setUint8(value: _noms.uint8): StructPrimitives; + int64: _noms.int64; // readonly + setInt64(value: _noms.int64): StructPrimitives; + int32: _noms.int32; // readonly + setInt32(value: _noms.int32): StructPrimitives; + int16: _noms.int16; // readonly + setInt16(value: _noms.int16): StructPrimitives; + int8: _noms.int8; // readonly + setInt8(value: _noms.int8): StructPrimitives; + float64: _noms.float64; // readonly + setFloat64(value: _noms.float64): StructPrimitives; + float32: _noms.float32; // readonly + setFloat32(value: _noms.float32): StructPrimitives; + bool: boolean; // readonly + setBool(value: boolean): StructPrimitives; + string: string; // readonly + setString(value: string): StructPrimitives; + blob: _noms.Blob; // readonly + setBlob(value: _noms.Blob): StructPrimitives; + value: _noms.Value; // readonly + setValue(value: _noms.Value): StructPrimitives; +} diff --git a/nomdl/codegen/test/gen/struct_recursive.noms.js b/nomdl/codegen/test/gen/struct_recursive.noms.js index f6f068f14c..0bc5d2c637 100644 --- a/nomdl/codegen/test/gen/struct_recursive.noms.js +++ b/nomdl/codegen/test/gen/struct_recursive.noms.js @@ -19,5 +19,9 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// list.tmpl + +export interface Tree extends _noms.Struct { + children: _noms.List; // readonly + setChildren(value: _noms.List): Tree; +} + diff --git a/nomdl/codegen/test/gen/struct_with_dup_list.noms.js b/nomdl/codegen/test/gen/struct_with_dup_list.noms.js index 925ad03f48..f841582f06 100644 --- a/nomdl/codegen/test/gen/struct_with_dup_list.noms.js +++ b/nomdl/codegen/test/gen/struct_with_dup_list.noms.js @@ -19,5 +19,9 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// list.tmpl + +export interface StructWithDupList extends _noms.Struct { + l: _noms.List<_noms.uint8>; // readonly + setL(value: _noms.List<_noms.uint8>): StructWithDupList; +} + diff --git a/nomdl/codegen/test/gen/struct_with_imports.noms.js b/nomdl/codegen/test/gen/struct_with_imports.noms.js index 673548f781..54dcaff8c8 100644 --- a/nomdl/codegen/test/gen/struct_with_imports.noms.js +++ b/nomdl/codegen/test/gen/struct_with_imports.noms.js @@ -23,5 +23,11 @@ import * as _noms from '@attic/noms'; } // enum.tmpl -// struct.tmpl -// list.tmpl + +export interface ImportUser extends _noms.Struct { + importedStruct: D; // readonly + setImportedStruct(value: D): ImportUser; + enum: LocalE; // readonly + setEnum(value: LocalE): ImportUser; +} + diff --git a/nomdl/codegen/test/gen/struct_with_list.noms.js b/nomdl/codegen/test/gen/struct_with_list.noms.js index 75a2816619..831d58660c 100644 --- a/nomdl/codegen/test/gen/struct_with_list.noms.js +++ b/nomdl/codegen/test/gen/struct_with_list.noms.js @@ -22,4 +22,14 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl + +export interface StructWithList extends _noms.Struct { + l: _noms.List<_noms.uint8>; // readonly + setL(value: _noms.List<_noms.uint8>): StructWithList; + b: boolean; // readonly + setB(value: boolean): StructWithList; + s: string; // readonly + setS(value: string): StructWithList; + i: _noms.int64; // readonly + setI(value: _noms.int64): StructWithList; +} diff --git a/nomdl/codegen/test/gen/struct_with_union_field.noms.js b/nomdl/codegen/test/gen/struct_with_union_field.noms.js index b6e86d611a..fc9932b19e 100644 --- a/nomdl/codegen/test/gen/struct_with_union_field.noms.js +++ b/nomdl/codegen/test/gen/struct_with_union_field.noms.js @@ -23,5 +23,19 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// set.tmpl + +export interface StructWithUnionField extends _noms.Struct { + a: _noms.float32; // readonly + setA(value: _noms.float32): StructWithUnionField; + b: ?_noms.float64; // readonly + setB(value: _noms.float64): StructWithUnionField; + c: ?string; // readonly + setC(value: string): StructWithUnionField; + d: ?_noms.Blob; // readonly + setD(value: _noms.Blob): StructWithUnionField; + e: ?_noms.Value; // readonly + setE(value: _noms.Value): StructWithUnionField; + f: ?_noms.NomsSet<_noms.uint8>; // readonly + setF(value: _noms.NomsSet<_noms.uint8>): StructWithUnionField; +} + diff --git a/nomdl/codegen/test/gen/struct_with_unions.noms.js b/nomdl/codegen/test/gen/struct_with_unions.noms.js index af23c7e553..307b224303 100644 --- a/nomdl/codegen/test/gen/struct_with_unions.noms.js +++ b/nomdl/codegen/test/gen/struct_with_unions.noms.js @@ -38,6 +38,24 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl -// struct.tmpl -// struct.tmpl + +export interface StructWithUnions extends _noms.Struct { + a: __unionOfBOfFloat64AndCOfString; // readonly + setA(value: __unionOfBOfFloat64AndCOfString): StructWithUnions; + d: __unionOfEOfFloat64AndFOfString; // readonly + setD(value: __unionOfEOfFloat64AndFOfString): StructWithUnions; +} + +export interface __unionOfBOfFloat64AndCOfString extends _noms.Struct { + b: ?_noms.float64; // readonly + setB(value: _noms.float64): __unionOfBOfFloat64AndCOfString; + c: ?string; // readonly + setC(value: string): __unionOfBOfFloat64AndCOfString; +} + +export interface __unionOfEOfFloat64AndFOfString extends _noms.Struct { + e: ?_noms.float64; // readonly + setE(value: _noms.float64): __unionOfEOfFloat64AndFOfString; + f: ?string; // readonly + setF(value: string): __unionOfEOfFloat64AndFOfString; +} diff --git a/nomdl/codegen/testDeps/leafDep/leafDep.noms.js b/nomdl/codegen/testDeps/leafDep/leafDep.noms.js index 074ee88483..c0e679e5da 100644 --- a/nomdl/codegen/testDeps/leafDep/leafDep.noms.js +++ b/nomdl/codegen/testDeps/leafDep/leafDep.noms.js @@ -21,5 +21,11 @@ import * as _noms from '@attic/noms'; _noms.registerPackage(pkg); } -// struct.tmpl + +export interface S extends _noms.Struct { + s: string; // readonly + setS(value: string): S; + b: boolean; // readonly + setB(value: boolean): S; +} // enum.tmpl