Commit 6de6f090 authored by Scott Graham's avatar Scott Graham Committed by Commit Bot

Fuchsia: Handling of more cases for default initialization in FIDL/JS

Initializing a struct member with the value of an enum would previously
fail to compile; implement this. This is slightly awkward because the
front end does not scope the enum value to the enum like the C++ (and
JS) bindings but rather only to the library. So the compiler needs to
know the type to which it's being assigned and use that to determine how
the enum's value is intended to be qualified.

Bug: 883496
Change-Id: Id8a9f75d07bb0acb11963ecbd37d4915b36c28e0
Reviewed-on: https://chromium-review.googlesource.com/c/1313286
Commit-Queue: Scott Graham <scottmg@chromium.org>
Reviewed-by: default avatarWez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605601}
parent bc7a25ff
...@@ -74,9 +74,16 @@ def _InlineSizeOfType(t): ...@@ -74,9 +74,16 @@ def _InlineSizeOfType(t):
raise NotImplementedError() raise NotImplementedError()
def _CompileConstant(val): def _CompileConstant(val, assignment_type):
"""|assignment_type| is the TypeClass to which |val| will be assigned. This is
is currently used to scope identifiers to their enum."""
if val.kind == fidl.ConstantKind.IDENTIFIER: if val.kind == fidl.ConstantKind.IDENTIFIER:
raise NotImplementedError() if not assignment_type:
raise Exception('Need assignment_type for IDENTIFIER constant')
type_compound = _ParseCompoundIdentifier(assignment_type.identifier)
type_name = _CompileCompoundIdentifier(type_compound)
val_compound = _ParseCompoundIdentifier(val.identifier)
return type_name + '.' + val_compound.name
elif val.kind == fidl.ConstantKind.LITERAL: elif val.kind == fidl.ConstantKind.LITERAL:
return _CompileLiteral(val.literal) return _CompileLiteral(val.literal)
else: else:
...@@ -136,7 +143,7 @@ class Compiler(object): ...@@ -136,7 +143,7 @@ class Compiler(object):
def _CompileConst(self, const): def _CompileConst(self, const):
compound = _ParseCompoundIdentifier(const.name) compound = _ParseCompoundIdentifier(const.name)
name = _CompileCompoundIdentifier(compound) name = _CompileCompoundIdentifier(compound)
value = _CompileConstant(const.value) value = _CompileConstant(const.value, None)
self.f.write('''/** self.f.write('''/**
* @const * @const
*/ */
...@@ -158,8 +165,8 @@ const %(name)s = %(value)s; ...@@ -158,8 +165,8 @@ const %(name)s = %(value)s;
const %(name)s = { const %(name)s = {
''' % data) ''' % data)
for member in enum.members: for member in enum.members:
self.f.write( self.f.write(''' %s: %s,\n''' % (member.name,
''' %s: %s,\n''' % (member.name, _CompileConstant(member.value))) _CompileConstant(member.value, None)))
self.f.write('};\n') self.f.write('};\n')
self.f.write('const _kTT_%(name)s = _kTT_%(type)s;\n\n' % data) self.f.write('const _kTT_%(name)s = _kTT_%(type)s;\n\n' % data)
...@@ -190,7 +197,8 @@ const %(name)s = { ...@@ -190,7 +197,8 @@ const %(name)s = {
'member_name': member_name, 'member_name': member_name,
}) })
self.f.write('''\ self.f.write(
'''\
const _kTT_%(name)s = { const _kTT_%(name)s = {
enc: function(e, o, v) { enc: function(e, o, v) {
if (v.$tag === $fidl__kInvalidUnionTag) throw "invalid tag"; if (v.$tag === $fidl__kInvalidUnionTag) throw "invalid tag";
...@@ -238,11 +246,11 @@ function %(name)s() { this.reset(); } ...@@ -238,11 +246,11 @@ function %(name)s() { this.reset(); }
%(name)s.prototype.reset = function(i) { %(name)s.prototype.reset = function(i) {
this.$tag = (i === undefined) ? $fidl__kInvalidUnionTag : i; this.$tag = (i === undefined) ? $fidl__kInvalidUnionTag : i;
''' % { ''' % {
'name': name, 'name': name,
'size': union.size, 'size': union.size,
'enc_cases': '\n'.join(enc_cases), 'enc_cases': '\n'.join(enc_cases),
'dec_cases': '\n'.join(dec_cases), 'dec_cases': '\n'.join(dec_cases),
}) })
for m in member_names: for m in member_names:
self.f.write(' this.%s = null;\n' % m) self.f.write(' this.%s = null;\n' % m)
self.f.write('}\n\n') self.f.write('}\n\n')
...@@ -283,7 +291,7 @@ function %(name)s(%(param_names)s) { ...@@ -283,7 +291,7 @@ function %(name)s(%(param_names)s) {
value = '%(member_name)s' value = '%(member_name)s'
if member.maybe_default_value: if member.maybe_default_value:
value = ('(%(member_name)s !== undefined) ? %(member_name)s : ' + value = ('(%(member_name)s !== undefined) ? %(member_name)s : ' +
_CompileConstant(member.maybe_default_value)) _CompileConstant(member.maybe_default_value, member.type))
elif self.fidl.declarations.get(member.type.identifier) == \ elif self.fidl.declarations.get(member.type.identifier) == \
fidl.DeclarationsMap.UNION: fidl.DeclarationsMap.UNION:
union_compound = _ParseCompoundIdentifier(member.type.identifier) union_compound = _ParseCompoundIdentifier(member.type.identifier)
......
...@@ -709,6 +709,20 @@ TEST_F(FidlGenJsTest, UnionReceive) { ...@@ -709,6 +709,20 @@ TEST_F(FidlGenJsTest, UnionReceive) {
EXPECT_EQ(helper.Get<uint32_t>("result_length"), 987654u); EXPECT_EQ(helper.Get<uint32_t>("result_length"), 987654u);
} }
TEST_F(FidlGenJsTest, DefaultUsingIdentifier) {
v8::Isolate* isolate = instance_->isolate();
BindingsSetupHelper helper(isolate);
std::string source = R"(
var temp = new DefaultUsingIdentifier();
this.result = temp.blorp_defaulting_to_beta;
)";
helper.runner().Run(source, "test.js");
EXPECT_EQ(helper.Get<int>("result"),
static_cast<int>(fidljstest::Blorp::BETA));
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
base::TestSuite test_suite(argc, argv); base::TestSuite test_suite(argc, argv);
......
...@@ -57,6 +57,10 @@ struct StructOfMultipleUnions { ...@@ -57,6 +57,10 @@ struct StructOfMultipleUnions {
UnionOfStructs trailing; UnionOfStructs trailing;
}; };
struct DefaultUsingIdentifier {
Blorp blorp_defaulting_to_beta = BETA;
};
interface Testola { interface Testola {
1: DoSomething(); 1: DoSomething();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment