context.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/language_server/context.h"
  5. #include <memory>
  6. #include "toolchain/base/shared_value_stores.h"
  7. #include "toolchain/diagnostics/null_diagnostics.h"
  8. #include "toolchain/lex/lex.h"
  9. #include "toolchain/lex/tokenized_buffer.h"
  10. #include "toolchain/parse/parse.h"
  11. #include "toolchain/parse/tree_and_subtrees.h"
  12. namespace Carbon::LanguageServer {
  13. auto Context::File::SetText(Context& context, llvm::StringRef text) -> void {
  14. // Clear state dependent on the source text.
  15. tree_and_subtrees_.reset();
  16. tree_.reset();
  17. tokens_.reset();
  18. value_stores_.reset();
  19. source_.reset();
  20. // TODO: Make the processing asynchronous, to better handle rapid text
  21. // updates.
  22. CARBON_CHECK(!source_ && !value_stores_ && !tokens_ && !tree_,
  23. "We currently cache everything together");
  24. // TODO: Diagnostics should be passed to the LSP instead of dropped.
  25. auto& null_consumer = NullDiagnosticConsumer();
  26. std::optional source =
  27. SourceBuffer::MakeFromStringCopy(filename_, text, null_consumer);
  28. if (!source) {
  29. // Failing here should be rare, but provide stub data for recovery so that
  30. // we can have a simple API.
  31. source = SourceBuffer::MakeFromStringCopy(filename_, "", null_consumer);
  32. CARBON_CHECK(source, "Making an empty buffer should always succeed");
  33. }
  34. source_ = std::make_unique<SourceBuffer>(std::move(*source));
  35. value_stores_ = std::make_unique<SharedValueStores>();
  36. tokens_ = std::make_unique<Lex::TokenizedBuffer>(
  37. Lex::Lex(*value_stores_, *source_, null_consumer));
  38. tree_ = std::make_unique<Parse::Tree>(
  39. Parse::Parse(*tokens_, null_consumer, context.vlog_stream()));
  40. tree_and_subtrees_ =
  41. std::make_unique<Parse::TreeAndSubtrees>(*tokens_, *tree_);
  42. }
  43. auto Context::LookupFile(llvm::StringRef filename) -> File* {
  44. if (!filename.ends_with(".carbon")) {
  45. CARBON_DIAGNOSTIC(LanguageServerFileUnsupported, Warning,
  46. "non-Carbon file requested");
  47. file_emitter_.Emit(filename, LanguageServerFileUnsupported);
  48. return nullptr;
  49. }
  50. if (auto lookup_result = files().Lookup(filename)) {
  51. return &lookup_result.value();
  52. } else {
  53. CARBON_DIAGNOSTIC(LanguageServerFileUnknown, Warning,
  54. "unknown file requested");
  55. file_emitter_.Emit(filename, LanguageServerFileUnknown);
  56. return nullptr;
  57. }
  58. }
  59. } // namespace Carbon::LanguageServer