This repository has been archived on 2023-11-14. You can view files and clone it, but cannot push or open issues/pull-requests.
vogue/src/Module.ts

130 lines
2.8 KiB
TypeScript
Raw Normal View History

2021-05-20 20:34:50 -04:00
import {
createAst,
DirectiveRule,
FunctionRule,
ImportRule,
LinkRule,
NamespaceRule,
Rule,
VariableRule
} from './createAst.js'
import path from 'path';
import debug from 'debug';
2021-05-16 20:41:45 -04:00
import { createRequire } from 'module';
import { pathToFileURL } from 'url';
const log = debug('vogue:module');
2021-05-02 17:42:04 -04:00
2021-05-20 20:34:50 -04:00
export type Link = {
2021-05-20 00:19:25 -04:00
name: string,
array: boolean,
required: boolean
}
2021-05-02 17:42:04 -04:00
export default class Module {
2021-05-20 00:19:25 -04:00
links: Link[] = [];
2021-05-02 17:42:04 -04:00
globals = [];
2021-05-20 00:19:25 -04:00
functions: {
[name: string]: {
code: string,
2021-05-20 20:34:50 -04:00
async: boolean,
2021-05-20 00:19:25 -04:00
parameters: string[]
}
} = {};
2021-05-20 20:34:50 -04:00
identifiers: {
[name: string]: Rule["type"]
} = {};
2021-05-02 17:42:04 -04:00
name = {
space: '',
last: '',
full: ''
2021-05-06 23:05:36 -04:00
};
2021-05-20 20:34:50 -04:00
imports: {
[key: string]: any
} = {};
variables: any = {
cold: [],
warm: []
2021-05-20 00:19:25 -04:00
};
2021-05-20 20:34:50 -04:00
// directives
'singleton': boolean = false;
'keepalive': boolean = false;
'static': string = '';
// other stuff
2021-05-20 00:19:25 -04:00
rootDir: string = '';
2021-05-20 20:34:50 -04:00
async directive({ directive, value }: DirectiveRule): Promise<void> {
if (typeof this[directive] === 'boolean')
(this[directive] as boolean) = value as boolean;
else if (typeof this[directive] === 'string')
(this[directive] as string) = value as string;
// = value as string;
}
2021-05-20 20:34:50 -04:00
async link({ required, array, name }: LinkRule): Promise<void> {
2021-05-20 00:19:25 -04:00
this.links.push({
name,
required,
array
});
}
2021-05-20 20:34:50 -04:00
async namespace({ namespace }: NamespaceRule): Promise<void> {
this.name.space = namespace;
this.name.full = this.name.space + '.' + this.name.last;
}
2021-05-20 20:34:50 -04:00
async function({ name, block, parameters, async }: FunctionRule): Promise<void> {
this.functions[name] = {
code: block,
2021-05-20 20:34:50 -04:00
parameters,
async
};
}
2021-05-20 20:34:50 -04:00
async import({ importName, name }: ImportRule): Promise<void> {
2021-05-16 20:41:45 -04:00
const nodePath = path.resolve(this.rootDir, 'node_module');
log('#'.repeat(80));
log(nodePath);
const __require__ = createRequire(nodePath);
const imported = __require__(importName);
2021-05-20 20:34:50 -04:00
if ('default' in imported) this.imports[name] = imported.default;
else this.imports[name] = imported;
}
2021-05-10 23:13:17 -04:00
2021-05-20 20:34:50 -04:00
async variable({ persist, name }: VariableRule): Promise<void> {
this.variables[persist ? 'cold' : 'warm'].push(name);
2021-05-10 23:13:17 -04:00
}
2021-05-20 00:19:25 -04:00
static async create(location: string, rootDir: string) {
2021-05-10 23:13:17 -04:00
const module = new Module();
const ast = createAst(location);
const name = path.parse(location).name;
2021-05-10 23:13:17 -04:00
module.name.last = name;
module.name.full = name;
2021-05-16 20:41:45 -04:00
module.rootDir = rootDir;
2021-05-10 23:13:17 -04:00
for (const item of ast) {
if ('name' in item) {
2021-05-20 20:34:50 -04:00
if (item.name in module.identifiers)
2021-05-10 23:13:17 -04:00
throw new Error('Identifier ' + item.name + ' already declared!');
2021-05-20 20:34:50 -04:00
else {
module.identifiers[item.name] = item.type;
}
}
2021-05-10 23:13:17 -04:00
2021-05-20 20:34:50 -04:00
if (item.type in module) {
const func = module[item.type] as ((arg0: Rule) => Promise<void>)
func.call(module, item);
2021-05-10 23:13:17 -04:00
}
}
log('='.repeat(80));
log(location);
log(module);
return module;
2021-05-10 23:13:17 -04:00
}
}