Skip to content

Commit 299cf2f

Browse files
committed
feat: support static string and add generate support.
1 parent 7c77d7a commit 299cf2f

21 files changed

+1019
-83
lines changed

bridge/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ if ($ENV{KRAKEN_JS_ENGINE} MATCHES "quickjs")
283283
core/dom/events/event_target.cc
284284
core/dom/events/event_target_impl.cc
285285
core/dom/events/event_target_impl.h
286+
core/dom/events/error_event.cc
287+
core/dom/events/error_event.h
286288
# core/dom/character_data.cc
287289
# core/dom/character_data.h
288290
# core/dom/comment.cc
@@ -311,6 +313,8 @@ if ($ENV{KRAKEN_JS_ENGINE} MATCHES "quickjs")
311313
out/qjs_event.h
312314
out/qjs_event_target.cc
313315
out/qjs_event_target.h
316+
out/event_type_names.h
317+
out/event_type_names.cc
314318
)
315319

316320
# Quickjs use __builtin_frame_address() to get stack pointer, we should add follow options to get it work with -O2

bridge/scripts/code_generator/bin/code_generator.js

+64-18
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ const packageJSON = require('../package.json');
55
const path = require('path');
66
const glob = require('glob');
77
const fs = require('fs');
8-
const { Blob } = require('../dist/blob');
9-
const { analyzer } = require('../dist/analyzer');
8+
const { IDLBlob } = require('../dist/idl/IDLBlob');
9+
const { JSONBlob } = require('../dist/json/JSONBlob');
10+
const { Template } = require('../dist/json/template');
11+
const { analyzer } = require('../dist/idl/analyzer');
12+
const { generateJSONTemplate } = require('../dist/json/generator');
1013

1114
program
1215
.version(packageJSON.version)
@@ -25,27 +28,70 @@ if (!path.isAbsolute(dist)) {
2528
dist = path.join(process.cwd(), dist);
2629
}
2730

