@@ -2,28 +2,40 @@ import { compileFromSource } from 'java-slang/dist/compiler';
2
2
import { BinaryWriter } from 'java-slang/dist/compiler/binary-writer' ;
3
3
import setupJVM , { parseBin } from 'java-slang/dist/jvm' ;
4
4
import { createModuleProxy , loadCachedFiles } from 'java-slang/dist/jvm/utils/integration' ;
5
+ import { convertErrorsToReadableMsgs , parseProgram , typeCheck } from 'java-slang/dist/types' ;
5
6
import { Context } from 'js-slang' ;
6
7
import loadSourceModules from 'js-slang/dist/modules/loader' ;
7
8
8
9
import Constants from './Constants' ;
9
10
import DisplayBufferService from './DisplayBufferService' ;
10
11
11
12
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
+ }
13
31
14
32
try {
15
33
const classFile = compileFromSource ( javaCode ) ;
16
34
compiled = {
17
- " Main.class" : Buffer . from ( new BinaryWriter ( ) . generateBinary ( classFile ) ) . toString ( 'base64' )
35
+ ' Main.class' : Buffer . from ( new BinaryWriter ( ) . generateBinary ( classFile ) ) . toString ( 'base64' )
18
36
} ;
19
37
} 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 ) ;
27
39
return Promise . resolve ( { status : 'error' } ) ;
28
40
}
29
41
@@ -64,6 +76,7 @@ export async function javaRun(javaCode: string, context: Context) {
64
76
}
65
77
return parseBin ( new DataView ( bytes . buffer ) ) ;
66
78
} ;
79
+
67
80
const loadNatives = async ( path : string ) => {
68
81
// dynamic load modules
69
82
if ( path . startsWith ( 'modules' ) ) {
@@ -74,6 +87,7 @@ export async function javaRun(javaCode: string, context: Context) {
74
87
}
75
88
return await import ( `java-slang/dist/jvm/stdlib/${ path } .js` ) ;
76
89
} ;
90
+
77
91
const stdout = ( str : string ) => {
78
92
if ( str . endsWith ( '\n' ) ) {
79
93
buffer . push ( str ) ;
@@ -85,24 +99,6 @@ export async function javaRun(javaCode: string, context: Context) {
85
99
buffer . push ( str ) ;
86
100
}
87
101
} ;
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
- } ;
106
102
107
103
// load cached classfiles from IndexedDB
108
104
return loadCachedFiles ( ( ) =>
@@ -128,7 +124,7 @@ export async function javaRun(javaCode: string, context: Context) {
128
124
readFileSync : readClassFiles ,
129
125
readFile : loadNatives ,
130
126
stdout,
131
- stderr,
127
+ stderr : ( msg : string ) => stderr ( 'Runtime' , msg ) ,
132
128
onFinish : ( ) => {
133
129
resolve (
134
130
context . errors . length
0 commit comments