summaryrefslogtreecommitdiffstats
path: root/clangd/SourceCode.h
diff options
context:
space:
mode:
Diffstat (limited to 'clangd/SourceCode.h')
-rw-r--r--clangd/SourceCode.h114
1 files changed, 109 insertions, 5 deletions
diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h
index b768d09a..85db9458 100644
--- a/clangd/SourceCode.h
+++ b/clangd/SourceCode.h
@@ -1,9 +1,8 @@
//===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,11 +12,16 @@
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H
+#include "Context.h"
#include "Protocol.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SHA1.h"
namespace clang {
@@ -32,8 +36,14 @@ using FileDigest = decltype(llvm::SHA1::hash({}));
FileDigest digest(StringRef Content);
Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID);
+// This context variable controls the behavior of functions in this file
+// that convert between LSP offsets and native clang byte offsets.
+// If not set, defaults to UTF-16 for backwards-compatibility.
+extern Key<OffsetEncoding> kCurrentOffsetEncoding;
+
// Counts the number of UTF-16 code units needed to represent a string (LSP
// specifies string lengths in UTF-16 code units).
+// Use of UTF-16 may be overridden by kCurrentOffsetEncoding.
size_t lspLength(StringRef Code);
/// Turn a [line, column] pair into an offset in Code.
@@ -55,6 +65,51 @@ Position offsetToPosition(llvm::StringRef Code, size_t Offset);
/// FIXME: This should return an error if the location is invalid.
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc);
+/// Return the file location, corresponding to \p P. Note that one should take
+/// care to avoid comparing the result with expansion locations.
+llvm::Expected<SourceLocation> sourceLocationInMainFile(const SourceManager &SM,
+ Position P);
+
+/// Turns a token range into a half-open range and checks its correctness.
+/// The resulting range will have only valid source location on both sides, both
+/// of which are file locations.
+///
+/// File locations always point to a particular offset in a file, i.e. they
+/// never refer to a location inside a macro expansion. Turning locations from
+/// macro expansions into file locations is ambiguous - one can use
+/// SourceManager::{getExpansion|getFile|getSpelling}Loc. This function
+/// calls SourceManager::getFileLoc on both ends of \p R to do the conversion.
+///
+/// User input (e.g. cursor position) is expressed as a file location, so this
+/// function can be viewed as a way to normalize the ranges used in the clang
+/// AST so that they are comparable with ranges coming from the user input.
+llvm::Optional<SourceRange> toHalfOpenFileRange(const SourceManager &Mgr,
+ const LangOptions &LangOpts,
+ SourceRange R);
+
+/// Returns true iff all of the following conditions hold:
+/// - start and end locations are valid,
+/// - start and end locations are file locations from the same file
+/// (i.e. expansion locations are not taken into account).
+/// - start offset <= end offset.
+/// FIXME: introduce a type for source range with this invariant.
+bool isValidFileRange(const SourceManager &Mgr, SourceRange R);
+
+/// Returns true iff \p L is contained in \p R.
+/// EXPECTS: isValidFileRange(R) == true, L is a file location.
+bool halfOpenRangeContains(const SourceManager &Mgr, SourceRange R,
+ SourceLocation L);
+
+/// Returns true iff \p L is contained in \p R or \p L is equal to the end point
+/// of \p R.
+/// EXPECTS: isValidFileRange(R) == true, L is a file location.
+bool halfOpenRangeTouches(const SourceManager &Mgr, SourceRange R,
+ SourceLocation L);
+
+/// Returns the source code covered by the source range.
+/// EXPECTS: isValidFileRange(R) == true.
+llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R);
+
// Converts a half-open clang source range to an LSP range.
// Note that clang also uses closed source ranges, which this can't handle!
Range halfOpenToRange(const SourceManager &SM, CharSourceRange R);
@@ -91,7 +146,56 @@ TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M,
llvm::Optional<std::string> getCanonicalPath(const FileEntry *F,
const SourceManager &SourceMgr);
-bool IsRangeConsecutive(const Range &Left, const Range &Right);
+bool isRangeConsecutive(const Range &Left, const Range &Right);
+
+/// Choose the clang-format style we should apply to a certain file.
+/// This will usually use FS to look for .clang-format directories.
+/// FIXME: should we be caching the .clang-format file search?
+/// This uses format::DefaultFormatStyle and format::DefaultFallbackStyle,
+/// though the latter may have been overridden in main()!
+format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
+ llvm::StringRef Content,
+ llvm::vfs::FileSystem *FS);
+
+// Cleanup and format the given replacements.
+llvm::Expected<tooling::Replacements>
+cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces,
+ const format::FormatStyle &Style);
+
+/// Collects identifiers with counts in the source code.
+llvm::StringMap<unsigned> collectIdentifiers(llvm::StringRef Content,
+ const format::FormatStyle &Style);
+
+/// Collects words from the source code.
+/// Unlike collectIdentifiers:
+/// - also finds text in comments:
+/// - splits text into words
+/// - drops stopwords like "get" and "for"
+llvm::StringSet<> collectWords(llvm::StringRef Content);
+
+/// Heuristically determine namespaces visible at a point, without parsing Code.
+/// This considers using-directives and enclosing namespace-declarations that
+/// are visible (and not obfuscated) in the file itself (not headers).
+/// Code should be truncated at the point of interest.
+///
+/// The returned vector is always non-empty.
+/// - The first element is the namespace that encloses the point: a declaration
+/// near the point would be within this namespace.
+/// - The elements are the namespaces in scope at the point: an unqualified
+/// lookup would search within these namespaces.
+///
+/// Using directives are resolved against all enclosing scopes, but no other
+/// namespace directives.
+///
+/// example:
+/// using namespace a;
+/// namespace foo {
+/// using namespace b;
+///
+/// visibleNamespaces are {"foo::", "", "a::", "b::", "foo::b::"}, not "a::b::".
+std::vector<std::string> visibleNamespaces(llvm::StringRef Code,
+ const format::FormatStyle &Style);
+
} // namespace clangd
} // namespace clang
#endif