28-
let files = glob.sync("**/*.d.ts", {
29-
cwd: source,
30-
});
31+
function genCodeFromTypeDefine() {
32+
// Generate code from type defines.
33+
let files = glob.sync("**/*.d.ts", {
34+
cwd: source,
35+
});
3136

32-
let blobs = files.map(file => {
33-
let filename = 'qjs_' + file.split('/').slice(-1)[0].replace('.d.ts', '');
34-
let implement = file.replace(path.join(__dirname, '../../')).replace('.d.ts', '');
35-
return new Blob(path.join(source, file), dist, filename, implement);
36-
});
37+
let blobs = files.map(file => {
38+
let filename = 'qjs_' + file.split('/').slice(-1)[0].replace('.d.ts', '');
39+
let implement = file.replace(path.join(__dirname, '../../')).replace('.d.ts', '');
40+
return new IDLBlob(path.join(source, file), dist, filename, implement);
41+
});
3742

38-
for (let i = 0; i < blobs.length; i ++) {
39-
let b = blobs[i];
40-
let result = analyzer(b);
43+
for (let i = 0; i < blobs.length; i ++) {
44+
let b = blobs[i];
45+
let result = analyzer(b);
4146

42-
if (!fs.existsSync(b.dist)) {
43-
fs.mkdirSync(b.dist, {recursive: true});
47+
if (!fs.existsSync(b.dist)) {
48+
fs.mkdirSync(b.dist, {recursive: true});
49+
}
50+
51+
let genFilePath = path.join(b.dist, b.filename);
52+
53+
fs.writeFileSync(genFilePath + '.h', result.header);
54+
fs.writeFileSync(genFilePath + '.cc', result.source);
4455
}
56+
}
57+
58+
// Generate code from json data.
59+
function genCodeFromJSONData() {
60+
let jsonFiles = glob.sync('**/*.json', {
61+
cwd: source
62+
});
63+
let templateFiles = glob.sync('**/*.tpl', {
64+
cwd: path.join(__dirname, '../static')
65+
});
4566

46-
let genFilePath = path.join(b.dist, b.filename);
67+
let blobs = jsonFiles.map(file => {
68+
let filename = file.split('/').slice(-1)[0].replace('.json', '');
69+
return new JSONBlob(path.join(source, file), dist, filename);
70+
});
4771

48-
fs.writeFileSync(genFilePath + '.h', result.header);
49-
fs.writeFileSync(genFilePath + '.cc', result.source);
72+
let templates = templateFiles.map(template => {
73+
let filename = template.split('/').slice(-1)[0].replace('.tpl', '');
74+
return new Template(path.join(path.join(__dirname, '../static'), template), filename);
75+
});
76+
77+
for (let i = 0; i < blobs.length; i ++) {
78+
let blob = blobs[i];
79+
blob.json.metadata.templates.forEach((targetTemplate) => {
80+
let targetTemplateHeaderData = templates.find(t => t.filename === targetTemplate + '.h');
81+
let targetTemplateBodyData = templates.find(t => t.filename === targetTemplate + '.h');
82+
let result = generateJSONTemplate(blobs[i], targetTemplateHeaderData, targetTemplateBodyData);
83+
let dist = blob.dist;
84+
85+
if (targetTemplate === 'qjs_atom') {
86+
dist = path.join(__dirname, '../../../third_party/quickjs')
87+
}
88+
89+
let genFilePath = path.join(dist, blob.filename);
90+
fs.writeFileSync(genFilePath + '.h', result.header);
91+
result.source && fs.writeFileSync(genFilePath + '.cc', result.source);
92+
});
93+
}
5094
}
5195

96+
// genCodeFromTypeDefine();
97+
genCodeFromJSONData();

bridge/scripts/code_generator/src/generator.ts

-12
This file was deleted.

bridge/scripts/code_generator/src/blob.ts renamed to bridge/scripts/code_generator/src/idl/IDLBlob.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import fs from 'fs';
22
import {ClassObject, FunctionObject} from "./declaration";
33

4-
export class Blob {
4+
export class IDLBlob {
55
raw: string;
66
dist: string;
77
source: string;

bridge/scripts/code_generator/src/analyzer.ts renamed to bridge/scripts/code_generator/src/idl/analyzer.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import ts, {HeritageClause, ScriptTarget, VariableStatement} from 'typescript';
2-
import {Blob} from './blob';
2+
import {IDLBlob} from './IDLBlob';
33
import {
44
ClassObject,
55
FunctionArguments,
@@ -10,7 +10,7 @@ import {
1010
} from './declaration';
1111
import {generatorSource} from './generator';
1212

13-
export function analyzer(blob: Blob) {
13+
export function analyzer(blob: IDLBlob) {
1414
let code = blob.raw;
1515
const sourceFile = ts.createSourceFile(blob.source, blob.raw, ScriptTarget.ES2020);
1616
blob.objects = sourceFile.statements.map(statement => walkProgram(statement)).filter(o => {

bridge/scripts/code_generator/src/generate_header.ts renamed to bridge/scripts/code_generator/src/idl/generateHeader.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {ClassObject, FunctionObject, PropsDeclaration} from "./declaration";
22
import {uniqBy, snakeCase} from "lodash";
3-
import {Blob} from "./blob";
3+
import {IDLBlob} from "./IDLBlob";
44
import {addIndent, getClassName} from "./utils";
55

6-
function generateInterfaceAdditionalHeader(blob: Blob, object: any): [string, string, string] {
6+
function generateInterfaceAdditionalHeader(blob: IDLBlob, object: any): [string, string, string] {
77
if (!(object instanceof ClassObject)) {
88
return ['', '', ''];
99
}
@@ -27,7 +27,7 @@ function generateInterfaceAdditionalHeader(blob: Blob, object: any): [string, st
2727
];
2828
}
2929

30-
export function generateCppHeader(blob: Blob) {
30+
export function generateCppHeader(blob: IDLBlob) {
3131
let classObject = blob.objects.find(object => object instanceof ClassObject);
3232
let interfaceDefines = generateInterfaceAdditionalHeader(blob, classObject);
3333
let haveInterfaceBase = !!classObject;

bridge/scripts/code_generator/src/genereate_source.ts renamed to bridge/scripts/code_generator/src/idl/generateSource.ts

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Blob} from "./blob";
1+
import {IDLBlob} from "./IDLBlob";
22
import {
33
ClassObject,
44
FunctionArguments,
@@ -85,7 +85,7 @@ function generateCallMethodName(name: string) {
8585
return name;
8686
}
8787

88-
function generateOptionalInitBody(blob: Blob, declare: FunctionDeclaration, argument: FunctionArguments, argsIndex: number, previousArguments: string[], options: GenFunctionBodyOptions) {
88+
function generateOptionalInitBody(blob: IDLBlob, declare: FunctionDeclaration, argument: FunctionArguments, argsIndex: number, previousArguments: string[], options: GenFunctionBodyOptions) {
8989
let call = '';
9090
let returnValueAssignment = '';
9191
if (declare.returnType[0] != FunctionArgumentType.void) {
@@ -110,7 +110,7 @@ if (argc <= ${argsIndex + 1}) {
110110
}`;
111111
}
112112

113-
function generateFunctionCallBody(blob: Blob, declaration: FunctionDeclaration, options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod: false}) {
113+
function generateFunctionCallBody(blob: IDLBlob, declaration: FunctionDeclaration, options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod: false}) {
114114
let minimalRequiredArgc = 0;
115115
declaration.args.forEach(m => {
116116
if (m.required) minimalRequiredArgc++;
@@ -157,14 +157,14 @@ ${optionalArgumentsInit.join('\n')}
157157
`;
158158
}
159159

160-
function generateGlobalFunctionSource(blob: Blob, object: FunctionObject) {
160+
function generateGlobalFunctionSource(blob: IDLBlob, object: FunctionObject) {
161161
let body = generateFunctionBody(blob, object.declare);
162162
return `static JSValue ${object.declare.name}(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
163163
${body}
164164
}`;
165165
}
166166

167-
function generateReturnValueInit(blob: Blob, type: ParameterType[], options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod: false}) {
167+
function generateReturnValueInit(blob: IDLBlob, type: ParameterType[], options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod: false}) {
168168
if (type[0] == FunctionArgumentType.void) return '';
169169

170170
if (options.isConstructor) {
@@ -180,7 +180,7 @@ function generateReturnValueInit(blob: Blob, type: ParameterType[], options: Gen
180180
return `Converter<${generateTypeConverter(type)}>::ImplType return_value;`;
181181
}
182182

183-
function generateReturnValueResult(blob: Blob, type: ParameterType[], options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod: false}): string {
183+
function generateReturnValueResult(blob: IDLBlob, type: ParameterType[], options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod: false}): string {
184184
if (type[0] == FunctionArgumentType.void) return 'JS_NULL';
185185
if (options.isConstructor) {
186186
return `return_value->ToQuickJS()`;
@@ -199,7 +199,7 @@ function generateReturnValueResult(blob: Blob, type: ParameterType[], options: G
199199

200200
type GenFunctionBodyOptions = {isConstructor?: boolean, isInstanceMethod?: boolean};
201201

202-
function generateFunctionBody(blob: Blob, declare: FunctionDeclaration, options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod : false}) {
202+
function generateFunctionBody(blob: IDLBlob, declare: FunctionDeclaration, options: GenFunctionBodyOptions = {isConstructor: false, isInstanceMethod : false}) {
203203
let paramCheck = generateMethodArgumentsCheck(declare);
204204
let callBody = generateFunctionCallBody(blob, declare, options);
205205
let returnValueInit = generateReturnValueInit(blob, declare.returnType, options);
@@ -222,22 +222,22 @@ ${addIndent(callBody, 4)}
222222
`;
223223
}
224224

225-
function generateClassConstructorCallback(blob: Blob, declare: FunctionDeclaration) {
225+
function generateClassConstructorCallback(blob: IDLBlob, declare: FunctionDeclaration) {
226226
return `JSValue QJS${getClassName(blob)}::ConstructorCallback(JSContext* ctx, JSValue func_obj, JSValue this_val, int argc, JSValue* argv, int flags) {
227227
${generateFunctionBody(blob, declare, {isConstructor: true})}
228228
}
229229
`;
230230
}
231231

232-
function generatePropertyGetterCallback(blob: Blob, prop: PropsDeclaration) {
232+
function generatePropertyGetterCallback(blob: IDLBlob, prop: PropsDeclaration) {
233233
return `static JSValue ${prop.name}AttributeGetCallback(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
234234
auto* ${blob.filename} = toScriptWrappable<${getClassName(blob)}>(this_val);
235235
assert(${blob.filename} != nullptr);
236236
return Converter<${generateTypeConverter(prop.type)}>::ToValue(ctx, ${blob.filename}->${prop.name}());
237237
}`;
238238
}
239239

240-
function generatePropertySetterCallback(blob: Blob, prop: PropsDeclaration) {
240+
function generatePropertySetterCallback(blob: IDLBlob, prop: PropsDeclaration) {
241241
return `static JSValue ${prop.name}AttributeSetCallback(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
242242
auto* ${blob.filename} = toScriptWrappable<${getClassName(blob)}>(this_val);
243243
ExceptionState exception_state;
@@ -249,15 +249,15 @@ function generatePropertySetterCallback(blob: Blob, prop: PropsDeclaration) {
249249
}`;
250250
}
251251

252-
function generateMethodCallback(blob: Blob, methods: FunctionDeclaration[]): string[] {
252+
function generateMethodCallback(blob: IDLBlob, methods: FunctionDeclaration[]): string[] {
253253
return methods.map(method => {
254254
return `static JSValue ${method.name}(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
255255
${ generateFunctionBody(blob, method, {isInstanceMethod: true}) }
256256
}`;
257257
});
258258
}
259259

260-
function generateClassSource(blob: Blob, object: ClassObject) {
260+
function generateClassSource(blob: IDLBlob, object: ClassObject) {
261261
let constructorCallback = '';
262262
if (object.construct) {
263263
constructorCallback = generateClassConstructorCallback(blob, object.construct);
@@ -281,7 +281,7 @@ function generateClassSource(blob: Blob, object: ClassObject) {
281281
].join('\n');
282282
}
283283

284-
function generateInstallGlobalFunctions(blob: Blob, installList: string[]) {
284+
function generateInstallGlobalFunctions(blob: IDLBlob, installList: string[]) {
285285
return `void QJS${getClassName(blob)}::InstallGlobalFunctions(ExecutingContext* context) {
286286
std::initializer_list<MemberInstaller::FunctionConfig> functionConfig {
287287
${installList.join(',\n')}
@@ -291,7 +291,7 @@ function generateInstallGlobalFunctions(blob: Blob, installList: string[]) {
291291
}`;
292292
}
293293

294-
function generateConstructorInstaller(blob: Blob) {
294+
function generateConstructorInstaller(blob: IDLBlob) {
295295
return `void QJS${getClassName(blob)}::InstallConstructor(ExecutingContext* context) {
296296
const WrapperTypeInfo* wrapperTypeInfo = GetWrapperTypeInfo();
297297
JSValue constructor = context->contextData()->constructorForType(wrapperTypeInfo);
@@ -303,7 +303,7 @@ function generateConstructorInstaller(blob: Blob) {
303303
}`;
304304
}
305305

306-
function generatePrototypeMethodsInstaller(blob: Blob, installList: string[]) {
306+
function generatePrototypeMethodsInstaller(blob: IDLBlob, installList: string[]) {
307307
return `void QJS${getClassName(blob)}::InstallPrototypeMethods(ExecutingContext* context) {
308308
const WrapperTypeInfo* wrapperTypeInfo = GetWrapperTypeInfo();
309309
JSValue prototype = context->contextData()->prototypeForType(wrapperTypeInfo);
@@ -317,7 +317,7 @@ function generatePrototypeMethodsInstaller(blob: Blob, installList: string[]) {
317317
`;
318318
}
319319

320-
function generatePrototypePropsInstaller(blob: Blob, installList: string[]) {
320+
function generatePrototypePropsInstaller(blob: IDLBlob, installList: string[]) {
321321
return `void QJS${getClassName(blob)}::InstallPrototypeProperties(ExecutingContext* context) {
322322
const WrapperTypeInfo* wrapperTypeInfo = GetWrapperTypeInfo();
323323
JSValue prototype = context->contextData()->prototypeForType(wrapperTypeInfo);
@@ -331,7 +331,7 @@ function generatePrototypePropsInstaller(blob: Blob, installList: string[]) {
331331
`;
332332
}
333333

334-
export function generateCppSource(blob: Blob) {
334+
export function generateCppSource(blob: IDLBlob) {
335335
let functionInstallList: string[] = [];
336336
let classMethodsInstallList: string[] = [];
337337
let classPropsInstallList: string[] = [];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {IDLBlob} from './IDLBlob';
2+
import {generateCppHeader} from "./generateHeader";
3+
import {generateCppSource} from "./generateSource";
4+
5+
export function generatorSource(blob: IDLBlob) {
6+
let header = generateCppHeader(blob);
7+
let source = generateCppSource(blob);
8+
return {
9+
header,
10+
source
11+
};
12+
}

bridge/scripts/code_generator/src/utils.ts renamed to bridge/scripts/code_generator/src/idl/utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Blob} from './blob';
1+
import {IDLBlob} from './IDLBlob';
22
import {camelCase} from 'lodash';
33

44
export function addIndent(str: String, space: number) {
@@ -12,7 +12,7 @@ export function addIndent(str: String, space: number) {
1212
return lines.join('\n');
1313
}
1414

15-
export function getClassName(blob: Blob) {
15+
export function getClassName(blob: IDLBlob) {
1616
let raw = camelCase(blob.filename[4].toUpperCase() + blob.filename.slice(5));
1717

1818
return `${raw[0].toUpperCase() + raw.slice(1)}`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {ClassObject, FunctionObject} from "../idl/declaration";
2+
import fs from "fs";
3+
4+
export class JSONBlob {
5+
raw: string;
6+
dist: string;
7+
source: string;
8+
filename: string;
9+
json: any;
10+
11+
constructor(source: string, dist: string, filename: string) {
12+
this.source = source;
13+
this.raw = fs.readFileSync(source, {encoding: 'utf-8'});
14+
this.dist = dist;
15+
this.filename = filename;
16+
this.json = JSON.parse(this.raw);
17+
}
18+
}

0 commit comments

Comments
 (0)