or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

error-handling.mdexecution-engine.mdexecution.mdindex.mdlanguage.mdtype-system.mdutilities.mdvalidation.md

language.mddocs/

0

# Language Processing and AST

1

2

Parse GraphQL documents into Abstract Syntax Trees (AST), manipulate AST nodes, and work with GraphQL source code. This module provides lexical analysis, parsing capabilities, and visitor patterns for AST traversal and manipulation.

3

4

## Capabilities

5

6

### Document Parsing

7

8

Parse GraphQL documents, values, and types from string sources into structured AST representations.

9

10

```python { .api }

11

def parse(source: Union[str, Source]) -> DocumentNode

12

def parse_value(source: Union[str, Source]) -> ValueNode

13

def parse_const_value(source: Union[str, Source]) -> ConstValueNode

14

def parse_type(source: Union[str, Source]) -> TypeNode

15

```

16

17

**Parameters:**

18

- `source`: GraphQL source string or Source object to parse

19

20

**Returns:** Corresponding AST node type

21

22

#### Usage Examples

23

24

```python

25

from graphql import parse, parse_value, parse_type

26

27

# Parse a complete GraphQL document

28

query = '''

29

query GetUser($id: ID!) {

30

user(id: $id) {

31

name

32

email

33

}

34

}

35

'''

36

document = parse(query)

37

print(document.kind) # 'document'

38

print(len(document.definitions)) # 1

39

40

# Parse individual values

41

value_ast = parse_value('"hello world"')

42

print(value_ast.kind) # 'string_value'

43

print(value_ast.value) # 'hello world'

44

45

# Parse type expressions

46

type_ast = parse_type('[String!]!')

47

print(type_ast.kind) # 'non_null_type'

48

```

49

50

### Source Handling

51

52

Manage GraphQL source code with location tracking for enhanced error reporting and tooling.

53

54

```python { .api }

55

class Source:

56

def __init__(self, body: str, name: str = "GraphQL request", location_offset: SourceLocation = None)

57

58

body: str

59

name: str

60

location_offset: SourceLocation

61

62

def get_location(source: Source, position: int) -> SourceLocation

63

64

class SourceLocation:

65

line: int

66

column: int

67

```

68

69

#### Usage Example

70

71

```python

72

from graphql import Source, get_location, parse

73

74

source = Source('''

75

query {

76

user {

77

name

78

}

79

}

80

''', name="user-query.graphql")

81

82

# Parse with source tracking

83

document = parse(source)

84

85

# Get location information

86

location = get_location(source, 20)

87

print(f"Line {location.line}, Column {location.column}")

88

```

89

90

### Lexical Analysis

91

92

Tokenize GraphQL source code for custom parsing or analysis tools.

93

94

```python { .api }

95

class Lexer:

96

def __init__(self, source: Source)

97

98

def next_token(self) -> Token

99

def lookahead(self) -> Token

100

101

class Token:

102

kind: TokenKind

103

start: int

104

end: int

105

line: int

106

column: int

107

value: Optional[str]

108

prev: Optional[Token]

109

next: Optional[Token]

110

111

class TokenKind(Enum):

112

SOF = "StartOfFile"

113

EOF = "EndOfFile"

114

BANG = "!"

115

DOLLAR = "$"

116

AMP = "&"

117

PAREN_L = "("

118

PAREN_R = ")"

119

SPREAD = "..."

120

COLON = ":"

121

EQUALS = "="

122

AT = "@"

123

BRACKET_L = "["

124

BRACKET_R = "]"

125

BRACE_L = "{"

126

PIPE = "|"

127

BRACE_R = "}"

128

NAME = "Name"

129

INT = "Int"

130

FLOAT = "Float"

131

STRING = "String"

132

BLOCK_STRING = "BlockString"

133

COMMENT = "Comment"

134

```

135

136

#### Usage Example

137

138

```python

139

from graphql import Source, Lexer, TokenKind

140

141

source = Source('{ hello world }')

142

lexer = Lexer(source)

143

144

token = lexer.next_token()

145

while token.kind != TokenKind.EOF:

146

print(f"{token.kind.value}: {token.value}")

147

token = lexer.next_token()

148

```

149

150

### AST Printing

151

152

Convert AST nodes back to GraphQL string representation.

153

154

```python { .api }

155

def print_ast(ast: Node) -> str

156

```

157

158

#### Usage Example

159

160

```python

161

from graphql import parse, print_ast

162

163

document = parse('{ user { name email } }')

164

printed = print_ast(document)

165

print(printed) # Formatted GraphQL string

166

```

167

168

### AST Traversal and Manipulation

169

170

Visit and transform AST nodes using the visitor pattern.

171

172

```python { .api }

173

def visit(root: Node, visitor: Visitor, visitor_keys: Optional[VisitorKeyMap] = None) -> Any

174

175

class Visitor:

176

def enter(self, node: Node, key: Optional[str], parent: Optional[Node], path: List[Union[int, str]], ancestors: List[Node]) -> Optional[VisitorAction]

177

def leave(self, node: Node, key: Optional[str], parent: Optional[Node], path: List[Union[int, str]], ancestors: List[Node]) -> Optional[Union[VisitorAction, Node]]

178

179

class ParallelVisitor:

180

def __init__(self, visitors: Sequence[Visitor])

181

182

class VisitorAction(Enum):

183

BREAK = object()

184

SKIP = object()

185

REMOVE = object()

186

IDLE = object()

187

188

# Visitor action constants

189

BREAK: VisitorAction

190

SKIP: VisitorAction

191

REMOVE: VisitorAction

192

IDLE: VisitorAction

193

```

194

195

