|
1 | 1 | #include "CodeService/Spell/CodeSpellChecker.h" |
2 | 2 | #include "LuaParser/LuaTokenTypeDetail.h" |
3 | 3 | #include "Util/format.h" |
| 4 | +#include "CodeService/Spell/TextParser.h" |
4 | 5 |
|
5 | 6 | CodeSpellChecker::CodeSpellChecker() |
6 | 7 | : _symSpell(std::make_shared<SymSpell>(SymSpell::Strategy::LazyLoaded)) |
@@ -29,6 +30,10 @@ void CodeSpellChecker::Analysis(DiagnosisContext& ctx, const CustomDictionary& c |
29 | 30 | { |
30 | 31 | IdentifyAnalysis(ctx, token, customDict); |
31 | 32 | } |
| 33 | + else if (token.TokenType == TK_STRING) |
| 34 | + { |
| 35 | + TextAnalysis(ctx, token, customDict); |
| 36 | + } |
32 | 37 | } |
33 | 38 | } |
34 | 39 |
|
@@ -182,7 +187,62 @@ void CodeSpellChecker::IdentifyAnalysis(DiagnosisContext& ctx, LuaToken& token, |
182 | 187 | token.Range.StartOffset + word.Range.Start + word.Range.Count - 1 |
183 | 188 | ); |
184 | 189 | std::string originText(token.Text.substr(word.Range.Start, word.Range.Count)); |
185 | | - ctx.PushDiagnosis(Util::format("Typo in identifier '{}'", originText), range, DiagnosisType::Spell, originText); |
| 190 | + ctx.PushDiagnosis(Util::format("Typo in identifier '{}'", originText), range, DiagnosisType::Spell, |
| 191 | + originText); |
| 192 | + } |
| 193 | + } |
| 194 | +} |
| 195 | + |
| 196 | +void CodeSpellChecker::TextAnalysis(DiagnosisContext& ctx, LuaToken& token, const CustomDictionary& customDict) |
| 197 | +{ |
| 198 | + std::shared_ptr<spell::TextParser> parser = std::make_shared<spell::TextParser>(token.Text); |
| 199 | + parser->Parse(); |
| 200 | + auto& identifiers = parser->GetIdentifiers(); |
| 201 | + if (identifiers.empty()) |
| 202 | + { |
| 203 | + return; |
| 204 | + } |
| 205 | + |
| 206 | + for (auto& identifier : identifiers) |
| 207 | + { |
| 208 | + auto& text = identifier.Item; |
| 209 | + |
| 210 | + if (customDict.count(text) != 0) |
| 211 | + { |
| 212 | + continue; |
| 213 | + } |
| 214 | + std::shared_ptr<spell::IdentifyParser> identifierParser = nullptr; |
| 215 | + |
| 216 | + auto it = _caches.find(text); |
| 217 | + if (it != _caches.end()) |
| 218 | + { |
| 219 | + identifierParser = it->second; |
| 220 | + } |
| 221 | + else |
| 222 | + { |
| 223 | + identifierParser = std::make_shared<spell::IdentifyParser>(text); |
| 224 | + identifierParser->Parse(); |
| 225 | + _caches.insert({text, identifierParser}); |
| 226 | + } |
| 227 | + |
| 228 | + auto& words = identifierParser->GetWords(); |
| 229 | + if (words.empty()) |
| 230 | + { |
| 231 | + continue; |
| 232 | + } |
| 233 | + |
| 234 | + for (auto& word : words) |
| 235 | + { |
| 236 | + if (!word.Item.empty() && !_symSpell->IsCorrectWord(word.Item) && customDict.count(word.Item) == 0) |
| 237 | + { |
| 238 | + auto range = TextRange(token.Range.StartOffset + identifier.Range.Start + word.Range.Start, |
| 239 | + token.Range.StartOffset + identifier.Range.Start + word.Range.Start + word.Range. |
| 240 | + Count - 1 |
| 241 | + ); |
| 242 | + std::string originText(token.Text.substr(identifier.Range.Start + word.Range.Start, word.Range.Count)); |
| 243 | + ctx.PushDiagnosis(Util::format("Typo in string '{}'", originText), range, DiagnosisType::Spell, |
| 244 | + originText); |
| 245 | + } |
186 | 246 | } |
187 | 247 | } |
188 | 248 | } |
0 commit comments