diff --git a/src/java/io/Writer.ts b/src/java/io/Writer.ts index 273dbb2..9d49bc8 100644 --- a/src/java/io/Writer.ts +++ b/src/java/io/Writer.ts @@ -131,16 +131,6 @@ export abstract class Writer extends JavaObject implements Closeable, Flushable, throw new IllegalArgumentException(new JavaString("Invalid number of arguments")); } } - - if (args.length === 1) { - this.write(args[0] as Uint16Array); - } else if (args.length === 3) { - const [c, offset, length] = args as [Uint16Array, int, int]; - this.write(c, offset, length); - } else { - const [c, offset, length] = args as [JavaString, int, int]; - this.write(c.toString(), offset, length); - } } /** Closes the stream, flushing it first. */ diff --git a/src/java/lang/Object.ts b/src/java/lang/Object.ts index 14c8890..f51b188 100644 --- a/src/java/lang/Object.ts +++ b/src/java/lang/Object.ts @@ -23,6 +23,25 @@ export class JavaObject implements IReflection { public constructor() { this.#id = JavaObject.#nextId++; + + if (!("#fqn" in this.constructor)) { + // Find the path to the class file. + const error = new Error(); + if (error.stack) { + const lines = error.stack?.split("\n"); + const candidates = lines.filter((line) => { return line.includes("at new"); }); + if (candidates.length > 0) { + const match = candidates[candidates.length - 1].match(/jree\/src((\/\w+)+)\.ts/); + if (match) { + const subPath = match[1].substring(1); // Remove leading slash. + const fqn = subPath.split("/").join("."); + + // @ts-expect-error + this.constructor["#fqn"] = fqn; + } + } + } + } } public static get class(): Class { diff --git a/src/java/lang/Throwable.ts b/src/java/lang/Throwable.ts index f048d7f..feacab6 100644 --- a/src/java/lang/Throwable.ts +++ b/src/java/lang/Throwable.ts @@ -3,23 +3,29 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +/* eslint-disable max-classes-per-file */ + import { JavaObject } from "./Object.js"; import { StackTraceElement } from "./StackTraceElement.js"; // import { System } from "./System"; creates a circular dependency + import type { JavaString } from "./String.js"; import type { PrintWriter } from "../io/PrintWriter.js"; import type { PrintStream } from "../io/PrintStream.js"; +class JavaObjectWithStack extends JavaObject { + protected stack?: string; +} + /** * The Throwable class is the superclass of all errors and exceptions in the Java language. * Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or * can be thrown by the Java throw statement. * Similarly, only this class or one of its subclasses can be the argument type in a catch clause. */ -export class Throwable extends JavaObject { - #stack?: string; +export class Throwable extends JavaObjectWithStack { #message: string | null = null; #cause: Throwable | null = null; @@ -136,7 +142,7 @@ export class Throwable extends JavaObject { */ public addSuppressed(exception: Throwable): void { if (this === exception) { - // Dynamically import the exception class to avoid a circular dependenc.jsy. + // Dynamically import the exception class to avoid a circular dependency. void import("./IllegalArgumentException.js").then((module) => { throw new module.IllegalArgumentException(); }); @@ -164,8 +170,8 @@ export class Throwable extends JavaObject { * @returns this Throwable object. */ public fillInStackTrace(): Throwable { - if (this.#stack) { - const lines = this.#stack.split("\n").slice(1); + if (this.stack) { + const lines = this.stack.split("\n").slice(1); this.#elements = lines.map((line) => { return new StackTraceElement(line); @@ -250,13 +256,13 @@ export class Throwable extends JavaObject { if (!s) { console.error(headLine.valueOf()); - console.error(this.#stack); + console.error(this.stack); return; } s.println(headLine); - s.println(`${this.#stack}`); + s.println(`${this.stack}`); } /** @@ -288,7 +294,7 @@ export class Throwable extends JavaObject { public override toString(): string { const message = this.getLocalizedMessage(); if (!message) { - return `${this.#stack}`; + return `${this.stack}`; } return `${this.constructor.name}: ${message}`;