Changeset View
Changeset View
Standalone View
Standalone View
src/lint/linter/ArcanistSpellingLinter.php
| Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | switch ($key) { | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| return parent::setLinterConfigurationValue($key, $value); | return parent::setLinterConfigurationValue($key, $value); | ||||
| } | } | ||||
| public function loadDictionary($path) { | public function loadDictionary($path) { | ||||
| $root = $this->getProjectRoot(); | // TOOLSETS: Restore the ability to reference resources relative to the | ||||
| $path = Filesystem::resolvePath($path, $root); | // project root. | ||||
| // $root = $this->getProjectRoot(); | |||||
| // $path = Filesystem::resolvePath($path, $root); | |||||
| $dict = phutil_json_decode(Filesystem::readFile($path)); | $dict = phutil_json_decode(Filesystem::readFile($path)); | ||||
| PhutilTypeSpec::checkMap( | PhutilTypeSpec::checkMap( | ||||
| $dict, | $dict, | ||||
| array( | array( | ||||
| 'rules' => 'map<string, map<string, string>>', | 'rules' => 'map<string, map<string, string>>', | ||||
| )); | )); | ||||
| $rules = $dict['rules']; | $rules = $dict['rules']; | ||||
| Show All 30 Lines | final class ArcanistSpellingLinter extends ArcanistLinter { | ||||
| public function getLintNameMap() { | public function getLintNameMap() { | ||||
| return array( | return array( | ||||
| self::LINT_SPELLING_EXACT => pht('Possible Spelling Mistake'), | self::LINT_SPELLING_EXACT => pht('Possible Spelling Mistake'), | ||||
| self::LINT_SPELLING_PARTIAL => pht('Possible Spelling Mistake'), | self::LINT_SPELLING_PARTIAL => pht('Possible Spelling Mistake'), | ||||
| ); | ); | ||||
| } | } | ||||
| public function lintPath($path) { | protected function lintPath(ArcanistWorkingCopyPath $path) { | ||||
| // TODO: This is a bit hacky. If no dictionaries were specified, then add | // TODO: This is a bit hacky. If no dictionaries were specified, then add | ||||
| // the default dictionary. | // the default dictionary. | ||||
| if (!$this->dictionaries) { | if (!$this->dictionaries) { | ||||
| $root = dirname(phutil_get_library_root('arcanist')); | $root = dirname(phutil_get_library_root('arcanist')); | ||||
| $this->loadDictionary($root.'/resources/spelling/english.json'); | $this->loadDictionary($root.'/resources/spelling/english.json'); | ||||
| } | } | ||||
| foreach ($this->exactWordRules as $misspelling => $correction) { | foreach ($this->exactWordRules as $misspelling => $correction) { | ||||
| $this->checkExactWord($path, $misspelling, $correction); | $this->checkExactWord($path, $misspelling, $correction); | ||||
| } | } | ||||
| foreach ($this->partialWordRules as $misspelling => $correction) { | foreach ($this->partialWordRules as $misspelling => $correction) { | ||||
| $this->checkPartialWord($path, $misspelling, $correction); | $this->checkPartialWord($path, $misspelling, $correction); | ||||
| } | } | ||||
| } | } | ||||
| private function checkExactWord($path, $word, $correction) { | private function checkExactWord( | ||||
| $text = $this->getData($path); | ArcanistWorkingCopyPath $path, | ||||
| $word, | |||||
| $correction) { | |||||
| $text = $path->getData(); | |||||
| $matches = array(); | $matches = array(); | ||||
| $num_matches = preg_match_all( | $num_matches = preg_match_all( | ||||
| '#\b'.preg_quote($word, '#').'\b#i', | '#\b'.preg_quote($word, '#').'\b#i', | ||||
| $text, | $text, | ||||
| $matches, | $matches, | ||||
| PREG_OFFSET_CAPTURE); | PREG_OFFSET_CAPTURE); | ||||
| if (!$num_matches) { | if (!$num_matches) { | ||||
| return; | return; | ||||
| } | } | ||||
| foreach ($matches[0] as $match) { | foreach ($matches[0] as $match) { | ||||
| $original = $match[0]; | $original = $match[0]; | ||||
| $replacement = self::fixLetterCase($correction, $original); | $replacement = self::fixLetterCase($correction, $original); | ||||
| $this->raiseLintAtOffset( | $this->raiseLintAtOffset( | ||||
| $match[1], | $match[1], | ||||
| self::LINT_SPELLING_EXACT, | self::LINT_SPELLING_EXACT, | ||||
| pht( | pht( | ||||
| "Possible spelling error. You wrote '%s', but did you mean '%s'?", | "Possible spelling error. You wrote '%s', but did you mean '%s'?", | ||||
| $word, | $word, | ||||
| $correction), | $correction), | ||||
| $original, | $original, | ||||
| $replacement); | $replacement); | ||||
| } | } | ||||
| } | } | ||||
| private function checkPartialWord($path, $word, $correction) { | private function checkPartialWord( | ||||
| $text = $this->getData($path); | ArcanistWorkingCopyPath $path, | ||||
| $word, | |||||
| $correction) { | |||||
| $text = $path->getData(); | |||||
| $pos = 0; | $pos = 0; | ||||
| while ($pos < strlen($text)) { | while ($pos < strlen($text)) { | ||||
| $next = stripos($text, $word, $pos); | $next = stripos($text, $word, $pos); | ||||
| if ($next === false) { | if ($next === false) { | ||||
| return; | return; | ||||
| } | } | ||||
| $original = substr($text, $next, strlen($word)); | $original = substr($text, $next, strlen($word)); | ||||
| $replacement = self::fixLetterCase($correction, $original); | $replacement = self::fixLetterCase($correction, $original); | ||||
| Show All 27 Lines | |||||