Cannot convert value of type 'CodeBlockSyntax' to expected argument type 'Syntax'

Hi,

I tried to build an AST parser using swift-syntax on version 0.50000.0. When I came back to the project 2 years later and updated the version to 0.50300.0, I've got a lot of errors like

Cannot convert value of type 'CodeBlockSyntax' to expected argument type 'Syntax'

After that I found SyntaxProtocol and updated all references to it. However, after that, all my test cases failed.

A short example:

let type = Mirror(reflecting: stmt).subjectType
let staticType = FunctionDeclSyntax.self
let comp = stmt is FunctionDeclSyntax
let testObj = stmt as? FunctionDeclSyntax
if type == staticType {
    print(comp)
    print(testObj)
}

Result (the breakpoint is on the if)

What I'm doing wrong?

Xcode version Version 12.4 (12D4e)
Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)

Thanks!

Hi Sundarr,

for performance reasons, we are no longer using Swift's runtime type system to model the type of the syntax nodes. If you look into it, you’ll notice that all syntax nodes are structs and thus there is no inheritance hierarchy between the different nodes anymore (e.g. FunctionDeclSyntax doesn't inherit from Syntax) and thus Swift's built in is and as operators are no longer working.

Instead, we provide is and as functions on the syntax nodes, which should be used instead. The protocols should only be used to e.g. add a convenience method to all Decl nodes, not for passing nodes around.

The change log contains more details on the change, as well examples of how your code should be rewritten to be compatible with the new version of SwiftSyntax.

Your example should probably look as follows in the new SwiftSyntax version. Notice that we’re now using stmt.is and stmt.as instead of stmt as and stmt is.

let stmt = Syntax(SyntaxFactory.makeBlankFunctionDecl())
let type = Mirror(reflecting: stmt).subjectType
print(type)
let staticType = FunctionDeclSyntax.self
let comp = stmt.is(FunctionDeclSyntax.self)
let testObj = stmt.as(FunctionDeclSyntax.self)
if type == staticType {
    print(comp)
    print(testObj)
}

I hope this helps. If not, please let me know.

Hi Alex,

Thanks for your reply! It really helps. But I have one more question:

        if let ifStmt = ast.as(IfStmtSyntax.self) {
            let body: Syntax = ifStmt.body // error, also ifStmt.body.as(Syntax.self) method is missing
            let bodyProtocol: SyntaxProtocol = ifStmt.body // ok, but as(Syntax.self) method is also missing and only asProtocol(...) is present

Should I use Syntax or SyntaxProtocol to work with ASTs?

Hi Alex,

I've solved all my previous questions and everything works well now. But now I have one more question. How to debug my code using SwiftSyntax?

I'd like to hit a breakpoint and see a Syntax value converted to String. I tried to add an extension:

extension Syntax {
    public var description: String {
        return String(describing: self)
    }
    
    public var debugDescription : String {
        return description
    }
}

but it doesn't seem to work :(

Terms of Service

Privacy Policy

Cookie Policy