Skip to content

Commit

Permalink
Check enum values before pass to native side. (lunchclass#145)
Browse files Browse the repository at this point in the history
Check enum values before pass to native side.

ISSUE=lunchclass#80
  • Loading branch information
hwanseung authored and Yeonwoo Jo committed Nov 15, 2017
1 parent aa97ece commit 57c0001
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 80 deletions.
1 change: 1 addition & 0 deletions core/core.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
{
'variables': {
'core_cpp_files': [
'enum_validator.h'
'idl_base.h',
'idl_types.h',
'js_type_traits.h',
Expand Down
34 changes: 34 additions & 0 deletions core/enum_validator.h
Original file line number Diff line number Diff line change
@@ -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.
*/

#ifndef CORE_ENUM_VALIDATOR_H_
#define CORE_ENUM_VALIDATOR_H_

#include <set>
#include <string>

class EnumValidator {
public:
static bool isValildEnum(const std::string value,
const std::set<std::string> enum_values) {
if (enum_values.count(value) > 0) {
return true;
}
return false;
}
};

#endif // CORE_ENUM_VALIDATOR_H_
3 changes: 0 additions & 3 deletions core/idl_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,5 @@ struct IDLLongLong final : public IDLBaseHelper<int64_t> {};
struct IDLLong final : public IDLBaseHelper<int32_t> {};
struct IDLShort final : public IDLBaseHelper<int16_t> {};
struct IDLString final : public IDLBaseHelper<std::string> {};
// FIXME(Hwansung): should be generated automatically in another file.
struct IDLOperationType final : public IDLBaseHelper<std::string> {};
struct IDLTestEnum final : public IDLBaseHelper<std::string> {};

#endif // CORE_IDL_TYPES_H_
77 changes: 0 additions & 77 deletions core/native_type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,81 +160,4 @@ struct NativeTypeTraits<IDLString> : public NativeTypeTraitsBase<IDLString> {
}
};

// FIXME(Hwansung): should be generated automatically in another file.
template <>
struct NativeTypeTraits<IDLOperationType>
: public NativeTypeTraitsBase<IDLOperationType> {
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;
}
};

template <>
struct NativeTypeTraits<IDLTestEnum>
: public NativeTypeTraitsBase<IDLTestEnum> {
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("value1") == 0 || value.compare("value2") == 0 ||
value.compare("value3") == 0) {
return true;
}
return false;
}
};

#endif // CORE_NATIVE_TYPE_TRAITS_H_
22 changes: 22 additions & 0 deletions generator/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import * as reader from './reader/simple_reader';

import snakeCase = require('snake-case');

import EnumTypes from './parser/enum_types';
import IDLDefinition from './parser/idl_definition';
import IDLEnum from './parser/idl_enum';
import IDLInterface from './parser/idl_interface';
import Parser from './parser/parser';

const TEMPLATE_DIR = path.resolve(__dirname, '../../../template');
Expand Down Expand Up @@ -72,6 +75,24 @@ async function generateInterface(
});
}

// TODO(hwansueng): This function should be improved.
async function postProcessing(definitions: IDLDefinition[]) {
let enum_types: EnumTypes = new EnumTypes(definitions);

for (const definition of definitions) {
if (definition.isIDLInterface()) {
const idl_interface: IDLInterface = definition as IDLInterface;
for (const member of idl_interface.members) {
if (member.arguments != null) {
for (let args of member.arguments) {
args.enum = enum_types.isEnumType(args.type);
}
}
}
}
}
}

async function main([root_dir, out_dir, ...idl_files]) {
// We expect that current working directory will be $BACARDI_PATH. But it
// might not be in Windows platform. So, we should resolve the path here.
Expand All @@ -94,6 +115,7 @@ async function main([root_dir, out_dir, ...idl_files]) {

let definitions: IDLDefinition[] =
await Parser.parse(await reader.readAll(relative_idl_files));
await postProcessing(definitions);
await generateInterface(env, out_dir, definitions);
await generateBacardi(env, out_dir, definitions);

Expand Down
41 changes: 41 additions & 0 deletions generator/parser/enum_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* 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';
import IDLEnum from './idl_enum';


export default class EnumTypes {
enums: IDLEnum[];

constructor(definitions: IDLDefinition[]) {
this.enums = [];
definitions.forEach((definition) => {
if (definition.isIDLEnum()) {
this.enums.push(definition as IDLEnum);
}
});
}

public isEnumType(source: string): IDLEnum {
for (const item of this.enums) {
if (item.name == source) {
return item;
}
}
return null;
}
}
3 changes: 3 additions & 0 deletions generator/parser/idl_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@
*/

import IDLDefinition from './idl_definition';
import IDLEnum from './idl_enum';
import IDLIdentifier from './idl_identifier';

// FIXME(zino): We should consider attribute and operation concept.

class Argument implements IDLIdentifier {
readonly type: string;
readonly name: string;
enum?: IDLEnum;

constructor(raw_argument_info: {}) {
this.type = raw_argument_info['idlType']['idlType'];
this.name = raw_argument_info['name'];
this.enum = null;
}
}

Expand Down
16 changes: 16 additions & 0 deletions template/interface_cpp.njk
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "core/js_type_traits.h"
#include "core/native_type_traits.h"
#include "core/enum_validator.h"

void {{name}}Bridge::Init(Napi::Env env, Napi::Object exports) {
Napi::Function js_constructor =
Expand Down Expand Up @@ -106,11 +107,26 @@ Napi::Value {{name}}Bridge::{{member.name | camelcase}}(const Napi::CallbackInfo
}

{% for argument in member.arguments %}
{% if argument.enum %}
const std::set<std::string> enum_value_set = {
{% for value in argument.enum.values %}
"{{value}}",
{% endfor %}
};
auto {{argument.name}} = NativeTypeTraits<IDLString
>::NativeValue(info.Env(), info[{{loop.index0}}]);
if (!EnumValidator::isValildEnum({{argument.name}}, enum_value_set)) {
Napi::TypeError::New(info.Env(), "it not matched with values of enum in idl.")
.ThrowAsJavaScriptException();
return Napi::Value();
}
{% else %}
auto {{argument.name}} = NativeTypeTraits<IDL{{argument.type | camelcase-}}
>::NativeValue(info.Env(), info[{{loop.index0}}]);
if (info.Env().IsExceptionPending()) {
return Napi::Value();
}
{% endif %}
{% endfor %}

{% if member.type != "void" %}
Expand Down

0 comments on commit 57c0001

Please sign in to comment.