From 63bc7177234ef391a46bc641ea4a6aa8d3b6bca2 Mon Sep 17 00:00:00 2001 From: Hwanseung Lee Date: Sat, 30 Sep 2017 22:29:42 +0900 Subject: [PATCH] implement enum --- core/idl_types.h | 2 ++ core/native_type_traits.h | 39 ++++++++++++++++++++++ examples/calculator.cc | 15 +++++++++ examples/calculator.h | 3 ++ examples/calculator.idl | 8 +++++ examples/calculator.js | 21 ++++++++++++ generator/parser/idl_definition.ts | 4 +++ generator/parser/idl_definition_factory.ts | 6 ++++ generator/parser/idl_enum.ts | 34 +++++++++++++++++++ template/interface_cpp.njk | 3 ++ 10 files changed, 135 insertions(+) create mode 100644 generator/parser/idl_enum.ts diff --git a/core/idl_types.h b/core/idl_types.h index 6112174..3047c76 100644 --- a/core/idl_types.h +++ b/core/idl_types.h @@ -25,5 +25,7 @@ struct IDLLongLong final : public IDLBaseHelper {}; struct IDLLong final : public IDLBaseHelper {}; struct IDLShort final : public IDLBaseHelper {}; struct IDLString final : public IDLBaseHelper {}; +// FIXME(Hwansung): should be generated automatically in another file. +struct IDLOperationType final : public IDLBaseHelper {}; #endif // CORE_IDL_TYPES_H_ diff --git a/core/native_type_traits.h b/core/native_type_traits.h index 454375d..4a3c325 100644 --- a/core/native_type_traits.h +++ b/core/native_type_traits.h @@ -160,4 +160,43 @@ struct NativeTypeTraits : public NativeTypeTraitsBase { } }; +// FIXME(Hwansung): should be generated automatically in another file. +template <> +struct NativeTypeTraits + : public NativeTypeTraitsBase { + static std::string NativeValue(const Napi::Env& env, + const Napi::Value& js_value) { + if (!js_value.IsString()) { + Napi::TypeError::New(env, "It's an invalid string.") + .ThrowAsJavaScriptException(); + return std::string(); + } + + std::string value = js_value.ToString().Utf8Value(); + if (!IsValidValue(value)) { + Napi::TypeError::New(env, "it not matched with values of enum in idl.") + .ThrowAsJavaScriptException(); + return std::string(); + } + + return js_value.ToString().Utf8Value(); + } + + static bool IsTypeEquals(const Napi::Value& js_value) { + if (js_value.IsString()) { + std::string value = js_value.ToString().Utf8Value(); + return IsValidValue(value); + } + return false; + } + + static bool IsValidValue(std::string value) { + if (value.compare("add") == 0 || value.compare("sub") == 0 || + value.compare("mul") == 0 || value.compare("div") == 0) { + return true; + } + return false; + } +}; + #endif // CORE_NATIVE_TYPE_TRAITS_H_ diff --git a/examples/calculator.cc b/examples/calculator.cc index f22d349..55d63e7 100644 --- a/examples/calculator.cc +++ b/examples/calculator.cc @@ -60,3 +60,18 @@ double Calculator::Div(double number1, double number2) { bool Calculator::IsEquals(int16_t number1, int16_t number2) { return number1 == number2; } + +double Calculator::Calculate(const std::string& operatorStr, + double number1, + double number2) { + if (operatorStr.compare("add") == 0) { + return number1 + number2; + } else if (operatorStr.compare("sub") == 0) { + return number1 - number2; + } else if (operatorStr.compare("mul") == 0) { + return number1 * number2; + } else if (operatorStr.compare("div") == 0) { + return number1 / number2; + } + return 0; +} diff --git a/examples/calculator.h b/examples/calculator.h index 5264941..6c8a92a 100644 --- a/examples/calculator.h +++ b/examples/calculator.h @@ -32,6 +32,9 @@ class Calculator { int64_t Mul(int64_t number1, int64_t number2); double Div(double number1, double number2); bool IsEquals(int16_t number1, int16_t number2); + double Calculate(const std::string& operatorStr, + double number1, + double number2); }; #endif // EXAMPLES_CALCULATOR_H_ diff --git a/examples/calculator.idl b/examples/calculator.idl index fbc661f..138958a 100644 --- a/examples/calculator.idl +++ b/examples/calculator.idl @@ -14,6 +14,13 @@ * limitations under the License. */ + enum OperationType { + "add", + "sub", + "mul", + "div" +}; + [ Constructor(), Constructor(long createdTime), @@ -27,6 +34,7 @@ interface Calculator { double mul(double number1, double number2); double div(double number1, double number2); bool isEquals(short number1, short number2); + double calculate(OperationType type, double number1, double number2); }; interface TernaryCalculator { diff --git a/examples/calculator.js b/examples/calculator.js index 3c110ee..a0e95ab 100644 --- a/examples/calculator.js +++ b/examples/calculator.js @@ -144,3 +144,24 @@ describe('generate one more bridge classes from one more interfaces', () => { assert.equal(ternary_calculator.add(1, 2, 3), 1 + 2 + 3); }); }); + +describe('enum type test', () => { + it('should be equal with expected value', () => { + assert.equal(calculator.calculate('add', 1, 2), 3); + assert.equal(calculator.calculate('sub', 2, 1), 1); + assert.equal(calculator.calculate('mul', 2, 1), 2); + assert.equal(calculator.calculate('div', 4, 1), 4); + }); + + it('should be throw error when invalid argument passed.', () => { + assert.throws(() => { + calculator.calculate('add', 1, 1, 1); + }, RangeError); + assert.throws(() => { + calculator.calculate(1, 1, 1); + }, TypeError); + assert.throws(() => { + calculator.calculate('not_match_value', 1, 1); + }, TypeError); + }); +}); diff --git a/generator/parser/idl_definition.ts b/generator/parser/idl_definition.ts index 87ba8b9..fd77eff 100644 --- a/generator/parser/idl_definition.ts +++ b/generator/parser/idl_definition.ts @@ -32,4 +32,8 @@ export default abstract class IDLDefinition { public isIDLInterface(): boolean { return this.raw_idl_definition_info['type'] == 'interface'; } + + public isIDLEnum(): boolean { + return this.raw_idl_definition_info['type'] == 'enum'; + } } diff --git a/generator/parser/idl_definition_factory.ts b/generator/parser/idl_definition_factory.ts index ba862fb..48bdf07 100644 --- a/generator/parser/idl_definition_factory.ts +++ b/generator/parser/idl_definition_factory.ts @@ -15,12 +15,15 @@ */ import IDLDefinition from './idl_definition'; +import IDLEnum from './idl_enum'; import IDLInterface from './idl_interface'; export default class IDLDefinitionFactory { static create(raw_idl_definition_info: {}): IDLDefinition { if (this.isIDLInterface(raw_idl_definition_info)) { return new IDLInterface(raw_idl_definition_info); + } else if (this.isIDLEnum(raw_idl_definition_info)) { + return new IDLEnum(raw_idl_definition_info); } return null; @@ -29,4 +32,7 @@ export default class IDLDefinitionFactory { private static isIDLInterface(raw_idl_definition_info: {}): boolean { return raw_idl_definition_info['type'] == 'interface'; } + private static isIDLEnum(raw_idl_definition_info: {}): boolean { + return raw_idl_definition_info['type'] == 'enum'; + } } diff --git a/generator/parser/idl_enum.ts b/generator/parser/idl_enum.ts new file mode 100644 index 0000000..1131cee --- /dev/null +++ b/generator/parser/idl_enum.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2017 The Bacardi Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import IDLDefinition from './idl_definition'; + +export default class IDLEnum extends IDLDefinition { + values: string[]; + + constructor(raw_idl_enum_info: {}) { + super(raw_idl_enum_info['name'], raw_idl_enum_info); + + this.values = []; + raw_idl_enum_info['values'].forEach(raw_value_info => { + this.values.push(raw_value_info); + }); + } + + render(): void { + // TODO(zino): We should implement this function. + } +} diff --git a/template/interface_cpp.njk b/template/interface_cpp.njk index 5cbdba6..33caa82 100644 --- a/template/interface_cpp.njk +++ b/template/interface_cpp.njk @@ -73,6 +73,9 @@ Napi::Value {{name}}Bridge::{{member.name | camelcase}}(const Napi::CallbackInfo {% for argument in member.arguments %} auto {{argument.name}} = NativeTypeTraits::NativeValue(info.Env(), info[{{loop.index - 1}}]); + if (info.Env().IsExceptionPending()) { + return Napi::Value(); + } {% endfor %} {% if member.type != "void" %}