# Getting SwiftSyntax subtree using source range

**URL:** <https://forums.swift.org/t/getting-swiftsyntax-subtree-using-source-range/21830>\
**Category:** Source Tooling\
**Tags:** gsoc-2019\
**Created:** [March 20, 2019, 10:42am UTC](https://forums.swift.org/t/getting-swiftsyntax-subtree-using-source-range/21830 "2019-03-20T10:42:47Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Salman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/salman/32/6413_2.png) [@Salman](https://forums.swift.org/u/Salman)\
**Post date:** [March 20, 2019, 10:42am UTC](https://forums.swift.org/t/getting-swiftsyntax-subtree-using-source-range/21830/1 "2019-03-20T10:42:47Z")

</div>

It take the range the give the syntax node at given range

I have tested on this [swift-file](https://gist.github.com/Salman544/b8f560b47afb02db32cdb43de6b7ea94)

```
public func format<Output: TextOutputStream>(syntax: Syntax, assumingFileURL url: URL, to outputStream: inout Output
    ) throws

//let transformedSyntax = pipeline.visit(syntax) it does not seem to work with transformedSyntax

let types = [ImportDeclSyntax.self, StructDeclSyntax.self, ClassDeclSyntax.self, UnknownDeclSyntax.self, FunctionDeclSyntax.self, VariableDeclSyntax.self, IfStmtSyntax.self, SwitchStmtSyntax.self, ForInStmtSyntax.self, WhileStmtSyntax.self, RepeatWhileStmtSyntax.self, DoStmtSyntax.self, CatchClauseSyntax.self, FunctionCallExprSyntax.self] as [Any.Type]`
let range = NSRange(location: 2222, length: 34)

visit(node: syntax) { (syntax) in
    
    if types.contains(where: { $0 == type(of: syntax)}) {
        
        if let syntax = getSyntax(syntax, by: range) {
            prettyPrint(context: context, node: syntax, debugOptions: debugOptions)
        }
    } else if type(of: syntax) != CodeBlockItemSyntax.self {
        
        if let syntax = getSyntax(syntax, by: range) {
            prettyPrint(context: context, node: syntax, debugOptions: debugOptions)
        }
    }

func visit(node: Syntax, printNode: (Syntax) -> Void) {
    
    printNode(node)
    
    for child in node.children {
        visit(node: child, printNode: printNode)
    }
}

func getSyntax(_ syntax: Syntax, by range: NSRange) -> Syntax? {
    
    if syntax.contentLength.utf8Length == range.length && syntax.endPosition.utf8Offset == range.length + range.location {
        return syntax
    }
    
    return nil
}

```

if the range is `{2222, 34} it will give the let url = URL(string: "some url")!`  
range is `{934, 23} it will give the case apiError(ApiError)`  
range is ` {726, 54} it will give the`  
`struct ApiError: Decodable { let message: String }`

but it does not work with [transformedSyntax](https://github.com/google/swift/blob/format/Sources/SwiftFormat/SwiftFormatter.swift#L76)

`let transformedSyntax = pipeline.visit(syntax)`

**Another problem that i am confused with**

Suppose the range is ` {782, 22}` it should return this node  
`class NetworkService {`  
but it is not returning this node because the syntax tree does not have it

if we have this `struct`

` struct Sample { let message: String }`

The nodes will be

1. `struct`
2. `Sample`
3. `{ let message: String }`
4. `{`
5. `let message: String`
6. `let`
7. `message: String`
8. `message`
9. `: String`
10. `:`
11. `String`
12. `}`

How can i solve this problem ?

---

<div class="post-metadata">

**Author:** ![akyrtzi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/akyrtzi/32/4963_2.png) [@akyrtzi](https://forums.swift.org/u/akyrtzi)\
**Post date:** [March 20, 2019, 6:14pm UTC](https://forums.swift.org/t/getting-swiftsyntax-subtree-using-source-range/21830/2 "2019-03-20T18:14:58Z")

</div>

I've moved the post to a separate topic. @harlanhaskins could you provide some guidance ?
