Cangjie Release Notes

0. 版本介绍

本版本为Cangjie语言首个LTS版本(LTS版本定义及维护周期详见<仓颉社区版本生命周期管理规范>),版本号为Cangjie 1.0.0。版本包含了仓颉应用开发必须的能力,包括编译器,运行时,标准库,和工具链。欢迎各位开发者使用,如有任何问题,欢迎在Cangjie社区提出issue,我们会第一时间处理。

1. 语言特性

Feature

  • 支持基础标识符,提供循环、条件分支等基础程序结构
  • 支持整数、浮点数、布尔、字符、字符串、元组、数组、区间类型、Unit 及 Nothing 基础数据类型;
  • 支持自定义数据类型 struct、class 以及 enum 枚举,同时支持 interface,用于抽象化描述对外功能;
  • 支持类型别名,以便于用户在不同场景中对同一类型做不同的描述;
  • 支持定义普通函数、操作符重载函数、const 函数、Lambda 表达式,以及更高阶的嵌套函数,此外,struct 中还可以定义 mut 函数。函数与函数之前可以重载,函数调用时,还可以使用尾随闭包、Flow 表达式等语法糖;
  • 支持模式匹配表达式,可以用来匹配 enum 构造器、Option 类型解构、向下数据类型转换等;
  • 支持定义泛型的自定义类型和函数,同时支持为泛型类型增加约束;
  • 支持 extend 扩展声明,为已有的类型扩展新的功能,它可以包含函数、属性,extend 还能为泛型类型提供特化能力;
  • 支持以包为编译单位组织代码,用户可以以父子包的结构组织模块功能,用户可以为包中的声明提供了不同可见范围的修饰符,用于控制可见性;
  • 支持异常处理,提供了 Exception 和 Error 两个基础异常类;
  • 支持简洁的并发语法:spawn 表达式;
  • 支持与 C 的跨语言互操作;
  • 支持反射功能,并为用户提供了反射库,用户级可以通过反射库接口调用任何带有反射信息的函数;
  • 提供基于词法宏的元编程能力,支持编译期的代码变换,开发者可以使用宏编写仓颉代码生成模板或定义自己的 DSL 文法。

更多特性详见开发指南

2. 编译器

仓颉编译器提供了仓颉语言编译能力。其实现上分为前端和后端,后端基于llvm开发。

Feature

  • 提供O0~O2, Os, Oz等不同优化能力,以满足不同需求。其中O2提供了诸如函数内联,常量传播,虚函数调用优化等,详见仓颉编译选项
  • 提供各类编译器安全检查,提升应用质量: 数组越界检查(Try-Best) 整数运算溢出检查(Try-Best) 移位溢出检查(Try-Best) 除零检查(Try-Best) 死代码检查(Try-Best) 变量未初始化检查
  • 支持cangjie GC: 仓颉后端基于LLVM完成了Cangjie语言支持,包括重写RewriteStatePoint相关操作,适用于仓颉的活跃变量分析等,主要实现pass为CJRewriteStatepointCJGCLiveAnalysis
  • 为了更好的性能,仓颉基于LLVM 新增了优化Pass,如下表:
Pass名称优化选项On概述
CJIRVerifiercj-ir-verifierO0~On确保由前端生成的IR符合仓颉规范。
InsertCJTBAAinsert-cj-tbaaO0~On为load, store, memcpy, 和barrier插入Cangjie TBAA元数据,以帮助编译器进行内存访问优化。
CJFillMetadatacj-fill-metadataO0~OnTypeInfo填充与反射信息填充。
CJRuntimeLoweringcj-runtime-loweringO0~On将仓颉前端生成的Intrinsics下降至运行时相关函数。
CJSpecificOptcj-specific-optO0~On仓颉特定后端优化:1. ​栈分配优化​: 消除未使用的内存分配2. ​内存操作优化​: 简化地址转换,内联memset3. ​数学函数优化​: 特殊处理pow函数4. ​安全检查​: 插入栈检查和浮点状态重置
CJBarrierOptcj-barrier-optO2~On优化Write Barrier,消除无用的Write Barrier开销。
CJRewriteStatepointcj-rewrite-statepointO0~On为call/invoke指令构建statepoint,在IR中显式体现仓颉GC可能执行时,需要的重定位操作。
CJSimpleOptcj-simple-optO2一系列适用于仓颉的优化:1. ​返回值优化​:消除结构体返回时的多余拷贝2. ​浮点转整数优化​:简化溢出检查流程3. ​互斥锁优化​:添加快速路径的原子操作4. ​整数比较优化​:利用符号信息简化比较5. ​数组大小优化​:将常量数组尺寸直接替换
CJSimpleRangeAnalysisPasscj-simple-range-analysisO2用于对整数和浮点数进行简单的范围分析,并基于分析结果优化控制流图(CFG)
CJLoopFloatOptcj-loop-float-optO2用于优化只涉及简单浮点计算的顶层循环。它通过将浮点计算转换为整数计算来提高性能
CJRSSCEPasscj-rssceO2用于消除冗余的栈结构复制。它通过内存定义范围分析和别名分析来实现这一目标。
CJDevirtualOptcj-devirtual-optO2优化虚函数调用至直接调用。
CJBarrierSplitcj-barrier-splitO2Barriers 指令拆分与优化,消除无用barrier。
CJPartialEscapeAnalysiscj-peaO1~On逃逸分析优化。
CJGenericIntrinsicOptcj-generic-intrinsic-optO0~On仓颉泛型Intrinsics优化。
CJBarrierLoweringcj-barrier-loweringO0Barrier指令Lower。

