Appearance
| 1 | namespace Syntax.Process is | |
| 2 | use Source | |
| 3 | use Trees | |
| 4 | ||
| 5 | use Logging.Logger | |
| 6 | ||
| 7 | // Walks the AST, finds every `@suppress("slug", ...)` pragma, and | |
| 8 | // registers a suppression region on the logger for each slug | |
| 9 | // covering the wrapped definition or statement. Runs once per | |
| 10 | // source file in a build, re-runs per file on each analyse-mode | |
| 11 | // edit (the entry clears the file's regions before re-collecting). | |
| 12 | // | |
| 13 | // The regions are consulted by `DIAGNOSTICS_STORE.is_suppressed` | |
| 14 | // at warn / info / hint emission time, so every IDed diagnostic | |
| 15 | // benefits without per-pass push / pop wiring. | |
| 16 | class COLLECT_SUPPRESS_PRAGMAS: Visitor is | |
| 17 | _logger: Logger | |
| 18 | ||
| 19 | init(logger: Logger) is | |
| 20 | super.init() | |
| 21 | ||
| 22 | _logger = logger | |
| 23 | si | |
| 24 | ||
| 25 | apply(source_file: Compiler.SOURCE_FILE) is | |
| 26 | _logger.clear_suppression_regions(source_file.file_name) | |
| 27 | ||
| 28 | _register_file_pragmas(source_file) | |
| 29 | ||
| 30 | source_file.definition.walk(self) | |
| 31 | si | |
| 32 | ||
| 33 | // A `@@suppress("slug")` before everything else in the file covers | |
| 34 | // the whole file, including warnings reported at top-level | |
| 35 | // statements — positions no wrapped definition or statement can | |
| 36 | // span. | |
| 37 | _register_file_pragmas(source_file: Compiler.SOURCE_FILE) is | |
| 38 | let list = cast Trees.Definitions.LIST?(source_file.definition) | |
| 39 | ||
| 40 | if !list? then | |
| 41 | return | |
| 42 | fi | |
| 43 | ||
| 44 | let file_pragmas = list.file_pragmas | |
| 45 | ||
| 46 | if !file_pragmas? then | |
| 47 | return | |
| 48 | fi | |
| 49 | ||
| 50 | for pragma in file_pragmas do | |
| 51 | if !pragma.is_name_equal_to("suppress") then | |
| 52 | continue | |
| 53 | fi | |
| 54 | ||
| 55 | let whole_file = Source.LOCATION.whole_file(pragma.location.file_name) | |
| 56 | ||
| 57 | for i in 0..pragma.arguments.expressions.count do | |
| 58 | let slug = pragma.try_get_string_literal_at(i) | |
| 59 | ||
| 60 | if slug? /\ slug.length > 0 then | |
| 61 | _logger.register_suppression_region(whole_file, slug) | |
| 62 | fi | |
| 63 | od | |
| 64 | od | |
| 65 | si | |
| 66 | ||
| 67 | visit(pragma: Definitions.PRAGMA) is | |
| 68 | _register(pragma.pragma, pragma.location) | |
| 69 | si | |
| 70 | ||
| 71 | visit(pragma: Statements.PRAGMA) is | |
| 72 | _register(pragma.pragma, pragma.location) | |
| 73 | si | |
| 74 | ||
| 75 | _register(pragma: Pragmas.PRAGMA, region: LOCATION) is | |
| 76 | if !pragma.is_name_equal_to("suppress") then | |
| 77 | return | |
| 78 | fi | |
| 79 | ||
| 80 | for i in 0..pragma.arguments.expressions.count do | |
| 81 | let slug = pragma.try_get_string_literal_at(i) | |
| 82 | ||
| 83 | if slug? /\ slug.length > 0 then | |
| 84 | _logger.register_suppression_region(region, slug) | |
| 85 | fi | |
| 86 | od | |
| 87 | si | |
| 88 | si | |
| 89 | si |