doImport swaps out the import directive and its argument (a total of 2 tokens) with the tokens in the specified file or globbing pattern. When the function returns, the cursor is on the token before where the import directive was. In other words, call Next() to access the first token that was import
(nesting int)
| 354 | // other words, call Next() to access the first token that was |
| 355 | // imported. |
| 356 | func (p *parser) doImport(nesting int) error { |
| 357 | // syntax checks |
| 358 | if !p.NextArg() { |
| 359 | return p.ArgErr() |
| 360 | } |
| 361 | importPattern := p.Val() |
| 362 | if importPattern == "" { |
| 363 | return p.Err("Import requires a non-empty filepath") |
| 364 | } |
| 365 | |
| 366 | // grab remaining args as placeholder replacements |
| 367 | args := p.RemainingArgs() |
| 368 | |
| 369 | // set up a replacer for non-variadic args replacement |
| 370 | repl := makeArgsReplacer(args) |
| 371 | |
| 372 | // grab all the tokens (if it exists) from within a block that follows the import |
| 373 | var blockTokens []Token |
| 374 | for currentNesting := p.Nesting(); p.NextBlock(currentNesting); { |
| 375 | blockTokens = append(blockTokens, p.Token()) |
| 376 | } |
| 377 | // initialize with size 1 |
| 378 | blockMapping := make(map[string][]Token, 1) |
| 379 | if len(blockTokens) > 0 { |
| 380 | // use such tokens to create a new dispenser, and then use it to parse each block |
| 381 | bd := NewDispenser(blockTokens) |
| 382 | |
| 383 | // one iteration processes one sub-block inside the import |
| 384 | for bd.Next() { |
| 385 | currentMappingKey := bd.Val() |
| 386 | |
| 387 | if currentMappingKey == "{" { |
| 388 | return p.Err("anonymous blocks are not supported") |
| 389 | } |
| 390 | |
| 391 | // load up all arguments (if there even are any) |
| 392 | currentMappingTokens := bd.RemainingArgsAsTokens() |
| 393 | |
| 394 | // load up the entire block |
| 395 | for mappingNesting := bd.Nesting(); bd.NextBlock(mappingNesting); { |
| 396 | currentMappingTokens = append(currentMappingTokens, bd.Token()) |
| 397 | } |
| 398 | |
| 399 | blockMapping[currentMappingKey] = currentMappingTokens |
| 400 | } |
| 401 | } |
| 402 | |
| 403 | // splice out the import directive and its arguments |
| 404 | // (2 tokens, plus the length of args) |
| 405 | tokensBefore := p.tokens[:p.cursor-1-len(args)-len(blockTokens)] |
| 406 | tokensAfter := p.tokens[p.cursor+1:] |
| 407 | var importedTokens []Token |
| 408 | var nodes []string |
| 409 | |
| 410 | // first check snippets. That is a simple, non-recursive replacement |
| 411 | if p.definedSnippets != nil && p.definedSnippets[importPattern] != nil { |
| 412 | importedTokens = p.definedSnippets[importPattern] |
| 413 | if len(importedTokens) > 0 { |
no test coverage detected