js-compiler: Add Context#addNodesRangeDiagnostic
MODIFY
packages/@romejs/js-compiler/lib/Context.ts
packages/@romejs/js-compiler/lib/Context.ts
*/
import {AnyNode, Program, ConstSourceType} from '@romejs/js-ast';
-import {SourceLocation} from '@romejs/parser-core';
+import {
+ SourceLocation,
+ extractSourceLocationRangeFromNodes,
+} from '@romejs/parser-core';
import {
PathOptions,
TransformExitResult,
@@ -154,4 +157,14 @@ export default class Context {
diag,
);
}
+
+ addNodesRangeDiagnostic(
+ nodes: Array<{loc?: SourceLocation}>,
+ diag: ContextPartialDiagnostic,
+ ) {
+ return this.addLocDiagnostic(
+ extractSourceLocationRangeFromNodes(nodes),
+ diag,
+ );
+ }
}

MODIFY
packages/@romejs/parser-core/index.ts
packages/@romejs/parser-core/index.ts
@@ -608,3 +608,49 @@ export function createParser<T, Args extends Array<unknown>>(
return new klass(...args);
};
}
+
+// Utility methods for dealing with nodes
+export function extractSourceLocationRangeFromNodes(
+ nodes: Array<{loc?: SourceLocation}>,
+): undefined | SourceLocation {
+ if (nodes.length === 0) {
+ return undefined;
+ }
+
+ let filename: undefined | string = undefined;
+ let start: undefined | Position = undefined;
+ let end: undefined | Position = undefined;
+
+ for (const node of nodes) {
+ const {loc} = node;
+ if (loc === undefined) {
+ continue;
+ }
+
+ if (start === undefined || loc.start.index < start.index) {
+ start = loc.start;
+ }
+
+ if (end === undefined || loc.end.index > end.index) {
+ end = loc.end;
+ }
+
+ if (filename === undefined) {
+ filename = loc.filename;
+ } else if (filename !== loc.filename) {
+ throw new Error(
+ `Mixed filenames in node, expected ${filename} but got ${loc.filename}`,
+ );
+ }
+ }
+
+ if (start === undefined || end === undefined) {
+ return undefined;
+ }
+
+ return {
+ filename,
+ start,
+ end,
+ };
+}

js-compiler: Add Context#addNodesRangeDiagnostic