#include "LuaCodeFormat.h" #include "CodeService/LuaEditorConfig.h" #include "CodeService/LuaFormatter.h" #include "CodeService/NameStyle/NameStyleChecker.h" #include "LuaParser/LuaParser.h" #include "Util/StringUtil.h" LuaCodeFormat& LuaCodeFormat::GetInstance() { static LuaCodeFormat instance; return instance; } LuaCodeFormat::LuaCodeFormat() : _defaultOptions(std::make_shared()), _codeSpellChecker(std::make_shared()), _customParser(std::make_shared()) { } void LuaCodeFormat::UpdateCodeStyle(const std::string& workspaceUri, const std::string& configPath) { auto editorconfig = LuaEditorConfig::LoadFromFile(configPath); if (editorconfig == nullptr) { return; } for (auto& pair : _editorConfigVector) { if (pair.first == workspaceUri) { pair.second = editorconfig; pair.second->SetWorkspace(workspaceUri); return; } } _editorConfigVector.push_back({ workspaceUri, editorconfig }); _editorConfigVector.back().second->SetWorkspace(workspaceUri); } void LuaCodeFormat::RemoveCodeStyle(const std::string& workspaceUri) { for (auto it = _editorConfigVector.begin(); it != _editorConfigVector.end(); ++it) { if (it->first == workspaceUri) { _editorConfigVector.erase(it); return; } } } void LuaCodeFormat::SetDefaultCodeStyle(ConfigMap& configMap) { if (!configMap.empty()) { LuaEditorConfig::ParseFromSection(_defaultOptions, configMap); } } void LuaCodeFormat::SetSupportNonStandardSymbol(const std::string& tokenType,const std::vector& tokens) { if (tokenType.size() == 1) { _customParser->SetTokens(tokenType.front(), tokens); } } void LuaCodeFormat::LoadSpellDictionary(const std::string& path) { _codeSpellChecker->LoadDictionary(path); } void LuaCodeFormat::LoadSpellDictionaryFromBuffer(const std::string& buffer) { _codeSpellChecker->LoadDictionaryFromBuffer(buffer); } std::string LuaCodeFormat::Reformat(const std::string& uri, std::string&& text, ConfigMap& configMap) { auto parser = LuaParser::LoadFromBuffer(std::move(text)); if (_customParser->IsSupportCustomTokens()) { parser->GetTokenParser()->SetCustomParser(_customParser); } parser->BuildAstWithComment(); if (parser->HasError()) { return ""; } auto options = GetOptions(uri); auto tempOptions = CalculateOptions(uri, configMap); LuaFormatter formatter(parser, tempOptions); formatter.BuildFormattedElement(); return formatter.GetFormattedText(); } std::string LuaCodeFormat::RangeFormat(const std::string& uri, LuaFormatRange& range, std::string&& text, ConfigMap& configMap) { auto parser = LuaParser::LoadFromBuffer(std::move(text)); if (_customParser->IsSupportCustomTokens()) { parser->GetTokenParser()->SetCustomParser(_customParser); } parser->BuildAstWithComment(); if (parser->HasError()) { return ""; } auto options = GetOptions(uri); auto tempOptions = CalculateOptions(uri, configMap); LuaFormatter formatter(parser, tempOptions); formatter.BuildFormattedElement(); return formatter.GetRangeFormattedText(range); } std::pair> LuaCodeFormat::Diagnose(const std::string& uri, std::string&& text) { auto parser = LuaParser::LoadFromBuffer(std::move(text)); if (_customParser->IsSupportCustomTokens()) { parser->GetTokenParser()->SetCustomParser(_customParser); } parser->BuildAstWithComment(); if (!parser->GetErrors().empty()) { return std::make_pair(false, std::vector()); } auto options = GetOptions(uri); LuaFormatter formatter(parser, *options); formatter.BuildFormattedElement(); DiagnosisContext ctx(parser, *options); formatter.CalculateDiagnosisInfos(ctx); if (options->enable_check_codestyle) { NameStyleChecker styleChecker(ctx); styleChecker.Analysis(); } ctx.DiagnoseLine(); return std::make_pair(true, ctx.GetDiagnosisInfos()); } std::vector LuaCodeFormat::SpellCheck(const std::string& uri, std::string&& text, const CodeSpellChecker::CustomDictionary& tempDict) { auto parser = LuaParser::LoadFromBuffer(std::move(text)); if (_customParser->IsSupportCustomTokens()) { parser->GetTokenParser()->SetCustomParser(_customParser); } parser->GetTokenParser()->Parse(); auto options = GetOptions(uri); DiagnosisContext ctx(parser, *options); _codeSpellChecker->Analysis(ctx, tempDict); return ctx.GetDiagnosisInfos(); } std::vector LuaCodeFormat::SpellCorrect(const std::string& word) { std::string letterWord = word; for (auto& c : letterWord) { c = std::tolower(c); } bool upperFirst = false; if (std::isupper(word.front())) { upperFirst = true; } auto suggests = _codeSpellChecker->GetSuggests(letterWord); for (auto& suggest : suggests) { if (!suggest.Term.empty()) { if (upperFirst) { suggest.Term[0] = std::toupper(suggest.Term[0]); } } } return suggests; } std::shared_ptr LuaCodeFormat::GetOptions(const std::string& uri) { std::size_t matchLength = 0; std::shared_ptr options = _defaultOptions; for (auto it = _editorConfigVector.begin(); it != _editorConfigVector.end(); it++) { if (StringUtil::StartWith(uri, it->first) && it->first.size() > matchLength) { matchLength = it->first.size(); options = it->second->Generate(uri); } } return options; } LuaCodeStyleOptions LuaCodeFormat::CalculateOptions(const std::string& uri, ConfigMap& configMap) { auto options = GetOptions(uri); if (configMap.empty()) { return *options; } else { LuaCodeStyleOptions tempOptions = *options; if (configMap.count("insertSpaces")) { tempOptions.indent_style = configMap.at("insertSpaces") == "true" ? IndentStyle::Space : IndentStyle::Tab; } if (configMap.count("tabSize")) { if (tempOptions.indent_style == IndentStyle::Tab) { tempOptions.tab_width = std::stoi(configMap.at("tabSize")); } else if (tempOptions.indent_style == IndentStyle::Space) { tempOptions.indent_size = std::stoi(configMap.at("tabSize")); } } return tempOptions; } }