Swift Abstract Syntax Tree
Swift Abstract Syntax Tree is an initiative to parse Swift Programming Language in Swift itself. The output of this utility is the corresponding Abstract Syntax Tree (AST) of the source code.
The AST produced in this tool is intended to be consumed in various scenarios. For example, source-to-source transformations like swift-transform and linting tools like swift-lint.
Refactoring, code manipulation and optimization can leverage this AST as well.
Other ideas could be llvm-codegen or jvm-codegen (thinking about JSwift) that consumes the AST and converts them into binary or bytecode. I have some proof-of-concepts, llswift-poc and jswift-poc, respectively. If you are interested in working on the codegens, send me email ryuichi@yanagiba.org.
Swift Abstract Syntax Tree is part of Yanagiba Project. Yanagiba umbrella project is a toolchain of compiler modules, libraries, and utilities, written in Swift and for Swift.
A Work In Progress
The Swift Abstract Syntax Tree is still in active development. Though many features are implemented, some with limitations.
Pull requests for new features, issues and comments for existing implementations are welcomed.
Please also be advised that the Swift language is under rapid development, its syntax is not stable. So the details are subject to change in order to catch up as Swift evolves.
Requirements
Installation
Standalone Tool
To use it as a standalone tool, clone this repository to your local machine by
git clone https://github.com/yanagiba/swift-ast
Go to the repository folder, run the following command:
swift build -c release
This will generate a swift-ast
executable inside .build/release
folder.
swift
Path (Optional)
Adding to It is possible to copy the swift-ast
to the bin
folder of
your local Swift installation.
For example, if which swift
outputs
/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Then you can copy swift-ast
to it by
cp .build/release/swift-ast /Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-ast
Once you have done this, you can invoke swift-ast
by
calling swift ast
in your terminal directly.
Embed Into Your Project
Add the swift-ast dependency to Package.swift
:
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "MyPackage",
dependencies: [
.package(url: "https://github.com/yanagiba/swift-ast.git", from: "0.19.9")
],
targets: [
.target(name: "MyTarget", dependencies: ["SwiftAST+Tooling"]),
],
swiftLanguageVersions: [.v5]
)
Usage
Command Line
Simply append the path of the file to swift-ast
. It will dump the AST to the
console.
swift-ast path/to/Awesome.swift
Multiple files can be parsed with one call:
swift-ast path1/to1/foo.swift path2/to2/bar.swift ... path3/to3/main.swift
CLI Options
By default, the AST output is in a plain text format without indentation nor color highlight to the keywords. The output format can be changed by providing the following option:
-print-ast
: with indentation and color highlight-dump-ast
: in a tree structure-diagnostics-only
: no output other than the diagnostics information
In addition, -github-issue
can be provided as the first argument option,
and the program will try to generate a GitHub issue template with pre-filled
content for you.
Use AST in Your Code
Loop Through AST Nodes
import AST
import Parser
import Source
do {
let sourceFile = try SourceReader.read(at: filePath)
let parser = Parser(source: sourceFile)
let topLevelDecl = try parser.parse()
for stmt in topLevelDecl.statements {
// consume statement
}
} catch {
// handle errors
}
Traverse AST Nodes
We provide a pre-order depth-first traversal implementation on all AST nodes.
In order to use this, simply write your visitor by conforming ASTVisitor
protocol with the visit
methods for the AST nodes that are interested to you.
You can also write your own traversal implementations
to override the default behaviors.
Returning false
from traverse
and visit
methods will stop the traverse.
class MyVisitor : ASTVisitor {
func visit(_ ifStmt: IfStatement) throws -> Bool {
// visit this if statement
return true
}
}
let myVisitor = MyVisitor()
let topLevelDecl = MyParse.parse()
myVisitor.traverse(topLevelDecl)
Development
Build & Run
Building the entire project can be done by simply calling:
make
This is equivalent to
swift build
The dev version of the tool can be invoked by:
.build/debug/swift-ast path/to/file.swift
Running Tests
Compile and run the entire tests by:
make test
Contact
Ryuichi Sai
License
Swift Abstract Syntax Tree is available under the Apache License 2.0. See the LICENSE file for more info.