mirror of
https://github.com/marko-js/marko.git
synced 2026-02-01 16:07:13 +00:00
parent
a8746841cc
commit
769078b26e
@ -1,114 +0,0 @@
|
||||
import * as babelTypes from "@babel/types";
|
||||
import { NodePath, Scope } from "@babel/traverse";
|
||||
import builder from "@babel/types/lib/builders/builder";
|
||||
import defineType from "@babel/types/lib/definitions/utils";
|
||||
import * as generatedValidators from "@babel/types/lib/validators/generated";
|
||||
import * as referencedValidators from "@babel/types/lib/validators/isReferenced";
|
||||
import types from "./types";
|
||||
|
||||
const {
|
||||
TYPES,
|
||||
VISITOR_KEYS,
|
||||
FLIPPED_ALIAS_KEYS,
|
||||
DEPRECATED_KEYS,
|
||||
is
|
||||
} = babelTypes;
|
||||
|
||||
const aliases = {};
|
||||
export const MARKO_TYPES = Object.keys(types);
|
||||
MARKO_TYPES.forEach(typeName => {
|
||||
const type = types[typeName];
|
||||
for (const alias of type.aliases) {
|
||||
aliases[alias] = aliases[alias] || [];
|
||||
aliases[alias].push(typeName);
|
||||
}
|
||||
defineType(typeName, type);
|
||||
});
|
||||
const ALIAS_TYPES = Object.keys(aliases);
|
||||
|
||||
// Update TYPES
|
||||
for (const type of [
|
||||
...Object.keys(VISITOR_KEYS),
|
||||
...Object.keys(FLIPPED_ALIAS_KEYS),
|
||||
...Object.keys(DEPRECATED_KEYS)
|
||||
]) {
|
||||
if (!TYPES.includes(type)) TYPES.push(type);
|
||||
}
|
||||
|
||||
// add marko validators & builders to `@babel/types` and `@babel/traverse`
|
||||
MARKO_TYPES.forEach(typeName => {
|
||||
const lowerName = typeName[0].toLowerCase() + typeName.slice(1);
|
||||
const checkKey = `is${typeName}`;
|
||||
const assertKey = `assert${typeName}`;
|
||||
const checkFn = (babelTypes[checkKey] = (node, opts) =>
|
||||
is(typeName, node, opts));
|
||||
const assertFn = (babelTypes[assertKey] = (node, opts) =>
|
||||
assert(typeName, node, opts));
|
||||
NodePath.prototype[checkKey] = function(opts) {
|
||||
return checkFn(this.node, opts);
|
||||
};
|
||||
NodePath.prototype[assertKey] = function(opts) {
|
||||
assertFn(this.node, opts);
|
||||
};
|
||||
// Add builder.
|
||||
babelTypes[typeName] = babelTypes[lowerName] = (...args) =>
|
||||
builder(typeName, ...args);
|
||||
});
|
||||
|
||||
ALIAS_TYPES.forEach(aliasName => {
|
||||
const checkKey = `is${aliasName}`;
|
||||
const originalCheck = generatedValidators[checkKey];
|
||||
generatedValidators[checkKey] = (node, opts) => {
|
||||
return is(aliasName, node, opts) || originalCheck(node, opts);
|
||||
};
|
||||
const originalProtoCheck = NodePath.prototype[checkKey];
|
||||
NodePath.prototype[checkKey] = function(opts) {
|
||||
return (
|
||||
is(aliasName, this.node, opts) ||
|
||||
originalProtoCheck.call(this, this.node, opts)
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const originalIsReferenced = referencedValidators.default;
|
||||
referencedValidators.default = (node, parent, grandparent) => {
|
||||
if (
|
||||
parent.type === "MarkoTag" &&
|
||||
parent.params &&
|
||||
parent.params.includes(node)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return originalIsReferenced(node, parent, grandparent);
|
||||
};
|
||||
|
||||
const originalCrawl = Scope.prototype.crawl;
|
||||
Scope.prototype.crawl = function() {
|
||||
const path = this.path;
|
||||
|
||||
originalCrawl.apply(this, arguments);
|
||||
|
||||
if (path.isMarkoTagBody()) {
|
||||
const params = path.parentPath.get("params");
|
||||
|
||||
if (params.length) {
|
||||
for (const param of params) {
|
||||
this.registerBinding("param", param);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function assert(typeName, node, opts) {
|
||||
if (!is(typeName, node, opts)) {
|
||||
throw new Error(
|
||||
`Expected type "${typeName}" with option ${JSON.stringify(
|
||||
opts
|
||||
)}, but instead got "${node.type}".`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// export babel stuff
|
||||
Object.assign(exports, babelTypes);
|
||||
export * from "@babel/types";
|
||||
@ -1,4 +1,6 @@
|
||||
import * as t from "../definitions";
|
||||
import "../types/patch";
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import SELF_CLOSING from "self-closing-tags";
|
||||
import Printer from "@babel/generator/lib/printer";
|
||||
|
||||
@ -1,3 +1,10 @@
|
||||
import "./generators";
|
||||
import * as types from "./definitions";
|
||||
import "./types/patch";
|
||||
import "./generator/patch";
|
||||
import "./traverse/patch";
|
||||
|
||||
import * as types from "@babel/types";
|
||||
import { MARKO_TYPES } from "./types/definitions";
|
||||
|
||||
types.MARKO_TYPES = MARKO_TYPES;
|
||||
|
||||
export { types };
|
||||
|
||||
46
packages/babel-types/src/traverse/patch.js
Normal file
46
packages/babel-types/src/traverse/patch.js
Normal file
@ -0,0 +1,46 @@
|
||||
import "../types/patch";
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import { NodePath, Scope } from "@babel/traverse";
|
||||
import { MARKO_TYPES, MARKO_ALIAS_TYPES } from "../types/definitions";
|
||||
|
||||
MARKO_TYPES.forEach(typeName => {
|
||||
const checkKey = `is${typeName}`;
|
||||
const assertKey = `assert${typeName}`;
|
||||
const checkFn = t[checkKey];
|
||||
const assertFn = t[assertKey];
|
||||
NodePath.prototype[checkKey] = function(opts) {
|
||||
return checkFn(this.node, opts);
|
||||
};
|
||||
NodePath.prototype[assertKey] = function(opts) {
|
||||
assertFn(this.node, opts);
|
||||
};
|
||||
});
|
||||
|
||||
MARKO_ALIAS_TYPES.forEach(aliasName => {
|
||||
const checkKey = `is${aliasName}`;
|
||||
const originalProtoCheck = NodePath.prototype[checkKey];
|
||||
NodePath.prototype[checkKey] = function(opts) {
|
||||
return (
|
||||
t.is(aliasName, this.node, opts) ||
|
||||
originalProtoCheck.call(this, this.node, opts)
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const originalCrawl = Scope.prototype.crawl;
|
||||
Scope.prototype.crawl = function() {
|
||||
const path = this.path;
|
||||
|
||||
originalCrawl.apply(this, arguments);
|
||||
|
||||
if (path.isMarkoTagBody()) {
|
||||
const params = path.parentPath.get("params");
|
||||
|
||||
if (params.length) {
|
||||
for (const param of params) {
|
||||
this.registerBinding("param", param);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -13,7 +13,7 @@ const valueFieldCommon = {
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
const MarkoDefinitions = {
|
||||
MarkoDocumentType: {
|
||||
aliases: ["Marko", "Statement"],
|
||||
builder: ["value"],
|
||||
@ -204,3 +204,11 @@ export default {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default MarkoDefinitions;
|
||||
export const MARKO_TYPES = Object.keys(MarkoDefinitions);
|
||||
export const MARKO_ALIAS_TYPES = Array.from(
|
||||
new Set(
|
||||
MARKO_TYPES.reduce((all, t) => all.concat(MarkoDefinitions[t].aliases), [])
|
||||
)
|
||||
);
|
||||
65
packages/babel-types/src/types/patch.js
Normal file
65
packages/babel-types/src/types/patch.js
Normal file
@ -0,0 +1,65 @@
|
||||
import * as babelTypes from "@babel/types";
|
||||
import builder from "@babel/types/lib/builders/builder";
|
||||
import defineType from "@babel/types/lib/definitions/utils";
|
||||
import * as generatedValidators from "@babel/types/lib/validators/generated";
|
||||
import * as referencedValidators from "@babel/types/lib/validators/isReferenced";
|
||||
import definitions, { MARKO_TYPES, MARKO_ALIAS_TYPES } from "./definitions";
|
||||
|
||||
const {
|
||||
TYPES,
|
||||
VISITOR_KEYS,
|
||||
FLIPPED_ALIAS_KEYS,
|
||||
DEPRECATED_KEYS,
|
||||
is
|
||||
} = babelTypes;
|
||||
|
||||
MARKO_TYPES.forEach(typeName => {
|
||||
defineType(typeName, definitions[typeName]);
|
||||
});
|
||||
|
||||
for (const type of [
|
||||
...Object.keys(VISITOR_KEYS),
|
||||
...Object.keys(FLIPPED_ALIAS_KEYS),
|
||||
...Object.keys(DEPRECATED_KEYS)
|
||||
]) {
|
||||
if (!TYPES.includes(type)) TYPES.push(type);
|
||||
}
|
||||
|
||||
MARKO_TYPES.forEach(typeName => {
|
||||
const lowerName = typeName[0].toLowerCase() + typeName.slice(1);
|
||||
const checkKey = `is${typeName}`;
|
||||
const assertKey = `assert${typeName}`;
|
||||
babelTypes[checkKey] = (node, opts) => is(typeName, node, opts);
|
||||
babelTypes[assertKey] = (node, opts) => assert(typeName, node, opts);
|
||||
babelTypes[typeName] = babelTypes[lowerName] = (...args) =>
|
||||
builder(typeName, ...args);
|
||||
});
|
||||
|
||||
MARKO_ALIAS_TYPES.forEach(aliasName => {
|
||||
const checkKey = `is${aliasName}`;
|
||||
const originalCheck = generatedValidators[checkKey];
|
||||
generatedValidators[checkKey] = (node, opts) =>
|
||||
is(aliasName, node, opts) || originalCheck(node, opts);
|
||||
});
|
||||
|
||||
const originalIsReferenced = referencedValidators.default;
|
||||
referencedValidators.default = (node, parent, grandparent) => {
|
||||
if (
|
||||
parent.type === "MarkoTag" &&
|
||||
parent.params &&
|
||||
parent.params.includes(node)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return originalIsReferenced(node, parent, grandparent);
|
||||
};
|
||||
|
||||
function assert(typeName, node, opts) {
|
||||
if (!is(typeName, node, opts)) {
|
||||
throw new Error(
|
||||
`Expected type "${typeName}" with option ${JSON.stringify(
|
||||
opts
|
||||
)}, but instead got "${node.type}".`
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user