Table of Contents
- Chapter 1: Basic Language Definitions
- Chapter 2: Core Syntax Rules
- 2.1 Variable Declarations
- 2.2 Basic Types
- 2.3 Expressions and Control Flow
- 2.4 Functions
- 2.5 Enum Types
- 2.6 Pattern Matching
- 2.7 Option Type
- 2.8 class Type
- 2.9 Unit Testing
- 2.10 Error Handling
- 2.11 Quick Reference Manual
- Chapter 3: Task Processing Workflow
- 3.1 Code Generation Workflow
- 3.2 Code Analysis Workflow
- Chapter 4: Checklist of 19 ⚠️ Common Pitfalls
- Chapter 5: Examples and Template Reference
- Chapter 6: Quality Control Standards
- Chapter 7: MCP Documentation Integration
Chapter 1: Basic Language Definitions
1.1 Files and Extensions
- File Extension:
.cj - Language Abbreviation:
cj(Cangjie) - Entry Function:
main()
1.2 Comments
// 单行注释
/*
* 多行注释
*/
/**
* 文档注释
*/
1.3 Code Block Structure
main() {
// 代码主体
let a: Int64 = 20
var b: Int64 = 12
println("${a}${b}")
}
Chapter 2: Core Syntax Rules
2.1 Variable Declarations
Syntax Format
修饰符 变量名: 变量类型 = 初始值
Mutability Modifiers
let- Immutable Variable(Can only be assigned once; cannot be modified after initialization)var- Mutable Variable(Can be assigned multiple times)
⚠️ Common Pitfall 1:let Variable shadowing is not supported; a variable with the same name cannot be redefined within the same scope.
Visibility Modifiers
| Modifier | Scope | Default Value |
|---|---|---|
private |
Visible within the class definition | ❌ |
public |
Visible both inside and outside the module | ❌ |
protected |
Visible to the current module and subclasses of the current class | ❌ |
internal |
Visible only within the current package and subpackages | ✅ Default |
Static Modifiers
static- Affects how member variables are stored and referenced
Example Code
main() {
let a: Int64 = 20 // 不可变变量
var b: Int64 = 12 // 可变变量
b = 23 // 可以修改var变量
println("${a}${b}")
}
Example Reference:examples/01_variable_declaration.cj
2.2 Basic Types
Numeric Types
Signed Integer:Int8、Int16、Int32、Int64、IntNative
Unsigned Integer:UInt8、UInt16、UInt32、UInt64、UIntNative
Floating-Point Type:Float16、Float32、Float64
Boolean Type:true、false
Character Type (Rune)
- Use
Runeto represent, and can represent all characters in the Unicode character set - Rune → UInt32:
UInt32(e)- Get Unicode scalar value - Integer → Rune:
Rune(num)- The value must be within the valid Unicode range- Valid range:
[0x0000, 0xD7FF]or[0xE000, 0x10FFFF]
- Valid range:
⚠️ Common Pitfall 2: When converting a Rune to an integer, ensure it is within the valid Unicode range; otherwise, a compilation error or runtime exception will occur.
Escape Characters
let slash: Rune = r'\\'
let newLine: Rune = r'\n'
let tab: Rune = r'\t'
Unicode Literal
let he: Rune = r'\u{4f60}' // 你
let llo: Rune = r'\u{597d}' // 好
String Type (String)
Cangjie supportsthree kinds of string literals:
1. Single-line string literal
The content is defined within a pair of single quotes or double quotes and can only be written on the same line:
let s1: String = ""
let s2 = 'Hello Cangjie Lang'
let s3 = "\"Hello Cangjie Lang\""
let s4 = 'Hello Cangjie Lang\n' // \n 是转义字符,表示换行
2. Multi-line string literal
There must be three double quotes at the beginning and end (""") or three single quotes ('''), and the content starts from the three quotes at the beginningAfter a newlineStart from the first line:
// 三个双引号
let s1: String = """
""" // 空字符串(换行后才开始)
// 三个单引号
let s2: String = '''
Hello,
Cangjie Lang'''
3. Multiline raw string literal
Starts with one or more hash signs (#) and a single quote or double quote,Escape rules do not apply,Interpolation is not supported:
let s1: String = #""# // 空字符串
let s2 = ##'#'\n'## // \n 不是换行符,是 \ 和 n 两个字符
let s3 = ###"
Hello,
Cangjie
Lang"### // 保留换行和缩进
⚠️ Common pitfall 4: In a multiline raw string literal, escape characters (such as \n、\t)will not be escaped, and the content in the literal remains as-is.
⚠️ Common pitfall 5: Multiline raw string literaldoes not support interpolation, do not use ${} syntax.
Interpolated string
⚠️ Common pitfall 3: In an interpolated string, using ${} expression
let fruit = "apples"
let count = 10
let s = "There are ${count * count} ${fruit}"
Applicable scope: Interpolated strings only apply tosingle-line string literalsandmultiline string literals,not applicable to multiline raw string literals。
Tuple
- Type representation:
(T1, T2, ..., TN) - At least binary:
(Int64, Float64)、(Int64, Float64, String) - Index access:
tuple[0]、tuple[1]
var tuple = (true, false)
println(tuple[0])
Array type
Array<T> // T 是元素类型,可以是任意类型
Range type
- Type representation:
Range<T>(generic) - Contains three values:
start、end、step - Constraints:
startandendhave the same type (T)steptype isInt64stepvalue cannot be equal to 0
Unit type
- Only value:
() - Supported operations: only assignment, equality check, inequality check
- ⚠️ Not supported: all other operations
Example reference:examples/02_basic_types.cj
2.3 Expressions and control flow
Conditional expression
⚠️ Common pitfall 5: The parentheses of a conditional expression cannot be omitted; this differs from many languages.
if (条件) { // ✅ 必须有括号
分支 1
} else {
分支 2
}
if expression
Basic form:
if (条件) {
分支 1
} else {
分支 2
}
if as an expression(return value):
let a = 10
let result = if (a > 5) {
"greater than 5"
} else {
"5 or less"
}
// result = "greater than 5"
Pattern matching (let pattern):
let a = Some(3)
let d = Some(1)
if (let Some(e) <- a && let Some(f) <- d) { // 两个模式都匹配
println("${e} ${f}") // 输出: 3 1
}
while expression
while (条件) {
循环体
}
// do-while 形式
do {
循环体
} while (条件)
for-in expression
for (迭代变量 in 序列) {
循环体
}
Tuple iteration:
let array = [(1, 2), (3, 4), (5, 6)]
for ((x, y) in array) {
println("${x}, ${y}")
}
Range iteration:
main() {
var sum = 0
for (i in 1..=100) { // 1 到 100(包含)
sum += i
}
println(sum)
}
Jump control
- Supports
break、continue - ⚠️ Common pitfall 6: labeled jumps are not supported
- ⚠️ Common pitfall 7: completely does not support
goto
Example reference:examples/03_control_flow.cj
2.4 Functions
Functions are first-class citizens
- Can be used as a function parameter or return value
- Can be assigned to a variable
- Functions themselves also have types
Function type
Syntax:(参数类型) -> 返回类型
- Parameter types are enclosed in
(), and multiple parameters are separated by,Separator - Parameter types and return type are connected by
->Connect
func add(a: Int64, b: Int64): Int64 {
return a + b
}
type FnType = (Int64) -> Unit
func display(a: Int64): Unit {
println(a)
}
// 命名参数
func name(name!:String)
// 命名参数还可以设置默认值
func name(name!:String = "小王")
Function parameters
⚠️ Common pitfall 8: Function parameters are by default let immutable variables defined
// a 和 b 默认是 let 不可变的(不能显式写 let 或 var)
func add(a: Int64, b: Int64): Int64 {
return a + b
}
⚠️ Important:
- Function parameters cannot explicitly use
letorvarmodifiers(including all functions such as top-level functions, class member methods, struct member methods, etc.) - Parameters are immutable by default
letImmutable
If you need to modify a parameter value, you should use a local variable:
func modify(a: Int64): Int64 {
var result = a
result = result + 1 // 修改局部变量
return result
}
Return value shorthand
func add(a: Int64, b: Int64): Int64 {
a + b // 最后一个表达式自动作为返回值
}
func returnAdd(): (Int64, Int64) -> Int64 {
add // 可以直接返回函数
}
Lambda expressions
Syntax:
{ p1: T1, ..., pn: Tn => expressions | declarations }
Example:
// 完整类型声明
let f1 = { a: Int64, b: Int64 => a + b }
// 无参 Lambda
var display = { =>
println("Hello")
println("World")
}
// 类型推断
var sum1: (Int64, Int64) -> Int64 = { a, b => a + b }
var sum2: (Int64, Int64) -> Int64 = { a: Int64, b => a + b }
// Lambda 作为参数
func f(a1: (Int64) -> Int64): Int64 {
a1(1)
}
main(): Int64 {
f({ a2 => a2 + 10 }) // 参数类型推断
}
Immediately invoked Lambda:
⚠️ Common mistake 9: Lambda expressions can be invoked immediately
let r2 = { => 123 }() // r2 = 123,立即执行
var g = { x: Int64 => println("x = ${x}") }
g(2) // 调用 Lambda
Example reference:examples/04_functions.cj
2.5 Enum types
Definition syntax
- Starts with
enumStart - Constructors are separated by
|Separator - There must be at least one named constructor
- The
|before the first constructor is optional
enum RGBColor {
| Red(UInt8) | Green(UInt8) | Blue(UInt8)
}
Constructor types
- No-argument constructor:
C - Parameterized constructor:
C(p1, p2, ..., pn)
Example reference:examples/05_enum.cj
2.6 Pattern matching
match expression
Basic syntax:
⚠️ Important: The statements after casedo not need {} parentheses, multi-line statements can simply be placed on new lines
match (待匹配值) {
case 模式1 => 处理1
case 模式2 => 处理2
case _ => 默认处理 // 通配符
}
Multi-line statements: simply use new lines, no need for {}
match (value) {
case 1 => println("one")
case 2 => println("two")
println("second number") // ✅ 多行直接换行
case _ => println("other")
}
Example:
main() {
let x = 0
match (x) {
case 1 => print("x = 1")
case 0 => print("x = 0") // 匹配
case 2 | 3 | 4 => print("other") // 多值匹配
case _ => print("其他")
}
}
Detailed explanation of pattern types
1. Constant pattern
Supports: integer literals, floating-point literals, character literals, boolean literals, string literals, Unit literals
⚠️ Common mistake 10: string interpolation is not supported
2. Wildcard pattern
Represented by _ , matches any value, usually used as the last case
3. Binding pattern
Uses an identifier to match and bind a value
main() {
let x = -10
let y = match (x) {
case 0 => "zero"
case n => "x is not zero and x = ${n}" // n 绑定匹配的值
}
println(y)
}
4. Tuple pattern
Used to match tuple values
main() {
let tv = ("Alice", 24)
let s = match (tv) {
case ("Bob", age) => "Bob is ${age} years old"
case ("Alice", age) => "Alice is ${age} years old" // age 是绑定模式
case (name, 100) => "${name} is 100 years old"
case (_, _) => "someone"
}
println(s)
}
5. Type pattern
Determines whether the runtime type is a subtype of a certain type
main() {
var d = Derived()
var r = match (d) {
case b: Base => b // b 是类型模式,匹配 Base 类型
case _ => 0
}
println("r = ${r}")
}
6. enum pattern
Used to match instances of enum types
enum TimeUnit {
| Year(UInt64)
| Month(UInt64)
}
main() {
let x = Year(2)
let s = match (x) {
case Year(n) => "x has ${n * 12} months" // 匹配
case TimeUnit.Month(n) => "x has ${n} months" // TimeUnit.Month 是完整路径
}
println(s)
}
Pattern nesting
⚠️ Important: Tuple patterns and enum patterns can nest any pattern
enum TimeUnit {
| Year(UInt64)
| Month(UInt64)
}
enum Command {
| SetTimeUnit(TimeUnit)
| GetTimeUnit
| Quit
}
main() {
let command = (SetTimeUnit(Year(2022)), SetTimeUnit(Year(2024)))
match (command) {
case (SetTimeUnit(Year(year)), _) => println("Set year ${year}")
case (_, SetTimeUnit(Month(month))) => println("Set month ${month}")
case _ => ()
}
}
Pattern Guard
After the pattern in case, you can use a where clause to add an additional conditional check (called a pattern guard).
Syntax:case 模式 where 条件 => 处理
⚠️ Important: Use the where keyword,not if
Example:
enum RGBColor {
| Red(Int16)
| Green(Int16)
| Blue(Int16)
}
main() {
let c = RGBColor.Green(-100)
let cs = match (c) {
case Red(r) where r < 0 => "Red = 0"
case Red(r) => "Red = ${r}"
case Green(g) where g < 0 => "Green = 0" // 匹配(因为 -100 < 0)
case Green(g) => "Green = ${g}"
case Blue(b) where b < 0 => "Blue = 0"
case Blue(b) => "Blue = ${b}"
}
println(cs) // 输出:Green = 0
}
Notes:
whereThe conditional expression after must be of typeBoolType- The pattern guard performs the conditional check after the pattern match succeeds
- Multiple cases can be arranged in order, matching from top to bottom
- ⚠️ Common mistake: Do not use
if, you should usewhere
Incorrect example:
match (value) {
case n if n > 0 => println("positive") // ❌ 编译错误:不是 if
case _ => println("other")
}
Correct way:
match (value) {
case n where n > 0 => println("positive") // ✅ 使用 where
case _ => println("other")
}
Example reference:examples/06_pattern_matching.cj
2.7 Option type
Definition
enum Option<T> {
| Some(T) // 有值
| None // 无值
}
Use cases
Use it when you need to indicate that a certain type may or may not have a value.
Common methods
1. Null coalescing operator ??
let optA: Option<Int64> = Option<Int64>.Some(42)
let a: Int64 = optA ?? 0 // 如果 optA 是 None,则使用默认值 0
2. Check whether there is a value
let optA: Option<Int64> = Option<Int64>.Some(42)
if (optA.isSome()) {
println("有值")
}
if (optA.isNone()) {
println("无值")
}
3. Extract the value via pattern matching
let optA: Option<Int64> = Option<Int64>.Some(42)
if (let Option<Int64>.Some(a) <- optA) {
println("值是: ${a}")
} else {
println("无值")
}
4. Short-circuit return
func getValue(): Option<Int64> {
// ... 一些逻辑
return Option<Int64>.None
}
func process(): Int64 {
let optA = getValue()
let a = optA ?? return 0 // 如果是 None,直接返回 0
// 继续处理 a
a + 1
}
5. Short-circuit throw exception
func getValue(): Option<Int64> {
return Option<Int64>.None
}
func processOrThrow(): Int64 {
let optA = getValue()
let a = optA ?? throw Exception("值不存在")
// 继续处理 a
a
}
6. match expression handling
let optA: Option<Int64> = Option<Int64>.Some(42)
let result = match (optA) {
case Option<Int64>.Some(value) => "值是: ${value}"
case Option<Int64>.None => "无值"
}
Example reference:examples/07_option_type.cj
2.8 class type
Definition syntax
class ClassName {
// 成员变量
// 成员属性
// 静态初始化器
// 构造函数
// 成员函数
// 操作符函数
}
Example
class Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public func area() {
width * height
}
}
let rec = Rectangle(10, 20)
let l = rec.height // l = 20
Access modifiers
For members of a class (variables, properties, constructors, functions):
| Modifier | Meaning | Default |
|---|---|---|
private |
Visible within the class definition | ❌ |
internal |
Visible within the current package and subpackages (including subpackages of subpackages) | ✅ Default |
protected |
Visible to the current module and subclasses of the current class | ❌ |
public |
Visible both inside and outside the module | ❌ |
⚠️ Common mistake 11: The default access modifier for members is internal, not private or public。
Example reference:examples/08_class.cj
2.9 Unit testing
Test macros
@Test- Applied to a top-level function or class, converts it into a unit test class@TestCase- Marks a function within a test class as a test case@Fail- Marks a test failure
Assertion macros
Assert assertion (stops the test case on failure)
@Assert(leftExpr, rightExpr) // 判断相等
@Assert(condition: Bool) // 判断条件
Expect assertion (continues execution on failure)
@Expect(leftExpr, rightExpr) // 判断相等
@Expect(condition: Bool) // 判断条件
Complete example
@Test
class LexerTest {
@TestCase
func test() {
let a = 1
// 方式一:手动判断
if (a != 1) {
@Fail("a is not 1")
}
// 方式二:Assert 条件
@Assert(a != 1)
// 方式三:Assert 相等
@Assert(a, 1)
}
}
Example reference:examples/09_unit_test.cj
2.10 Error handling
Basic exception handling
// 抛出异常
throw Exception("错误信息")
// 捕获异常
try {
// 可能抛出异常的代码
} catch (e: ExceptionType) {
// 处理异常
}
Example reference:examples/10_error_handling.cj
2.11 Quick reference manual
Code block structure
main() {
// 条件判断(必须有括号)
if (条件) {
// ...
} else {
// ...
}
// 循环
while (条件) { }
do { } while (条件)
for (变量 in 序列) { }
// 模式匹配
match (值) {
case 模式 => 处理
case _ => 默认
}
}
Type suffix quick reference
| Type | Suffix |
|---|---|
| Integer | Int8, Int16, Int32, Int64, IntNative |
| Unsigned integer | UInt8, UInt16, UInt32, UInt64, UIntNative |
| Floating point | Float16, Float32, Float64 |
| Character | Rune |
| String | String |
| Tuple | (T1, T2, ...) |
| Array | Array<T> |
| Range | Range<T> |
| Function | (T1, T2) -> Rt |
Example reference:examples/11_quick_reference.cj
2.12 Collections
Cangjie provides a variety of collection types, suitable for different usage scenarios:
Collection types
1. Array - Fixed-size array
- Usage scenario: No need to add or remove elements, but need to modify elements
- Literal:
let arr: Array<String> = ["A", "B", "C"] - Features: Fixed size, contiguous memory, fast access speed
main() {
// 创建 Array
let arr: Array<String> = ["A", "B", "C"]
// 访问元素(使用下标)
println(arr[0]) // 输出: A
// 修改元素
arr[0] = "X"
println(arr[0]) // 输出: X
// 获取大小
println(arr.size) // 输出: 3
}
2. ArrayList - Dynamic array
- Usage scenario: Need to frequently add, delete, query, and modify elements
- Features: Variable size, supports dynamically adding and removing elements
import std.collection.ArrayList
main() {
// 创建 ArrayList
let list = ArrayList<Int64>()
// 添加元素(使用 add 方法)
list.add(1, at: 0) // 在位置 0 添加 1
list.add(2, at: 1) // 在位置 1 添加 2
// 或使用 add 添加整个数组
let arr = [3, 4, 5]
list.add(all: arr) // list: [1, 2, 3, 4, 5]
// 访问元素(使用 get 方法,返回 Option)
let value = list.get(0)
match (value) {
case Option<Int64>.Some(v) => println("First: ${v}")
case Option<Int64>.None => println("Not found")
}
// 或使用下标访问
println(list[0]) // 输出: 1
// 修改元素
list[0] = 10
// 删除元素
list.remove(at: 0) // 移除第一个元素
// 获取大小
println(list.size)
}
3. HashSet - Hash set
- Usage scenario: Want every element to be unique
- Features: Unique elements, fast lookup
import std.collection.HashSet
main() {
// 创建 HashSet
let set = HashSet<Int64>()
// 添加元素
set.add(1)
set.add(2)
set.add(3)
set.add(1) // 重复元素不会被添加
// 检查是否包含
if (set.contains(2)) {
println("包含 2")
}
// 获取大小
println(set.size) // 输出: 3
// 删除元素
set.remove(2)
}
4. HashMap - Hash map
- Usage scenario: Want to store a series of mapping relationships (key-value pairs)
- Literal:
let map: HashMap<String, Int> = HashMap(("A", 1), ("B", 2))orHashMap([("A", 1), ("B", 2)]) - Features: Key-value pair storage, fast lookup
import std.collection.HashMap
main() {
// 创建 HashMap(使用字面量)
let map: HashMap<String, Int64> = HashMap(
("A", 1),
("B", 2),
("C", 3)
)
// 或者使用方括号
let map2: HashMap<String, Int64> = HashMap([
("A", 1),
("B", 2),
("C", 3)
])
// 或者空 HashMap
let emptyMap = HashMap<String, Int64>()
// 添加元素(使用 add 方法)
emptyMap.add("D", 4)
// 访问元素(使用 get 方法,返回 Option)
let value = map.get("A")
match (value) {
case Option<Int64>.Some(v) => println("A = ${v}")
case Option<Int64>.None => println("Not found")
}
// 或使用下标访问
println(map["A"]) // 输出: 1
// 修改元素
map["A"] = 10
// 检查是否包含键
if (map.contains("B")) {
println("包含键 B")
}
// 删除元素
map.remove("C")
// 获取大小
println(map.size)
}
Common collection methods
Add element:
- Array: cannot add (fixed size)
- ArrayList:
add(element, at: index)oradd(all: array) - HashSet:
add(element) - HashMap:
add(key, value)ormap[key] = value
Access element:
- Array:
array[index]orarray.get(index) - ArrayList:
list[index]orlist.get(index)(returns Option) - HashMap:
map[key]ormap.get(key)(returns Option)
Modify elements:
- All collections support
[]modification via subscript
Delete elements:
- Array: cannot delete
- ArrayList:
remove(at: index) - HashSet:
remove(element) - HashMap:
remove(key)
Other common methods:
size- Get the number of elements (property)clear()- Clear all elements (ArrayList, HashSet, HashMap)contains(element)- Check whether it contains (HashSet, HashMap)get(index)- Get an element (ArrayList, HashMap, returns Option)
Example reference:examples/12_collections.cj
2.13 Packages
Cangjie uses packages to organize code, providing modularization and namespace management.
Package declaration
Basic syntax:
package package.name
Directory structure corresponds to package declaration:
src
└── directory_0
├── directory_1
│ ├── a.cj // package demo.directory_0.directory_1
│ └── b.cj // package demo.directory_0.directory_1
└── c.cj // package demo.directory_0
└── main.cj // package demo
Example:
// a.cj
package demo.directory_0.directory_1
public func funcA() {
println("Function A")
}
// b.cj
package demo.directory_0.directory_1
public func funcB() {
println("Function B")
}
// c.cj
package demo.directory_0
public func funcC() {
println("Function C")
}
// main.cj
package demo
import demo.directory_0.directory_1.{funcA, funcB}
import demo.directory_0.funcC
main() {
funcA() // 调用 demo.directory_0.directory_1.funcA
funcB() // 调用 demo.directory_0.directory_1.funcB
funcC() // 调用 demo.directory_0.funcC
}
Import
Basic syntax:
package currentPackage
import std.math.* // 导入 std.math 的所有内容
import package1.foo // 导入 package1.foo
import {package1.foo, package2.bar, package1.MyClass} // 导入多个
Usage example:
package demo
import std.math.*
import package1.helper
import {package1.MyClass, package2.Utils}
main() {
// 直接使用导入的方法和类型
let result = pow(2, 3) // std.math.pow
helper() // package1.helper
let obj = MyClass() // package1.MyClass
Utils.doSomething() // package2.Utils
}
Import methods
1. Import all (wildcard):
import std.math.*
// 可以直接使用 std.math 中的所有内容
let value = sqrt(16)
2. Import specific items:
import std.math.pi
// 只能使用 pi
println(pi)
3. Import multiple items:
import {std.math.sin, std.math.cos}
// 可以使用 sin 和 cos
4. Renamed import:
import std.math as math
let value = math.sqrt(16)
Access modifiers and packages
- private: visible only in the current file
- internal: visible in the current package and subpackages (default)
- public: visible both inside and outside the module
Example:
package demo.math
// 默认为 internal,仅 demo.math 及其子包可见
func internalFunc() {
println("internal")
}
// public,任何地方都可访问
public func publicFunc() {
println("public")
}
// private,仅当前文件可见
private func privateFunc() {
println("private")
}
Example reference:examples/13_package_import.cj
Chapter 3: Task Processing Flow
3.1 Code generation flow
Scenario 1: Basic code generation
Requirement identification:
- Identify variable type (let/var)
- Determine data type (Int64, String, Rune, etc.)
- Determine whether a type annotation is needed
Generation steps:
- Load the corresponding template (from the
templates/directory) - Apply syntax rules (refer to Chapter 2)
- ⚠️ Check the 19 common pitfalls
- Generate the final code
Example template:
// templates/basic/variable_declaration.cj.template
{{MODIFIER}} {{VARIABLE_NAME}}: {{TYPE}} = {{INIT_VALUE}}
Scenario 2: Function definition generation
Requirement identification:
- Function name and parameter list
- Parameter types and return type
- Whether named parameters are needed
- Whether default values are needed
Generation steps:
- Load the function definition template
- Determine whether parameters need the
varmodifier (default let) - Check the return value type
- Apply ⚠️ common pitfall 8 (function parameters are immutable by default)
Scenario 3: Control flow generation
Requirement identification:
- Conditional judgment/loop/pattern matching
- Whether parentheses are needed (⚠️ parentheses must be added)
- Whether pattern matching is needed
Generation steps:
- Choose the appropriate control structure
- ⚠️Ensure the conditional expression has parentheses (common pitfall 5)
- Check whether
break/continueis needed (labels are not supported, common pitfalls 6/7) - Generate code
Scenario 4: class definition generation
Requirement identification:
- Class name and member variables
- Constructor
- Member functions
- Access modifiers
Generation steps:
- Load the class template
- ⚠️Apply the default access modifier
internal(common pitfall 11) - Generate constructors
- Generate member functions
Scenario 5: Pattern matching generation
Requirement identification:
- match expression or if pattern matching
- Pattern type (constant/wildcard/binding/Tuple/enum/type)
- Whether nested patterns are needed
Generation steps:
- Select the matching pattern
- ⚠️Check case order (matched in order)
- ⚠️Ensure the wildcard is last (common mistake 9)
- Generate matching code
Scenario 6: Unit test generation
Requirement identification:
- Test classes and test cases
- Assertion type (Assert/Expect)
- Test data
Generation steps:
- Load the test template
- Add
@Testand@TestCasemacros - Select the assertion type
- Generate test code
3.2 Code analysis process
Scenario 1: Syntax correctness analysis
Analysis steps:
- Parse the code structure
- Check against the 11 syntax modules in Chapter 2
- ⚠️Check against the list of 19 common mistakes (Chapter 4)
- Provide correction suggestions
Check items:
- Whether variable declarations are correct (let/var)
- Whether type annotations are correct or inferable
- Whether conditional expressions have parentheses ⚠️
- Whether string interpolation uses
${}⚠️ - Whether function parameters are modified (or var is explicitly used) ⚠️
- Whether access modifiers meet requirements (default internal) ⚠️
Scenario 2: Potential error detection
Analysis steps:
- Identify code patterns that may trigger the 19 ⚠️ common mistakes
- Analyze runtime behavior
- Provide specific correction suggestions
Key checks:
- let variable shadowing ⚠️
- Rune conversion range ⚠️
- Raw string escaping ⚠️
- break/continue label jumps ⚠️
- Illegal Unit type operations ⚠️
- match case order ⚠️
Scenario 3: Code optimization suggestions
Analysis steps:
- Check code style and best practices
- Provide optimization suggestions
- Recommend appropriate templates and examples
Optimization items:
- Whether Lambda can be used to simplify the code
- Whether pattern matching can be used to replace complex if-else
- Whether the Option type should be used to handle possible null values
- Whether enum should be used to improve type safety
Chapter 4: Checklist of 19 ⚠️ common mistakes
Variable-related
-
⚠️
letdoes not support variable shadowing- Error: Redefining a let variable with the same name in the same scope
- Fix: Use a different variable name or use var
- Reference: Section 2.1
-
⚠️ Function parameters are
letimmutable by default- Error: Modifying parameter values inside a function
- Fix: Use
varto explicitly declare mutable parameters - Reference: Section 2.4
-
⚠️ The default access modifier for member variables is
internal- Error: mistakenly assuming the default is
private - Fix: explicitly declare access modifiers as required
- Reference: Section 2.8
- Error: mistakenly assuming the default is
Control Flow Related
-
⚠️ All conditional expressions must have parentheses
- Error:
if x > 0 { } - Fix:
if (x > 0) { } - Reference: Section 2.3
- Error:
-
⚠️ Not supported
goto- Error: using goto statements
- Fix: refactor the code structure, using functions or loop control
- Reference: Section 2.3
-
⚠️
break/continueLabel jumps are not supported- Error:
break outerLoop; - Fix: refactor the nested loop logic
- Reference: Section 2.3
- Error:
Type Conversion Related
-
⚠️ Rune to integer conversion must ensure it is within the valid Unicode range
- Error:
Rune(0xD800)(surrogate region characters) - Fix: ensure the value is within
[0x0000, 0xD7FF]or[0xE000, 0x10FFFF] - Reference: Section 2.2
- Error:
-
⚠️ Escape characters in raw string literals are not escaped
- Error: thinking
##"\n"##will produce a newline character - Fix: use a regular string
"\\n"or understand the characteristics of raw strings - Reference: Section 2.2
- Error: thinking
Pattern Matching Related
-
⚠️ The case of a match expression matches in order
- Error: placing a specific case after the wildcard
- Fix: place specific cases first, and place the wildcard
_last - Reference: Section 2.6
-
⚠️ Constant patterns do not support string interpolation
- Error: using
"Hello ${name}" - Fix: use binding patterns or runtime computation
- Reference: Section 2.6
- Error: using
String Related
- ⚠️ Interpolated strings use
${}rather than{}- Error:
"Hello {name}" - Fix:
"Hello ${name}" - Reference: Section 2.2
- Error:
Function Related
- ⚠️ Lambda expressions can be called immediately
- Note:
{ => 123 }()is valid syntax and executes the Lambda immediately - Reference: Section 2.4
- Note:
Type System Related
- ⚠️ The Unit type only supports assignment, equality, and inequality operations
- Error: performing other operations (such as arithmetic operations) on
()Perform other operations (such as arithmetic operations) - Fix: understand the limitations of the Unit type
- Reference: Section 2.2
- Error: performing other operations (such as arithmetic operations) on
Other
-
⚠️ A tuple requires at least two elements
- Error: defining a single-element tuple
- Fix: use a concrete type or add a second element
- Reference: Section 2.2
-
⚠️ The step of a range type cannot equal 0
- Error:
Range(1, 10, 0) - Fix: ensure step is non-zero
- Reference: Section 2.2
- Error:
-
⚠️ An enum must have at least one named constructor
- Error: defining an empty enum
- Fix: add at least one constructor
- Reference: Section 2.5
-
⚠️ The case of a match expression does not require
{}parentheses- Error:
case 1 => { println("1") } - Correction:
case 1 => println("1") - Reference: Section 2.6
- Error:
-
⚠️ The Option type is used to indicate that a value may or may not be present
- Note: Not all cases require Option; use it only when it is necessary to explicitly indicate that a value may be absent
- Reference: Section 2.7
-
⚠️ Duration and sleep in
std.coredo not need to be imported- Note: These are built-in types and functions and can be used directly
- Reference: Section 2.10
Chapter 5: Examples and Template Reference
5.1 Code Examples (examples/)
A total of 39 examples, categorized by difficulty and syntax module:
Basic Examples (01-15):
- 01_variable_declaration.cj - Variable Declaration
- 02_basic_types.cj - Basic Types
- 03_control_flow.cj - Control Flow
- 04_functions.cj - Functions
- 05_enum.cj - Enums
- 06_pattern_matching.cj - Pattern Matching
- 07_option_type.cj - Option Type
- 08_class.cj - class Type
- 09_unit_test.cj - Unit Testing
- 10_error_handling.cj - Error Handling
- 11_quick_reference.cj - Quick Reference Manual
- 12-15: More Basic Examples
Intermediate Examples (16-27):
- Lambda Expressions and Higher-Order Functions
- Complex Pattern Matching
- class Inheritance and Polymorphism
- Collection Operations
- Exception Handling
- Writing Test Cases
Advanced Examples (28-39):
- Comprehensive Application Cases
- Performance Optimization Techniques
- Best Practice Demonstrations
5.2 Code Templates (templates/)
Organized by scenario:
basic/:
- hello_world.cj.template
- package_structure.cj.template
- main_function.cj.template
functions/:
- function_definition.cj.template
- lambda.cj.template
- higher_order_function.cj.template
control_flow/:
- conditional_logic.cj.template
- loops.cj.template
- error_handling.cj.template
data_structures/:
- class_definition.cj.template
- enum_definition.cj.template
- collection_operations.cj.template
testing/:
- unit_test.cj.template
- test_case.cj.template
Chapter 6: Quality Control Standards
6.1 Code Generation Quality Checks
When generating code, you must ensure:
- ⚠️Conditional expressions all have parentheses
- ⚠️String interpolation uses
${} - ⚠️Function parameters are not modified (or var is explicitly used)
- ⚠️Access modifiers meet requirements (default internal)
- Type annotations are correct or can be inferred
- Pattern matching covers all cases
- ⚠️None of the 19 common pitfalls are violated
6.2 Code Analysis Quality Checks
When analyzing code, you must provide:
- Check against the 11 syntax modules
- ⚠️Check against the 19 common pitfalls
- Type system consistency verification
- Provide specific correction suggestions
- Label common pitfall numbers (e.g., ⚠️Common Pitfall 5)
6.3 Response Quality Standards
- Accuracy: Syntax rules must be correct
- Completeness: Cover all relevant syntax points
- Practicality: Provide executable code examples
- Readability: Add clear comments and explanations
- ⚠️Common Pitfall Labeling: Clearly label the 19 common pitfalls
Chapter 7: MCP Documentation Integration
7.1 MCP Tool Usage Strategy
Priority:
- This SKILL.md(Core Syntax Manual)
- reference/(Detailed Reference Manual)
- MCP Documentation(Official Complete Documentation)
Trigger Conditions:
- Query standard library APIs (std, stdx)
- Query advanced features (generics, concurrency, macros, etc.)
- Query the latest features in the official documentation
- Need more detailed explanations and examples
7.2 MCP Tool List
Currently available MCP tools:
-
search_documents - Search Cangjie Documentation
- Purpose: Search related documentation by keyword
- Example: Query "lambda closure higher-order function"
-
get_document_content - Get Document Content
- Purpose: Get the complete content of the specified document
- Supports retrieval by section (section parameter)
-
list_documents - List Documents
- Purpose: Browse the document structure
- Supports path navigation (similar to the ls command)
-
get_document_overview - Get Document Overview
- Purpose: View the category structure and navigation tree
- Supports tree view (view_type="tree")
7.3 Usage Examples
# 查询lambda相关文档
search_documents(query="lambda closure")
# 获取某个文档的特定章节
get_document_content(
doc_id="manual_source_zh_cn_functions",
section="lambda"
)
# 浏览标准库结构
list_documents(category="libs", subcategory="std")
7.4 Document Categories
- manual - Basic Manual
- libs - Standard Library (std, stdx)
- ohos - OpenHarmony Documentation
- tools - Development Tools
- extra - Additional Content
Appendix A: Quick Reference
A.1 Keywords
let、var、if、else、while、do、for、match、case、func、class、enum、init、return、package、import、public、private、protected、internal、static
A.2 Operators
- Arithmetic: addition +, subtraction -, multiplication *, division /, modulo %
- Comparison: equal ==, not equal !=, less than <, greater than >, less than or equal <=, greater than or equal >=
- Logic: and &&, or ||, not !
- Range: .. half-open interval, ..= closed interval
- Pattern matching: pattern binding <-, case separator =>
A.3 Commonly Used Standard Libraries
std.core- Core types and functionsstd.io- Input and outputstd.collection- Collection typesstd.time- Time and date
Appendix B: Version History
- v1.0.0 (2025-01-07) - Initial Version
- Includes 11 core syntax modules
- 39 code examples
- 19 ⚠️ common pitfalls
- Complete code generation and analysis workflow
Appendix C: Contribution Guide
Contributions of new examples, templates, and improvement suggestions are welcome!
How to Contribute:
- Fork the repository
- Create a feature branch
- Submit changes
- Open a Pull Request
Quality Requirements:
- Code must comply with Cangjie syntax specifications
- Examples must have clear comments
- Templates must have usage instructions
- Documentation must indicate relevant syntax modules and common pitfalls
Appendix D: License
MIT License
End
Documentation Maintenance: Cangjie Language Community Last Updated:2025-01-07 Version:v1.0.0