Appearance
| 1 | namespace Analysis is | |
| 2 | use System.Exception | |
| 3 | use IO.Std | |
| 4 | ||
| 5 | use Collections.Iterable | |
| 6 | ||
| 7 | use Pair = Collections.KeyValuePair | |
| 8 | ||
| 9 | use IoC | |
| 10 | use Logging | |
| 11 | use Source | |
| 12 | use Compiler | |
| 13 | ||
| 14 | trait CommandHandler is | |
| 15 | handle(request: Protocol.Request, writer: IO.TextWriter) | |
| 16 | si | |
| 17 | ||
| 18 | trait SourceFileLookup is | |
| 19 | file_names: Iterable[string] | |
| 20 | find_source_file(file_name: string) -> SOURCE_FILE? | |
| 21 | si | |
| 22 | ||
| 23 | class ANALYSER is | |
| 24 | _log: IO.TextWriter | |
| 25 | _symbol_table: Semantic.SYMBOL_TABLE | |
| 26 | _timers: TIMERS | |
| 27 | ||
| 28 | _command_map: Collections.MAP[string,CommandHandler] | |
| 29 | _despatcher: COMMAND_DESPATCHER | |
| 30 | ||
| 31 | init( | |
| 32 | compiler: COMPILER, | |
| 33 | timers: TIMERS, | |
| 34 | symbol_table: Semantic.SYMBOL_TABLE, | |
| 35 | symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS, | |
| 36 | symbol_definition_locations: Semantic.SYMBOL_DEFINITION_LOCATIONS, | |
| 37 | completer: Syntax.Process.COMPLETER, | |
| 38 | signature_help: Syntax.Process.SIGNATURE_HELP, | |
| 39 | reader: IO.TextReader, | |
| 40 | writer: IO.TextWriter, | |
| 41 | library_files: Iterable[string], | |
| 42 | build_flags: GLOBAL_BUILD_FLAGS, | |
| 43 | watchdog: WATCHDOG | |
| 44 | ) is | |
| 45 | _log = Std.error | |
| 46 | _timers = timers | |
| 47 | _symbol_table = symbol_table | |
| 48 | ||
| 49 | _command_map = Collections.MAP[string,CommandHandler]() | |
| 50 | ||
| 51 | // Report the whole counter vocabulary from the first STATS | |
| 52 | // request, so a name that has not fired reads as zero rather | |
| 53 | // than as absent - the difference between "this path was not | |
| 54 | // taken" and "this build does not know that path". | |
| 55 | WORK_COUNTERS.declare_all(_timers) | |
| 56 | ||
| 57 | build_flags.want_compile_up_to_expressions = true | |
| 58 | ||
| 59 | let file_edited_handler = FILE_EDITED_HANDLER(watchdog, timers, compiler, build_flags, library_files, symbol_table) | |
| 60 | ||
| 61 | let edit_delta_handler = EDIT_DELTA_HANDLER(watchdog, file_edited_handler) | |
| 62 | ||
| 63 | let compile_handler = COMPILE_HANDLER(watchdog, timers, compiler, file_edited_handler, build_flags) | |
| 64 | ||
| 65 | let full_compiler = FULL_COMPILER(watchdog, compiler, file_edited_handler, timers) | |
| 66 | ||
| 67 | let despatcher = | |
| 68 | COMMAND_DESPATCHER( | |
| 69 | REQUEST_READER(reader), | |
| 70 | writer, | |
| 71 | _timers, | |
| 72 | _log, | |
| 73 | watchdog, | |
| 74 | full_compiler, | |
| 75 | build_flags.want_analysis_stats, | |
| 76 | build_flags.analysis_idle_timeout_seconds | |
| 77 | ) | |
| 78 | ||
| 79 | _despatcher = despatcher | |
| 80 | ||
| 81 | // Let a query that arrived mid-compile be answered at the | |
| 82 | // next per-file boundary of the compile-expressions walk, | |
| 83 | // rather than waiting for the whole compile. | |
| 84 | compiler.on_file_boundary = () is despatcher.serve_pending_queries(); si | |
| 85 | ||
| 86 | // Let an edit that arrives mid-compile cut that compile short, | |
| 87 | // rather than have it run on computing diagnostics the edit | |
| 88 | // has already made stale. | |
| 89 | compile_handler.is_superseded = () -> bool => despatcher.is_superseded() | |
| 90 | ||
| 91 | let hover_handler = HOVER_HANDLER(watchdog, timers, symbol_use_locations, full_compiler) | |
| 92 | let hover_map_handler = HOVERMAP_HANDLER(watchdog, symbol_use_locations) | |
| 93 | let semantic_tokens_handler = SEMANTICTOKENS_HANDLER(watchdog, symbol_use_locations, file_edited_handler, full_compiler) | |
| 94 | let inlay_hints_handler = INLAY_HINTS_HANDLER(watchdog) | |
| 95 | let definition_handler = DEFINITION_HANDLER(watchdog, symbol_use_locations, full_compiler) | |
| 96 | let declaration_handler = DECLARATION_HANDLER(watchdog, symbol_use_locations, full_compiler) | |
| 97 | let completion_handler = COMPLETION_HANDLER(watchdog, completer, file_edited_handler, full_compiler) | |
| 98 | let signature_handler = SIGNATURE_HANDLER(watchdog, signature_help, file_edited_handler) | |
| 99 | let symbols_handler = SYMBOLS_HANDLER(watchdog, symbol_definition_locations, file_edited_handler, full_compiler) | |
| 100 | let references_handler = REFERENCES_HANDLER(watchdog, symbol_use_locations, full_compiler) | |
| 101 | let implementation_handler = IMPLEMENTATION_HANDLER(watchdog, symbol_use_locations, full_compiler) | |
| 102 | let type_definition_handler = TYPE_DEFINITION_HANDLER(watchdog, symbol_use_locations, full_compiler) | |
| 103 | let rename_request_handler = RENAME_REQUEST_HANDLER(watchdog, symbol_use_locations, full_compiler) | |
| 104 | let restart_handler = RESTART_HANDLER(watchdog) | |
| 105 | let heap_check_handler = HEAP_CHECK_HANDLER(watchdog) | |
| 106 | let add_references_handler = ADD_REFERENCES_HANDLER(compiler) | |
| 107 | let stats_handler = STATS_HANDLER(timers) | |
| 108 | let set_open_files_handler = SET_OPEN_FILES_HANDLER(compiler, file_edited_handler) | |
| 109 | let format_handler = FORMAT_HANDLER(compiler, build_flags) | |
| 110 | let format_range_handler = FORMATRANGE_HANDLER(compiler, build_flags) | |
| 111 | let describe_type_handler = DESCRIBE_TYPE_HANDLER(watchdog, symbol_table, full_compiler) | |
| 112 | let code_actions_handler = CODE_ACTIONS_HANDLER(watchdog, file_edited_handler) | |
| 113 | ||
| 114 | _despatcher.add_handler(typeof Protocol.Request.EDIT, file_edited_handler) | |
| 115 | _despatcher.add_handler(typeof Protocol.Request.EDIT_DELTA, edit_delta_handler) | |
| 116 | _despatcher.add_handler(typeof Protocol.Request.SET_OPEN_FILES, set_open_files_handler) | |
| 117 | _despatcher.add_handler(typeof Protocol.Request.COMPILE, compile_handler) | |
| 118 | _despatcher.add_handler(typeof Protocol.Request.HOVER, hover_handler, true) | |
| 119 | _despatcher.add_handler(typeof Protocol.Request.HOVER_MAP, hover_map_handler, true) | |
| 120 | _despatcher.add_handler(typeof Protocol.Request.SEMANTIC_TOKENS, semantic_tokens_handler, true) | |
| 121 | _despatcher.add_handler(typeof Protocol.Request.INLAY_HINTS, inlay_hints_handler, true) | |
| 122 | _despatcher.add_handler(typeof Protocol.Request.DEFINITION, definition_handler, true) | |
| 123 | _despatcher.add_handler(typeof Protocol.Request.DECLARATION, declaration_handler, true) | |
| 124 | _despatcher.add_handler(typeof Protocol.Request.COMPLETE, completion_handler, true) | |
| 125 | _despatcher.add_handler(typeof Protocol.Request.SIGNATURE, signature_handler, true) | |
| 126 | _despatcher.add_handler(typeof Protocol.Request.SYMBOLS, symbols_handler, true) | |
| 127 | _despatcher.add_handler(typeof Protocol.Request.REFERENCES, references_handler) | |
| 128 | _despatcher.add_handler(typeof Protocol.Request.IMPLEMENTATION, implementation_handler) | |
| 129 | _despatcher.add_handler(typeof Protocol.Request.TYPE_DEFINITION, type_definition_handler, true) | |
| 130 | _despatcher.add_handler(typeof Protocol.Request.RENAME, rename_request_handler) | |
| 131 | _despatcher.add_handler(typeof Protocol.Request.RESTART, restart_handler) | |
| 132 | _despatcher.add_handler(typeof Protocol.Request.HEAP_CHECK, heap_check_handler) | |
| 133 | _despatcher.add_handler(typeof Protocol.Request.ADD_REFERENCES, add_references_handler) | |
| 134 | _despatcher.add_handler(typeof Protocol.Request.STATS, stats_handler, true) | |
| 135 | _despatcher.add_handler(typeof Protocol.Request.FORMAT, format_handler) | |
| 136 | _despatcher.add_handler(typeof Protocol.Request.FORMAT_RANGE, format_range_handler) | |
| 137 | _despatcher.add_handler(typeof Protocol.Request.DESCRIBE_TYPE, describe_type_handler) | |
| 138 | _despatcher.add_handler(typeof Protocol.Request.CODE_ACTIONS, code_actions_handler) | |
| 139 | si | |
| 140 | ||
| 141 | run() is | |
| 142 | do | |
| 143 | if !_despatcher.poll() then | |
| 144 | _log.write_line("ghūl: exiting") | |
| 145 | return | |
| 146 | fi | |
| 147 | od | |
| 148 | si | |
| 149 | si | |
| 150 | si |