111 lines
2.3 KiB
TypeScript
111 lines
2.3 KiB
TypeScript
|
|
import { createAst, DirectiveRule, DirectiveValue, FunctionRule, ImportRule, LinkRule, NamespaceRule, VariableRule } from './createAst'
|
||
|
|
import path from 'path';
|
||
|
|
import debug from 'debug';
|
||
|
|
import { createRequire } from 'module';
|
||
|
|
import { pathToFileURL } from 'url';
|
||
|
|
const log = debug('vogue:module');
|
||
|
|
|
||
|
|
type Link = {
|
||
|
|
name: string,
|
||
|
|
array: boolean,
|
||
|
|
required: boolean
|
||
|
|
}
|
||
|
|
|
||
|
|
export default class Module {
|
||
|
|
links: Link[] = [];
|
||
|
|
globals = [];
|
||
|
|
functions: {
|
||
|
|
[name: string]: {
|
||
|
|
code: string,
|
||
|
|
parameters: string[]
|
||
|
|
}
|
||
|
|
} = {};
|
||
|
|
identifiers = {};
|
||
|
|
name = {
|
||
|
|
space: '',
|
||
|
|
last: '',
|
||
|
|
full: ''
|
||
|
|
};
|
||
|
|
imports = {};
|
||
|
|
variables = {
|
||
|
|
cold: [],
|
||
|
|
warm: []
|
||
|
|
};
|
||
|
|
directives: {
|
||
|
|
[key: string]: DirectiveValue
|
||
|
|
} = {
|
||
|
|
'singleton': false,
|
||
|
|
'keepalive': false,
|
||
|
|
'static': ''
|
||
|
|
};
|
||
|
|
rootDir: string = '';
|
||
|
|
|
||
|
|
|
||
|
|
async directive({directive, value}: DirectiveRule) {
|
||
|
|
this.directives[directive] = value;
|
||
|
|
}
|
||
|
|
|
||
|
|
async link({required, array, name}: LinkRule) {
|
||
|
|
this.links.push({
|
||
|
|
name,
|
||
|
|
required,
|
||
|
|
array
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async namespace({namespace}: NamespaceRule) {
|
||
|
|
this.name.space = namespace;
|
||
|
|
this.name.full = this.name.space + '.' + this.name.last;
|
||
|
|
}
|
||
|
|
|
||
|
|
async function({name, block, parameters}: FunctionRule) {
|
||
|
|
this.functions[name] = {
|
||
|
|
code: block,
|
||
|
|
parameters
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
async import({importName, name}: ImportRule) {
|
||
|
|
const nodePath = path.resolve(this.rootDir, 'node_module');
|
||
|
|
log('#'.repeat(80));
|
||
|
|
log(nodePath);
|
||
|
|
const __require__ = createRequire(nodePath);
|
||
|
|
const imported = __require__(importName);
|
||
|
|
if('default' in imported) this.imports[name] = imported.default;
|
||
|
|
else this.imports[name] = imported;
|
||
|
|
}
|
||
|
|
|
||
|
|
async variable({persist, name}: VariableRule) {
|
||
|
|
this.variables[persist ? 'cold' : 'warm'].push(name);
|
||
|
|
}
|
||
|
|
|
||
|
|
static async create(location: string, rootDir: string) {
|
||
|
|
const module = new Module();
|
||
|
|
const ast = createAst(location);
|
||
|
|
const name = path.parse(location).name;
|
||
|
|
|
||
|
|
module.name.last = name;
|
||
|
|
module.name.full = name;
|
||
|
|
module.rootDir = rootDir;
|
||
|
|
|
||
|
|
for (const item of ast) {
|
||
|
|
if ('name' in item) {
|
||
|
|
if(item.name in module.identifiers)
|
||
|
|
throw new Error('Identifier ' + item.name + ' already declared!');
|
||
|
|
else module.identifiers[item.name] = item.type;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(item.type in module) {
|
||
|
|
await module[item.type](item);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
log('='.repeat(80));
|
||
|
|
log(location);
|
||
|
|
log(module);
|
||
|
|
|
||
|
|
return module;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|