Skip to content

Commit

Permalink
feat: split v8 and quickjs templates.
Browse files Browse the repository at this point in the history
  • Loading branch information
david committed Dec 6, 2024
1 parent aa957cc commit 251cdf6
Show file tree
Hide file tree
Showing 53 changed files with 1,456 additions and 99 deletions.
27 changes: 16 additions & 11 deletions bridge/scripts/code_generator/bin/code_generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const { JSONBlob } = require('../dist/json/JSONBlob');
const { JSONTemplate } = require('../dist/json/JSONTemplate');
const { analyzer, buildClassRelationship } = require('../dist/idl/analyzer');
const { generatorSource } = require('../dist/idl/generator')
const { generateUnionTypes, generateUnionTypeFileName } = require('../dist/idl/generateUnionTypes')
const { generateUnionTypes, generateUnionTypeFileName } = require('../dist/idl/generator')
const { generateJSONTemplate } = require('../dist/json/generator');
const { generateNamesInstaller } = require("../dist/json/generator");
const { generatePluginAPI } = require("../dist/idl/pluginAPIGenerator/cppGen");
Expand All @@ -21,12 +21,13 @@ const { ClassObject } = require('../dist/idl/declaration');
program
.version(packageJSON.version)
.description('WebF code generator.')
.requiredOption('-p, --platform <platform>', 'the target JS engine platform', 'quickjs')
.requiredOption('-s, --source <path>', 'source directory.')
.requiredOption('-d, --dist <path>', 'destionation directory.')

program.parse(process.argv);

let {source, dist} = program.opts();
let {source, dist, platform} = program.opts();

