add interpreter directive formatter and update parser
MODIFY
packages/@romejs/js-formatter/builders/core/InterpreterDirective.ts
packages/@romejs/js-formatter/builders/core/InterpreterDirective.ts
* LICENSE file in the root directory of this source tree.
*/
-import {Token} from "../../tokens";
+import {Token, concat, hardline} from "../../tokens";
+import { Builder } from "@romejs/js-formatter";
+import { InterpreterDirective } from "@romejs/js-ast";
-export default function InterpreterDirective(): Token {
- throw new Error("unimplemented");
+export default function InterpreterDirective(
+ builder: Builder,
+ node: InterpreterDirective
+): Token {
+ return concat([`#!${node.value}`, hardline, hardline]);
}

MODIFY
packages/@romejs/js-formatter/builders/core/Program.ts
packages/@romejs/js-formatter/builders/core/Program.ts
@@ -18,6 +18,10 @@ export default function Program(builder: Builder, node: Program): Token {
tokens.push(hardline);
}
+ if (node.interpreter) {
+ tokens.push(builder.tokenize(node.interpreter, node));
+ }
+
tokens.push(
builder.tokenizeInnerComments(node, false),
builder.tokenizeStatementList(node.body, node),

MODIFY
packages/@romejs/js-parser/parser/statement.ts
packages/@romejs/js-parser/parser/statement.ts
@@ -62,7 +62,7 @@ import {
WithStatement,
} from "@romejs/js-ast";
import * as charCodes from "@romejs/string-charcodes";
-import {nextToken, setStrict, skipLineComment} from "../tokenizer/index";
+import {nextToken, setStrict, skipLineComment, parseInterpreterDirective} from "../tokenizer/index";
import {
ParseExportResult,
ParseImportResult,
@@ -136,18 +136,12 @@ export function parsePossibleInterpreterDirective(
parser.match(tt.hash) &&
parser.input[ob1Get0(parser.state.endPos.index)] === "!"
) {
- // Parse as a regular comment, we should abstract this logic
- // TODO this gets pushed to all the comments which is bad
- const comment = skipLineComment(parser, 2);
+ const directive = parseInterpreterDirective(parser, 1);
// Advance to next token
parser.next();
- return {
- type: "InterpreterDirective",
- value: comment.value,
- loc: comment.loc,
- };
+ return directive;
} else {
return undefined;
}

MODIFY
packages/@romejs/js-parser/tokenizer/index.ts
packages/@romejs/js-parser/tokenizer/index.ts
* LICENSE file in the root directory of this source tree.
*/
-import {AnyComment, NumericLiteral} from "@romejs/js-ast";
+import {AnyComment, NumericLiteral, InterpreterDirective} from "@romejs/js-ast";
import {Position, SourceLocation} from "@romejs/parser-core";
import {JSParser} from "../parser";
import {xhtmlEntityNameToChar} from "../xhtmlEntities";
@@ -410,6 +410,34 @@ export function skipLineComment(parser: JSParser, startSkip: number): AnyComment
);
}
+export function skipInterpreterDirective(parser: JSParser, startSkip: number): InterpreterDirective {
+ const startIndex = parser.state.index;
+ const startPos = parser.getPositionFromState();
+ parser.state.index = ob1Add(parser.state.index, startSkip);
+ let ch = parser.input.charCodeAt(getIndex(parser));
+ if (parser.state.index < parser.length) {
+ while (
+ ch !== charCodes.lineFeed &&
+ ch !== charCodes.carriageReturn &&
+ ch !== charCodes.lineSeparator &&
+ ch !== charCodes.paragraphSeparator &&
+ bumpIndex(parser) < parser.length
+ ) {
+ ch = parser.input.charCodeAt(getIndex(parser));
+ }
+ }
+ const loc = parser.finishLocAt(startPos, parser.getPositionFromState());
+
+ return {
+ type: 'InterpreterDirective',
+ value: parser.getRawInput(
+ ob1Add(startIndex, startSkip),
+ parser.state.index,
+ ),
+ loc,
+ }
+}
+
// Called at the start of the parse and after every token. Skips
// whitespace and comments, and.
function skipSpace(parser: JSParser): void {

add interpreter directive formatter and update parser