typedraft
Version:
TypeDraft is a superset of typescript with built-in support for DSL extension and literate programming.
91 lines (90 loc) • 3.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const export_class_1 = require("./export-class");
const method_1 = require("./method");
const local_context_1 = require("./local-context");
const utility_1 = require("../common/utility");
const traverse_1 = require("@babel/traverse");
const inline_context_1 = require("./inline-context");
const draft_dsl_match_1 = require("draft-dsl-match");
class ModuleCode {
constructor(code) {
this.m_File = utility_1.ToFile(code);
}
ToDraft() {
this.m_File = utility_1.ToFile(utility_1.ToString(this.m_File));
let draft = [];
this.Traverse({
Program(path) {
this._module.m_Path = path;
},
ExpressionStatement(path) {
const expression = path.get("expression");
if (expression.isStringLiteral()) {
const literal = expression.node.value.trim();
if (literal.startsWith("use") && path.parentPath.isBlockStatement()) {
draft.unshift(new inline_context_1.InlineContext(path.parentPath));
}
}
}
}, {
_module: this
});
this.m_Path.get("body").forEach(path => {
if (path.isEmptyStatement()) {
path.remove();
return;
}
const to_add = draft_dsl_match_1.MatchDSL(path).when(() => {
return IsExportClassCode(path);
}, (path) => new export_class_1.ExportClassCode(path)).when(() => {
return IsMethodCode(path);
}, (path) => new method_1.MethodCode(path)).when(() => {
return IsLocalContext(path);
}, (path) => new local_context_1.LocalContext(path.scope.parent.getBinding(path.node.id.name))).with(draft_dsl_match_1.__, () => {
return null;
}).run();
if (to_add) {
draft.push(to_add);
}
});
return draft;
}
Traverse(visitor, state = null) {
this.m_File = utility_1.ToFile(utility_1.ToString(this.m_File));
traverse_1.default(this.m_File, visitor, null, state);
}
}
exports.ModuleCode = ModuleCode;
function IsExportClassCode(path) {
return path.isExportNamedDeclaration() && path.get("declaration").isClassDeclaration();
}
exports.IsExportClassCode = IsExportClassCode;
function IsMethodCode(path) {
if (!path.isExpressionStatement()) {
return false;
}
const expression = path.get("expression");
if (!expression.isBinaryExpression()) {
return false;
}
const left = expression.get("left");
const right = expression.get("right");
return left.isJSXElement() && right.isFunctionExpression();
}
exports.IsMethodCode = IsMethodCode;
function IsLocalContext(path) {
if (!path.isFunctionDeclaration()) {
return false;
}
const [directive] = path.node.body.directives;
const is_local_context = path.scope.parent.getBinding(path.node.id.name).referencePaths.some(path => {
var _a, _b, _c, _d, _e;
const used_as_jsx = (_b = (_a = path.parentPath) === null || _a === void 0 ? void 0 : _a.parentPath) === null || _b === void 0 ? void 0 : _b.isJSXElement();
const used_as_statement = (_e = (_d = (_c = path.parentPath) === null || _c === void 0 ? void 0 : _c.parentPath) === null || _d === void 0 ? void 0 : _d.parentPath) === null || _e === void 0 ? void 0 : _e.isExpressionStatement();
const has_context = Boolean(directive);
return used_as_jsx && (has_context || used_as_statement);
});
return is_local_context;
}
exports.IsLocalContext = IsLocalContext;