TBR x/ref: Allow JS Enums to be used like EnumName.LabelName
MultiPart: 2/2
Change-Id: I049a64414f10e7eda31bf57e61c08c5825633006
diff --git a/lib/vdl/codegen/javascript/gen_type_def.go b/lib/vdl/codegen/javascript/gen_type_def.go
index d1a399d..76acc2a 100644
--- a/lib/vdl/codegen/javascript/gen_type_def.go
+++ b/lib/vdl/codegen/javascript/gen_type_def.go
@@ -4,6 +4,7 @@
"fmt"
"v.io/v23/vdl"
+ "v.io/x/ref/lib/vdl/vdlutil"
)
// makeTypeDefinitionsString generates a string that defines the specified types.
@@ -30,7 +31,11 @@
for _, def := range sortedDefs {
if def.Type.Name() != "" {
- str += makeConstructorDefinitionString(def.Type, jsnames)
+ if def.Type.Kind() == vdl.Enum {
+ str += makeEnumLabelString(def.Type, jsnames)
+ } else {
+ str += makeConstructorDefinitionString(def.Type, jsnames)
+ }
}
}
@@ -112,6 +117,24 @@
return fmt.Sprintf("module.exports.%s = %s;\n", name, ctorName)
}
+// makeEnumLabelString creates a string that defines the labels in an enum.
+// e.g. `module.Exports.MyEnum = {
+// ALabel: (Registry.lookupOrCreateConstructor(_typeMyEnum))("ALabel"),
+// BLabel: (Registry.lookupOrCreateConstructor(_typeMyEnum))("BLabel"),
+// }`
+
+func makeEnumLabelString(t *vdl.Type, jsnames typeNames) string {
+ _, name := vdl.SplitIdent(t.Name())
+ str := fmt.Sprintf("module.exports.%s = {\n", name)
+ for i := 0; i < t.NumEnumLabel(); i++ {
+ enumVal := vdl.ZeroValue(t)
+ enumVal.AssignEnumIndex(i)
+ str += fmt.Sprintf(" %s: %s,\n", vdlutil.ToConstCase(t.EnumLabel(i)), typedConst(jsnames, enumVal))
+ }
+ str += "};\n"
+ return str
+}
+
func jsKind(k vdl.Kind) string {
switch k {
case vdl.Any:
diff --git a/lib/vdl/codegen/javascript/pkg_types.go b/lib/vdl/codegen/javascript/pkg_types.go
index f7445d9..7f986da 100644
--- a/lib/vdl/codegen/javascript/pkg_types.go
+++ b/lib/vdl/codegen/javascript/pkg_types.go
@@ -6,6 +6,7 @@
"strings"
"v.io/x/ref/lib/vdl/compile"
+ "v.io/x/ref/lib/vdl/vdlutil"
"v.io/v23/vdl"
)
@@ -52,6 +53,10 @@
return name
}
+ if t.Kind() == vdl.Enum {
+ return fmt.Sprintf("%s.%s._type", tn.LookupConstructor(t), vdlutil.ToConstCase(t.EnumLabel(0)))
+ }
+
return "new " + tn.LookupConstructor(t) + "()._type"
}
diff --git a/lib/vdl/codegen/javascript/type_test.go b/lib/vdl/codegen/javascript/type_test.go
index bc3df73..7e932f2 100644
--- a/lib/vdl/codegen/javascript/type_test.go
+++ b/lib/vdl/codegen/javascript/type_test.go
@@ -57,6 +57,9 @@
{
Type: vdl.ListType(vdl.ByteType),
},
+ {
+ Type: vdl.NamedType("ColorsBeginningWithAOrB", vdl.EnumType("Aqua", "Beige")),
+ },
},
},
},
@@ -75,6 +78,7 @@
expectedResult := `var _type1 = new vdl.Type();
var _type2 = new vdl.Type();
+var _typeColorsBeginningWithAOrB = new vdl.Type();
var _typeNamedList = new vdl.Type();
var _typeNamedStruct = new vdl.Type();
_type1.kind = vdl.Kind.LIST;
@@ -83,6 +87,9 @@
_type2.kind = vdl.Kind.LIST;
_type2.name = "";
_type2.elem = vdl.Types.BYTE;
+_typeColorsBeginningWithAOrB.kind = vdl.Kind.ENUM;
+_typeColorsBeginningWithAOrB.name = "ColorsBeginningWithAOrB";
+_typeColorsBeginningWithAOrB.labels = ["Aqua", "Beige"];
_typeNamedList.kind = vdl.Kind.LIST;
_typeNamedList.name = "NamedList";
_typeNamedList.elem = _typeNamedStruct;
@@ -91,8 +98,13 @@
_typeNamedStruct.fields = [{name: "List", type: _typeNamedList}, {name: "Bool", type: new otherPkg.NamedBool()._type}, {name: "UnnamedTypeField", type: _type1}];
_type1.freeze();
_type2.freeze();
+_typeColorsBeginningWithAOrB.freeze();
_typeNamedList.freeze();
_typeNamedStruct.freeze();
+module.exports.ColorsBeginningWithAOrB = {
+ AQUA: canonicalize.reduce(new (vdl.Registry.lookupOrCreateConstructor(_typeColorsBeginningWithAOrB))('Aqua', true), _typeColorsBeginningWithAOrB),
+ BEIGE: canonicalize.reduce(new (vdl.Registry.lookupOrCreateConstructor(_typeColorsBeginningWithAOrB))('Beige', true), _typeColorsBeginningWithAOrB),
+};
module.exports.NamedList = (vdl.Registry.lookupOrCreateConstructor(_typeNamedList));
module.exports.NamedStruct = (vdl.Registry.lookupOrCreateConstructor(_typeNamedStruct));
`