This commit is contained in:
Fangrui Song 2018-10-15 01:26:13 -07:00
parent cb7ed9415d
commit 87ea7d244d
6 changed files with 47 additions and 137 deletions

View File

@ -84,20 +84,15 @@ bool TrimPath(Project *project, std::string &path) {
}
lsCompletionItem BuildCompletionItem(const std::string &path,
bool use_angle_brackets, bool is_stl) {
bool use_angle_brackets) {
lsCompletionItem item;
item.label = ElideLongPath(path);
item.detail = path; // the include path, used in de-duplicating
item.textEdit.newText = path;
item.insertTextFormat = lsInsertTextFormat::PlainText;
item.use_angle_brackets_ = use_angle_brackets;
if (is_stl) {
item.kind = lsCompletionItemKind::Module;
item.priority_ = 2;
} else {
item.kind = lsCompletionItemKind::File;
item.priority_ = 1;
}
item.priority_ = 0;
return item;
}
@ -166,8 +161,7 @@ void IncludeComplete::AddFile(const std::string &path) {
std::string trimmed_path = path;
bool use_angle_brackets = TrimPath(project_, trimmed_path);
lsCompletionItem item =
BuildCompletionItem(trimmed_path, use_angle_brackets, false /*is_stl*/);
lsCompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets);
std::unique_lock<std::mutex> lock(completion_items_mutex, std::defer_lock);
if (is_scanning)
@ -196,7 +190,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
CompletionCandidate candidate;
candidate.absolute_path = directory + path;
candidate.completion_item =
BuildCompletionItem(path, use_angle_brackets, false /*is_stl*/);
BuildCompletionItem(path, use_angle_brackets);
results.push_back(candidate);
});

View File

@ -19,7 +19,6 @@ limitations under the License.
#include "maybe.h"
#include "position.h"
#include "serializer.h"
#include "symbol.h"
#include "utils.h"
#include <clang/Basic/FileManager.h>

View File

@ -220,6 +220,14 @@ enum class lsSymbolKind : uint8_t {
};
MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);
struct lsSymbolInformation {
std::string_view name;
lsSymbolKind kind;
lsLocation location;
std::optional<std::string_view> containerName;
};
MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName);
struct lsTextDocumentIdentifier {
lsDocumentUri uri;
};
@ -394,3 +402,31 @@ MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message);
// encounters a c++ declaration.
enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 };
MAKE_REFLECT_TYPE_PROXY(LanguageId);
// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in
// front of others.
enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var };
MAKE_REFLECT_TYPE_PROXY(SymbolKind);
enum class Role : uint16_t {
None = 0,
Declaration = 1 << 0,
Definition = 1 << 1,
Reference = 1 << 2,
Read = 1 << 3,
Write = 1 << 4,
Call = 1 << 5,
Dynamic = 1 << 6,
Address = 1 << 7,
Implicit = 1 << 8,
All = (1 << 9) - 1,
};
MAKE_REFLECT_TYPE_PROXY(Role);
inline uint16_t operator&(Role lhs, Role rhs) {
return uint16_t(lhs) & uint16_t(rhs);
}
inline Role operator|(Role lhs, Role rhs) {
return Role(uint16_t(lhs) | uint16_t(rhs));
}

View File

@ -16,7 +16,6 @@ limitations under the License.
#include "message_handler.h"
#include "pipeline.hh"
#include "query_utils.h"
#include "symbol.h"
#include <algorithm>
using namespace ccls;

View File

@ -39,78 +39,15 @@ limitations under the License.
#include <malloc.h>
#endif
#include <llvm/ADT/SmallString.h>
#include <llvm/Support/Path.h>
#include <string>
namespace {
// Returns the canonicalized absolute pathname, without expanding symbolic
// links. This is a variant of realpath(2), C++ rewrite of
// https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/realpath.c
std::optional<std::string> RealPathNotExpandSymlink(std::string path) {
if (path.empty()) {
errno = EINVAL;
return std::nullopt;
}
if (path[0] == '\0') {
errno = ENOENT;
return std::nullopt;
}
// Do not use PATH_MAX because it is tricky on Linux.
// See https://eklitzke.org/path-max-is-tricky
char tmp[1024];
std::string resolved;
size_t i = 0;
struct stat sb;
if (path[0] == '/') {
resolved = "/";
i = 1;
} else {
if (!getcwd(tmp, sizeof tmp))
return std::nullopt;
resolved = tmp;
}
while (i < path.size()) {
auto j = path.find('/', i);
if (j == std::string::npos)
j = path.size();
auto next_token = path.substr(i, j - i);
i = j + 1;
if (resolved.back() != '/')
resolved += '/';
if (next_token.empty() || next_token == ".") {
// Handle consequential slashes and "."
continue;
} else if (next_token == "..") {
// Strip the last path component except when it is single "/"
if (resolved.size() > 1)
resolved.resize(resolved.rfind('/', resolved.size() - 2) + 1);
continue;
}
// Append the next path component.
// Here we differ from realpath(3), we use stat(2) instead of
// lstat(2) because we do not want to resolve symlinks.
resolved += next_token;
if (stat(resolved.c_str(), &sb) != 0)
return std::nullopt;
if (!S_ISDIR(sb.st_mode) && j < path.size()) {
errno = ENOTDIR;
return std::nullopt;
}
}
// Remove trailing slash except when a single "/".
if (resolved.size() > 1 && resolved.back() == '/')
resolved.pop_back();
return resolved;
}
} // namespace
std::string NormalizePath(const std::string &path) {
std::optional<std::string> resolved = RealPathNotExpandSymlink(path);
return resolved ? *resolved : path;
llvm::SmallString<256> P(path);
llvm::sys::path::remove_dots(P, true);
return {P.data(), P.size()};
}
void FreeUnusedMemory() {

View File

@ -1,55 +0,0 @@
/* Copyright 2017-2018 ccls Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#pragma once
#include "lsp.h"
#include "serializer.h"
// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in
// front of others.
enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var };
MAKE_REFLECT_TYPE_PROXY(SymbolKind);
enum class Role : uint16_t {
None = 0,
Declaration = 1 << 0,
Definition = 1 << 1,
Reference = 1 << 2,
Read = 1 << 3,
Write = 1 << 4,
Call = 1 << 5,
Dynamic = 1 << 6,
Address = 1 << 7,
Implicit = 1 << 8,
All = (1 << 9) - 1,
};
MAKE_REFLECT_TYPE_PROXY(Role);
inline uint16_t operator&(Role lhs, Role rhs) {
return uint16_t(lhs) & uint16_t(rhs);
}
inline Role operator|(Role lhs, Role rhs) {
return Role(uint16_t(lhs) | uint16_t(rhs));
}
struct lsSymbolInformation {
std::string_view name;
lsSymbolKind kind;
lsLocation location;
std::optional<std::string_view> containerName;
};
MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName);