/*
* Copyright 2025 the original author or authors.
*
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://docs.moderne.io/licensing/moderne-source-available-license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Cursor, SourceFile, Tree} from "./tree";
import {TreeVisitor} from "./visitor";
import {PrintOutputCapture, TreePrinters} from "./print";
import {RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "./rpc";
import {updateIfChanged} from "./util";
export const ParseErrorKind = "org.openrewrite.tree.ParseError";
export interface ParseError extends SourceFile {
readonly kind: typeof ParseErrorKind;
readonly text: string;
readonly erroneous?: SourceFile;
}
export function isParseError(tree: any): tree is ParseError {
return tree["kind"] === ParseErrorKind;
}
export class ParseErrorVisitor
extends TreeVisitor {
async isAcceptable(sourceFile: SourceFile, p: P): Promise {
return isParseError(sourceFile);
}
protected async accept(t: Tree, p: P): Promise {
if (t.kind === ParseErrorKind) {
return this.visitParseError(t as ParseError, p);
}
throw new Error("Unexpected tree kind: " + t.kind);
}
protected async visitParseError(e: ParseError, p: P): Promise {
return this.produceTree(e, p);
}
}
TreePrinters.register(ParseErrorKind, () => new class extends ParseErrorVisitor {
protected async visitParseError(e: ParseError, p: PrintOutputCapture): Promise {
for (let marker of e.markers.markers) {
p.append(p.markerPrinter.beforePrefix(marker, new Cursor(marker, this.cursor), it => it))
}
await this.visitMarkers(e.markers, p);
for (let marker of e.markers.markers) {
p.append(p.markerPrinter.beforeSyntax(marker, new Cursor(marker, this.cursor), it => it))
}
p.append(e.text);
for (let marker of e.markers.markers) {
p.append(p.markerPrinter.afterSyntax(marker, new Cursor(marker, this.cursor), it => it))
}
return e;
}
})
RpcCodecs.registerCodec(ParseErrorKind, {
async rpcReceive(before: ParseError, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
markers: await q.receive(before.markers),
sourcePath: await q.receive(before.sourcePath),
charsetName: await q.receive(before.charsetName),
charsetBomMarked: await q.receive(before.charsetBomMarked),
checksum: await q.receive(before.checksum),
fileAttributes: await q.receive(before.fileAttributes),
text: await q.receive(before.text),
});
},
async rpcSend(after: ParseError, q: RpcSendQueue): Promise {
await q.getAndSend(after, p => p.id);
await q.getAndSend(after, p => p.markers);
await q.getAndSend(after, p => p.sourcePath);
await q.getAndSend(after, p => p.charsetName);
await q.getAndSend(after, p => p.charsetBomMarked);
await q.getAndSend(after, p => p.checksum);
await q.getAndSend(after, p => p.fileAttributes);
await q.getAndSend(after, p => p.text);
}
});