-
Notifications
You must be signed in to change notification settings - Fork 11
/
Translator.kt
102 lines (90 loc) · 3.85 KB
/
Translator.kt
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
96
97
98
99
100
101
102
package org.polystat.j2eo.translator
import arrow.core.None
import arrow.core.Some
import org.polystat.j2eo.eotree.* // ktlint-disable no-wildcard-imports
import org.polystat.j2eo.translator.preprocessor.PreprocessorState
import org.polystat.j2eo.translator.preprocessor.preprocess
import org.polystat.j2eo.util.findMainClass
import org.polystat.j2eo.util.generateEntryPoint
import org.polystat.j2eo.util.logger
import tree.Compilation.CompilationUnit
import tree.Compilation.Package
import tree.Compilation.SimpleCompilationUnit
import tree.Compilation.TopLevelComponent
import tree.Declaration.ImportDeclaration
import java.nio.file.Path
import java.time.LocalDateTime
import java.util.* // ktlint-disable no-wildcard-imports
class Translator(val relativePath: Path) {
fun translate(unit: CompilationUnit, context: Context): EOProgram {
return if (unit is SimpleCompilationUnit)
mapSimpleCompilationUnit(unit, context)
else
throw IllegalArgumentException(
"CompilationUnit of type " +
unit.javaClass.simpleName +
" is not supported"
)
}
// @todo #165:30m We should add license to EOLicense()
fun mapPackage(pkg: Package, context: Context): EOProgram {
return EOProgram(
EOLicense(),
EOMetas(
Some(pkg.compoundName.names.joinToString(".")),
ArrayList()
),
pkg.components.components
.map { obj -> mapTopLevelComponent(obj, context) }
)
}
private fun mapSimpleCompilationUnit(unit: SimpleCompilationUnit, context: Context): EOProgram {
// preprocessUnit(unit)
val preprocessorState = PreprocessorState()
preprocess(preprocessorState, unit)
val bnds = unit.components.components
.map { obj: TopLevelComponent? -> mapTopLevelComponent(obj!!, context) }
.map { bnd: org.polystat.j2eo.eotree.EOBnd -> bnd as EOBndExpr }
// FIXME: assuming there is only one top-level component and it is a class
val mainClassName = findMainClass(unit)
var entrypointBnds = listOf<EOBndExpr>()
if (mainClassName != null) {
entrypointBnds = generateEntryPoint(mainClassName)
} else {
logger.info { "No entry point here!" }
}
// FIXME: assuming there is only one top-level component and it is a class
// Always calling the 'main' method
val stdAliases = (
preprocessorState.stdTokensForCurrentAlias
.map { EOMeta("alias", it) }.toList() +
(unit.imports?.imports?.map { mapImport(it, context) } ?: listOf())
).distinct()
val eoAliases = preprocessorState.eoClassesForCurrentAlias
.map { EOMeta("alias", it) }.toList()
val pkg = relativePath.toList().dropLast(1).joinToString(".")
return EOProgram(
EOLicense(
EOComment(LocalDateTime.now().toString()),
EOComment("j2eo team")
),
EOMetas(
if (pkg.isNotEmpty()) Some(pkg) else None,
stdAliases + eoAliases
),
bnds + entrypointBnds
)
}
private fun mapTopLevelComponent(component: TopLevelComponent, context: Context): org.polystat.j2eo.eotree.EOBnd {
return if (component.classDecl != null) {
mapClass(component.classDecl, context)
} else if (component.interfaceDecl != null) {
mapInterface(component.interfaceDecl, context)
} else {
throw IllegalArgumentException("Supplied TopLevelComponent does not have neither class nor interface")
}
}
private fun mapImport(importDecl: ImportDeclaration, context: Context): EOMeta {
return EOMeta("alias", importDecl.compoundName.names.joinToString("."))
}
}