Skip to content

Commit 1f5c9f1

Browse files
committed
Add typechecker from java-slang
1 parent 1971477 commit 1f5c9f1

File tree

1 file changed

+24
-28
lines changed

1 file changed

+24
-28
lines changed

src/commons/utils/JavaHelper.ts

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,40 @@ import { compileFromSource } from 'java-slang/dist/compiler';
22
import { BinaryWriter } from 'java-slang/dist/compiler/binary-writer';
33
import setupJVM, { parseBin } from 'java-slang/dist/jvm';
44
import { createModuleProxy, loadCachedFiles } from 'java-slang/dist/jvm/utils/integration';
5+
import { convertErrorsToReadableMsgs, parseProgram, typeCheck } from 'java-slang/dist/types';
56
import { Context } from 'js-slang';
67
import loadSourceModules from 'js-slang/dist/modules/loader';
78

89
import Constants from './Constants';
910
import DisplayBufferService from './DisplayBufferService';
1011

1112
export async function javaRun(javaCode: string, context: Context) {
12-
let compiled = {}
13+
let compiled = {};
14+
15+
const stderr = (type: 'TypeCheck' | 'Compile' | 'Runtime', msg: string) => {
16+
context.errors.push({
17+
type: type as any,
18+
severity: 'Error' as any,
19+
location: { start: { line: -1, column: -1 }, end: { line: -1, column: -1 } },
20+
explain: () => msg,
21+
elaborate: () => msg
22+
});
23+
};
24+
25+
const typeCheckResult = typeCheck(parseProgram(javaCode));
26+
if (typeCheckResult.hasTypeErrors) {
27+
const typeErrMsg = convertErrorsToReadableMsgs(javaCode, typeCheckResult.errors).join('\n');
28+
stderr('TypeCheck', typeErrMsg);
29+
return Promise.resolve({ status: 'error' });
30+
}
1331

1432
try {
1533
const classFile = compileFromSource(javaCode);
1634
compiled = {
17-
"Main.class": Buffer.from(new BinaryWriter().generateBinary(classFile)).toString('base64')
35+
'Main.class': Buffer.from(new BinaryWriter().generateBinary(classFile)).toString('base64')
1836
};
1937
} catch (e) {
20-
context.errors.push({
21-
type: "CompileError" as any,
22-
severity: "Error" as any,
23-
location: { start: { line: -1, column: -1 }, end: { line: -1, column: -1 } },
24-
explain: () => e,
25-
elaborate: () => e
26-
});
38+
stderr('TypeCheck', e);
2739
return Promise.resolve({ status: 'error' });
2840
}
2941

@@ -64,6 +76,7 @@ export async function javaRun(javaCode: string, context: Context) {
6476
}
6577
return parseBin(new DataView(bytes.buffer));
6678
};
79+
6780
const loadNatives = async (path: string) => {
6881
// dynamic load modules
6982
if (path.startsWith('modules')) {
@@ -74,6 +87,7 @@ export async function javaRun(javaCode: string, context: Context) {
7487
}
7588
return await import(`java-slang/dist/jvm/stdlib/${path}.js`);
7689
};
90+
7791
const stdout = (str: string) => {
7892
if (str.endsWith('\n')) {
7993
buffer.push(str);
@@ -85,24 +99,6 @@ export async function javaRun(javaCode: string, context: Context) {
8599
buffer.push(str);
86100
}
87101
};
88-
const stderr = (msg: string) => {
89-
context.errors.push({
90-
type: 'Runtime' as any,
91-
severity: 'Error' as any,
92-
location: {
93-
start: {
94-
line: -1,
95-
column: -1
96-
},
97-
end: {
98-
line: -1,
99-
column: -1
100-
}
101-
},
102-
explain: () => msg,
103-
elaborate: () => msg
104-
});
105-
};
106102

107103
// load cached classfiles from IndexedDB
108104
return loadCachedFiles(() =>
@@ -128,7 +124,7 @@ export async function javaRun(javaCode: string, context: Context) {
128124
readFileSync: readClassFiles,
129125
readFile: loadNatives,
130126
stdout,
131-
stderr,
127+
stderr: (msg: string) => stderr('Runtime', msg),
132128
onFinish: () => {
133129
resolve(
134130
context.errors.length

0 commit comments

Comments
 (0)