mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Diagnostic rendering was part of the data model: `Loc::FormatLocation` and `Loc::FormatSnippet` wrote plain text to a stream, so no capability, color, or terminal width could reach them. A diagnostic is now one message with labels, contexts, and location information attached, and `Diagnostics::Renderer` draws it into a `Terminal::Buffer`. The design is in `toolchain/docs/diagnostics_rendering.md` (#7668), authoring in `toolchain/docs/diagnostics.md`. Before: ``` example.carbon:6:3: error: 1 argument passed to function expecting 0 arguments Run0(1); ^~~~~~~ example.carbon:3:1: note: calling function declared here fn Run0() {} ^~~~~~~~~~~ ``` After: ``` error: 1 argument passed to function expecting 0 arguments ╭─┤ example.carbon:6:3 ┆ 3 │ fn Run0() {} · ─────┬───── · ╰──┤ calling function declared here ┆ -> 6 │ Run0(1); · ─────── ╰──────────── ``` `--no-diagnostic-snippets` gives a compact form, `example.carbon:6:3-9`. File tests use it; the rendering tests under `toolchain/diagnostics/testdata` ask for snippets. C++ interop diagnostics are data now rather than text Clang drew: `SemIR::ClangSourceLocId` names a `clang::SourceRange`, and a Clang location is marked as the point it names. `StreamConsumer` moves to a `:renderer` target that `:emitter` does not depend on, keeping `common/terminal` out of `consumer.h`. Capabilities come from the file behind the error stream, so tests get plain ASCII. `renderer_fuzzer` draws diagnostics built from fuzzer bytes with every capability combination, since a shape the renderer doesn't expect must never be why the compiler dies while reporting a problem. TODOs mark the follow-ups: line weights and crossing lines, wrapping that keeps a quoted type whole, and ordering diagnostics that share a byte offset. Also: `IncorrectExtension`'s hint moves into its message, since its note had no location of its own, and `strip_noise` in `check_diagnostics.py` blanks multi-line `#define`s instead of deleting them. Assisted-by: Claude Code
363 lines
10 KiB
Python
363 lines
10 KiB
Python
# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
# Exceptions. See /LICENSE for license information.
|
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
load("//bazel/cc_rules:defs.bzl", "cc_library")
|
|
load("//testing/fuzzing:rules.bzl", "cc_fuzz_test")
|
|
|
|
package(default_visibility = ["//visibility:public"])
|
|
|
|
filegroup(
|
|
name = "testdata",
|
|
srcs = glob(["testdata/**/*.carbon"]),
|
|
)
|
|
|
|
cc_library(
|
|
name = "context",
|
|
srcs = [
|
|
"action.cpp",
|
|
"call.cpp",
|
|
"class.cpp",
|
|
"context.cpp",
|
|
"control_flow.cpp",
|
|
"convert.cpp",
|
|
"cpp/access.cpp",
|
|
"cpp/call.cpp",
|
|
"cpp/constant.cpp",
|
|
"cpp/context.cpp",
|
|
"cpp/custom_type_mapping.cpp",
|
|
"cpp/diagnostic_consumer.cpp",
|
|
"cpp/export.cpp",
|
|
"cpp/generate_ast.cpp",
|
|
"cpp/impl_lookup.cpp",
|
|
"cpp/import.cpp",
|
|
"cpp/location.cpp",
|
|
"cpp/macros.cpp",
|
|
"cpp/operators.cpp",
|
|
"cpp/overload_resolution.cpp",
|
|
"cpp/thunk.cpp",
|
|
"cpp/type_mapping.cpp",
|
|
"custom_witness.cpp",
|
|
"decl_name_stack.cpp",
|
|
"deduce.cpp",
|
|
"deferred_definition_worklist.cpp",
|
|
"eval.cpp",
|
|
"eval_inst.cpp",
|
|
"facet_type.cpp",
|
|
"full_pattern_stack.cpp",
|
|
"function.cpp",
|
|
"generic.cpp",
|
|
"global_init.cpp",
|
|
"impl.cpp",
|
|
"impl_lookup.cpp",
|
|
"impl_validation.cpp",
|
|
"import.cpp",
|
|
"import_ref.cpp",
|
|
"inst.cpp",
|
|
"inst_block_stack.cpp",
|
|
"interface.cpp",
|
|
"keyword_modifier_set.cpp",
|
|
"literal.cpp",
|
|
"member_access.cpp",
|
|
"merge.cpp",
|
|
"modifiers.cpp",
|
|
"name_component.cpp",
|
|
"name_lookup.cpp",
|
|
"name_scope.cpp",
|
|
"operator.cpp",
|
|
"pattern.cpp",
|
|
"pattern_match.cpp",
|
|
"period_self.cpp",
|
|
"pointer_dereference.cpp",
|
|
"require_impls_stack.cpp",
|
|
"return.cpp",
|
|
"scope_stack.cpp",
|
|
"subst.cpp",
|
|
"thunk.cpp",
|
|
"type.cpp",
|
|
"type_completion.cpp",
|
|
"type_structure.cpp",
|
|
"unused.cpp",
|
|
],
|
|
hdrs = [
|
|
"action.h",
|
|
"call.h",
|
|
"class.h",
|
|
"context.h",
|
|
"control_flow.h",
|
|
"convert.h",
|
|
"cpp/access.h",
|
|
"cpp/call.h",
|
|
"cpp/constant.h",
|
|
"cpp/context.h",
|
|
"cpp/custom_type_mapping.h",
|
|
"cpp/diagnostic_consumer.h",
|
|
"cpp/diagnostic_listener.h",
|
|
"cpp/export.h",
|
|
"cpp/generate_ast.h",
|
|
"cpp/impl_lookup.h",
|
|
"cpp/import.h",
|
|
"cpp/location.h",
|
|
"cpp/macros.h",
|
|
"cpp/operators.h",
|
|
"cpp/overload_resolution.h",
|
|
"cpp/thunk.h",
|
|
"cpp/type_mapping.h",
|
|
"custom_witness.h",
|
|
"decl_introducer_state.h",
|
|
"decl_name_stack.h",
|
|
"deduce.h",
|
|
"deferred_definition_worklist.h",
|
|
"diagnostic_helpers.h",
|
|
"eval.h",
|
|
"eval_inst.h",
|
|
"facet_type.h",
|
|
"full_pattern_stack.h",
|
|
"function.h",
|
|
"generic.h",
|
|
"global_init.h",
|
|
"impl.h",
|
|
"impl_lookup.h",
|
|
"impl_validation.h",
|
|
"import.h",
|
|
"import_ref.h",
|
|
"inst.h",
|
|
"inst_block_stack.h",
|
|
"interface.h",
|
|
"keyword_modifier_set.h",
|
|
"lexical_lookup.h",
|
|
"literal.h",
|
|
"member_access.h",
|
|
"merge.h",
|
|
"modifiers.h",
|
|
"name_component.h",
|
|
"name_lookup.h",
|
|
"name_scope.h",
|
|
"operator.h",
|
|
"param_and_arg_refs_stack.h",
|
|
"pattern.h",
|
|
"pattern_match.h",
|
|
"pending_block.h",
|
|
"period_self.h",
|
|
"pointer_dereference.h",
|
|
"region_stack.h",
|
|
"require_impls_stack.h",
|
|
"return.h",
|
|
"scope_index.h",
|
|
"scope_stack.h",
|
|
"subst.h",
|
|
"thunk.h",
|
|
"type.h",
|
|
"type_completion.h",
|
|
"type_structure.h",
|
|
"unused.h",
|
|
],
|
|
deps = [
|
|
":core_identifier",
|
|
":node_stack",
|
|
"//common:array_stack",
|
|
"//common:check",
|
|
"//common:checked_save_and_restore",
|
|
"//common:concepts",
|
|
"//common:emplace_by_calling",
|
|
"//common:enum_mask_base",
|
|
"//common:find",
|
|
"//common:growing_range",
|
|
"//common:increment_scope",
|
|
"//common:map",
|
|
"//common:move_only",
|
|
"//common:ostream",
|
|
"//common:raw_string_ostream",
|
|
"//common:set",
|
|
"//common:vlog",
|
|
"//toolchain/base:canonical_value_store",
|
|
"//toolchain/base:index_base",
|
|
"//toolchain/base:int",
|
|
"//toolchain/base:kind_switch",
|
|
"//toolchain/base:shared_value_stores",
|
|
"//toolchain/base:value_ids",
|
|
"//toolchain/base:value_store",
|
|
"//toolchain/check:generic_region_stack",
|
|
"//toolchain/diagnostics:emitter",
|
|
"//toolchain/diagnostics:format_providers",
|
|
"//toolchain/lex:token_info",
|
|
"//toolchain/lex:token_kind",
|
|
"//toolchain/lex:tokenized_buffer",
|
|
"//toolchain/parse:node_kind",
|
|
"//toolchain/parse:tree",
|
|
"//toolchain/sem_ir:absolute_node_ref",
|
|
"//toolchain/sem_ir:clang_decl",
|
|
"//toolchain/sem_ir:cpp_file",
|
|
"//toolchain/sem_ir:diagnostic_loc_converter",
|
|
"//toolchain/sem_ir:expr_info",
|
|
"//toolchain/sem_ir:file",
|
|
"//toolchain/sem_ir:formatter",
|
|
"//toolchain/sem_ir:mangler",
|
|
"//toolchain/sem_ir:read_only_ast_source",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
"@llvm-project//clang:ast",
|
|
"@llvm-project//clang:basic",
|
|
"@llvm-project//clang:codegen",
|
|
"@llvm-project//clang:frontend",
|
|
"@llvm-project//clang:lex",
|
|
"@llvm-project//clang:parse",
|
|
"@llvm-project//clang:sema",
|
|
"@llvm-project//clang:tooling",
|
|
"@llvm-project//llvm:Support",
|
|
],
|
|
)
|
|
|
|
cc_library(
|
|
name = "dump",
|
|
srcs = ["dump.cpp"],
|
|
deps = [
|
|
":context",
|
|
"//common:check",
|
|
"//common:ostream",
|
|
"//common:raw_string_ostream",
|
|
"//toolchain/lex:dump",
|
|
"//toolchain/lex:tokenized_buffer",
|
|
"//toolchain/parse:dump",
|
|
"//toolchain/parse:tree",
|
|
"//toolchain/sem_ir:dump",
|
|
"//toolchain/sem_ir:file",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
],
|
|
# Always link dump methods.
|
|
alwayslink = 1,
|
|
)
|
|
|
|
cc_library(
|
|
name = "check",
|
|
srcs = [
|
|
"check.cpp",
|
|
"check_unit.cpp",
|
|
"check_unit.h",
|
|
"handle.h",
|
|
"node_id_traversal.cpp",
|
|
"node_id_traversal.h",
|
|
] +
|
|
# Glob handler files to avoid missing any.
|
|
glob([
|
|
"handle_*.cpp",
|
|
]),
|
|
hdrs = ["check.h"],
|
|
deps = [
|
|
":context",
|
|
":core_identifier",
|
|
":dump",
|
|
":emitter",
|
|
"//common:check",
|
|
"//common:error",
|
|
"//common:find",
|
|
"//common:growing_range",
|
|
"//common:hashtable_key_context",
|
|
"//common:map",
|
|
"//common:ostream",
|
|
"//common:pretty_stack_trace_function",
|
|
"//common:vlog",
|
|
"//toolchain/base:fixed_size_value_store",
|
|
"//toolchain/base:kind_switch",
|
|
"//toolchain/base:shared_value_stores",
|
|
"//toolchain/base:timings",
|
|
"//toolchain/diagnostics:emitter",
|
|
"//toolchain/diagnostics:format_providers",
|
|
"//toolchain/diagnostics:renderer",
|
|
"//toolchain/lex:token_index",
|
|
"//toolchain/lex:token_kind",
|
|
"//toolchain/lex:tokenized_buffer",
|
|
"//toolchain/parse:node_category",
|
|
"//toolchain/parse:node_kind",
|
|
"//toolchain/parse:tree",
|
|
"//toolchain/sem_ir:absolute_node_ref",
|
|
"//toolchain/sem_ir:entry_point",
|
|
"//toolchain/sem_ir:expr_info",
|
|
"//toolchain/sem_ir:file",
|
|
"//toolchain/sem_ir:formatter",
|
|
"//toolchain/sem_ir:read_only_ast_source",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
"@llvm-project//clang:ast",
|
|
"@llvm-project//clang:frontend",
|
|
"@llvm-project//clang:sema",
|
|
"@llvm-project//llvm:Support",
|
|
],
|
|
)
|
|
|
|
cc_fuzz_test(
|
|
name = "check_fuzzer",
|
|
size = "small",
|
|
srcs = ["check_fuzzer.cpp"],
|
|
corpus = glob(["fuzzer_corpus/*"]),
|
|
deps = [
|
|
"//common:exe_path",
|
|
"//testing/fuzzing:libfuzzer_header",
|
|
"//toolchain/driver",
|
|
"@llvm-project//llvm:Support",
|
|
],
|
|
)
|
|
|
|
cc_library(
|
|
name = "generic_region_stack",
|
|
srcs = ["generic_region_stack.cpp"],
|
|
hdrs = ["generic_region_stack.h"],
|
|
deps = [
|
|
"//common:array_stack",
|
|
"//common:check",
|
|
"//common:map",
|
|
"//common:ostream",
|
|
"//common:vlog",
|
|
"//toolchain/sem_ir:file",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
"@llvm-project//llvm:Support",
|
|
],
|
|
)
|
|
|
|
cc_library(
|
|
name = "node_stack",
|
|
srcs = ["node_stack.cpp"],
|
|
hdrs = ["node_stack.h"],
|
|
deps = [
|
|
"//common:check",
|
|
"//common:ostream",
|
|
"//common:vlog",
|
|
"//toolchain/parse:node_kind",
|
|
"//toolchain/parse:tree",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
"@llvm-project//llvm:Support",
|
|
],
|
|
)
|
|
|
|
cc_library(
|
|
name = "core_identifier",
|
|
srcs = ["core_identifier.cpp"],
|
|
hdrs = ["core_identifier.h"],
|
|
textual_hdrs = ["core_identifier.def"],
|
|
deps = [
|
|
"//common:enum_base",
|
|
"//toolchain/base:shared_value_stores",
|
|
"//toolchain/base:value_ids",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
],
|
|
)
|
|
|
|
cc_library(
|
|
name = "emitter",
|
|
srcs = ["diagnostic_emitter.cpp"],
|
|
hdrs = ["diagnostic_emitter.h"],
|
|
deps = [
|
|
":context",
|
|
"//common:ostream",
|
|
"//common:raw_string_ostream",
|
|
"//toolchain/diagnostics:emitter",
|
|
"//toolchain/lex:token_index",
|
|
"//toolchain/parse:tree",
|
|
"//toolchain/sem_ir:absolute_node_ref",
|
|
"//toolchain/sem_ir:diagnostic_loc_converter",
|
|
"//toolchain/sem_ir:file",
|
|
"//toolchain/sem_ir:stringify",
|
|
"//toolchain/sem_ir:typed_insts",
|
|
"@llvm-project//clang:ast",
|
|
"@llvm-project//llvm:Support",
|
|
],
|
|
)
|