#### Usage Example

196

197

```python

198

from graphql import parse, visit, Visitor

199

200

class FieldNameCollector(Visitor):

201

def __init__(self):

202

self.field_names = []

203

204

def enter(self, node, key, parent, path, ancestors):

205

if node.kind == 'field':

206

self.field_names.append(node.name.value)

207

208

document = parse('{ user { name email posts { title } } }')

209

collector = FieldNameCollector()

210

visit(document, collector)

211

print(collector.field_names) # ['user', 'name', 'email', 'posts', 'title']

212

```

213

214

### Location and Error Reporting

215

216

Print formatted location information for debugging and error reporting.

217

218

```python { .api }

219

def print_location(location: Location) -> str

220

def print_source_location(source: Source, location: SourceLocation) -> str

221

222

class Location:

223

start: int

224

end: int

225

start_token: Token

226

end_token: Token

227

source: Source

228

```

229

230

## AST Node Types

231

232

### Base Node Types

233

234

```python { .api }

235

class Node:

236

kind: str

237

loc: Optional[Location]

238

239

class NameNode(Node):

240

kind: str = 'name'

241

value: str

242

243

class DocumentNode(Node):

244

kind: str = 'document'

245

definitions: List[DefinitionNode]

246

```

247

248

### Definition Nodes

249

250

```python { .api }

251

class DefinitionNode(Node):

252

pass

253

254

class ExecutableDefinitionNode(DefinitionNode):

255

pass

256

257

class OperationDefinitionNode(ExecutableDefinitionNode):

258

kind: str = 'operation_definition'

259

operation: OperationType

260

name: Optional[NameNode]

261

variable_definitions: Optional[List[VariableDefinitionNode]]

262

directives: Optional[List[DirectiveNode]]

263

selection_set: SelectionSetNode

264

265

class OperationType(Enum):

266

QUERY = 'query'

267

MUTATION = 'mutation'

268

SUBSCRIPTION = 'subscription'

269

270

class FragmentDefinitionNode(ExecutableDefinitionNode):

271

kind: str = 'fragment_definition'

272

name: NameNode

273

variable_definitions: Optional[List[VariableDefinitionNode]]

274

type_condition: NamedTypeNode

275

directives: Optional[List[DirectiveNode]]

276

selection_set: SelectionSetNode

277

```

278

279

### Selection Nodes

280

281

```python { .api }

282

class SelectionNode(Node):

283

pass

284

285

class FieldNode(SelectionNode):

286

kind: str = 'field'

287

alias: Optional[NameNode]

288

name: NameNode

289

arguments: Optional[List[ArgumentNode]]

290

directives: Optional[List[DirectiveNode]]

291

selection_set: Optional[SelectionSetNode]

292

293

class SelectionSetNode(Node):

294

kind: str = 'selection_set'

295

selections: List[SelectionNode]

296

297

class FragmentSpreadNode(SelectionNode):

298

kind: str = 'fragment_spread'

299

name: NameNode

300

directives: Optional[List[DirectiveNode]]

301

302

class InlineFragmentNode(SelectionNode):

303

kind: str = 'inline_fragment'

304

type_condition: Optional[NamedTypeNode]

305

directives: Optional[List[DirectiveNode]]

306

selection_set: SelectionSetNode

307

```

308

309

### Value Nodes

310

311

```python { .api }

312

class ValueNode(Node):

313

pass

314

315

class ConstValueNode(ValueNode):

316

pass

317

318

class VariableNode(ValueNode):

319

kind: str = 'variable'

320

name: NameNode

321

322

class IntValueNode(ConstValueNode):

323

kind: str = 'int_value'

324

value: str

325

326

class FloatValueNode(ConstValueNode):

327

kind: str = 'float_value'

328

value: str

329

330

class StringValueNode(ConstValueNode):

331

kind: str = 'string_value'

332

value: str

333

block: bool

334

335

class BooleanValueNode(ConstValueNode):

336

kind: str = 'boolean_value'

337

value: bool

338

339

class NullValueNode(ConstValueNode):

340

kind: str = 'null_value'

341

342

class EnumValueNode(ConstValueNode):

343

kind: str = 'enum_value'

344

value: str

345

346

class ListValueNode(ValueNode):

347

kind: str = 'list_value'

348

values: List[ValueNode]

349

350

class ObjectValueNode(ValueNode):

351

kind: str = 'object_value'

352

fields: List[ObjectFieldNode]

353

354

class ObjectFieldNode(Node):

355

kind: str = 'object_field'

356

name: NameNode

357

value: ValueNode

358

```

359

360

### Type Nodes

361

362

```python { .api }

363

class TypeNode(Node):

364

pass

365

366

class NamedTypeNode(TypeNode):

367

kind: str = 'named_type'

368

name: NameNode

369

370

class ListTypeNode(TypeNode):

371

kind: str = 'list_type'

372

type: TypeNode

373

374

class NonNullTypeNode(TypeNode):

375

kind: str = 'non_null_type'

376

type: Union[NamedTypeNode, ListTypeNode]

377

```

378

379

### Predicate Functions

380

381

```python { .api }

382

def is_definition_node(node: Node) -> bool

383

def is_executable_definition_node(node: Node) -> bool

384

def is_selection_node(node: Node) -> bool

385

def is_value_node(node: Node) -> bool

386

def is_const_value_node(node: Node) -> bool

387

def is_type_node(node: Node) -> bool

388

def is_type_system_definition_node(node: Node) -> bool

389

def is_type_definition_node(node: Node) -> bool

390

def is_type_system_extension_node(node: Node) -> bool

391

def is_type_extension_node(node: Node) -> bool

392

```