   }
 
   public func traverse(_ decl: ProtocolDeclaration) throws -> Bool {
-    return try visit(decl)
+    guard try visit(decl) else { return false }
+
+    for member in decl.members {
+      switch member {
+      case .method(let method):
+        for param in method.signature.parameterList {
+          if let defaultArg = param.defaultArgumentClause {
+            guard try traverse(defaultArg) else { return false }
+          }
+        }
+      case .initializer(let initializer):
+        for param in initializer.parameterList {
+          if let defaultArg = param.defaultArgumentClause {
+            guard try traverse(defaultArg) else { return false }
+          }
+        }
+      case .subscript(let member):
+        for param in member.parameterList {
+          if let defaultArg = param.defaultArgumentClause {
+            guard try traverse(defaultArg) else { return false }
+          }
+        }
+      case .compilerControl(let stmt):
+        guard try traverse(stmt) else { return false }
+      default:
+        continue
+      }
+    }
+
+    return true
   }
 
   public func traverse(_ decl: StructDeclaration) throws -> Bool {
-    return try visit(decl)
+    guard try visit(decl) else { return false }
+
+    for member in decl.members {
+      switch member {
+      case .declaration(let decl):
+        guard try traverse(decl) else { return false }
+      case .compilerControl(let stmt):
+        guard try traverse(stmt) else { return false }
+      }
+    }
+
+    return true
   }
 
   public func traverse(_ decl: SubscriptDeclaration) throws -> Bool {
-    return try visit(decl)
+    guard try visit(decl) else { return false }
+
+    for param in decl.parameterList {
+      if let defaultArg = param.defaultArgumentClause {
+        guard try traverse(defaultArg) else { return false }
+      }
+    }
+
+    switch decl.body {
+    case .codeBlock(let codeBlock):
+      return try traverse(codeBlock)
+    case .getterSetterBlock(let block):
+      guard try traverse(block.getter.codeBlock) else { return false }
+      if let setterBlock = block.setter?.codeBlock {
+        guard try traverse(setterBlock) else { return false }
+      }
+    default:
+      return true
+    }
+
+    return true
   }
 
   public func traverse(_ decl: TypealiasDeclaration) throws -> Bool {

  }

  public func traverse(_ decl: VariableDeclaration) throws -> Bool {
    return try visit(decl)
  }

  // Statements

  }

  public func traverse(_ decl: ClassDeclaration) throws -> Bool {
    guard try visit(decl) else { return false }

    for member in decl.members {
      switch member {
      case .declaration(let decl):
        guard try traverse(decl) else { return false }
      case .compilerControl(let stmt):
        guard try traverse(stmt) else { return false }
      }
    }

    return true
  }

  public func traverse(_ decl: ConstantDeclaration) throws -> Bool {
    guard try visit(decl) else { return false }

    for initializer in decl.initializerList {
      if let expr = initializer.initializerExpression {
        guard try traverse(expr) else { return false }
      }
    }

    return true
  }

  public func traverse(_ decl: DeinitializerDeclaration) throws -> Bool {
    guard try visit(decl) else { return false }

    return try traverse(decl.body)
  }

  public func traverse(_ decl: EnumDeclaration) throws -> Bool {
    guard try visit(decl) else { return false }

    for member in decl.members {
      switch member {
      case .declaration(let decl):
        guard try traverse(decl) else { return false }
      case .compilerControl(let stmt):
        guard try traverse(stmt) else { return false }
      default:
        continue // we don't traverse `union` and `rawValue` cases for now
      }
    }

    return true
  }

  public func traverse(_ decl: ExtensionDeclaration) throws -> Bool {
    guard try visit(decl) else { return false }

    for member in decl.members {
      switch member {
      case .declaration(let decl):
        guard try traverse(decl) else { return false }
      case .compilerControl(let stmt):
        guard try traverse(stmt) else { return false }
      }
    }

    return true
  }

  public func traverse(_ decl: FunctionDeclaration) throws -> Bool {
    guard try visit(decl) else { return false }

    for param in decl.signature.parameterList {
      if let defaultArg = param.defaultArgumentClause {
        guard try traverse(defaultArg) else { return false }
      }
    }

    if let body = decl.body {
      guard try traverse(body) else { return false }
    }

    return true
  }

  public func traverse(_ decl: ImportDeclaration) throws -> Bool {
