# spirit
**Repository Path**: digital-engine/spirit
## Basic Information
- **Project Name**: spirit
- **Description**: 一种轻量的转译型语言,可生成Java代码。它致力于减少Java代码的冗余,并提供流畅的开发体验。它能够和Java代码无缝集成,并减少60%的代码量。
- **Primary Language**: Java
- **License**: GPL-3.0
- **Default Branch**: develop
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 16
- **Forks**: 0
- **Created**: 2019-11-24
- **Last Updated**: 2025-03-05
## Categories & Tags
**Categories**: scripting-language
**Tags**: None
## README
# Spirit
一种轻量的转译型语言,可生成Java代码。它致力于减少Java代码的冗余,并提供流畅的开发体验。它能够和Java代码无缝集成,并减少60%的代码量。
## 名词解释
### 转译
源代码,不直接编译成机器码或者字节码,而是转换成另外一种高级语言代码。例如:TypeScript编译成JavaScript。
### 轻量
将精力集中在核心功能的开发上,预留接口,可供拓展。
### 无缝集成
语法和Java相近,支持在源代码中直接调用Java的库。
## 代码示例
### 原始代码
```go
func main() {
print "hello world!"
}
```
### 目标代码
```java
package com.sum.test.main;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Main {
public static void main(String[] args) {
log.info("hello world!");
}
}
```
## 快速开始
### 原理解析
Spirit提供名为spirit:compile的Maven插件。它能够将Maven项目中,src/main/resources/sources目录下(如果不存在sources文件夹,请手动创建),后缀名为.sp的源码文件,转译成Java代码。目标代码会生成在src/main/java目录下。
**src/main/resources/sources目录下的.sp文件 ==编译==> src/main/java目录下的.java文件**
### 依赖配置
在pom.xml中引入以下jar包:
```xml
com.gitee.digital-engine
spirit-stdlib
3.0.0
org.slf4j
slf4j-api
1.7.25
org.apache.commons
commons-lang3
3.9
```
### 插件配置
在pom.xml中引入以下插件:
```xml
com.gitee.digital-engine
spirit-maven-plugin
3.0.0
compile
generateConfig
```
### 编辑器安装
因为IntelliJ IDEA 、Eclipse等集成开发环境,目前还不支持编辑Spirit代码,所以需要使用编辑器。在这里,选用sublime编辑器。
1. 下载并安装sublime编辑器。
2. 打开sublime,点击上方Preferences->Browse Packages按钮,找到User文件夹。
3. 将spirit-editor项目中,sublime-plugs目录下的所有文件,都拷贝到User文件夹中。(spirit-editor项目地址:https://gitee.com/digital-engine/spirit-editor.git)
4. 在任意目录下,创建Main.sp文件,并在sublime中打开,输入如下内容,观察代码是否已经有样式:
```go
func main() {
print "hello world!"
}
```
### 代码编译
1. 在src/main/resources/sources目录下,创建com.gitee.spirit.example文件夹,该文件夹将直接作为包。
2. 在以上文件夹下,创建Main.sp文件,并在sublime中打开,输入如下内容:
```go
func main() {
print "hello world!"
}
```
3. 执行Maven命令(mvn spirit:compile)并刷新,在src/main/java目录下,观察生成的Java代码:
```java
package com.sum.test.main;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Main {
public static void main(String[] args) {
log.info("hello world!");
}
}
```
## 语法速成(10min)
作为一种“新”的编程语言,Spirit确实有一定的“学习成本”。如果之前接触过Java、JavaScript等语言,你会感到十分亲切。从设计之初,Spirit便支持和Java混编(混编的意思是:你可以在Spirit代码中,尽情地调用Java代码)。所以作者的建议是,项目可以以Java为主,适当合理地使用Spirit(反正Spirit代码也会转译成Java代码的嘛:sweat_smile:)。Spirit的语法是比较懒散的,如果你掌握了这个核心特点,那么就掌握了这门语言。
### 缺省public
Spirit代码:
```java
class People {
String name
Integer age
}
```
转译成Java代码:
```java
public class People {
public String name;
public Integer age;
}
```
### 缺省new
Spirit代码:
```java
class PeopleFactory {
People newPeople(String name, Integer age) {
return People(name, age)
}
}
```
转译成Java代码:
```java
public class PeopleFactory {
public People newPeople(String name, Integer age) {
return new People(name, age);
}
}
```
### 缺省括号
Spirit代码:
```java
if "Jessica".equals(name) {
log.info("Name is equal!")
}
```
转译成Java代码:
```java
if ("Jessica".equals(name)) {
log.info("Name is equal!");
}
```
### 缺省类型
Spirit代码:
```java
class People {
name = "Jessica"
age = 18
func toString() {
return name + "_" + age
}
}
```
转译成Java代码:
```java
public class People {
public String name = "Jessica";
public Integer age = 18;
public String toString() {
return name + "_" + age;
}
}
```
### 缺省集合
Spirit代码:
```java
class Example {
list = ["Jessica", "Jessie"]
map = {"Jessica": 18, "Jessie": 18}
}
```
转译成Java代码:
```java
public class Example {
public List list = Lists.of("Jessica", "Jessie");
public Map map = Maps.of("Jessica": 18, "Jessie": 18);
}
```
### 缺省遍历
Spirit代码:
```java
for str in list {
log.info("The item is {}", str)
}
// Or something like this
for str in list : log.info("The item is {}", str)
```
转译成Java代码:
```go
for (String str : list) {
log.info("The item is {}", str);
}
```
## 进阶语法(10min)
### 日志输出
Spirit代码:
```go
class PeopleLogger {
func logPeople(People people) {
print people.toString()
}
}
```
转译成Java代码:
```java
@Slf4j
public class PeopleLogger {
public void logPeople(People people) {
log.info(people.toString());
}
}
```
### builder模式
Spirit代码(建议配合lombok的@Builder使用):
```java
class PeopleFactory {
func newPeople(String name, Integer age) {
return People{name = name, age = age}
}
}
```
转译成Java代码:
```java
public class PeopleFactory {
public People newPeople(String name, Integer age) {
return People.builder().name(name).age(age).build();
}
}
```
### 缺省builder模式
Spirit代码(方法入参类型非常明确的情况下,可以用“$”符号替代类型):
```java
class PeopleLogger {
func logPeople(People people) {
log.info(people.toString())
}
func logPeople(String name, Integer age) {
logPeople(${name = name, age = age})
}
}
```
转译成Java代码:
```java
public class PeopleLogger {
public void logPeople(People people) {
log.info(people.toString());
}
public void logPeople(String name, Integer age) {
logPeople(People.builder().name(name).age(age).build());
}
}
```
## 高阶语法(10min)
### JSON构造
Spirit代码:
```java
jsonMap = {
"name": "Jessica",
"age": 18,
"father": {"Jack": 38},
"sisters": ["jessie", "jenny"]
}
print JSON.toJSONString(jsonMap)
```
转译成Java代码:
```java
Map jsonMap = Maps.of(
"name": "Jessica",
"age": 18,
"father": Maps.of("Jack", 38),
"sisters": Lists.of("jessie", "jenny")
);
log.info(JSON.toJSONString(jsonMap));
```
### 宏构造模式
格式为 obj = $Type{ expression }的语义单元,被称为宏构造语义单元。编译器会查找和Type类型,绑定的插件,解析“{}”内的表达式,并生成额外的Java代码。例如:在使用tk.mybatis时,利用宏构造模式,创建一个用来查询的Example对象。
Spirit代码:
```go
example = $Example{
class = People.class,
name != people.getName()?,
age >= people.getAge()!,
alias like "%" + people.getName() + "%",
order by id desc
}
```
转译成Java代码(减少约70%的代码):
```java
Example example$1 = new Example(People.class);
Example.Criteria criteria$1 = example$1.createCriteria();
if (people.getName() != null) {
criteria$1.andNotEqualTo("name", people.getName());
}
Objects.requireNonNull(people.getAge(), "people.getAge() is null!");
criteria$1.andGreaterThanOrEqualTo("age", people.getAge());
criteria$1.andLike("alias", "%" + people.getName() + "%");
example$1.orderBy("id").desc();
Example example = example$1;
```
## 版本说明
| 版本 | 说明 |
| :--- | ---------------------------------------------------------- |
| 1.0 | 调研编译器的可行性。 |
| 2.0 | 完成编译器的基本设计,并完成核心功能。 |
| 3.0 | 参考Java编译器一部分逻辑,重构了核心功能,进入预发布状态。 |
## 未来
提供更多的sublime插件。
## 加入我(们)
欢迎通过以下方式联系作者。
QQ群(1群):777458862
邮箱:digital_engine@163.com