diff --git a/nomdl/codegen/code/generate.go b/nomdl/codegen/code/generate.go index c92537d31b..109f172497 100644 --- a/nomdl/codegen/code/generate.go +++ b/nomdl/codegen/code/generate.go @@ -429,18 +429,18 @@ func firstToLower(s string) string { return string(b) } -// ToTypeJS returns a string containing Go code that instantiates a Type instance equivalent to t for JavaScript. -func (gen *Generator) ToTypeJS(t types.Type, fileID, nomsName string, indent int) string { +// ToTypeValueJS returns a string containing JS code that instantiates a Type instance equivalent to t for JavaScript. +func (gen *Generator) ToTypeValueJS(t types.Type, inPackageDef bool, indent int) string { d.Chk.True(!t.HasPackageRef() && !t.IsUnresolved() || t.HasOrdinal(), "%s does not have an ordinal set", t.Name()) if t.HasPackageRef() { return fmt.Sprintf(`%s(%s.parse('%s'), %d)`, gen.ImportJS("makeType"), gen.ImportJS("Ref"), t.PackageRef().String(), t.Ordinal()) } if t.IsUnresolved() { - if fileID != "" { - return fmt.Sprintf(`%s.makeType(__packageInFile_%s_CachedRef, %d)`, nomsName, fileID, t.Ordinal()) + if inPackageDef { + return fmt.Sprintf(`%s(new %s(), %d)`, gen.ImportJS("makeType"), gen.ImportJS("Ref"), t.Ordinal()) } - return fmt.Sprintf(`%s(new %s(), %d)`, gen.ImportJS("makeType"), gen.ImportJS("Ref"), t.Ordinal()) + return fmt.Sprintf("%s(_pkg.ref, %d)", gen.ImportJS("makeType"), t.Ordinal()) } if types.IsPrimitiveKind(t.Kind()) { @@ -451,7 +451,7 @@ func (gen *Generator) ToTypeJS(t types.Type, fileID, nomsName string, indent int case types.CompoundDesc: types := make([]string, len(desc.ElemTypes)) for i, t := range desc.ElemTypes { - types[i] = gen.ToTypeJS(t, fileID, nomsName, 0) + types[i] = gen.ToTypeValueJS(t, inPackageDef, 0) } return fmt.Sprintf(`%s(%s.%s, %s)`, gen.ImportJS("makeCompoundType"), gen.ImportJS("Kind"), kindToString(t.Kind()), strings.Join(types, ", ")) case types.EnumDesc: @@ -460,7 +460,7 @@ func (gen *Generator) ToTypeJS(t types.Type, fileID, nomsName string, indent int flatten := func(f []types.Field) string { out := make([]string, 0, len(f)) for _, field := range f { - out = append(out, fmt.Sprintf(`%snew %s('%s', %s, %t),`, ind(indent+1), gen.ImportJS("Field"), field.Name, gen.ToTypeJS(field.T, fileID, nomsName, 0), field.Optional)) + out = append(out, fmt.Sprintf(`%snew %s('%s', %s, %t),`, ind(indent+1), gen.ImportJS("Field"), field.Name, gen.ToTypeValueJS(field.T, inPackageDef, 0), field.Optional)) } return strings.Join(out, "\n") } diff --git a/nomdl/codegen/codegen.go b/nomdl/codegen/codegen.go index d3f2236e19..867a384e94 100644 --- a/nomdl/codegen/codegen.go +++ b/nomdl/codegen/codegen.go @@ -277,7 +277,7 @@ func (gen *codeGen) readTemplates() *template.Template { "defToUser": gen.generator.DefToUser, "defToValue": gen.generator.DefToValue, "defType": gen.generator.DefType, - "importJs": gen.generator.ImportJS, + "importJS": gen.generator.ImportJS, "importJsType": gen.generator.ImportJSType, "isLast": gen.generator.IsLast, "mayHaveChunks": gen.generator.MayHaveChunks, @@ -285,7 +285,7 @@ func (gen *codeGen) readTemplates() *template.Template { "refToJSIdentfierName": gen.generator.RefToJSIdentfierName, "title": strings.Title, "toTypesType": gen.generator.ToType, - "toTypesTypeJS": gen.generator.ToTypeJS, + "toTypeValueJS": gen.generator.ToTypeValueJS, "userToDef": gen.generator.UserToDef, "userToValue": gen.generator.UserToValue, "userType": gen.generator.UserType, diff --git a/nomdl/codegen/js/list.tmpl b/nomdl/codegen/js/list.tmpl index 889995a8dd..9094ed8f32 100644 --- a/nomdl/codegen/js/list.tmpl +++ b/nomdl/codegen/js/list.tmpl @@ -1 +1,4 @@ -{{/* Lists in JS needs no codegen */}} \ No newline at end of file + +export function new{{userType .Type}}(values: Array<{{userTypeJS .ElemType}}>): Promise<{{importJsType "NomsList"}}<{{userTypeJS .ElemType}}>> { + return {{importJS "newList"}}(values, {{importJS "makeListType"}}({{toTypeValueJS .ElemType false 0}})); +} diff --git a/nomdl/codegen/js/map.tmpl b/nomdl/codegen/js/map.tmpl index 29dd64eaea..7594bc9989 100644 --- a/nomdl/codegen/js/map.tmpl +++ b/nomdl/codegen/js/map.tmpl @@ -1 +1,4 @@ -{{/* Maps in JS needs no codegen */}} \ No newline at end of file + +export function new{{userType .Type}}(values: Array): Promise<{{importJsType "NomsMap"}}<{{userTypeJS .KeyType}}, {{userTypeJS .ValueType}}>> { + return {{importJS "newMap"}}(values, {{importJS "makeMapType"}}({{toTypeValueJS .KeyType false 0}}, {{toTypeValueJS .ValueType false 0}})); +} diff --git a/nomdl/codegen/js/package.tmpl b/nomdl/codegen/js/package.tmpl index e4f8edaa9a..1e8c17dca6 100644 --- a/nomdl/codegen/js/package.tmpl +++ b/nomdl/codegen/js/package.tmpl @@ -1,10 +1,10 @@ {{if .HasTypes}} -const _pkg = new {{importJs "Package"}}([{{range $i, $t := .Types}} - {{toTypesTypeJS $t "" "_noms" 3}},{{end}} +const _pkg = new {{importJS "Package"}}([{{range $i, $t := .Types}} + {{toTypeValueJS $t true 3}},{{end}} ], [{{range $deps := .Dependencies}} - {{importJs "Ref"}}.parse('{{$deps}}'),{{end}} + {{importJS "Ref"}}.parse('{{$deps}}'),{{end}} ]); -{{importJs "registerPackage"}}(_pkg);{{range $i, $t := .Types}} -export const typeFor{{userType $t}} = {{importJs "makeType"}}(_pkg.ref, {{$i}}); +{{importJS "registerPackage"}}(_pkg);{{range $i, $t := .Types}} +export const typeFor{{userType $t}} = {{importJS "makeType"}}(_pkg.ref, {{$i}}); const {{userType $t}}$typeDef = _pkg.types[{{$i}}];{{end}} {{end}} diff --git a/nomdl/codegen/js/set.tmpl b/nomdl/codegen/js/set.tmpl index 6a84292a43..4f8d668968 100644 --- a/nomdl/codegen/js/set.tmpl +++ b/nomdl/codegen/js/set.tmpl @@ -1 +1,4 @@ -{{/* Sets in JS needs no codegen */}} \ No newline at end of file + +export function new{{userType .Type}}(values: Array<{{userTypeJS .ElemType}}>): Promise<{{importJsType "NomsSet"}}<{{userTypeJS .ElemType}}>> { + return {{importJS "newSet"}}(values, {{importJS "makeSetType"}}({{toTypeValueJS .ElemType false 0}})); +} diff --git a/nomdl/codegen/js/struct.tmpl b/nomdl/codegen/js/struct.tmpl index 24278d3935..d2a4ff6537 100644 --- a/nomdl/codegen/js/struct.tmpl +++ b/nomdl/codegen/js/struct.tmpl @@ -11,4 +11,4 @@ interface {{.Name}}$Interface extends {{importJsType "Struct"}} { set{{title .Name}}(value: {{userTypeJS .T}}): {{$name}}$Interface;{{end}} } -export const {{.Name}}: Class<{{.Name}}$Interface> = {{importJs "createStructClass"}}(typeFor{{userType .Type}}, {{userType .Type}}$typeDef); +export const {{.Name}}: Class<{{.Name}}$Interface> = {{importJS "createStructClass"}}(typeFor{{userType .Type}}, {{userType .Type}}$typeDef); diff --git a/nomdl/codegen/test/gen/list_int64.noms.js b/nomdl/codegen/test/gen/list_int64.noms.js index 28aece7893..0dfd441e3c 100644 --- a/nomdl/codegen/test/gen/list_int64.noms.js +++ b/nomdl/codegen/test/gen/list_int64.noms.js @@ -2,4 +2,17 @@ // @flow /* eslint-disable */ +import { + int64Type as _int64Type, + makeListType as _makeListType, + newList as _newList, +} from '@attic/noms'; +import type { + NomsList as _NomsList, + int64 as _int64, +} from '@attic/noms'; + +export function newListOfInt64(values: Array<_int64>): Promise<_NomsList<_int64>> { + return _newList(values, _makeListType(_int64Type)); +} diff --git a/nomdl/codegen/test/gen/map.noms.js b/nomdl/codegen/test/gen/map.noms.js index 28aece7893..4b8cc709e9 100644 --- a/nomdl/codegen/test/gen/map.noms.js +++ b/nomdl/codegen/test/gen/map.noms.js @@ -2,4 +2,23 @@ // @flow /* eslint-disable */ +import { + boolType as _boolType, + makeMapType as _makeMapType, + newMap as _newMap, + stringType as _stringType, + valueType as _valueType, +} from '@attic/noms'; +import type { + NomsMap as _NomsMap, + Value as _Value, +} from '@attic/noms'; + +export function newMapOfBoolToString(values: Array): Promise<_NomsMap> { + return _newMap(values, _makeMapType(_boolType, _stringType)); +} + +export function newMapOfStringToValue(values: Array): Promise<_NomsMap> { + return _newMap(values, _makeMapType(_stringType, _valueType)); +} diff --git a/nomdl/codegen/test/gen/ref.noms.js b/nomdl/codegen/test/gen/ref.noms.js index 9c3cd9be5d..642d66ab6e 100644 --- a/nomdl/codegen/test/gen/ref.noms.js +++ b/nomdl/codegen/test/gen/ref.noms.js @@ -9,11 +9,17 @@ import { createStructClass as _createStructClass, float32Type as _float32Type, makeCompoundType as _makeCompoundType, + makeListType as _makeListType, + makeSetType as _makeSetType, makeStructType as _makeStructType, makeType as _makeType, + newList as _newList, + newSet as _newSet, registerPackage as _registerPackage, + stringType as _stringType, } from '@attic/noms'; import type { + NomsList as _NomsList, NomsSet as _NomsSet, RefValue as _RefValue, Struct as _Struct, @@ -47,3 +53,15 @@ interface StructWithRef$Interface extends _Struct { } export const StructWithRef: Class = _createStructClass(typeForStructWithRef, StructWithRef$typeDef); + +export function newListOfRefOfFloat32(values: Array<_RefValue<_float32>>): Promise<_NomsList<_RefValue<_float32>>> { + return _newList(values, _makeListType(_makeCompoundType(_Kind.Ref, _float32Type))); +} + +export function newListOfString(values: Array): Promise<_NomsList> { + return _newList(values, _makeListType(_stringType)); +} + +export function newSetOfFloat32(values: Array<_float32>): Promise<_NomsSet<_float32>> { + return _newSet(values, _makeSetType(_float32Type)); +} diff --git a/nomdl/codegen/test/gen/set.noms.js b/nomdl/codegen/test/gen/set.noms.js index 28aece7893..61a6861419 100644 --- a/nomdl/codegen/test/gen/set.noms.js +++ b/nomdl/codegen/test/gen/set.noms.js @@ -2,4 +2,16 @@ // @flow /* eslint-disable */ +import { + boolType as _boolType, + makeSetType as _makeSetType, + newSet as _newSet, +} from '@attic/noms'; +import type { + NomsSet as _NomsSet, +} from '@attic/noms'; + +export function newSetOfBool(values: Array): Promise<_NomsSet> { + return _newSet(values, _makeSetType(_boolType)); +} diff --git a/nomdl/codegen/test/gen/sha1_b3ecb0f.js b/nomdl/codegen/test/gen/sha1_b3ecb0f.js index f7666962fd..65cb5df6d0 100644 --- a/nomdl/codegen/test/gen/sha1_b3ecb0f.js +++ b/nomdl/codegen/test/gen/sha1_b3ecb0f.js @@ -9,8 +9,10 @@ import { blobType as _blobType, createStructClass as _createStructClass, makeCompoundType as _makeCompoundType, + makeListType as _makeListType, makeStructType as _makeStructType, makeType as _makeType, + newList as _newList, registerPackage as _registerPackage, } from '@attic/noms'; import type { @@ -46,3 +48,11 @@ interface A$Interface extends _Struct { } export const A: Class = _createStructClass(typeForA, A$typeDef); + +export function newListOfListOfBlob(values: Array<_NomsList<_Blob>>): Promise<_NomsList<_NomsList<_Blob>>> { + return _newList(values, _makeListType(_makeCompoundType(_Kind.List, _blobType))); +} + +export function newListOfBlob(values: Array<_Blob>): Promise<_NomsList<_Blob>> { + return _newList(values, _makeListType(_blobType)); +} diff --git a/nomdl/codegen/test/gen/struct.noms.js b/nomdl/codegen/test/gen/struct.noms.js index 9525ee7355..e5bde27975 100644 --- a/nomdl/codegen/test/gen/struct.noms.js +++ b/nomdl/codegen/test/gen/struct.noms.js @@ -7,12 +7,15 @@ import { Package as _Package, boolType as _boolType, createStructClass as _createStructClass, + makeListType as _makeListType, makeStructType as _makeStructType, makeType as _makeType, + newList as _newList, registerPackage as _registerPackage, stringType as _stringType, } from '@attic/noms'; import type { + NomsList as _NomsList, Struct as _Struct, } from '@attic/noms'; @@ -47,3 +50,7 @@ interface Struct$Interface extends _Struct { } export const Struct: Class = _createStructClass(typeForStruct, Struct$typeDef); + +export function newListOfStruct(values: Array): Promise<_NomsList> { + return _newList(values, _makeListType(_makeType(_pkg.ref, 0))); +} diff --git a/nomdl/codegen/test/gen/struct_recursive.noms.js b/nomdl/codegen/test/gen/struct_recursive.noms.js index 02396ef754..d52a8e4893 100644 --- a/nomdl/codegen/test/gen/struct_recursive.noms.js +++ b/nomdl/codegen/test/gen/struct_recursive.noms.js @@ -9,8 +9,10 @@ import { Ref as _Ref, createStructClass as _createStructClass, makeCompoundType as _makeCompoundType, + makeListType as _makeListType, makeStructType as _makeStructType, makeType as _makeType, + newList as _newList, registerPackage as _registerPackage, } from '@attic/noms'; import type { @@ -45,3 +47,7 @@ interface Tree$Interface extends _Struct { } export const Tree: Class = _createStructClass(typeForTree, Tree$typeDef); + +export function newListOfTree(values: Array): Promise<_NomsList> { + return _newList(values, _makeListType(_makeType(_pkg.ref, 0))); +} 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 65da8d7bc1..7020e5f2c4 100644 --- a/nomdl/codegen/test/gen/struct_with_dup_list.noms.js +++ b/nomdl/codegen/test/gen/struct_with_dup_list.noms.js @@ -8,8 +8,10 @@ import { Package as _Package, createStructClass as _createStructClass, makeCompoundType as _makeCompoundType, + makeListType as _makeListType, makeStructType as _makeStructType, makeType as _makeType, + newList as _newList, registerPackage as _registerPackage, uint8Type as _uint8Type, } from '@attic/noms'; @@ -46,3 +48,7 @@ interface StructWithDupList$Interface extends _Struct { } export const StructWithDupList: Class = _createStructClass(typeForStructWithDupList, StructWithDupList$typeDef); + +export function newListOfUint8(values: Array<_uint8>): Promise<_NomsList<_uint8>> { + return _newList(values, _makeListType(_uint8Type)); +} diff --git a/nomdl/codegen/test/gen/struct_with_imports.noms.js b/nomdl/codegen/test/gen/struct_with_imports.noms.js index 91d15e7056..9ccf3bbba6 100644 --- a/nomdl/codegen/test/gen/struct_with_imports.noms.js +++ b/nomdl/codegen/test/gen/struct_with_imports.noms.js @@ -8,11 +8,14 @@ import { Ref as _Ref, createStructClass as _createStructClass, makeEnumType as _makeEnumType, + makeListType as _makeListType, makeStructType as _makeStructType, makeType as _makeType, + newList as _newList, registerPackage as _registerPackage, } from '@attic/noms'; import type { + NomsList as _NomsList, Struct as _Struct, } from '@attic/noms'; import * as dep from './sha1_eda4273.js'; @@ -57,3 +60,7 @@ interface ImportUser$Interface extends _Struct { } export const ImportUser: Class = _createStructClass(typeForImportUser, ImportUser$typeDef); + +export function newListOfD(values: Array): Promise<_NomsList> { + return _newList(values, _makeListType(_makeType(_Ref.parse('sha1-eda4273cba9d5d4a1bccf41bcaec64743863cde0'), 0))); +} 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 70acc7dc4e..167d63111c 100644 --- a/nomdl/codegen/test/gen/struct_with_union_field.noms.js +++ b/nomdl/codegen/test/gen/struct_with_union_field.noms.js @@ -11,8 +11,10 @@ import { float32Type as _float32Type, float64Type as _float64Type, makeCompoundType as _makeCompoundType, + makeSetType as _makeSetType, makeStructType as _makeStructType, makeType as _makeType, + newSet as _newSet, registerPackage as _registerPackage, stringType as _stringType, uint8Type as _uint8Type, @@ -69,3 +71,7 @@ interface StructWithUnionField$Interface extends _Struct { } export const StructWithUnionField: Class = _createStructClass(typeForStructWithUnionField, StructWithUnionField$typeDef); + +export function newSetOfUint8(values: Array<_uint8>): Promise<_NomsSet<_uint8>> { + return _newSet(values, _makeSetType(_uint8Type)); +} diff --git a/nomdl/codegen/test/list-int64-test.js b/nomdl/codegen/test/list-int64-test.js new file mode 100644 index 0000000000..646963cba2 --- /dev/null +++ b/nomdl/codegen/test/list-int64-test.js @@ -0,0 +1,14 @@ +// @flow + +import {assert} from 'chai'; +import {suite, test} from 'mocha'; +import {newListOfInt64} from './gen/list_int64.noms.js'; +import {makeListType, int64Type} from '@attic/noms'; + +suite('list_int64.noms', () => { + test('constructor', async () => { + const l = await newListOfInt64([0, 1, 2, 3]); + assert.equal(l.length, 4); + assert.isTrue(l.type.equals(makeListType(int64Type))); + }); +}); diff --git a/nomdl/codegen/test/map-test.js b/nomdl/codegen/test/map-test.js new file mode 100644 index 0000000000..7eac224cca --- /dev/null +++ b/nomdl/codegen/test/map-test.js @@ -0,0 +1,13 @@ +// @flow + +import {assert} from 'chai'; +import {suite, test} from 'mocha'; +import {newMapOfBoolToString} from './gen/map.noms.js'; +import {makeMapType, boolType, stringType} from '@attic/noms'; + +suite('map.noms', () => { + test('constructor', async () => { + const s = await newMapOfBoolToString([true, 'yes', false, 'no']); + assert.isTrue(s.type.equals(makeMapType(boolType, stringType))); + }); +}); diff --git a/nomdl/codegen/test/package.json b/nomdl/codegen/test/package.json index 56b2251790..c3d3bea82a 100644 --- a/nomdl/codegen/test/package.json +++ b/nomdl/codegen/test/package.json @@ -9,7 +9,7 @@ "author": "", "license": "ISC", "devDependencies": { - "@attic/noms": "^7.6.0", + "@attic/noms": "^7.6.1", "babel-cli": "6.6.5", "babel-core": "6.7.2", "babel-eslint": "5.0.0", diff --git a/nomdl/codegen/test/set-test.js b/nomdl/codegen/test/set-test.js new file mode 100644 index 0000000000..9816244945 --- /dev/null +++ b/nomdl/codegen/test/set-test.js @@ -0,0 +1,13 @@ +// @flow + +import {assert} from 'chai'; +import {suite, test} from 'mocha'; +import {newSetOfBool} from './gen/set.noms.js'; +import {makeSetType, boolType} from '@attic/noms'; + +suite('set.noms', () => { + test('constructor', async () => { + const s = await newSetOfBool([true]); + assert.isTrue(s.type.equals(makeSetType(boolType))); + }); +}); diff --git a/nomdl/codegen/test/struct-optional-test.js b/nomdl/codegen/test/struct-optional-test.js new file mode 100644 index 0000000000..6dd31b5bd9 --- /dev/null +++ b/nomdl/codegen/test/struct-optional-test.js @@ -0,0 +1,25 @@ +// @flow + +import {assert} from 'chai'; +import {suite, test} from 'mocha'; + +import {OptionalStruct} from './gen/struct_optional.noms.js'; + +suite('struct_optional.noms', () => { + test('constructor', async () => { + const os = new OptionalStruct({}); + assert.isUndefined(os.s); + assert.isUndefined(os.b); + + const os2 = os.setS('hi'); + assert.equal(os2.s, 'hi'); + assert.isUndefined(os2.b); + + const os3 = os2.setB(true); + assert.equal(os3.s, 'hi'); + assert.equal(os3.b, true); + + const os4 = os2.setB(undefined).setS(undefined); + assert.isTrue(os4.equals(os)); + }); +}); diff --git a/nomdl/codegen/test/struct-recursive-test.js b/nomdl/codegen/test/struct-recursive-test.js index e69ab559ba..d2e3dc9b67 100644 --- a/nomdl/codegen/test/struct-recursive-test.js +++ b/nomdl/codegen/test/struct-recursive-test.js @@ -2,7 +2,7 @@ import {assert} from 'chai'; import {suite, test} from 'mocha'; -import {Tree, typeForTree} from './gen/struct_recursive.noms.js'; +import {Tree, typeForTree, newListOfTree} from './gen/struct_recursive.noms.js'; import {newList, makeListType} from '@attic/noms'; suite('struct_recursive.noms', () => { @@ -13,5 +13,11 @@ suite('struct_recursive.noms', () => { new Tree({children: await newList([], listOfTreeType)}), ], listOfTreeType)}); assert.equal(t.children.length, 2); + + const t2: Tree = new Tree({children: await newListOfTree([ + new Tree({children: await newListOfTree([])}), + new Tree({children: await newListOfTree([])}), + ])}); + assert.isTrue(t.equals(t2)); }); });