Skip to content

Commit

Permalink
Implement to call function which take dictionaries type as parameter (#…
Browse files Browse the repository at this point in the history
…185)

This patch is first step to implement dictionaries feature.
it is possible only to call function which take dictionaries type 
as parameter in this patch. so we should implement below things
to enhance dictionaries feature.
 - convert native object from javascript type and pass as parameter
 - should implement function which return dictionaries type

ISSUE=#169
  • Loading branch information
hwanseung authored and romandev committed Nov 29, 2017
1 parent 9c747a9 commit 578ba56
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 1 deletion.
23 changes: 23 additions & 0 deletions generator/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import * as nunjucks from 'nunjucks';
import * as path from 'path';

import * as file from './base/file';
import DictionaryTypes from './parser/dictionary_types';
import EnumTypes from './parser/enum_types';
import IDLDefinition from './parser/idl_definition';
import IDLDictionary from './parser/idl_dictionary';
import IDLEnum from './parser/idl_enum';
import IDLInterface from './parser/idl_interface';
import Parser from './parser/parser';
Expand Down Expand Up @@ -76,6 +78,7 @@ async function generateInterface(
// TODO(hwansueng): This function should be improved.
async function postProcessing(definitions: IDLDefinition[]) {
let enum_types: EnumTypes = new EnumTypes(definitions);
let dict_types: DictionaryTypes = new DictionaryTypes(definitions);

for (const definition of definitions) {
if (definition.isIDLInterface()) {
Expand All @@ -84,13 +87,32 @@ async function postProcessing(definitions: IDLDefinition[]) {
if (member.arguments != null) {
for (let args of member.arguments) {
args.enum = enum_types.isEnumType(args.type);
args.dictionary = dict_types.isDictionaryType(args.type);
}
}
}
}
}
}

async function generateDictionaryType(
env: nunjucks.Environment, output_path: string,
definitions: IDLDefinition[]) {
const [dictionary_tmpl] = await Promise.all(
[file.read(path.resolve(TEMPLATE_DIR, 'dictionary_types.njk'))]);

definitions.forEach(async (definition) => {
if (definition.isIDLDictionary()) {
const dictionary_file_path = path.resolve(
output_path,
definition.idl_dir_name + '/' +
changeCase.snakeCase(definition.name) + '.h');
await file.write(
dictionary_file_path, env.renderString(dictionary_tmpl, definition));
}
});
}

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 @@ -107,6 +129,7 @@ async function main([root_dir, out_dir, ...idl_files]) {

let definitions: IDLDefinition[] =
await Parser.parse(await reader.readAll(relative_idl_files));
await generateDictionaryType(env, out_dir, definitions);
await postProcessing(definitions);
await generateInterface(env, out_dir, definitions);
await generateBacardi(env, out_dir, definitions);
Expand Down
40 changes: 40 additions & 0 deletions generator/parser/dictionary_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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 IDLDictionary from './idl_dictionary';

export default class DictionaryTypes {
readonly dictionaries: IDLDictionary[];

constructor(definitions: IDLDefinition[]) {
this.dictionaries = [];
definitions.forEach((definition) => {
if (definition.isIDLDictionary()) {
this.dictionaries.push(definition as IDLDictionary);
}
});
}

public isDictionaryType(source: string): IDLDictionary {
for (const item of this.dictionaries) {
if (item.name == source) {
return item;
}
}
return null;
}
}
4 changes: 4 additions & 0 deletions generator/parser/idl_definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ export default abstract class IDLDefinition {
public isIDLEnum(): boolean {
return this.raw_idl_definition_info['type'] == 'enum';
}

public isIDLDictionary(): boolean {
return this.raw_idl_definition_info['type'] == 'dictionary';
}
}
6 changes: 6 additions & 0 deletions generator/parser/idl_definition_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import IDLDefinition from './idl_definition';
import IDLDictionary from './idl_dictionary';
import IDLEnum from './idl_enum';
import IDLInterface from './idl_interface';

Expand All @@ -24,6 +25,8 @@ export default class IDLDefinitionFactory {
return new IDLInterface(raw_idl_definition_info);
} else if (this.isIDLEnum(raw_idl_definition_info)) {
return new IDLEnum(raw_idl_definition_info);
} else if (this.isIDLDictionary(raw_idl_definition_info)) {
return new IDLDictionary(raw_idl_definition_info);
}

return null;
Expand All @@ -35,4 +38,7 @@ export default class IDLDefinitionFactory {
private static isIDLEnum(raw_idl_definition_info: {}): boolean {
return raw_idl_definition_info['type'] == 'enum';
}
private static isIDLDictionary(raw_idl_definition_info: {}): boolean {
return raw_idl_definition_info['type'] == 'dictionary';
}
}
46 changes: 46 additions & 0 deletions generator/parser/idl_dictionary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* 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 IDLIdentifier from './idl_identifier';

class DictionaryMember implements IDLIdentifier {
readonly type: string;
readonly name: string;

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

export default class IDLDictionary extends IDLDefinition {
readonly members: DictionaryMember[];

constructor(raw_idl_dic_info: {}) {
super(raw_idl_dic_info['name'], raw_idl_dic_info);

this.members = [];

raw_idl_dic_info['members'].forEach(raw_member_info => {
this.members.push(new DictionaryMember(raw_member_info));
});
}

render(): void {
// TODO(zino): We should implement this function.
}
}
3 changes: 3 additions & 0 deletions generator/parser/idl_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

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

Expand All @@ -24,11 +25,13 @@ class Argument implements IDLIdentifier {
readonly type: string;
readonly name: string;
enum?: IDLEnum;
dictionary?: IDLDictionary;

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

Expand Down
36 changes: 36 additions & 0 deletions template/dictionary_types.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* 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 GEN_DICTIONARY_{{name | snakecase | upper}}_H_
#define GEN_DICTIONARY_{{name | snakecase | upper}}_H_

class {{name}} {
public:
{% for member in members %}
{{member.type}} {{member.name}}() const {
return {{member.name}}_;
}
void set{{member.name | pascalcase}}({{member.type}} {{member.name}}) {
{{member.name}}_ = {{member.name}};
}
{% endfor %}
private:
{% for member in members %}
{{member.type}} {{member.name}}_;
{% endfor %}
};

#endif // GEN_DICTIONARY_{{name | snakecase | upper}}_H_
3 changes: 3 additions & 0 deletions template/interface_cpp.njk
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ if (!EnumValidator::isValildEnum({{argument.name}}, enum_value_set)) {
.ThrowAsJavaScriptException();
return{% if not is_constructor %} Napi::Value(){% endif %};
}
{% elif argument.dictionary %}
{{argument.type | pascalcase}} {{argument.name}};
// FIXME(hwanseung): Convert to native dictionary object from javascript object.
{% else %}
auto {{argument.name}} = NativeTypeTraits<IDL{{argument.type | pascalcase-}}
>::NativeValue(info.Env(), info[{{loop.index0}}]);
Expand Down
Empty file.
30 changes: 30 additions & 0 deletions test/interface_dictionary.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 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 * as bindings from 'bindings';

const bacardi = bindings('bacardi.node');

test(
'Test call function which take dictionaries type as parameter',
async () => {
let test_interface = new bacardi.TestInterface();

var testDict = {a: 10};
test_interface.voidMethodTestDictionaryArg(testDict);
expect(bacardi.TestInterface.getLastCallInfo())
.toBe('VoidMethodTestDictionaryArg()');
});
4 changes: 4 additions & 0 deletions test/test_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,7 @@ double TestInterface::GetStaticDoubleNumber() {
void TestInterface::SetStaticDoubleNumber(double number) {
TestInterface::static_double_number_ = number;
}

void TestInterface::VoidMethodTestDictionaryArg(TestDict testDict) {
last_call_info_ = "VoidMethodTestDictionaryArg()";
}
5 changes: 5 additions & 0 deletions test/test_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <string>

#include "test/test_dict.h"

class TestInterface {
public:
TestInterface();
Expand Down Expand Up @@ -58,6 +60,9 @@ class TestInterface {
static double GetStaticDoubleNumber();
static void SetStaticDoubleNumber(double number);

// Dictionary
void VoidMethodTestDictionaryArg(TestDict testDict);

private:
// FIXME(zino): Currently, we should set this variable in each methods. It's
// not elegance way. We should find a way to get function name and signature
Expand Down
9 changes: 8 additions & 1 deletion test/test_interface.idl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface TestInterface {
double doubleMethod(double number);
string stringMethod(string string);

// enum
// Enum
void voidMethodTestEnumArg(TestEnum enumValue);
TestEnum enumReturnMethod(long index);

Expand All @@ -51,10 +51,17 @@ interface TestInterface {
static attribute double staticDoubleNumber;
void readonlyAssignTest(double number);
static double StaticTest(double number);

// Dictionary
void voidMethodTestDictionaryArg(TestDict dicValue);
};

enum TestEnum {
"value1",
"value2",
"value3"
};

dictionary TestDict {
double a;
};

0 comments on commit 578ba56

Please sign in to comment.