# 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