if (!path.isAbsolute(source)) {
source = path.join(process.cwd(), source);
Expand All @@ -46,27 +47,31 @@ function wirteFileIfChanged(filePath, content) {
fs.writeFileSync(filePath, content, 'utf-8');
}

function generatePlatformPrefix() {
return platform === 'quickjs' ? 'qjs' : 'v8';
}

function genCodeFromTypeDefine() {
// Generate code from type defines.
let typeFiles = glob.sync("**/*.d.ts", {
cwd: source,
});

let blobs = typeFiles.map(file => {
let filename = 'qjs_' + file.split('/').slice(-1)[0].replace('.d.ts', '');
let filename = generatePlatformPrefix() + '_' + file.split('/').slice(-1)[0].replace('.d.ts', '');
let implement = file.replace(path.join(__dirname, '../../')).replace('.d.ts', '');
return new IDLBlob(path.join(source, file), dist, filename, implement);
});

ClassObject.globalClassMap = Object.create(null);

// Analyze all files first.
for (let i = 0; i < blobs.length; i ++) {
for (let i = 0; i < blobs.length; i++) {
let b = blobs[i];
analyzer(b, definedPropertyCollector, unionTypeCollector);
}

for (let i = 0; i < blobs.length; i ++) {
for (let i = 0; i < blobs.length; i++) {
let b = blobs[i];
let result = generatorSource(b);

Expand All @@ -87,9 +92,9 @@ function genCodeFromTypeDefine() {
return -(n.value - p.value);
})
});
for(let i = 0; i < unionTypes.length; i ++) {
let result = generateUnionTypes(unionTypes[i]);
let filename = generateUnionTypeFileName(unionTypes[i]);
for (let i = 0; i < unionTypes.length; i++) {
let result = generateUnionTypes(platform, unionTypes[i]);
let filename = generateUnionTypeFileName(platform, unionTypes[i]);
wirteFileIfChanged(path.join(dist, filename) + '.h', result.header);
wirteFileIfChanged(path.join(dist, filename) + '.cc', result.source);
}
Expand All @@ -101,7 +106,7 @@ function genCodeFromJSONData() {
cwd: source
});
let templateFiles = glob.sync('**/*.tpl', {
cwd: path.join(__dirname, '../templates/json_templates')
cwd: path.join(__dirname, '../templates/json_templates/', platform)
});

let blobs = jsonFiles.map(file => {
Expand All @@ -111,10 +116,10 @@ function genCodeFromJSONData() {

let templates = templateFiles.map(template => {
let filename = template.split(path.sep).slice(-1)[0].replace('.tpl', '');
return new JSONTemplate(path.join(path.join(__dirname, '../templates/json_templates'), template), filename);
return new JSONTemplate(path.join(path.join(__dirname, '../templates/json_templates/', platform), template), filename);
});

for (let i = 0; i < blobs.length; i ++) {
for (let i = 0; i < blobs.length; i++) {
let blob = blobs[i];
blob.json.metadata.templates.forEach((targetTemplate) => {
if (targetTemplate.template === 'make_names') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ClassObject, ClassObjectKind, FunctionObject} from "./declaration";
import {ClassObject, ClassObjectKind, FunctionObject} from "../../declaration";
import _ from "lodash";
import {IDLBlob} from "./IDLBlob";
import {getClassName} from "./utils";
import {IDLBlob} from "../../IDLBlob";
import {getClassName} from "../../utils";
import fs from 'fs';
import path from 'path';
import {
Expand All @@ -11,14 +11,7 @@ import {
isPointerType,
isTypeHaveNull
} from "./generateSource";
import {GenerateOptions} from "./generator";
import {ParameterType} from "./analyzer";
import {
generateUnionConstructor,
generateUnionContentType, generateUnionMemberName, generateUnionMemberType, generateUnionPropertyHeaders,
generateUnionTypeClassName,
generateUnionTypeFileName
} from "./generateUnionTypes";
import {GenerateOptions, readTemplate} from "../../generator";

export enum TemplateKind {
globalFunction,
Expand All @@ -41,12 +34,8 @@ export function getTemplateKind(object: ClassObject | FunctionObject | null): Te
return TemplateKind.null;
}

function readTemplate(name: string) {
return fs.readFileSync(path.join(__dirname, '../../templates/idl_templates/' + name + '.h.tpl'), {encoding: 'utf-8'});
}

export function generateCppHeader(blob: IDLBlob, options: GenerateOptions) {
const baseTemplate = fs.readFileSync(path.join(__dirname, '../../templates/idl_templates/base.h.tpl'), {encoding: 'utf-8'});
export function generateQuickJSCppHeader(blob: IDLBlob, options: GenerateOptions) {
const baseTemplate = fs.readFileSync(path.join(__dirname, '../../../../templates/idl_templates/quickjs/base.h.tpl'), {encoding: 'utf-8'});
let headerOptions = {
interface: false,
dictionary: false,
Expand All @@ -61,7 +50,7 @@ export function generateCppHeader(blob: IDLBlob, options: GenerateOptions) {
if (!headerOptions.interface) {
object = (object as ClassObject);
headerOptions.interface = true;
return _.template(readTemplate('interface'))({
return _.template(readTemplate('quickjs', 'interface'))({
className: getClassName(blob),
parentClassName: object.parent,
blob: blob,
Expand All @@ -76,7 +65,7 @@ export function generateCppHeader(blob: IDLBlob, options: GenerateOptions) {
if (!headerOptions.dictionary) {
headerOptions.dictionary = true;
let props = (object as ClassObject).props;
return _.template(readTemplate('dictionary'))({
return _.template(readTemplate('quickjs', 'dictionary'))({
className: getClassName(blob),
blob: blob,
object: object,
Expand All @@ -89,7 +78,7 @@ export function generateCppHeader(blob: IDLBlob, options: GenerateOptions) {
case TemplateKind.globalFunction: {
if (!headerOptions.global_function) {
headerOptions.global_function = true;
return _.template(readTemplate('global_function'))({
return _.template(readTemplate('quickjs', 'global_function'))({
className: getClassName(blob),
blob: blob
});
Expand All @@ -105,23 +94,4 @@ export function generateCppHeader(blob: IDLBlob, options: GenerateOptions) {
}).split('\n').filter(str => {
return str.trim().length > 0;
}).join('\n');
}

export function generateUnionTypeHeader(unionType: ParameterType): string {
return _.template(readTemplate('union'))({
unionType,
generateUnionTypeClassName,
generateUnionTypeFileName,
generateUnionContentType,
generateUnionConstructor,
generateUnionPropertyHeaders,
generateCoreTypeValue,
generateUnionMemberType,
generateUnionMemberName,
isTypeHaveNull,
isPointerType,
getPointerType,
}).split('\n').filter(str => {
return str.trim().length > 0;
}).join('\n');
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {IDLBlob} from "./IDLBlob";
import {IDLBlob} from "../../IDLBlob";
import {
ClassObject,
FunctionArguments,
Expand All @@ -7,21 +7,20 @@ import {
FunctionObject,
ParameterMode,
PropsDeclaration,
} from "./declaration";
import {addIndent, getClassName, getWrapperTypeInfoNameOfClassName} from "./utils";
import {ParameterType} from "./analyzer";
} from "../../declaration";
import {addIndent, getClassName, getWrapperTypeInfoNameOfClassName} from "../../utils";
import {ParameterType} from "../../analyzer";
import _ from 'lodash';
import fs from 'fs';
import path from 'path';
import {getTemplateKind, TemplateKind} from "./generateHeader";
import {GenerateOptions} from "./generator";
import {GenerateOptions, generateUnionTypeFileName} from "../../generator";
import {
generateTypeRawChecker,
generateUnionConstructorImpl,
generateUnionMemberName,
generateUnionTypeClassName,
generateUnionTypeClear,
generateUnionTypeFileName,
generateUnionTypeSetter,
getUnionTypeName
} from "./generateUnionTypes";
Expand Down Expand Up @@ -557,11 +556,11 @@ ${addIndent(callBody, 4)}
}

function readTemplate(name: string) {
return fs.readFileSync(path.join(__dirname, '../../templates/idl_templates/' + name + '.cc.tpl'), {encoding: 'utf-8'});
return fs.readFileSync(path.join(__dirname, '../../../../templates/idl_templates/quickjs/' + name + '.cc.tpl'), {encoding: 'utf-8'});
}

export function generateCppSource(blob: IDLBlob, options: GenerateOptions) {
const baseTemplate = fs.readFileSync(path.join(__dirname, '../../templates/idl_templates/base.cc.tpl'), {encoding: 'utf-8'});
export function generateQuickJSCppSource(blob: IDLBlob, options: GenerateOptions) {
const baseTemplate = fs.readFileSync(path.join(__dirname, '../../../../templates/idl_templates/quickjs/base.cc.tpl'), {encoding: 'utf-8'});
const className = getClassName(blob)

const contents = blob.objects.map(object => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {ParameterType} from "./analyzer";
import {FunctionArgumentType} from "./declaration";
import {ParameterType} from "../../analyzer";
import {FunctionArgumentType} from "../../declaration";
import _ from "lodash";
import {generateUnionTypeHeader} from "./generateHeader";
import {
generateCoreTypeValue,
generateUnionTypeSource, isDictionary,
Expand All @@ -10,22 +9,6 @@ import {
trimNullTypeFromType
} from "./generateSource";

export function generateUnionTypeFileName(unionType: ParameterType[]) {
let filename = 'qjs_union';
for (let i = 0; i < unionType.length; i++) {
let v = unionType[i].value;
if (isTypeHaveNull(unionType[i])) continue;
if (typeof v == 'number') {
filename += '_' + FunctionArgumentType[v];
} else if (unionType[i].isArray && typeof v == 'object' && !Array.isArray(v)) {
filename += '_' + 'sequence' + FunctionArgumentType[v.value as number];
} else if (typeof v == 'string') {
filename += _.snakeCase(v);
}
}
return filename;
}

export function generateUnionTypeClassName(unionTypes: ParameterType[]) {
let className = 'QJSUnion';
for (let i = 0; i < unionTypes.length; i++) {
Expand All @@ -35,15 +18,6 @@ export function generateUnionTypeClassName(unionTypes: ParameterType[]) {
return className;
}

export function generateUnionTypes(unionType: ParameterType) {
let header = generateUnionTypeHeader(unionType);
let source = generateUnionTypeSource(unionType);
return {
header,
source
}
}

export function getUnionTypeName(unionType: ParameterType) {
let v = unionType.value;
if (typeof v == 'number') {
Expand Down
2 changes: 1 addition & 1 deletion bridge/scripts/code_generator/src/idl/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
ParameterMode,
PropsDeclaration,
} from './declaration';
import {isUnionType} from "./generateSource";
import {isUnionType} from "./IDLAPIGenerator/quickjs/generateSource";

interface DefinedPropertyCollector {
properties: Set<string>;
Expand Down
71 changes: 67 additions & 4 deletions bridge/scripts/code_generator/src/idl/generator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import {IDLBlob} from './IDLBlob';
import {generateCppHeader} from "./generateHeader";
import {generateCppSource} from "./generateSource";
import {generateQuickJSCppHeader} from "./IDLAPIGenerator/quickjs/generateHeader";
import {
generateCoreTypeValue,
generateQuickJSCppSource,
generateUnionTypeSource, getPointerType, isPointerType,
isTypeHaveNull
} from "./IDLAPIGenerator/quickjs/generateSource";
import {ParameterType} from "./analyzer";
import {FunctionArgumentType} from "./declaration";
import _ from "lodash";
import {
generateUnionConstructor,
generateUnionContentType, generateUnionMemberName, generateUnionMemberType, generateUnionPropertyHeaders,
generateUnionTypeClassName
} from "./IDLAPIGenerator/quickjs/generateUnionTypes";
import fs from "fs";
import path from "path";

export function generateSupportedOptions(): GenerateOptions {
let globalFunctionInstallList: string[] = [];
Expand Down Expand Up @@ -35,10 +50,58 @@ export type GenerateOptions = {
export function generatorSource(blob: IDLBlob) {
let options = generateSupportedOptions();

let source = generateCppSource(blob, options);
let header = generateCppHeader(blob, options);
let source = generateQuickJSCppSource(blob, options);
let header = generateQuickJSCppHeader(blob, options);
return {
header,
source
};
}

export function readTemplate(platform: string, name: string) {
return fs.readFileSync(path.join(__dirname, `../../templates/idl_templates/${platform}/` + name + '.h.tpl'), {encoding: 'utf-8'});
}

export function generateUnionTypeHeader(platform: string, unionType: ParameterType): string {
return _.template(readTemplate(platform, 'union'))({
unionType,
generateUnionTypeClassName,
generateUnionTypeFileName,
generateUnionContentType,
generateUnionConstructor,
generateUnionPropertyHeaders,
generateCoreTypeValue,
generateUnionMemberType,
generateUnionMemberName,
isTypeHaveNull,
isPointerType,
getPointerType,
}).split('\n').filter(str => {
return str.trim().length > 0;
}).join('\n');
}

export function generateUnionTypes(platform: string, unionType: ParameterType) {
let header = generateUnionTypeHeader(platform, unionType);
let source = generateUnionTypeSource(unionType);
return {
header,
source
}
}

export function generateUnionTypeFileName(platform: string, unionType: ParameterType[]) {
let filename = `${platform == 'quickjs' ? 'qjs' : 'v8'}_union`;
for (let i = 0; i < unionType.length; i++) {
let v = unionType[i].value;
if (isTypeHaveNull(unionType[i])) continue;
if (typeof v == 'number') {
filename += '_' + FunctionArgumentType[v];
} else if (unionType[i].isArray && typeof v == 'object' && !Array.isArray(v)) {
filename += '_' + 'sequence' + FunctionArgumentType[v.value as number];
} else if (typeof v == 'string') {
filename += _.snakeCase(v);
}
}
return filename;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import fs from 'fs';
import path from 'path';
import {IDLBlob} from '../IDLBlob';
import {getTemplateKind, TemplateKind} from '../generateHeader';
import {getTemplateKind, TemplateKind} from '../IDLAPIGenerator/quickjs/generateHeader';
import _ from 'lodash';
import {ClassObject, FunctionArguments, FunctionArgumentType} from '../declaration';
import {GenerateOptions, generateSupportedOptions} from '../generator';
import {ParameterType} from '../analyzer';
import {getPointerType, isPointerType} from '../generateSource';
import {getPointerType, isPointerType} from '../IDLAPIGenerator/quickjs/generateSource';

function readHeaderTemplate(name: string) {
return fs.readFileSync(path.join(__dirname, '../../../templates/idl_templates/plugin_api_templates/' + name + '.h.tpl'), {encoding: 'utf-8'});
Expand Down
Loading

0 comments on commit 251cdf6

Please sign in to comment.