Appearance
| 1 | namespace Logging is | |
| 2 | use Source; | |
| 3 | ||
| 4 | // Stores the lexical-scope diagnostic suppression regions registered | |
| 5 | // by `@suppress("code")` pragmas — see | |
| 6 | // `Syntax.Process.COLLECT_SUPPRESS_PRAGMAS`. Consulted by | |
| 7 | // `DIAGNOSTICS_STORE.is_suppressed(code, location)` on every IDed | |
| 8 | // warn / info / hint emission, so the lookup needs to be O(1) per | |
| 9 | // file plus O(N) over the regions in *this file* that mention | |
| 10 | // *this code*. | |
| 11 | // | |
| 12 | // We deliberately do not reuse `Semantic.LOCATION_MAP[T]`, which | |
| 13 | // indexes per line by replicating each entry across every line a | |
| 14 | // location spans. That layout is correct for symbol-use lookups | |
| 15 | // (one-line points stored, point-in-region queries) but would | |
| 16 | // duplicate a 100-line class-level `@suppress` into 100 buckets; | |
| 17 | // suppression regions are typically wide, so we want one stored | |
| 18 | // entry per registration. | |
| 19 | class SUPPRESSION_REGIONS is | |
| 20 | _by_file: Collections.MAP[string, Collections.MAP[string, Collections.LIST[LOCATION]]]; | |
| 21 | ||
| 22 | init() is | |
| 23 | _by_file = Collections.MAP[string, Collections.MAP[string, Collections.LIST[LOCATION]]](); | |
| 24 | si | |
| 25 | ||
| 26 | register(region: LOCATION, code: string) is | |
| 27 | let by_code: Collections.MAP[string, Collections.LIST[LOCATION]] mut; | |
| 28 | ||
| 29 | if !_by_file.try_get_value(region.file_name, by_code ref) then | |
| 30 | by_code = Collections.MAP[string, Collections.LIST[LOCATION]](); | |
| 31 | _by_file.add(region.file_name, by_code); | |
| 32 | fi | |
| 33 | ||
| 34 | let locations: Collections.LIST[LOCATION] mut; | |
| 35 | ||
| 36 | if !by_code.try_get_value(code, locations ref) then | |
| 37 | locations = Collections.LIST[LOCATION](); | |
| 38 | by_code.add(code, locations); | |
| 39 | fi | |
| 40 | ||
| 41 | locations.add(region); | |
| 42 | si | |
| 43 | ||
| 44 | clear(path: string) is | |
| 45 | _by_file.remove(path); | |
| 46 | si | |
| 47 | ||
| 48 | clear() is | |
| 49 | _by_file.clear(); | |
| 50 | si | |
| 51 | ||
| 52 | contains(code: string, location: LOCATION) -> bool is | |
| 53 | let by_code: Collections.MAP[string, Collections.LIST[LOCATION]] mut; | |
| 54 | ||
| 55 | if !_by_file.try_get_value(location.file_name, by_code ref) then | |
| 56 | return false; | |
| 57 | fi | |
| 58 | ||
| 59 | let locations: Collections.LIST[LOCATION] mut; | |
| 60 | ||
| 61 | if !by_code.try_get_value(code, locations ref) then | |
| 62 | return false; | |
| 63 | fi | |
| 64 | ||
| 65 | for region in locations do | |
| 66 | if region.contains(location) then | |
| 67 | return true; | |
| 68 | fi | |
| 69 | od | |
| 70 | ||
| 71 | return false; | |
| 72 | si | |
| 73 | si | |
| 74 | si |