mirror of
https://github.com/quinton-ashley/java2js
synced 2024-12-29 10:11:54 +01:00
1.0.4
This commit is contained in:
parent
e2ed130148
commit
159919e856
20
ide.js
20
ide.js
@ -1,9 +1,13 @@
|
||||
window.ide = {};
|
||||
ide.log = document.getElementById('javaConsole');
|
||||
ide.file0 = document.getElementById('javaFile');
|
||||
(async () => {
|
||||
window.ide = {};
|
||||
ide.log = document.getElementById('javaConsole');
|
||||
ide.file0 = document.getElementById('javaFile');
|
||||
|
||||
ide.file0.onchange = () => {
|
||||
ide.log.value = '';
|
||||
let file = ide.file0.value;
|
||||
jdk.run(file);
|
||||
};
|
||||
await jdk.init();
|
||||
|
||||
ide.file0.onchange = () => {
|
||||
ide.log.value = '';
|
||||
let file = ide.file0.value;
|
||||
jdk.run(file);
|
||||
};
|
||||
})();
|
||||
|
122
jdk.js
122
jdk.js
@ -45,7 +45,9 @@
|
||||
|
||||
/* JDK implementation in modern JavaScript */
|
||||
class JDK {
|
||||
constructor() {
|
||||
constructor() {}
|
||||
|
||||
async init() {
|
||||
this.java = {};
|
||||
let pkgs = ['com', 'lang', 'org', 'io', 'util'];
|
||||
for (let pkg of pkgs) {
|
||||
@ -76,50 +78,23 @@
|
||||
for (let name of names) {
|
||||
lang.push('java.lang.' + name);
|
||||
}
|
||||
this.import(lang);
|
||||
await this.import(lang);
|
||||
} catch (e) {}
|
||||
|
||||
// stub main for now
|
||||
this.main = () => {};
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
load() {
|
||||
let ready = 0;
|
||||
// load all imported classes
|
||||
for (let className in this.imports) {
|
||||
let imp = this.imports[className];
|
||||
if (imp.classPath) {
|
||||
imp.classPath = className.split('.');
|
||||
}
|
||||
if (imp.ready) {
|
||||
ready++;
|
||||
continue;
|
||||
}
|
||||
if (imp.load) {
|
||||
try {
|
||||
imp.load();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
continue;
|
||||
}
|
||||
imp.load = null;
|
||||
imp.ready = true;
|
||||
ready++;
|
||||
}
|
||||
}
|
||||
// some classes may load slower than others,
|
||||
// wait for them all before launching the Java program
|
||||
if (ready != Object.keys(this.imports).length) {
|
||||
let _this = this;
|
||||
setTimeout(() => {
|
||||
_this.load();
|
||||
}, 100);
|
||||
} else {
|
||||
this.launch();
|
||||
}
|
||||
}
|
||||
// async load() {
|
||||
// // load all imported classes
|
||||
// for (let className in this.imports) {
|
||||
// let imp = this.imports[className];
|
||||
// imp.classPath ??= className.split('.');
|
||||
// await imp.load();
|
||||
// }
|
||||
|
||||
// this.launch();
|
||||
// }
|
||||
|
||||
launch() {
|
||||
// make java.lang classes global
|
||||
@ -144,15 +119,15 @@
|
||||
return _class;
|
||||
}
|
||||
|
||||
import(classNames) {
|
||||
async import(classNames) {
|
||||
if (!classNames) return;
|
||||
if (typeof classNames == 'string') {
|
||||
classNames = [classNames];
|
||||
}
|
||||
|
||||
let ready = 0;
|
||||
|
||||
let classes = [];
|
||||
for (let className of classNames) {
|
||||
log('importing ' + className);
|
||||
let imp = this.imports[className];
|
||||
if (imp) {
|
||||
// class is ready for use
|
||||
@ -170,34 +145,29 @@
|
||||
}
|
||||
src += '.js';
|
||||
|
||||
const getJS = new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
document.body.appendChild(script);
|
||||
script.onload = resolve;
|
||||
script.onerror = reject;
|
||||
script.async = true;
|
||||
script.src = src;
|
||||
});
|
||||
const loadJS = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
document.body.appendChild(script);
|
||||
script.onload = resolve;
|
||||
script.onerror = reject;
|
||||
script.async = true;
|
||||
script.src = src;
|
||||
});
|
||||
};
|
||||
|
||||
getJS.then(() => {});
|
||||
}
|
||||
await loadJS();
|
||||
|
||||
if (ready != classNames.length) {
|
||||
throw 'loading java classes';
|
||||
}
|
||||
await imp.load();
|
||||
|
||||
let classes = [];
|
||||
for (let className of classNames) {
|
||||
let imp = this.imports[className];
|
||||
classes.push(this.getClass(imp.classPath));
|
||||
}
|
||||
if (classNames.length == 1) {
|
||||
classes = classes[0];
|
||||
}
|
||||
|
||||
if (classNames.length == 1) classes = classes[0];
|
||||
return classes;
|
||||
}
|
||||
|
||||
run(file) {
|
||||
async run(file) {
|
||||
let classLine = file.indexOf('public class');
|
||||
let imports = file.slice(0, classLine);
|
||||
imports = imports.match(/(?<=^import )[^;]*/gm) || [];
|
||||
@ -205,17 +175,6 @@
|
||||
let userName = window?.QuintOS?.userName || 'quinton-ashley';
|
||||
let className = file.slice(classLine + 13, file.indexOf(' {', classLine + 13));
|
||||
|
||||
let prefix = `(jdk.imports['com.${userName}.${className}'] = {}).load = () => {\n\n`;
|
||||
|
||||
// handle Java class imports
|
||||
for (let i = 0; i < imports.length; i++) {
|
||||
let imp = imports[i];
|
||||
let impPath = imp.split('.');
|
||||
let impName = impPath[impPath.length - 1];
|
||||
prefix += `let ${impName} = jdk.import('${imp}');\n`;
|
||||
}
|
||||
prefix += '\n';
|
||||
|
||||
// hacky support for Java 15 triple quotes
|
||||
file = file.replaceAll(/"""([^"]*)"""/g, (match, str) => {
|
||||
str = str.replaceAll(/(.*)(\n|$)/g, '"$1\\n"+').slice(0, -1);
|
||||
@ -234,8 +193,6 @@
|
||||
|
||||
// log(file);
|
||||
|
||||
let suffix = `\njdk.main = ${className}.main;\n}`;
|
||||
|
||||
window.file0 = file;
|
||||
|
||||
let trans = java_to_javascript(file);
|
||||
@ -245,14 +202,27 @@
|
||||
trans = trans.replace(/(\([^\)]*\) =>)/gm, 'async $1');
|
||||
trans = trans.replace(/([\w_\$]+\.next(Int|Float|Double|Line|Short|Long)*\(\))/gm, 'await $1');
|
||||
|
||||
let prefix = `((jdk.imports['com.${userName}.${className}'] = {}).load = async () => {\n\n`;
|
||||
|
||||
// handle Java class imports
|
||||
for (let i = 0; i < imports.length; i++) {
|
||||
let imp = imports[i];
|
||||
let impPath = imp.split('.');
|
||||
let impName = impPath[impPath.length - 1];
|
||||
prefix += `let ${impName} = await jdk.import('${imp}');\n`;
|
||||
}
|
||||
prefix += '\n';
|
||||
|
||||
let suffix = `\njdk.main = ${className}.main;\njdk.launch();\n})();`;
|
||||
|
||||
trans = prefix + trans + suffix;
|
||||
|
||||
log(trans);
|
||||
|
||||
try {
|
||||
eval(trans);
|
||||
this.load();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (window?.ide) ide.log.value += e;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.io.File'].load = () => {
|
||||
jdk.imports['java.io.File'].load = async () => {
|
||||
class File {
|
||||
constructor(file) {
|
||||
this.absPath = file;
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.io.InputStream'].load = () => {
|
||||
jdk.imports['java.io.InputStream'].load = async () => {
|
||||
class InputStream {
|
||||
constructor() {
|
||||
this.reset();
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.io.PrintStream'].load = () => {
|
||||
jdk.imports['java.io.PrintStream'].load = async () => {
|
||||
class PrintStream {
|
||||
constructor() {
|
||||
this.log = '';
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Character'].load = () => {
|
||||
jdk.imports['java.lang.Character'].load = async () => {
|
||||
class Character {}
|
||||
Character.isDigit = (c) => {
|
||||
c = c.charCodeAt(0);
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Double'].load = () => {
|
||||
jdk.imports['java.lang.Double'].load = async () => {
|
||||
class Double {
|
||||
constructor() {
|
||||
throw 'new Double() not supported';
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Float'].load = () => {
|
||||
jdk.imports['java.lang.Float'].load = async () => {
|
||||
class Float {}
|
||||
Float.parseFloat = (d) => {
|
||||
return parseFloat(d);
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Integer'].load = () => {
|
||||
jdk.imports['java.lang.Integer'].load = async () => {
|
||||
class Integer {}
|
||||
Integer.parseInt = (d) => {
|
||||
return parseInt(d);
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Long'].load = () => {
|
||||
jdk.imports['java.lang.Long'].load = async () => {
|
||||
class Long {}
|
||||
Long.parseLong = (d) => {
|
||||
return parseInt(d);
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Short'].load = () => {
|
||||
jdk.imports['java.lang.Short'].load = async () => {
|
||||
class Short {}
|
||||
Short.parseShort = (d) => {
|
||||
return parseInt(d);
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.String'].load = () => {};
|
||||
jdk.imports['java.lang.String'].load = async () => {};
|
||||
// String is special, I just extended js String prototype
|
||||
String.prototype.hashCode = () => {
|
||||
let h = this._hashCode;
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.StringBuilder'].load = () => {
|
||||
jdk.imports['java.lang.StringBuilder'].load = async () => {
|
||||
class StringBuilder {
|
||||
constructor() {
|
||||
this._str = '';
|
||||
|
@ -1,7 +1,7 @@
|
||||
jdk.imports['java.lang.System'].load = () => {
|
||||
const Formatter = jdk.import('java.util.Formatter');
|
||||
const InputStream = jdk.import('java.io.InputStream');
|
||||
const PrintStream = jdk.import('java.io.PrintStream');
|
||||
jdk.imports['java.lang.System'].load = async () => {
|
||||
const Formatter = await jdk.import('java.util.Formatter');
|
||||
const InputStream = await jdk.import('java.io.InputStream');
|
||||
const PrintStream = await jdk.import('java.io.PrintStream');
|
||||
|
||||
class System {}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.lang.Thread'].load = () => {
|
||||
jdk.imports['java.lang.Thread'].load = async () => {
|
||||
class Thread {
|
||||
async sleep(millis) {
|
||||
await setTimeout(millis);
|
||||
|
@ -1,5 +1,5 @@
|
||||
jdk.imports['java.util.AbstractList'].load = () => {
|
||||
const Itr = jdk.import('java.util.Itr');
|
||||
jdk.imports['java.util.AbstractList'].load = async () => {
|
||||
const Itr = await jdk.import('java.util.Itr');
|
||||
|
||||
class AbstractList {
|
||||
constructor() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
jdk.imports['java.util.ArrayList'].load = () => {
|
||||
let AbstractList = jdk.import('java.util.AbstractList');
|
||||
jdk.imports['java.util.ArrayList'].load = async () => {
|
||||
let AbstractList = await jdk.import('java.util.AbstractList');
|
||||
|
||||
class ArrayList extends AbstractList {
|
||||
constructor(...args) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.Arrays'].load = () => {
|
||||
jdk.imports['java.util.Arrays'].load = async () => {
|
||||
class Arrays {
|
||||
fill(data, begin, nbElem, param) {
|
||||
const max = begin + nbElem;
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.Collections'].load = () => {
|
||||
jdk.imports['java.util.Collections'].load = async () => {
|
||||
class Collections {
|
||||
sort(list) {
|
||||
if (!list.size()) return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
jdk.imports['java.util.Formatter'].load = () => {
|
||||
const IllegalFormatException = jdk.import('java.util.IllegalFormatException');
|
||||
jdk.imports['java.util.Formatter'].load = async () => {
|
||||
const IllegalFormatException = await jdk.import('java.util.IllegalFormatException');
|
||||
|
||||
class Formatter {
|
||||
format(format, ...args) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.HashMap'].load = () => {
|
||||
jdk.imports['java.util.HashMap'].load = async () => {
|
||||
class HashMap {
|
||||
constructor() {
|
||||
this.content = {};
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.HashSet'].load = () => {
|
||||
jdk.imports['java.util.HashSet'].load = async () => {
|
||||
class HashSet {
|
||||
constructor() {
|
||||
this.content = {};
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.IllegalFormatException'].load = () => {
|
||||
jdk.imports['java.util.IllegalFormatException'].load = async () => {
|
||||
// TODO import and extend exception
|
||||
|
||||
class IllegalFormatException {
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.Itr'].load = () => {
|
||||
jdk.imports['java.util.Itr'].load = async () => {
|
||||
class Itr {
|
||||
constructor(list) {
|
||||
this.cursor = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
jdk.imports['java.util.LinkedList'].load = () => {
|
||||
let AbstractList = jdk.import('java.util.AbstractList');
|
||||
jdk.imports['java.util.LinkedList'].load = async () => {
|
||||
let AbstractList = await jdk.import('java.util.AbstractList');
|
||||
|
||||
class LinkedList extends AbstractList {
|
||||
constructor(...args) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.Random'].load = () => {
|
||||
jdk.imports['java.util.Random'].load = async () => {
|
||||
class Random {
|
||||
constructor() {
|
||||
this.seed = undefined;
|
||||
|
@ -1,5 +1,5 @@
|
||||
jdk.imports['java.util.Scanner'].load = () => {
|
||||
const File = jdk.import('java.io.File');
|
||||
jdk.imports['java.util.Scanner'].load = async () => {
|
||||
const File = await jdk.import('java.io.File');
|
||||
|
||||
class Scanner {
|
||||
constructor(input) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
jdk.imports['java.util.Stack'].load = () => {
|
||||
jdk.imports['java.util.Stack'].load = async () => {
|
||||
class Stack {
|
||||
constructor() {
|
||||
this.content = new Array();
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "java2js",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"description": "Converts Java to JavaScript with support for p5.js and QuintOS.",
|
||||
"main": "java2js.js",
|
||||
"scripts": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user