source: frontend/node_modules/acorn-import-phases/src/plugin.cjs

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/**
2 * @param {{ defer?: boolean, source?: boolean }} options
3 * @param {typeof import("acorn").Parser} Parser
4 * @param {typeof import("acorn").tokTypes} acorn
5 */
6exports.plugin = function acornImportPhase(options, Parser, tt) {
7 return class extends Parser {
8 parseImport(node) {
9 this._phase = null;
10 const result = super.parseImport(node);
11 if (this._phase) {
12 node.phase = this._phase;
13 }
14 return result;
15 }
16
17 parseImportSpecifiers() {
18 let phase =
19 options.defer !== false && this.isContextual("defer")
20 ? "defer"
21 : options.source !== false && this.isContextual("source")
22 ? "source"
23 : null;
24 if (!phase) return super.parseImportSpecifiers();
25
26 const phaseId = this.parseIdent();
27 if (this.isContextual("from") || this.type === tt.comma) {
28 const defaultSpecifier = this.startNodeAt(phaseId.start, phaseId.loc && phaseId.loc.start);
29 defaultSpecifier.local = phaseId;
30 this.checkLValSimple(phaseId, /* BIND_LEXICAL */ 2);
31
32 const nodes = [this.finishNode(defaultSpecifier, "ImportDefaultSpecifier")];
33 if (this.eat(tt.comma)) {
34 if (this.type !== tt.star && this.type !== tt.braceL) {
35 this.unexpected();
36 }
37 nodes.push(...super.parseImportSpecifiers());
38 }
39 return nodes;
40 }
41
42 this._phase = phase;
43
44 if (phase === "defer") {
45 if (this.type !== tt.star) {
46 this.raiseRecoverable(
47 phaseId.start,
48 "'import defer' can only be used with namespace imports ('import defer * as identifierName from ...')."
49 );
50 }
51 } else if (phase === "source") {
52 if (this.type !== tt.name) {
53 this.raiseRecoverable(
54 phaseId.start,
55 "'import source' can only be used with direct identifier specifier imports."
56 );
57 }
58 }
59
60 const specifiers = super.parseImportSpecifiers();
61
62 if (phase === "source" && specifiers.some(s => s.type !== "ImportDefaultSpecifier")) {
63 this.raiseRecoverable(
64 phaseId.start,
65 `'import source' can only be used with direct identifier specifier imports ('import source identifierName from ...').`
66 );
67 }
68
69 return specifiers;
70 }
71
72 parseExprImport(forNew) {
73 const node = super.parseExprImport(forNew);
74
75 if (node.type === "MetaProperty" && (node.property.name === "defer" || node.property.name === "source")) {
76 if (this.type === tt.parenL) {
77 const dynImport = this.parseDynamicImport(this.startNodeAt(node.start, node.loc && node.loc.start));
78 dynImport.phase = node.property.name;
79 return dynImport;
80 } else {
81 this.raiseRecoverable(
82 node.start,
83 `'import.${node.property.name}' can only be used in a dynamic import.`
84 );
85 }
86 }
87
88 return node;
89 }
90
91 parseImportMeta(node) {
92 this.next();
93
94 var containsEsc = this.containsEsc;
95 node.property = this.parseIdent(true);
96
97 const { name } = node.property;
98
99 if (name !== "meta" && name !== "defer" && name !== "source") {
100 this.raiseRecoverable(
101 node.property.start,
102 "The only valid meta property for import is 'import.meta'"
103 );
104 }
105 if (containsEsc) {
106 this.raiseRecoverable(
107 node.start,
108 `'import.${name}' must not contain escaped characters`
109 );
110 }
111 if (
112 name === "meta" &&
113 this.options.sourceType !== "module" &&
114 !this.options.allowImportExportEverywhere
115 ) {
116 this.raiseRecoverable(
117 node.start,
118 "Cannot use 'import.meta' outside a module"
119 );
120 }
121
122 return this.finishNode(node, "MetaProperty");
123 }
124 };
125};
Note: See TracBrowser for help on using the repository browser.