Files
pig-farm-controller-fe/node_modules/acorn-import-phases/src/plugin.cjs
2025-09-19 14:25:20 +08:00

126 lines
3.8 KiB
JavaScript

/**
* @param {{ defer?: boolean, source?: boolean }} options
* @param {typeof import("acorn").Parser} Parser
* @param {typeof import("acorn").tokTypes} acorn
*/
exports.plugin = function acornImportPhase(options, Parser, tt) {
return class extends Parser {
parseImport(node) {
this._phase = null;
const result = super.parseImport(node);
if (this._phase) {
node.phase = this._phase;
}
return result;
}
parseImportSpecifiers() {
let phase =
options.defer !== false && this.isContextual("defer")
? "defer"
: options.source !== false && this.isContextual("source")
? "source"
: null;
if (!phase) return super.parseImportSpecifiers();
const phaseId = this.parseIdent();
if (this.isContextual("from") || this.type === tt.comma) {
const defaultSpecifier = this.startNodeAt(phaseId.start, phaseId.loc && phaseId.loc.start);
defaultSpecifier.local = phaseId;
this.checkLValSimple(phaseId, /* BIND_LEXICAL */ 2);
const nodes = [this.finishNode(defaultSpecifier, "ImportDefaultSpecifier")];
if (this.eat(tt.comma)) {
if (this.type !== tt.star && this.type !== tt.braceL) {
this.unexpected();
}
nodes.push(...super.parseImportSpecifiers());
}
return nodes;
}
this._phase = phase;
if (phase === "defer") {
if (this.type !== tt.star) {
this.raiseRecoverable(
phaseId.start,
"'import defer' can only be used with namespace imports ('import defer * as identifierName from ...')."
);
}
} else if (phase === "source") {
if (this.type !== tt.name) {
this.raiseRecoverable(
phaseId.start,
"'import source' can only be used with direct identifier specifier imports."
);
}
}
const specifiers = super.parseImportSpecifiers();
if (phase === "source" && specifiers.some(s => s.type !== "ImportDefaultSpecifier")) {
this.raiseRecoverable(
phaseId.start,
`'import source' can only be used with direct identifier specifier imports ('import source identifierName from ...').`
);
}
return specifiers;
}
parseExprImport(forNew) {
const node = super.parseExprImport(forNew);
if (node.type === "MetaProperty" && (node.property.name === "defer" || node.property.name === "source")) {
if (this.type === tt.parenL) {
const dynImport = this.parseDynamicImport(this.startNodeAt(node.start, node.loc && node.loc.start));
dynImport.phase = node.property.name;
return dynImport;
} else {
this.raiseRecoverable(
node.start,
`'import.${node.property.name}' can only be used in a dynamic import.`
);
}
}
return node;
}
parseImportMeta(node) {
this.next();
var containsEsc = this.containsEsc;
node.property = this.parseIdent(true);
const { name } = node.property;
if (name !== "meta" && name !== "defer" && name !== "source") {
this.raiseRecoverable(
node.property.start,
"The only valid meta property for import is 'import.meta'"
);
}
if (containsEsc) {
this.raiseRecoverable(
node.start,
`'import.${name}' must not contain escaped characters`
);
}
if (
name === "meta" &&
this.options.sourceType !== "module" &&
!this.options.allowImportExportEverywhere
) {
this.raiseRecoverable(
node.start,
"Cannot use 'import.meta' outside a module"
);
}
return this.finishNode(node, "MetaProperty");
}
};
};