-
Notifications
You must be signed in to change notification settings - Fork 45
/
gen-jython-bindings.js
95 lines (83 loc) · 2.34 KB
/
gen-jython-bindings.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// generates import declarations for the Jython
// interpreter
const fs = require('fs')
// checks if the given thing is a Java file
let isFile = file =>
fs.statSync(file).isFile()
&& file.endsWith('.java')
// checks if the given thing is a folder
let isDir = file =>
fs.statSync(file).isDirectory()
// scans the given source code folder
let scan = (folder, package, bindings) => {
if (!isDir) {
console.log(`skipped ${folder}; does not exist`)
return
}
let files = fs.readdirSync(folder)
// first scan sub folders
for (let file of files) {
let path = `${folder}/${file}`
if (!isDir(path))
continue
let subpack = package !== ''
? `${package}.${file}`
: file
scan(path, subpack, bindings)
}
// scan java class files
for (let file of files) {
let path = `${folder}/${file}`
if (!isFile(path))
continue
// read all lines
let lines = fs.readFileSync(path, {
encoding: 'utf-8',
}).split('\n')
.map(line => line.trim())
// search for public class declarations
for (let line of lines) {
let match = line.match(
/public( final)?( abstract)? (?:class|enum|record) ([a-zA-Z0-9]*)(.*)?/)
if (!match || match.length < 4)
continue
let clazz = match[3]
let fullName = `${package}.${clazz}`
let binding = bindings[clazz]
if (binding) {
console.log(
`skip ${fullName};`,
` existing binding: ${binding}`)
break
}
bindings[clazz] = fullName
break
}
}
}
let generate = (folders, target) => {
let bindings = {}
for (let folder of folders) {
scan(folder, '', bindings)
}
let text = Object.keys(bindings)
.sort()
.map(clazz => `import ${bindings[clazz]} as ${clazz}\n`)
.reduce((t, s) => t.concat(s))
let out = `olca-app/src/org/openlca/app/devtools/python/${target}`
let header = '# auto-generated bindings; do not edit them\n'
fs.writeFileSync(out, header + text)
}
let main = () => {
let modPath = '../olca-modules'
// duplicate class names are skipped, so
// the order of the folders is important
let modFolders = [
`${modPath}/olca-core/src/main/java`,
`${modPath}/olca-io/src/main/java`,
`${modPath}/olca-proto-io/src/main/java`,
`${modPath}/olca-ipc/src/main/java`,
]
generate(modFolders, 'mod_bindings.py')
}
main()