Skip to content

Commit bfcb3d1

Browse files
committed
stash
1 parent 85ac0ab commit bfcb3d1

File tree

2 files changed

+194
-11
lines changed

2 files changed

+194
-11
lines changed

Sources/ASTGen/ASTGen.swift

Lines changed: 193 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ extension Array {
1111
}
1212
}
1313

14+
extension Collection {
15+
public var only: Element {
16+
if isEmpty { fatalError("Empty Collection.") }
17+
else if count > 1 { fatalError("More than one element") }
18+
return first!
19+
}
20+
}
21+
1422
extension UnsafePointer {
1523
public var raw: UnsafeMutableRawPointer {
1624
UnsafeMutableRawPointer(mutating: self)
@@ -20,16 +28,42 @@ extension UnsafePointer {
2028
struct ASTGenVisitor: SyntaxTransformVisitor {
2129
let ctx: UnsafeMutableRawPointer
2230
let base: UnsafePointer<CChar>
31+
32+
// TOOD: we need to be up updating this.
33+
var declContext: UnsafeMutableRawPointer
34+
35+
// TODO: this some how messes up the witness table when I uncomment it locally :/
36+
// public func visit<T>(_ node: T?) -> [UnsafeMutableRawPointer]? {
37+
// if let node = node { return visit(node) }
38+
// return nil
39+
// }
2340

41+
public func visit(_ node: SourceFileSyntax) -> [UnsafeMutableRawPointer] {
42+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
43+
var out = [UnsafeMutableRawPointer]()
44+
45+
for element in node.statements {
46+
let swiftASTNodes = visit(element).only
47+
if element.item.is(StmtSyntax.self) || element.item.is(ExprSyntax.self) {
48+
out.append(SwiftTopLevelCodeDecl_create(ctx, declContext, loc, swiftASTNodes))
49+
} else {
50+
assert(element.item.is(DeclSyntax.self))
51+
out.append(swiftASTNodes)
52+
}
53+
}
54+
55+
return out
56+
}
57+
2458
public func visit(_ node: FunctionCallExprSyntax) -> [UnsafeMutableRawPointer] {
25-
let args = visit(node.argumentList).first!
59+
let args = visit(node.argumentList).only
2660
// TODO: hack
27-
let callee = visit(node.calledExpression.as(IdentifierExprSyntax.self)!).first!
61+
let callee = visit(node.calledExpression).only
2862
let call = SwiftFunctionCallExpr_create(self.ctx, callee, args)
2963

3064
return [call]
3165
}
32-
66+
3367
public func visit(_ node: IdentifierExprSyntax) -> [UnsafeMutableRawPointer] {
3468
let loc = self.base.advanced(by: node.position.utf8Offset).raw
3569

@@ -40,9 +74,43 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
4074

4175
return [SwiftIdentifierExpr_create(ctx, id, loc)]
4276
}
77+
78+
public func visit(_ node: SimpleTypeIdentifierSyntax) -> [UnsafeMutableRawPointer] {
79+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
80+
81+
var text = node.name.text
82+
let id = text.withUTF8 { buf in
83+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
84+
}
85+
86+
return [SimpleIdentTypeRepr_create(ctx, loc, id)]
87+
}
88+
89+
public func visit(_ node: IdentifierPatternSyntax) -> [UnsafeMutableRawPointer] {
90+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
91+
92+
var text = node.identifier.text
93+
let id = text.withUTF8 { buf in
94+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
95+
}
96+
97+
return [SwiftIdentifierExpr_create(ctx, id, loc)]
98+
}
4399

100+
public func visit(_ node: MemberAccessExprSyntax) -> [UnsafeMutableRawPointer] {
101+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
102+
let base = visit(node.base!).only
103+
var nameText = node.name.text
104+
let name = nameText.withUTF8 { buf in
105+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
106+
}
107+
108+
return [UnresolvedDotExpr_create(ctx, base, loc, name, loc)]
109+
}
110+
111+
44112
public func visit(_ node: TupleExprElementListSyntax) -> [UnsafeMutableRawPointer] {
45-
let elements = node.map { visit($0).first! }
113+
let elements = node.map { visit($0).only }
46114

47115
// TODO: find correct paren locs.
48116
let lParenLoc = self.base.advanced(by: node.position.utf8Offset).raw
@@ -52,22 +120,137 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
52120
SwiftTupleExpr_create(self.ctx, lParenLoc, elementsRef, rParenLoc)
53121
}]
54122
}
123+
124+
public func visit(_ node: PatternBindingSyntax) -> [UnsafeMutableRawPointer] {
125+
let pattern = visit(node.pattern)
126+
let initializer = visit(node.initializer!)
127+
128+
return [pattern.only, initializer.only]
129+
}
130+
131+
public func visit(_ node: VariableDeclSyntax) -> [UnsafeMutableRawPointer] {
132+
let components = visit(node.bindings)
133+
assert(components.count == 2)
134+
let pattern = components.first!
135+
let initializer = components.last!
55136

137+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
138+
let isStateic = false // TODO: compute this
139+
let isLet = node.letOrVarKeyword.tokenKind == .letKeyword
140+
141+
// TODO: don't drop "initializer" on the floor.
142+
return [SwiftVarDecl_create(ctx, pattern, loc, isStateic, isLet, declContext)]
143+
}
144+
145+
public func visit(_ node: CodeBlockSyntax) -> [UnsafeMutableRawPointer] {
146+
let statements = visit(node.statements)
147+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
148+
149+
return [statements.withBridgedArrayRef { ref in
150+
BraceStmt_create(ctx, loc, ref, loc)
151+
}]
152+
}
153+
154+
public func visit(_ node: FunctionParameterSyntax) -> [UnsafeMutableRawPointer] {
155+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
156+
157+
let firstName: UnsafeMutableRawPointer?
158+
let secondName: UnsafeMutableRawPointer?
159+
160+
if let nodeFirstName = node.firstName {
161+
var text = nodeFirstName.text
162+
firstName = text.withUTF8 { buf in
163+
SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count).raw
164+
}
165+
} else {
166+
firstName = nil
167+
}
168+
169+
if let nodeSecondName = node.secondName {
170+
var text = nodeSecondName.text
171+
secondName = text.withUTF8 { buf in
172+
SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count).raw
173+
}
174+
} else {
175+
secondName = nil
176+
}
177+
178+
return [ParamDecl_create(ctx, loc, loc, firstName, loc, secondName, declContext)]
179+
}
180+
181+
public func visit(_ node: FunctionDeclSyntax) -> [UnsafeMutableRawPointer] {
182+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
183+
184+
var nameText = node.identifier.text
185+
let name = nameText.withUTF8 { buf in
186+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
187+
}
188+
189+
let body: UnsafeMutableRawPointer?
190+
if let nodeBody = node.body {
191+
body = visit(nodeBody).only
192+
} else {
193+
body = nil
194+
}
195+
196+
let returnType: UnsafeMutableRawPointer?
197+
if let output = node.signature.output {
198+
returnType = visit(output.returnType).only
199+
} else {
200+
returnType = nil
201+
}
202+
203+
let params = node.signature.input.parameterList.map { visit($0).only }
204+
return [params.withBridgedArrayRef { ref in
205+
FuncDecl_create(ctx, loc, false, loc, name, loc, false, nil, false, nil, loc, ref, loc, body, returnType, declContext)
206+
}]
207+
}
208+
209+
public func visit(_ node: IfStmtSyntax) -> [UnsafeMutableRawPointer] {
210+
let conditions = node.conditions.map { self.visit($0).only }
211+
assert(conditions.count == 1) // TODO: handle multiple conditions.
212+
213+
let body = visit(node.body).only
214+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
215+
216+
if let elseBody = node.elseBody, node.elseKeyword != nil {
217+
let elseStmt = visit(elseBody.data).only // TODO: don't use SyntaxData
218+
return [IfStmt_create(ctx, loc, conditions.only, body, loc,
219+
elseStmt)]
220+
}
221+
222+
return [IfStmt_create(ctx, loc, conditions.only, body, nil, nil)]
223+
}
224+
56225
public func visit(_ node: StringLiteralExprSyntax) -> [UnsafeMutableRawPointer] {
57226
let loc = self.base.advanced(by: node.position.utf8Offset).raw
58-
var segment = node.segments.first!.as(StringSegmentSyntax.self)!.content.text
227+
var segment = node.segments.only.as(StringSegmentSyntax.self)!.content.text
59228
return segment.withUTF8 { buf in
60229
let id = SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
61230
return [SwiftStringLiteralExpr_create(ctx, id, buf.count, loc)]
62231
}
63232
}
233+
234+
public func visit(_ node: IntegerLiteralExprSyntax) -> [UnsafeMutableRawPointer] {
235+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
236+
var segment = node.digits.text
237+
return segment.withUTF8 { buf in
238+
let id = SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
239+
return [SwiftIntegerLiteralExpr_create(ctx, id, buf.count, loc)]
240+
}
241+
}
64242
}
65243

66244
@_cdecl("parseTopLevelSwift")
67245
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!
246+
buffer: UnsafePointer<CChar>, declContext: UnsafeMutableRawPointer,
247+
ctx: UnsafeMutableRawPointer,
248+
outputContext: UnsafeMutableRawPointer,
249+
callback: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void
250+
) {
251+
let syntax = try! Parser.parse(source: String(cString: buffer))
252+
// dump(syntax)
253+
ASTGenVisitor(ctx: ctx, base: buffer, declContext: declContext)
254+
.visit(syntax)
255+
.forEach { callback($0, outputContext) }
73256
}

Sources/SwiftSyntax/Syntax.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/// Each node has accessors for its known children, and allows efficient
1515
/// iteration over the children through its `children` property.
1616
public struct Syntax: SyntaxProtocol, SyntaxHashable {
17-
let data: SyntaxData
17+
public let data: SyntaxData
1818

1919
public var _syntaxNode: Syntax {
2020
return self

0 commit comments

Comments
 (0)