3. 运行时

仓颉运行时是仓颉的核心组件之一,以高性能和轻量化为设计目标,为仓颉语言在全场景下的高性能表现提供有力支持。

Feature

特性名称详细说明
内存管理自动内存管理模块使用了低时延的全并发内存整理算法,其核心目标是追求更低的业务时延与更低的内存开销,帮助开发者更好地聚焦业务本身。
线程管理线程管理模块则提供了更轻量,更具弹性能力的线程管理方案,能更好地应对各种体量的并发场景。
异常管理在仓颉中,从严重程度分类异常类有 Exception 和 Error :- Error 类描述仓颉语言运行时,系统内部错误和资源耗尽错误,应用程序不应该抛出这种类型错误,如果出现内部错误,只能通知给用户,尽快安全终止程序。- Exception 类描述的是程序运行时的逻辑错误或者 IO 错误导致的异常,例如数组越界或者试图打开一个不存在的文件等,这类异常需要在程序中捕获处理。
回栈仓颉是基于frame pointer的回栈,即使用rbp寄存器保存栈帧地址,rsp保存栈顶指针,在过程调用时将上一个栈帧地址入栈保存。
包管理支持以package粒度加载仓颉包,支持反射特性。
对象模型包含仓颉对象元数据、成员信息、方法信息、方法表。
跨语言调用通过FFI(外部函数接口)实现仓颉语言和C、ArkTs之间的函数调用和数据交互。
DFX提供日志打印、CPU采集、堆快照文件导出等功能,支持运行时状态监测和故障排查。

4. 标准库

仓颉提供了丰富的标准库能力,例如collection,timer, io,文件处理等。具体的库列表详见下文,具体的API详见API手册

Feature

包名功能
std.core标准库的核心包,提供了适用仓颉语言编程最基本的一些 API 能力。
std.argopt提供从命令行参数字符串解析出参数名和参数值的相关能力。
std.ast主要包含了仓颉源码的语法解析器和仓颉语法树节点,提供语法解析函数。
std.binary提供仓颉数据类型和二进制字节序列间的互相转换接口。
std.collection提供了常见数据结构的高效实现、相关抽象的接口的定义以及在集合类型中常用的函数功能。
std.collection.concurrent提供了并发安全的集合类型实现。
std.console提供和标准输入、标准输出、标准错误进行交互的方法。
std.convert提供从字符串转到特定类型的 Convert 系列函数。
std.crypto提供对称加解密通用接口以及常用摘要算法的通用接口
std.database.sql提供仓颉访问数据库的接口。
std.deriving提供了一种根据类、结构体和枚举类型的字段、属性等自动生成接口实现的方法。
std.env提供当前进程的相关信息与功能、包括环境变量、命令行参数、标准流、退出程序。也提供标准输入、标准输出、标准错误进行交互的方法。
std.fs提供对文件、文件夹、路径、文件元数据信息的一些操作函数。
std.io提供程序与外部设备进行数据交换的能力。
std.math提供常见的数学运算,常数定义,浮点数处理等功能。
std.math.numeric供对基础类型可表达范围之外提供扩展能力。
std.net用于进行网络通信,提供启动 Socket 服务器、连接 Socket 服务器、发送数据、接收数据等功能和 IP 地址、IP前缀(又称IP子网)、Socket 地址的相关数据结构。
std.objectpool提供了对象缓存和复用的功能。
std.overflow提供了整数运算溢出时的处理能力。
std.posix主要适配 POSIX 系统接口。
std.process主要提供 Process 进程操作接口,主要包括进程创建,标准流获取,进程等待,进程信息查询等。
std.random提供生成伪随机数的能力。
std.reflect提供了反射功能,使得程序在运行时能够获取到各种实例的类型信息,并进行各种读写和调用操作。
std.regex提供正则表达式分析处理文本的能力,支持查找、分割、替换、验证等功能。
std.runtime支持与程序的运行时环境进行交互,提供了一系列函数和变量,用于控制、管理和监视程序的执行。
std.sort提供数组类型的排序函数。
std.sync提供并发编程相关的能力。
std.time提供了与时间相关的类型,包括日期时间,时间间隔,单调时间和时区等,并提供了计算和比较的功能。
std.unicode提供了按 unicode 编码标准处理字符的能力。
std.unittest用于编写仓颉项目单元测试代码,提供包括代码编写、运行和调测在内的基本功能,并为有经验的用户提供的一些高级功能。

