mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-21 23:25:07 +00:00
Add caseSensitivity to config->{completion,workspaceSymbol}
This commit is contained in:
parent
e522ce8179
commit
73bd987b1a
@ -6,7 +6,7 @@ include(DefaultCMakeBuildType)
|
|||||||
|
|
||||||
# Required libclang version
|
# Required libclang version
|
||||||
set(LIBCLANG_VERSION 6.0.0 CACHE STRING "libclang version")
|
set(LIBCLANG_VERSION 6.0.0 CACHE STRING "libclang version")
|
||||||
set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}
|
set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}
|
||||||
CACHE STRING "Downloaded libclang location")
|
CACHE STRING "Downloaded libclang location")
|
||||||
option(SYSTEM_LIBCLANG "Use system installation of libclang instead of \
|
option(SYSTEM_LIBCLANG "Use system installation of libclang instead of \
|
||||||
downloading libclang" OFF)
|
downloading libclang" OFF)
|
||||||
@ -33,7 +33,8 @@ if(NOT CYGWIN)
|
|||||||
set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF)
|
set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
# CMake sets MSVC for both MSVC and Clang(Windows)
|
||||||
|
if(MSVC)
|
||||||
# Common MSVC/Clang(Windows) options
|
# Common MSVC/Clang(Windows) options
|
||||||
target_compile_options(ccls PRIVATE
|
target_compile_options(ccls PRIVATE
|
||||||
/nologo
|
/nologo
|
||||||
@ -87,7 +88,7 @@ endif()
|
|||||||
### Libraries
|
### Libraries
|
||||||
|
|
||||||
# See cmake/FindClang.cmake
|
# See cmake/FindClang.cmake
|
||||||
find_package(Clang ${CLANG_VERSION} REQUIRED)
|
find_package(Clang ${LIBCLANG_VERSION} REQUIRED)
|
||||||
target_link_libraries(ccls PRIVATE Clang::Clang)
|
target_link_libraries(ccls PRIVATE Clang::Clang)
|
||||||
|
|
||||||
# Enable threading support
|
# Enable threading support
|
||||||
@ -97,7 +98,7 @@ target_link_libraries(ccls PRIVATE Threads::Threads)
|
|||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
||||||
target_link_libraries(ccls PRIVATE -lc++experimental)
|
target_link_libraries(ccls PRIVATE -lc++experimental)
|
||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
elseif(MSVC)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(ccls PRIVATE -lstdc++fs)
|
target_link_libraries(ccls PRIVATE -lstdc++fs)
|
||||||
endif()
|
endif()
|
||||||
@ -161,8 +162,8 @@ endif()
|
|||||||
if(NOT SYSTEM_LIBCLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
if(NOT SYSTEM_LIBCLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||||
add_custom_command(TARGET ccls
|
add_custom_command(TARGET ccls
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
${DOWNLOADED_CLANG_DIR}/bin/libclang.dll
|
${DOWNLOADED_CLANG_DIR}/bin/libclang.dll
|
||||||
$<TARGET_FILE_DIR:ccls>
|
$<TARGET_FILE_DIR:ccls>
|
||||||
COMMENT "Copying libclang.dll to build directory ...")
|
COMMENT "Copying libclang.dll to build directory ...")
|
||||||
endif()
|
endif()
|
||||||
@ -190,7 +191,7 @@ else()
|
|||||||
support clang-format 6.0.0")
|
support clang-format 6.0.0")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_target(format
|
add_custom_target(format
|
||||||
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold
|
||||||
${Clang_FORMAT_ERROR})
|
${Clang_FORMAT_ERROR})
|
||||||
endif()
|
endif()
|
||||||
|
@ -15,9 +15,6 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
// TODO: See if we can use clang_indexLoc_getFileLocation to get a type ref on
|
|
||||||
// |Foobar| in DISALLOW_COPY(Foobar)
|
|
||||||
|
|
||||||
#if CINDEX_VERSION >= 47
|
#if CINDEX_VERSION >= 47
|
||||||
#define CINDEX_HAVE_PRETTY 1
|
#define CINDEX_HAVE_PRETTY 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -89,6 +89,11 @@ struct Config {
|
|||||||
} codeLens;
|
} codeLens;
|
||||||
|
|
||||||
struct Completion {
|
struct Completion {
|
||||||
|
// 0: case-insensitive
|
||||||
|
// 1: case-folded, i.e. insensitive if no input character is uppercase.
|
||||||
|
// 2: case-sensitive
|
||||||
|
int caseSensitivity = 2;
|
||||||
|
|
||||||
// Some completion UI, such as Emacs' completion-at-point and company-lsp,
|
// Some completion UI, such as Emacs' completion-at-point and company-lsp,
|
||||||
// display completion item label and detail side by side.
|
// display completion item label and detail side by side.
|
||||||
// This does not look right, when you see things like:
|
// This does not look right, when you see things like:
|
||||||
@ -209,6 +214,7 @@ struct Config {
|
|||||||
} index;
|
} index;
|
||||||
|
|
||||||
struct WorkspaceSymbol {
|
struct WorkspaceSymbol {
|
||||||
|
int caseSensitivity = 1;
|
||||||
// Maximum workspace search results.
|
// Maximum workspace search results.
|
||||||
int maxNum = 1000;
|
int maxNum = 1000;
|
||||||
// If true, workspace search results will be dynamically rescored/reordered
|
// If true, workspace search results will be dynamically rescored/reordered
|
||||||
@ -227,6 +233,7 @@ struct Config {
|
|||||||
MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport);
|
MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport);
|
||||||
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
|
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
|
||||||
MAKE_REFLECT_STRUCT(Config::Completion,
|
MAKE_REFLECT_STRUCT(Config::Completion,
|
||||||
|
caseSensitivity,
|
||||||
detailedLabel,
|
detailedLabel,
|
||||||
filterAndSort,
|
filterAndSort,
|
||||||
includeBlacklist,
|
includeBlacklist,
|
||||||
@ -248,7 +255,7 @@ MAKE_REFLECT_STRUCT(Config::Index,
|
|||||||
onDidChange,
|
onDidChange,
|
||||||
threads,
|
threads,
|
||||||
whitelist);
|
whitelist);
|
||||||
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, maxNum, sort);
|
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
||||||
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
||||||
MAKE_REFLECT_STRUCT(Config,
|
MAKE_REFLECT_STRUCT(Config,
|
||||||
compilationDatabaseCommand,
|
compilationDatabaseCommand,
|
||||||
|
@ -81,7 +81,11 @@ IndexFile* FileConsumer::TryConsumeFile(
|
|||||||
|
|
||||||
CXFileUniqueID file_id;
|
CXFileUniqueID file_id;
|
||||||
if (clang_getFileUniqueID(file, &file_id) != 0) {
|
if (clang_getFileUniqueID(file, &file_id) != 0) {
|
||||||
EmitError(file);
|
std::string file_name = FileName(file);
|
||||||
|
if (!file_name.empty()) {
|
||||||
|
LOG_S(ERROR) << "Could not get unique file id for " << file_name
|
||||||
|
<< " when parsing " << parse_file_;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,12 +130,3 @@ std::vector<std::unique_ptr<IndexFile>> FileConsumer::TakeLocalState() {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileConsumer::EmitError(CXFile file) const {
|
|
||||||
std::string file_name = ToString(clang_getFileName(file));
|
|
||||||
// TODO: Investigate this more, why can we get an empty file name?
|
|
||||||
if (!file_name.empty()) {
|
|
||||||
LOG_S(ERROR) << "Could not get unique file id for " << file_name
|
|
||||||
<< " when parsing " << parse_file_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -68,8 +68,6 @@ struct FileConsumer {
|
|||||||
std::vector<std::unique_ptr<IndexFile>> TakeLocalState();
|
std::vector<std::unique_ptr<IndexFile>> TakeLocalState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void EmitError(CXFile file) const;
|
|
||||||
|
|
||||||
std::unordered_map<CXFileUniqueID, std::unique_ptr<IndexFile>> local_;
|
std::unordered_map<CXFileUniqueID, std::unique_ptr<IndexFile>> local_;
|
||||||
FileConsumerSharedState* shared_;
|
FileConsumerSharedState* shared_;
|
||||||
std::string parse_file_;
|
std::string parse_file_;
|
||||||
|
@ -78,8 +78,11 @@ int FuzzyMatcher::MatchScore(int i, int j, bool last) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
FuzzyMatcher::FuzzyMatcher(std::string_view pattern) {
|
FuzzyMatcher::FuzzyMatcher(std::string_view pattern, int sensitivity) {
|
||||||
CalculateRoles(pattern, pat_role, &pat_set);
|
CalculateRoles(pattern, pat_role, &pat_set);
|
||||||
|
if (sensitivity == 1)
|
||||||
|
sensitivity = pat_set & 1 << Upper ? 2 : 0;
|
||||||
|
case_sensitivity = sensitivity;
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (size_t i = 0; i < pattern.size(); i++)
|
for (size_t i = 0; i < pattern.size(); i++)
|
||||||
if (pattern[i] != ' ') {
|
if (pattern[i] != ' ') {
|
||||||
@ -112,12 +115,13 @@ int FuzzyMatcher::Match(std::string_view text) {
|
|||||||
cur[j][1] + MissScore(j, true));
|
cur[j][1] + MissScore(j, true));
|
||||||
// For the first char of pattern, apply extra restriction to filter bad
|
// For the first char of pattern, apply extra restriction to filter bad
|
||||||
// candidates (e.g. |int| in |PRINT|)
|
// candidates (e.g. |int| in |PRINT|)
|
||||||
if (low_pat[i] == low_text[j] &&
|
cur[j + 1][1] = (case_sensitivity ? pat[i] == text[j]
|
||||||
(i || text_role[j] != Tail || pat[i] == text[j])) {
|
: low_pat[i] == low_text[j] &&
|
||||||
cur[j + 1][1] = std::max(pre[j][0] + MatchScore(i, j, false),
|
(i || text_role[j] != Tail ||
|
||||||
pre[j][1] + MatchScore(i, j, true));
|
pat[i] == text[j]))
|
||||||
} else
|
? std::max(pre[j][0] + MatchScore(i, j, false),
|
||||||
cur[j + 1][1] = kMinScore * 2;
|
pre[j][1] + MatchScore(i, j, true))
|
||||||
|
: cur[j + 1][1] = kMinScore * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +135,7 @@ int FuzzyMatcher::Match(std::string_view text) {
|
|||||||
|
|
||||||
TEST_SUITE("fuzzy_match") {
|
TEST_SUITE("fuzzy_match") {
|
||||||
bool Ranks(std::string_view pat, std::vector<const char*> texts) {
|
bool Ranks(std::string_view pat, std::vector<const char*> texts) {
|
||||||
FuzzyMatcher fuzzy(pat);
|
FuzzyMatcher fuzzy(pat, 0);
|
||||||
std::vector<int> scores;
|
std::vector<int> scores;
|
||||||
for (auto text : texts)
|
for (auto text : texts)
|
||||||
scores.push_back(fuzzy.Match(text));
|
scores.push_back(fuzzy.Match(text));
|
||||||
@ -150,7 +154,7 @@ TEST_SUITE("fuzzy_match") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("test") {
|
TEST_CASE("test") {
|
||||||
FuzzyMatcher fuzzy("");
|
FuzzyMatcher fuzzy("", 0);
|
||||||
CHECK(fuzzy.Match("") == 0);
|
CHECK(fuzzy.Match("") == 0);
|
||||||
CHECK(fuzzy.Match("aaa") < 0);
|
CHECK(fuzzy.Match("aaa") < 0);
|
||||||
|
|
||||||
|
@ -12,10 +12,11 @@ class FuzzyMatcher {
|
|||||||
// overflow.
|
// overflow.
|
||||||
constexpr static int kMinScore = INT_MIN / 4;
|
constexpr static int kMinScore = INT_MIN / 4;
|
||||||
|
|
||||||
FuzzyMatcher(std::string_view pattern);
|
FuzzyMatcher(std::string_view pattern, int case_sensitivity);
|
||||||
int Match(std::string_view text);
|
int Match(std::string_view text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int case_sensitivity;
|
||||||
std::string pat;
|
std::string pat;
|
||||||
std::string_view text;
|
std::string_view text;
|
||||||
int pat_set, text_set;
|
int pat_set, text_set;
|
||||||
|
@ -188,9 +188,6 @@ struct TypeDef : NameMixin<TypeDef<F>> {
|
|||||||
types == o.types && funcs == o.funcs && vars == o.vars &&
|
types == o.types && funcs == o.funcs && vars == o.vars &&
|
||||||
kind == o.kind && hover == o.hover && comments == o.comments;
|
kind == o.kind && hover == o.hover && comments == o.comments;
|
||||||
}
|
}
|
||||||
bool operator!=(const TypeDef& o) const {
|
|
||||||
return !(*this == o);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
template <typename TVisitor, typename Family>
|
template <typename TVisitor, typename Family>
|
||||||
void Reflect(TVisitor& visitor, TypeDef<Family>& value) {
|
void Reflect(TVisitor& visitor, TypeDef<Family>& value) {
|
||||||
@ -269,9 +266,6 @@ struct FuncDef : NameMixin<FuncDef<F>> {
|
|||||||
kind == o.kind && storage == o.storage && hover == o.hover &&
|
kind == o.kind && storage == o.storage && hover == o.hover &&
|
||||||
comments == o.comments;
|
comments == o.comments;
|
||||||
}
|
}
|
||||||
bool operator!=(const FuncDef& o) const {
|
|
||||||
return !(*this == o);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TVisitor, typename Family>
|
template <typename TVisitor, typename Family>
|
||||||
@ -359,7 +353,6 @@ struct VarDef : NameMixin<VarDef<F>> {
|
|||||||
extent == o.extent && type == o.type && kind == o.kind &&
|
extent == o.extent && type == o.type && kind == o.kind &&
|
||||||
storage == o.storage && hover == o.hover && comments == o.comments;
|
storage == o.storage && hover == o.hover && comments == o.comments;
|
||||||
}
|
}
|
||||||
bool operator!=(const VarDef& o) const { return !(*this == o); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TVisitor, typename Family>
|
template <typename TVisitor, typename Family>
|
||||||
|
@ -49,7 +49,7 @@ std::optional<std::string> ReadJsonRpcContentFrom(
|
|||||||
return opt_c && *opt_c == expected;
|
return opt_c && *opt_c == expected;
|
||||||
};
|
};
|
||||||
if (!expect_char('\r') || !expect_char('\n')) {
|
if (!expect_char('\r') || !expect_char('\n')) {
|
||||||
LOG_S(INFO) << "Unexpected token (expected \r\n sequence)";
|
LOG_S(INFO) << "Unexpected token (expected \\r\\n sequence)";
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ void FilterAndSortCompletionResponse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fuzzy match and remove awful candidates.
|
// Fuzzy match and remove awful candidates.
|
||||||
FuzzyMatcher fuzzy(complete_text);
|
FuzzyMatcher fuzzy(complete_text, g_config->completion.caseSensitivity);
|
||||||
for (auto& item : items) {
|
for (auto& item : items) {
|
||||||
item.score_ =
|
item.score_ =
|
||||||
CaseFoldingSubsequenceMatch(complete_text, *item.filterText).first
|
CaseFoldingSubsequenceMatch(complete_text, *item.filterText).first
|
||||||
|
@ -129,7 +129,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler<In_WorkspaceSymbol> {
|
|||||||
int longest = 0;
|
int longest = 0;
|
||||||
for (int i : result_indices)
|
for (int i : result_indices)
|
||||||
longest = std::max(longest, int(db->GetSymbolName(i, true).size()));
|
longest = std::max(longest, int(db->GetSymbolName(i, true).size()));
|
||||||
FuzzyMatcher fuzzy(query);
|
FuzzyMatcher fuzzy(query, g_config->workspaceSymbol.caseSensitivity);
|
||||||
std::vector<std::pair<int, int>> permutation(result_indices.size());
|
std::vector<std::pair<int, int>> permutation(result_indices.size());
|
||||||
for (int i = 0; i < int(result_indices.size()); i++) {
|
for (int i = 0; i < int(result_indices.size()); i++) {
|
||||||
permutation[i] = {
|
permutation[i] = {
|
||||||
|
37
src/query.cc
37
src/query.cc
@ -625,15 +625,15 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
|||||||
/*onFound:*/
|
/*onFound:*/
|
||||||
[this, &previous_id_map, ¤t_id_map](IndexType* previous,
|
[this, &previous_id_map, ¤t_id_map](IndexType* previous,
|
||||||
IndexType* current) {
|
IndexType* current) {
|
||||||
std::optional<QueryType::Def> previous_remapped_def =
|
std::optional<QueryType::Def> prev_remapped =
|
||||||
ToQuery(previous_id_map, previous->def);
|
ToQuery(previous_id_map, previous->def);
|
||||||
std::optional<QueryType::Def> current_remapped_def =
|
std::optional<QueryType::Def> current_remapped =
|
||||||
ToQuery(current_id_map, current->def);
|
ToQuery(current_id_map, current->def);
|
||||||
if (current_remapped_def &&
|
if (current_remapped &&
|
||||||
previous_remapped_def != current_remapped_def &&
|
!(prev_remapped == current_remapped) &&
|
||||||
!current_remapped_def->detailed_name.empty()) {
|
!current_remapped->detailed_name.empty()) {
|
||||||
types_def_update.push_back(QueryType::DefUpdate(
|
types_def_update.push_back(QueryType::DefUpdate(
|
||||||
current->usr, std::move(*current_remapped_def)));
|
current->usr, std::move(*current_remapped)));
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCESS_UPDATE_DIFF(QueryTypeId, types_declarations, declarations, Use);
|
PROCESS_UPDATE_DIFF(QueryTypeId, types_declarations, declarations, Use);
|
||||||
@ -686,15 +686,15 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
|||||||
/*onFound:*/
|
/*onFound:*/
|
||||||
[this, &previous_id_map, ¤t_id_map](IndexFunc* previous,
|
[this, &previous_id_map, ¤t_id_map](IndexFunc* previous,
|
||||||
IndexFunc* current) {
|
IndexFunc* current) {
|
||||||
std::optional<QueryFunc::Def> previous_remapped_def =
|
std::optional<QueryFunc::Def> prev_remapped =
|
||||||
ToQuery(previous_id_map, previous->def);
|
ToQuery(previous_id_map, previous->def);
|
||||||
std::optional<QueryFunc::Def> current_remapped_def =
|
std::optional<QueryFunc::Def> current_remapped =
|
||||||
ToQuery(current_id_map, current->def);
|
ToQuery(current_id_map, current->def);
|
||||||
if (current_remapped_def &&
|
if (current_remapped &&
|
||||||
previous_remapped_def != current_remapped_def &&
|
!(prev_remapped == current_remapped) &&
|
||||||
!current_remapped_def->detailed_name.empty()) {
|
!current_remapped->detailed_name.empty()) {
|
||||||
funcs_def_update.push_back(QueryFunc::DefUpdate(
|
funcs_def_update.push_back(QueryFunc::DefUpdate(
|
||||||
current->usr, std::move(*current_remapped_def)));
|
current->usr, std::move(*current_remapped)));
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, Use);
|
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, Use);
|
||||||
@ -736,15 +736,14 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
|||||||
/*onFound:*/
|
/*onFound:*/
|
||||||
[this, &previous_id_map, ¤t_id_map](IndexVar* previous,
|
[this, &previous_id_map, ¤t_id_map](IndexVar* previous,
|
||||||
IndexVar* current) {
|
IndexVar* current) {
|
||||||
std::optional<QueryVar::Def> previous_remapped_def =
|
std::optional<QueryVar::Def> prev_remapped =
|
||||||
ToQuery(previous_id_map, previous->def);
|
ToQuery(previous_id_map, previous->def);
|
||||||
std::optional<QueryVar::Def> current_remapped_def =
|
std::optional<QueryVar::Def> current_remapped =
|
||||||
ToQuery(current_id_map, current->def);
|
ToQuery(current_id_map, current->def);
|
||||||
if (current_remapped_def &&
|
if (current_remapped && !(prev_remapped == current_remapped) &&
|
||||||
previous_remapped_def != current_remapped_def &&
|
!current_remapped->detailed_name.empty())
|
||||||
!current_remapped_def->detailed_name.empty())
|
vars_def_update.push_back(
|
||||||
vars_def_update.push_back(QueryVar::DefUpdate(
|
QueryVar::DefUpdate(current->usr, std::move(*current_remapped)));
|
||||||
current->usr, std::move(*current_remapped_def)));
|
|
||||||
|
|
||||||
PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, Use);
|
PROCESS_UPDATE_DIFF(QueryVarId, vars_declarations, declarations, Use);
|
||||||
PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Use);
|
PROCESS_UPDATE_DIFF(QueryVarId, vars_uses, uses, Use);
|
||||||
|
Loading…
Reference in New Issue
Block a user