Skip to content

Commit ec8b6db

Browse files
committed
Add proof of concept for ASTGen.
1 parent 681eacd commit ec8b6db

File tree

153 files changed

+346
-171
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+346
-171
lines changed

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
3+
project(SwiftSyntax LANGUAGES Swift)
4+
5+
set(min_supported_swift_version 5.7)
6+
if(CMAKE_Swift_COMPILER_VERSION VERSION_LESS "${min_supported_swift_version}")
7+
message(FATAL_ERROR "Outdated Swift compiler: "
8+
"Swift ${min_supported_swift_version} or newer is required.")
9+
endif()
10+
11+
add_subdirectory(Sources)

Changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Note: This is in reverse chronological order, so newer entries are added to the
77
* To clarify that the edits passed to `IncrementalParseTransition` are applied concurrently, introduce a new `ConcurrentEdit` type that provides the guarantee and allows translation of sequentially applied edits to the expected concurrent form.
88
* The `SwiftSyntaxParser` type and a few related types now live in their own module (also named `SwiftSyntaxParser`). This allows using `SwiftSyntax` for code generation purposes without having a compatible `_InternalSwiftSyntaxParser.dylib` around.
99

10-
`import SwiftSyntaxParser` where necessary.
10+
`import SSwiftSyntaxParser` where necessary.
1111
* `DiagnosticEngine` has been removed. Instead, `SyntaxParser` takes a closure through which it emits parser diagnostics. Depending on your needs, use the closure to handle the diagnostics or write + hook up your own diagnostics engine.
1212

1313
## Swift 5.3

Examples/AddOneToIntegerLiterals.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import SwiftSyntax
2-
import SwiftSyntaxParser
1+
import SSwiftSyntax
2+
import SSwiftSyntaxParser
33
import Foundation
44

55
/// AddOneToIntegerLiterals will visit each token in the Syntax tree, and

Package.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ let package = Package(
4646
],
4747
products: [
4848
.library(name: "SwiftParser", type: .static, targets: ["SwiftParser"]),
49-
.library(name: "SwiftSyntax", type: .static, targets: ["SwiftSyntax"]),
49+
.library(name: "SSwiftSyntax", type: .static, targets: ["SSwiftSyntax"]),
5050
.library(name: "SwiftSyntaxParser", type: .static, targets: ["SwiftSyntaxParser"]),
5151
.library(name: "SwiftSyntaxBuilder", type: .static, targets: ["SwiftSyntaxBuilder"]),
5252
.executable(name: "generate-swift-syntax-builder", targets: ["generate-swift-syntax-builder"])
@@ -60,10 +60,10 @@ let package = Package(
6060
),
6161
.target(
6262
name: "SwiftDiagnostics",
63-
dependencies: ["SwiftSyntax"]
63+
dependencies: ["SSwiftSyntax"]
6464
),
6565
.target(
66-
name: "SwiftSyntax",
66+
name: "SSwiftSyntax",
6767
dependencies: ["_CSwiftSyntax"],
6868
exclude: [
6969
"Misc.swift.gyb",
@@ -88,15 +88,15 @@ let package = Package(
8888
),
8989
.target(
9090
name: "SwiftSyntaxBuilder",
91-
dependencies: ["SwiftSyntax"],
91+
dependencies: ["SSwiftSyntax"],
9292
exclude: [
9393
"gyb_helpers",
9494
"ResultBuilders.swift.gyb",
9595
]
9696
),
9797
.target(
9898
name: "SwiftSyntaxParser",
99-
dependencies: ["SwiftSyntax"],
99+
dependencies: ["SSwiftSyntax"],
100100
exclude: [
101101
"NodeDeclarationHash.swift.gyb",
102102
"Serialization.swift.gyb",
@@ -105,22 +105,22 @@ let package = Package(
105105
),
106106
.target(
107107
name: "_SwiftSyntaxTestSupport",
108-
dependencies: ["SwiftSyntax"]
108+
dependencies: ["SSwiftSyntax"]
109109
),
110110
.target(
111111
name: "SwiftParser",
112-
dependencies: ["SwiftDiagnostics", "SwiftSyntax"],
112+
dependencies: ["SwiftDiagnostics", "SSwiftSyntax"],
113113
exclude: [
114114
"README.md"
115115
]
116116
),
117117
.executableTarget(
118118
name: "lit-test-helper",
119-
dependencies: ["SwiftSyntax", "SwiftSyntaxParser"]
119+
dependencies: ["SSwiftSyntax", "SwiftSyntaxParser"]
120120
),
121121
.executableTarget(
122122
name: "swift-parser-test",
123-
dependencies: ["SwiftDiagnostics", "SwiftSyntax", "SwiftParser", .product(name: "ArgumentParser", package: "swift-argument-parser")]
123+
dependencies: ["SwiftDiagnostics", "SSwiftSyntax", "SwiftParser", .product(name: "ArgumentParser", package: "swift-argument-parser")]
124124
),
125125
.executableTarget(
126126
name: "generate-swift-syntax-builder",
@@ -148,7 +148,7 @@ let package = Package(
148148
),
149149
.testTarget(
150150
name: "SwiftSyntaxTest",
151-
dependencies: ["SwiftSyntax", "_SwiftSyntaxTestSupport"]
151+
dependencies: ["SSwiftSyntax", "_SwiftSyntaxTestSupport"]
152152
),
153153
.testTarget(
154154
name: "SwiftSyntaxBuilderTest",
@@ -161,7 +161,7 @@ let package = Package(
161161
),
162162
.testTarget(
163163
name: "PerformanceTest",
164-
dependencies: ["SwiftSyntax", "SwiftSyntaxParser", "SwiftParser"],
164+
dependencies: ["SSwiftSyntax", "SwiftSyntaxParser", "SwiftParser"],
165165
exclude: ["Inputs"]
166166
),
167167
.testTarget(

Sources/ASTGen/ASTGen.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import SwiftParser
2+
import SSwiftSyntax
3+
4+
import CASTBridging
5+
6+
extension Array {
7+
public func withBridgedArrayRef<T>(_ c: (BridgedArrayRef) -> T) -> T {
8+
withUnsafeBytes { buf in
9+
c(BridgedArrayRef(data: buf.baseAddress!, numElements: count))
10+
}
11+
}
12+
}
13+
14+
extension UnsafePointer {
15+
public var raw: UnsafeMutableRawPointer {
16+
UnsafeMutableRawPointer(mutating: self)
17+
}
18+
}
19+
20+
struct ASTGenVisitor: SyntaxTransformVisitor {
21+
let ctx: UnsafeMutableRawPointer
22+
let base: UnsafePointer<CChar>
23+
24+
public func visit(_ node: FunctionCallExprSyntax) -> [UnsafeMutableRawPointer] {
25+
let args = visit(node.argumentList).first!
26+
// TODO: hack
27+
let callee = visit(node.calledExpression.as(IdentifierExprSyntax.self)!).first!
28+
let call = SwiftFunctionCallExpr_create(self.ctx, callee, args)
29+
30+
return [call]
31+
}
32+
33+
public func visit(_ node: IdentifierExprSyntax) -> [UnsafeMutableRawPointer] {
34+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
35+
36+
var text = node.identifier.text
37+
let id = text.withUTF8 { buf in
38+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
39+
}
40+
41+
return [SwiftIdentifierExpr_create(ctx, id, loc)]
42+
}
43+
44+
public func visit(_ node: TupleExprElementListSyntax) -> [UnsafeMutableRawPointer] {
45+
let elements = node.map { visit($0).first! }
46+
47+
// TODO: find correct paren locs.
48+
let lParenLoc = self.base.advanced(by: node.position.utf8Offset).raw
49+
let rParenLoc = self.base.advanced(by: node.position.utf8Offset).raw
50+
51+
return [elements.withBridgedArrayRef { elementsRef in
52+
SwiftTupleExpr_create(self.ctx, lParenLoc, elementsRef, rParenLoc)
53+
}]
54+
}
55+
56+
public func visit(_ node: StringLiteralExprSyntax) -> [UnsafeMutableRawPointer] {
57+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
58+
var segment = node.segments.first!.as(StringSegmentSyntax.self)!.content.text
59+
return segment.withUTF8 { buf in
60+
let id = SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
61+
return [SwiftStringLiteralExpr_create(ctx, id, buf.count, loc)]
62+
}
63+
}
64+
}
65+
66+
@_cdecl("parseTopLevelSwift")
67+
public func parseTopLevelSwift(
68+
buffer: UnsafePointer<CChar>, ctx: UnsafeMutableRawPointer
69+
) -> UnsafeMutableRawPointer {
70+
let syntax = try! Parser.parse(source: String(cString: buffer))
71+
let count = ASTGenVisitor(ctx: ctx, base: buffer).visit(syntax)
72+
return count.first!
73+
}

Sources/ASTGen/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
add_library(ASTGen
2+
ASTGen.swift)
3+
4+
# TOOD: error when SWIFT_SOURCE_DIR is not defined.
5+
6+
target_compile_options(ASTGen PUBLIC
7+
"-enable-library-evolution"
8+
"-emit-module-interface"
9+
"-g"
10+
# Includes we shouldn't need
11+
"-I${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
12+
"-I${CMAKE_CURRENT_BINARY_DIR}/../SwiftParser"
13+
"-I${CMAKE_CURRENT_BINARY_DIR}/../SwiftDiagnostics")
14+
15+
target_include_directories(SwiftDiagnostics PUBLIC
16+
"${SWIFT_SOURCE_DIR}/include/"
17+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
18+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftParser"
19+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftDiagnostics")
20+
21+
target_link_directories(SwiftDiagnostics PUBLIC
22+
"${SWIFT_SOURCE_DIR}/include/"
23+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
24+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftParser"
25+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftDiagnostics")
26+
27+
add_dependencies(ASTGen SwiftParser)

Sources/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
add_subdirectory(SwiftSyntax)
2+
add_subdirectory(SwiftDiagnostics)
3+
add_subdirectory(SwiftParser)
4+
add_subdirectory(ASTGen)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
file(GLOB_RECURSE _LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES
2+
"${CMAKE_CURRENT_SOURCE_DIR}/*.swift")
3+
set(LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES)
4+
foreach(source ${_LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES})
5+
file(TO_CMAKE_PATH "${source}" source)
6+
list(APPEND LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES ${source})
7+
endforeach()
8+
message(STATUS "Using Swift Parser library for libswift SwiftParser (${SWIFT_SYNTAX_SOURCE_DIR}).")
9+
10+
add_library(SwiftDiagnostics
11+
"${LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES}")
12+
add_dependencies(SwiftDiagnostics SSwiftSyntax)
13+
14+
target_include_directories(SwiftDiagnostics PUBLIC
15+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
16+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftParser")
17+
18+
target_link_directories(SwiftDiagnostics PUBLIC
19+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
20+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftParser")

Sources/SwiftDiagnostics/Diagnostic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SwiftSyntax
13+
import SSwiftSyntax
1414

1515
public struct Diagnostic: CustomDebugStringConvertible {
1616
/// The message that should be displayed to the user

Sources/SwiftDiagnostics/FixIt.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SwiftSyntax
13+
import SSwiftSyntax
1414

1515
/// Types conforming to this protocol represent Fix-It messages that can be
1616
/// shown to the client.

Sources/SwiftParser/Attributes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
extension Parser {
1616
mutating func parseAttributeList() -> RawAttributeListSyntax? {

Sources/SwiftParser/Availability.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
extension Parser {
1616
enum AvailabilitySpecSource {

Sources/SwiftParser/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
file(GLOB_RECURSE _LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES
2+
"${CMAKE_CURRENT_SOURCE_DIR}/*.swift")
3+
set(LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES)
4+
foreach(source ${_LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES})
5+
file(TO_CMAKE_PATH "${source}" source)
6+
list(APPEND LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES ${source})
7+
endforeach()
8+
message(STATUS "Using Swift Parser library for libswift SwiftParser (${SWIFT_SYNTAX_SOURCE_DIR}).")
9+
10+
add_library(SwiftParser
11+
"${LIBSWIFT_SWIFT_SYNTAX_PARSER_SOURCES}")
12+
add_dependencies(SwiftParser SSwiftSyntax)
13+
add_dependencies(SwiftParser SwiftDiagnostics)
14+
15+
target_include_directories(SwiftDiagnostics PUBLIC
16+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
17+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftDiagnostics")
18+
19+
target_link_directories(SwiftDiagnostics PUBLIC
20+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
21+
"${CMAKE_CURRENT_BINARY_DIR}/../SwiftDiagnostics")
22+
23+
# TODO: why do we need to do this manually?
24+
target_compile_options(SwiftParser PUBLIC
25+
"-I${CMAKE_CURRENT_BINARY_DIR}/../SwiftSyntax"
26+
"-I${CMAKE_CURRENT_BINARY_DIR}/../SwiftDiagnostics")

Sources/SwiftParser/CharacterInfo.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ extension Unicode.Scalar {
9393
}
9494
}
9595

96-
#if swift(<5.7)
9796
extension UnsafeRawBufferPointer {
9897
/// Returns a typed buffer to the memory referenced by this buffer,
9998
/// assuming that the memory is already bound to the specified type.
@@ -122,7 +121,6 @@ extension UnsafeRawBufferPointer {
122121
return .init(start: s.assumingMemoryBound(to: T.self), count: n)
123122
}
124123
}
125-
#endif
126124

127125
private var InfoTable: CharacterInfoTable = (
128126
// 0 NUL 1 SOH 2 STX 3 ETX

Sources/SwiftParser/Declarations.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
extension Parser {
1616
@_spi(RawSyntax)

Sources/SwiftParser/Diagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SwiftDiagnostics
14-
import SwiftSyntax
14+
import SSwiftSyntax
1515

1616
extension UnexpectedNodesSyntax {
1717
func tokens(satisfying isIncluded: (TokenSyntax) -> Bool) -> [TokenSyntax] {

Sources/SwiftParser/Diagnostics/ParserDiagnosticMessages.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SwiftDiagnostics
14-
import SwiftSyntax
14+
import SSwiftSyntax
1515

1616
let diagnosticDomain: String = "SwiftParser"
1717

Sources/SwiftParser/Directives.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
extension Parser {
1616
/// Parse a conditional compilation block.

Sources/SwiftParser/Expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
extension Parser {
1616
public enum ExprFlavor {

Sources/SwiftParser/Lexer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
/// A lexical analyzer for the Swift programming language.
1616
///

Sources/SwiftParser/Lookahead.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
extension Parser {
1616
/// Token lookahead for the parser.

Sources/SwiftParser/LoopProgressCondition.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftSyntax
13+
@_spi(RawSyntax) import SSwiftSyntax
1414

1515
/// A type that can be used in place of a `while true` loop.
1616
/// See `evaluate` for more detail.

0 commit comments

Comments
 (0)