5. 工具链

1 IDE插件

Feature

  • 支持仓颉语言服务,包括代码高亮、自动补全、定义跳转、查找引用、诊断报错、选中高亮、悬浮提示、定义搜索、重命名、大纲视图、面包屑导航、类型层次结构等
  • 支持创建仓颉工程
  • 支持编译仓颉工程
  • 支持调试服务,包括断点调试、调试信息查看、程序控制、表达式求值、反向调试等
  • 支持仓颉代码格式化

2 cjpm

Feature

cjpm是编译仓颉项目的构建工具,该工具使用仓颉语言实现,提供项目创建、项目编译、项目运行、单元测试等能力,其中项目支持多模块自动分析依赖,完成顺序构建。其设计目标是简化用户的工作流,提升多平台开发效率,并提供高度可定制的配置选项。

cjpm 主要功能说明如下:

  • 新建仓颉模块
  • 检查依赖,输出包依赖拓扑序
  • 打印包依赖关系
  • 编译仓颉程序
  • 运行可执行产物
  • 编译并执行测试用例
  • 编译并执行性能用例
  • 清除编译产物
  • 安装/卸载模块可执行产物
  • 命令扩展机制
  • 构建脚本能力

cjpm 提供了一个 cjpm.toml 配置文件,位于模块根目录,用户可在其中对整个模块进行一系列配置。主要配置项包括:模块基本信息、编译透传选项、依赖的模块信息、命令剖面配置、平台隔离配置项、工作空间信息等。

3 cjdb

Feature

cjdb 是一款基于 lldb 开发的仓颉程序命令行调试工具, 为仓颉开发者提供程序调试的能力。

cjdb 主要功能说明如下:

  • 调试器启动被调程序
  • 源码断点/函数断点/条件断点
  • 观察点
  • 程序运行
  • 函数进入、单步、函数退出、继续执行
  • 变量查看/变量修改
  • 表达式计算
  • 仓颉线程查看

4 cjfmt

Feature

cjfmt 仓颉格式化工具是一款基于仓颉语言编程规范开发的代码自动格式化工具。

cjfmt 主要功能说明如下:

  • 文件格式化
  • 目录格式化
  • 片段格式化
  • 通过配置文件定制格式化风格

5 cjlint

Feature

cjlint 是一款静态检查工具,该工具是基于仓颉语言编程规范开发。通过它可以识别代码中不符合编程规范的问题,帮助开发者发现代码中的漏洞,写出满足 Clean Source 要求的仓颉代码。

该工具可以通过 -f 选项指定检查目录,-r 用来指定生成扫描报告的格式,目前支持json格式和csv格式。当前也支持规则级告警屏蔽和源代码注释告警屏蔽等能力。

6 cjcov

Feature

cjcov 是一款面向仓颉语言的覆盖率统计工具,用于生成仓颉语言程序的覆盖率报告。

7 cjprof

Feature

cjprof 是仓颉语言的性能分析工具,支持以下功能(目前仅支持 Linux 系统):

  • 对仓颉语言程序进行 CPU 热点函数采样,导出采样数据。
  • 对热点函数采样数据进行分析,生成 CPU 热点函数统计报告或火焰图。
  • 导出仓颉语言应用程序堆内存,并对其进行分析生成分析报告。

8 cjtrace-recover

Feature

cjtrace-recover 是仓颉语言的异常堆栈信息还原工具。

如果开发者在编译仓颉应用时开启了外形混淆,那么仓颉应用在运行时如果遇到问题,抛出的异常信息中的堆栈信息也是被混淆的状态,这导致开发者难以定位问题发生原因。cjtrace-recover 可以帮助开发者还原混淆过的异常堆栈信息,从而更好地定位和排查问题原因。具体来说,cjtrace-recover 可以还原异常堆栈信息中的以下两种信息:

  • 被混淆的函数名
  • 被混淆的路径名