Spellchecker refactoring

This commit is contained in:
Ekaterina Shliakhovetskaja
2009-10-12 20:05:03 +04:00
parent 0cb8e1b155
commit 9065a9cb83
62 changed files with 4700 additions and 1593 deletions
Binary file not shown.
-11
View File
@@ -9,17 +9,6 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="properties" exported="" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/jazzy-core.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/lib-src/jazzy-0.5.2.src.zip!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module" module-name="lang-api" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="platform-api" />
+10 -5
View File
@@ -9,18 +9,23 @@
<application-components>
<component>
<interface-class>com.intellij.spellchecker.options.CachedDictionaryState</interface-class>
<implementation-class>com.intellij.spellchecker.options.CachedDictionaryState</implementation-class>
<interface-class>com.intellij.spellchecker.state.CachedDictionaryState</interface-class>
<implementation-class>com.intellij.spellchecker.state.CachedDictionaryState</implementation-class>
</component>
</application-components>
<project-components>
<component>
<interface-class>com.intellij.spellchecker.options.ProjectDictionaryState</interface-class>
<implementation-class>com.intellij.spellchecker.options.ProjectDictionaryState</implementation-class>
<interface-class>com.intellij.spellchecker.state.ProjectDictionaryState</interface-class>
<implementation-class>com.intellij.spellchecker.state.ProjectDictionaryState</implementation-class>
</component>
<component>
<interface-class>com.intellij.spellchecker.state.AggregatedDictionaryState</interface-class>
<implementation-class>com.intellij.spellchecker.state.AggregatedDictionaryState</implementation-class>
</component>
</project-components>
<actions>
<!-- Add your actions here -->
@@ -51,7 +56,7 @@
<inspectionToolProvider
implementation="com.intellij.spellchecker.inspections.SpellCheckerInspectionToolProvider"/>
<nameSuggestionProvider id="DictionarySuggestionProvider" implementation="com.intellij.spellchecker.DictionarySuggestionProvider"/>
<nameSuggestionProvider id="DictionarySuggestionProvider" implementation="com.intellij.spellchecker.quickfixes.DictionarySuggestionProvider"/>
<severitiesProvider implementation="com.intellij.spellchecker.SpellCheckerSeveritiesProvider"/>
<spellchecker.support implementation="com.intellij.spellchecker.tokenizer.SpellcheckingStrategy"/>
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker;
import com.intellij.spellchecker.dictionary.Loader;
import com.intellij.spellchecker.dictionary.Processor;
import org.jetbrains.annotations.NotNull;
import java.io.*;
public class FileLoader implements Loader {
private String url;
public FileLoader(String url) {
this.url = url;
}
public void load(@NotNull Processor processor) {
InputStream io = SpellCheckerManager.class.getResourceAsStream(url);
DataInputStream in = new DataInputStream(io);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
try{
String strLine;
while ((strLine = br.readLine()) != null) {
processor.process(strLine);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
br.close();
}
catch (IOException ignored) {
}
}
}
}
@@ -1,257 +1,148 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.spellchecker.engine.SpellChecker;
import com.intellij.spellchecker.engine.SpellCheckerFactory;
import com.intellij.spellchecker.options.SpellCheckerConfiguration;
import com.intellij.spellchecker.options.ProjectDictionaryState;
import com.intellij.spellchecker.options.CachedDictionaryState;
import com.intellij.spellchecker.util.Strings;
import com.intellij.spellchecker.dictionary.Dictionary;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.*;
/**
* Spell checker inspection provider.
*/
public final class SpellCheckerManager {
private static final Logger LOG = Logger.getInstance("#com.intellij.spellchecker.SpellCheckerManager");
private static final int MAX_SUGGESTIONS_THRESHOLD = 10;
private Project project;
private static HighlightDisplayLevel level;
private Set<String> dictionaries = new HashSet<String>();
private Dictionary projectWordList;
private Dictionary cachedWordList;
public Set<String> getDictionaries() {
return dictionaries;
}
@NonNls
private static final String[] DICT_URLS = new String[]{"english.dic", "jetbrains.dic"};
public static SpellCheckerManager getInstance(Project project) {
return ServiceManager.getService(project, SpellCheckerManager.class);
}
private final SpellCheckerConfiguration configuration;
private final SpellChecker spellChecker = SpellCheckerFactory.create();
public SpellCheckerManager(SpellCheckerConfiguration configuration, final Project project) {
this.configuration = configuration;
this.project = project;
reloadConfiguration();
}
@NotNull
public static HighlightDisplayLevel getHighlightDisplayLevel() {
return HighlightDisplayLevel.find(SpellCheckerSeveritiesProvider.TYPO);
}
@NotNull
public SpellChecker getSpellChecker() {
return spellChecker;
}
public boolean hasProblem(@NotNull String word) {
return !isIgnored(word) && !spellChecker.isCorrect(word);
}
private boolean isIgnored(@NotNull String word) {
return spellChecker.isIgnored(word.toLowerCase());
}
public List<String> getVariants(@NotNull String prefix) {
return spellChecker.getVariants(prefix);
}
@NotNull
public List<String> getSuggestions(@NotNull String word) {
if (!isIgnored(word) && !spellChecker.isCorrect(word)) {
List<String> suggestions = spellChecker.getSuggestions(word, MAX_SUGGESTIONS_THRESHOLD);
if (suggestions.size() != 0) {
boolean capitalized = Strings.isCapitalized(word);
boolean upperCases = Strings.isUpperCase(word);
if (capitalized) {
Strings.capitalize(suggestions);
}
else if (upperCases) {
Strings.upperCase(suggestions);
}
}
List<String> result = new ArrayList<String>();
for (String s : suggestions) {
if (!result.contains(s)) {
result.add(s);
}
}
return result;
}
return Collections.emptyList();
}
@NotNull
public List<String> getSuggestionsExt(@NotNull String word) {
return spellChecker.getSuggestionsExt(word, MAX_SUGGESTIONS_THRESHOLD);
}
/**
* Load dictionary from stream.
*
* @param inputStream Dictionary input stream
* @throws java.io.IOException if dictionary load with problems
*/
public void addDictionary(@NotNull InputStream inputStream) throws IOException {
addDictionary(inputStream, Charset.defaultCharset().name());
}
/**
* Load dictionary from stream.
*
* @param inputStream Dictionary input stream
* @param encoding Encoding
* @throws java.io.IOException if dictionary load with problems
*/
public void addDictionary(@NotNull InputStream inputStream, @NonNls String encoding) throws IOException {
addDictionary(inputStream, encoding, Locale.getDefault());
}
/**
* Load dictionary from stream.
*
* @param inputStream Dictionary input stream
* @param encoding Encoding
* @param locale Locale of dictionary
* @throws java.io.IOException if dictionary load with problems
*/
public void addDictionary(@NotNull InputStream inputStream, @NonNls String encoding, @NonNls @NotNull Locale locale) throws IOException {
spellChecker.addDictionary(inputStream, encoding, locale);
}
public void acceptWordAsCorrect(@NotNull String word) {
String lowerCased = word.toLowerCase();
projectWordList.acceptWord(word);
cachedWordList.acceptWord(word);
spellChecker.addToDictionary(lowerCased);
}
public void reloadConfiguration() {
initDictionaries();
spellChecker.reset();
projectWordList = ServiceManager.getService(project, ProjectDictionaryState.class).getDictionary();
cachedWordList = ServiceManager.getService(project, CachedDictionaryState.class).getDictionary();
for (String word : projectWordList.getWords()) {
cachedWordList.acceptWord(word);
}
for (String word : ejectAll(cachedWordList.getWords())) {
String lowerCased = word.toLowerCase();
spellChecker.addToDictionary(lowerCased);
}
}
public void applyConfiguration() {
initDictionaries();
spellChecker.reset();
assert projectWordList != null;
assert cachedWordList != null;
for (String word : projectWordList.getWords()) {
cachedWordList.acceptWord(word);
}
for (String word : ejectAll(cachedWordList.getWords())) {
String lowerCased = word.toLowerCase();
spellChecker.addToDictionary(lowerCased);
}
}
private void initDictionaries() {
for (String dictUrl : DICT_URLS) {
initDictionary(dictUrl);
}
}
private void initDictionary(String url) {
InputStream is = SpellCheckerManager.class.getResourceAsStream(url);
if (is != null) {
try {
dictionaries.add(url);
addDictionary(is);
}
catch (IOException e) {
LOG.error("Dictionary could not be loaded", e);
}
}
}
public void restartInspections() {
//reloadConfiguration();
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Project[] projects = ProjectManager.getInstance().getOpenProjects();
for (Project project : projects) {
if (project.isInitialized() && project.isOpen() && !project.isDefault()) {
DaemonCodeAnalyzer.getInstance(project).restart();
}
}
}
});
}
private HashSet<String> ejectAll(Set<String> from) {
HashSet<String> words = new HashSet<String>(from);
// from.clear();
return words;
}
public Dictionary getProjectWordList() {
return projectWordList;
}
public Dictionary getCachedWordList() {
return cachedWordList;
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.dictionary.Loader;
import com.intellij.spellchecker.engine.SpellCheckerEngine;
import com.intellij.spellchecker.engine.SpellCheckerFactory;
import com.intellij.spellchecker.state.StateLoader;
import com.intellij.spellchecker.util.Strings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class SpellCheckerManager {
private static final int MAX_SUGGESTIONS_THRESHOLD = 5;
private static final int MAX_METRICS = 1;
private Project project;
private SpellCheckerEngine spellChecker;
private Dictionary userDictionary;
public static SpellCheckerManager getInstance(Project project) {
return ServiceManager.getService(project, SpellCheckerManager.class);
}
public SpellCheckerManager(Project project) {
this.project = project;
reloadConfiguration();
}
public Dictionary getUserDictionary() {
return userDictionary;
}
public void reloadConfiguration() {
spellChecker = SpellCheckerFactory.create();
fillEngineDictionary();
}
private void fillEngineDictionary() {
spellChecker.reset();
final StateLoader stateLoader = new StateLoader(project);
Loader[] loaders = new Loader[]{new FileLoader("english.dic"), new FileLoader("jetbrains.dic"), stateLoader};
for (Loader loader : loaders) {
spellChecker.loadDictionary(loader);
}
userDictionary = stateLoader.getDictionary();
}
public boolean hasProblem(@NotNull String word) {
return !spellChecker.isCorrect(word);
}
public void acceptWordAsCorrect(@NotNull String word) {
final String transformed = spellChecker.getTransformation().transform(word);
if (transformed != null) {
userDictionary.addToDictionary(transformed);
spellChecker.addToDictionary(transformed);
}
}
public void updateUserWords(@Nullable Collection<String> words) {
Set<String> transformed = spellChecker.getTransformation().transform(words);
userDictionary.replaceAll(transformed);
fillEngineDictionary();
restartInspections();
}
@NotNull
public static HighlightDisplayLevel getHighlightDisplayLevel() {
return HighlightDisplayLevel.find(SpellCheckerSeveritiesProvider.TYPO);
}
@NotNull
public List<String> getSuggestions(@NotNull String word) {
if (!spellChecker.isCorrect(word)) {
List<String> suggestions = spellChecker.getSuggestions(word, MAX_SUGGESTIONS_THRESHOLD, MAX_METRICS);
if (suggestions.size() != 0) {
boolean capitalized = Strings.isCapitalized(word);
boolean upperCases = Strings.isUpperCase(word);
if (capitalized) {
Strings.capitalize(suggestions);
}
else if (upperCases) {
Strings.upperCase(suggestions);
}
}
List<String> result = new ArrayList<String>();
for (String s : suggestions) {
if (!result.contains(s)) {
result.add(s);
}
}
return result;
}
return Collections.emptyList();
}
@NotNull
public List<String> getVariants(@NotNull String prefix) {
return Collections.emptyList();
}
public void restartInspections() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Project[] projects = ProjectManager.getInstance().getOpenProjects();
for (Project project : projects) {
if (project.isInitialized() && project.isOpen() && !project.isDefault()) {
DaemonCodeAnalyzer.getInstance(project).restart();
}
}
}
});
}
}
@@ -0,0 +1,120 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import com.intellij.spellchecker.trie.Action;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class AggregatedDictionary implements Dictionary {
private static final String DICTIONARY_NAME = "common";
private Dictionary cachedDictionary;
private ProjectDictionary projectDictionary;
public String getName() {
return DICTIONARY_NAME;
}
public AggregatedDictionary(@NotNull ProjectDictionary projectDictionary, @NotNull Dictionary cachedDictionary) {
this.projectDictionary = projectDictionary;
this.cachedDictionary = cachedDictionary;
this.cachedDictionary.addToDictionary(projectDictionary.getWords());
}
public boolean isEmpty() {
return false;
}
public boolean contains(String word) {
if (word == null) {
return false;
}
return cachedDictionary.contains(word);
}
public void addToDictionary(String word) {
getProjectDictionary().addToDictionary(word);
getCachedDictionary().addToDictionary(word);
}
public void removeFromDictionary(String word) {
getProjectDictionary().removeFromDictionary(word);
getCachedDictionary().removeFromDictionary(word);
}
public void replaceAll(@Nullable Collection<String> words) {
Set<String> oldWords = getProjectDictionary().getWords();
getProjectDictionary().replaceAll(words);
if (oldWords != null) {
for (String word : oldWords) {
if (words == null || !words.contains(word)) {
getCachedDictionary().removeFromDictionary(word);
}
}
}
}
public void clear() {
getProjectDictionary().clear();
}
public void traverse(final Action action) {
cachedDictionary.traverse(action);
}
public Set<String> getWords() {
Set<String> words = new HashSet<String>();
words.addAll(cachedDictionary.getWords());
return words;
}
@Nullable
public Set<String> getEditableWords() {
return getProjectDictionary().getEditableWords();
}
@Nullable
public Set<String> getNotEditableWords() {
Set<String> words = getWords();
Set<String> editable = getEditableWords();
if (words != null && editable != null) {
words.removeAll(editable);
}
return words;
}
public void addToDictionary(@Nullable Collection<String> words) {
getProjectDictionary().addToDictionary(words);
getCachedDictionary().addToDictionary(words);
}
public Dictionary getCachedDictionary() {
return cachedDictionary;
}
public ProjectDictionary getProjectDictionary() {
return projectDictionary;
}
}
@@ -1,32 +1,54 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public interface Dictionary {
Set<String> getWords();
void acceptWord(@NotNull String word);
void replaceAllWords(Set<String> newWords);
String getName();
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import com.intellij.spellchecker.trie.Action;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Set;
public interface Dictionary {
String getName();
boolean contains(String word);
boolean isEmpty();
void addToDictionary(String word);
void removeFromDictionary(String word);
void addToDictionary(@Nullable Collection<String> words);
void replaceAll(@Nullable Collection<String> words);
void clear();
void traverse(final Action action);
@Nullable
Set<String> getWords();
@Nullable
Set<String> getEditableWords();
@Nullable
Set<String> getNotEditableWords();
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import org.jetbrains.annotations.NotNull;
public interface Loader {
void load(@NotNull Processor processor);
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import org.jetbrains.annotations.Nullable;
public interface Processor {
void process(@Nullable String word);
}
@@ -1,89 +1,192 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
*
* @author shkate@jetbrains.com
*/
public class ProjectDictionary extends UserDictionary {
@NotNull
public List<Dictionary> dictionaries = new ArrayList<Dictionary>();
public ProjectDictionary() {
}
public ProjectDictionary(String name) {
super(name);
}
@Override
public Set<String> getWords() {
Set<String> words = new HashSet<String>();
for (Dictionary dictionary : dictionaries) {
words.addAll(dictionary.getWords());
}
return words;
}
@Override
public void acceptWord(@NotNull String word) {
getUserDictionary().acceptWord(word);
}
@Override
public void replaceAllWords(Set<String> newWords) {
getUserDictionary().replaceAllWords(newWords);
}
public void setDictionaries(@NotNull List<Dictionary> dictionaries) {
this.dictionaries = dictionaries;
}
@NotNull
public List<Dictionary> getDictionaries(){
return dictionaries;
}
public Dictionary getUserDictionary() {
final String name = getCurrentUserName();
Dictionary userDictionary = null;
for (Dictionary dictionary : dictionaries) {
if (dictionary.getName().equals(name)){
userDictionary = dictionary;
break;
}
}
if (userDictionary==null){
userDictionary = new UserDictionary(name);
dictionaries.add((UserDictionary)userDictionary);
}
return userDictionary;
}
public static String getCurrentUserName() {
return System.getProperty("user.name");
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import com.intellij.spellchecker.trie.Action;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class ProjectDictionary implements Dictionary {
private static final String DEFAULT_CURRENT_USER_NAME = "default.user";
private static final String DEFAULT_PROJECT_DICTIONARY_NAME = "project";
private String activeName;
private Set<Dictionary> dictionaries;
public ProjectDictionary() {
}
public ProjectDictionary(Set<Dictionary> dictionaries) {
this.dictionaries = dictionaries;
}
public boolean isEmpty() {
return false;
}
public String getName() {
return DEFAULT_PROJECT_DICTIONARY_NAME;
}
public String getActiveName() {
return activeName;
}
public void setActiveName(String name) {
this.activeName = name;
}
public boolean contains(String word) {
if (word == null || dictionaries == null) {
return false;
}
for (Dictionary dictionary : dictionaries) {
if (dictionary.contains(word)) {
return true;
}
}
return false;
}
public void addToDictionary(String word) {
getActiveDictionary().addToDictionary(word);
}
public void removeFromDictionary(String word) {
getActiveDictionary().removeFromDictionary(word);
}
@NotNull
private Dictionary getActiveDictionary() {
return ensureCurrentUserDictionary();
}
@NotNull
private Dictionary ensureCurrentUserDictionary() {
if (activeName == null) {
activeName = DEFAULT_CURRENT_USER_NAME;
}
Dictionary result = getDictionaryByName(activeName);
if (result == null) {
result = new UserDictionary(this.activeName);
if (dictionaries == null) {
dictionaries = new HashSet<Dictionary>();
}
dictionaries.add(result);
}
return result;
}
@Nullable
private Dictionary getDictionaryByName(@NotNull String name) {
if (dictionaries == null) {
return null;
}
Dictionary result = null;
for (Dictionary dictionary : dictionaries) {
if (dictionary.getName().equals(name)) {
result = dictionary;
break;
}
}
return result;
}
public void replaceAll(@Nullable Collection<String> words) {
getActiveDictionary().replaceAll(words);
}
public void clear() {
getActiveDictionary().clear();
}
@Nullable
public Set<String> getWords() {
if (dictionaries == null) {
return null;
}
Set<String> words = new HashSet<String>();
for (Dictionary dictionary : dictionaries) {
words.addAll(dictionary.getWords());
}
return words;
}
public void traverse(Action action) {
if (dictionaries == null) {
return;
}
for (Dictionary dictionary : dictionaries) {
dictionary.traverse(action);
}
}
@Nullable
public Set<String> getEditableWords() {
return getActiveDictionary().getWords();
}
@Nullable
public Set<String> getNotEditableWords() {
Set<String> words = getWords();
Set<String> editable = getEditableWords();
if (words != null && editable != null) {
words.removeAll(editable);
}
return words;
}
public void addToDictionary(@Nullable Collection<String> words) {
getActiveDictionary().addToDictionary(words);
}
public Set<Dictionary> getDictionaries() {
return dictionaries;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProjectDictionary that = (ProjectDictionary)o;
if (activeName != null ? !activeName.equals(that.activeName) : that.activeName != null) return false;
if (dictionaries != null ? !dictionaries.equals(that.dictionaries) : that.dictionaries != null) return false;
return true;
}
@Override
public int hashCode() {
int result = activeName != null ? activeName.hashCode() : 0;
result = 31 * result + (dictionaries != null ? dictionaries.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "ProjectDictionary{" + "activeName='" + activeName + '\'' + ", dictionaries=" + dictionaries + '}';
}
}
@@ -1,73 +1,126 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
*
* @author shkate@jetbrains.com
*/
@Tag("dictionary")
public class UserDictionary implements Dictionary {
@Tag("words")
@AbstractCollection(surroundWithTag = false,elementTag = "w",elementValueAttribute = "")
public Set<String> words = new HashSet<String>();
@Attribute(NAME_ATTRIBUTE)
public String name = "new";
private static final String NAME_ATTRIBUTE = "name";
public UserDictionary() {
}
public UserDictionary(String name) {
this.name = name;
}
@NotNull
public String getName() {
return name;
}
public Set<String> getWords() {
return Collections.unmodifiableSet(words);
}
public void acceptWord(@NotNull String word) {
words.add(word);
}
public void replaceAllWords(Set<String> newWords) {
replaceAll(words, newWords);
}
private static void replaceAll(Set<String> words, Set<String> newWords) {
words.clear();
words.addAll(newWords);
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.dictionary;
import com.intellij.spellchecker.trie.Action;
import com.intellij.spellchecker.trie.CharSequenceKeyAnalyzer;
import com.intellij.spellchecker.trie.PatriciaTrie;
import com.intellij.spellchecker.trie.Trie;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class UserDictionary implements Dictionary {
private String name;
private Trie<String, String> trie = new PatriciaTrie<String, String>(new CharSequenceKeyAnalyzer());
public UserDictionary(String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean contains(String word) {
return word != null && trie.containsKey(word);
}
@Nullable
public Set<String> getWords() {
return trie.keySet();
}
@Nullable
public Set<String> getEditableWords() {
return trie.keySet();
}
@Nullable
public Set<String> getNotEditableWords() {
return null;
}
public void clear() {
trie.clear();
}
public void addToDictionary(String word) {
if (word == null) {
return;
}
trie.put(word, word);
}
public void removeFromDictionary(String word) {
if (word == null) {
return;
}
trie.remove(word);
}
public void replaceAll(@Nullable Collection<String> words) {
clear();
addToDictionary(words);
}
public void addToDictionary(@Nullable Collection<String> words) {
if (words == null || words.isEmpty()) {
return;
}
for (String word : words) {
addToDictionary(word);
}
}
public boolean isEmpty() {
return (trie == null || trie.size() == 0);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserDictionary that = (UserDictionary)o;
return !(name != null ? !name.equals(that.name) : that.name != null);
}
public void traverse(final Action action){
trie.traverse(new PatriciaTrie.Cursor<String, String>() {
public SelectStatus select(Map.Entry<? extends String, ? extends String> entry) {
action.run(entry);
return SelectStatus.CONTINUE;
}
});
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
@Override
public String toString() {
return "UserDictionary{" + "name='" + name + '\'' + ", words.count=" + trie.size() + '}';
}
}
@@ -0,0 +1,115 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
import com.intellij.spellchecker.dictionary.*;
import com.intellij.spellchecker.trie.Action;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class BaseSpellChecker implements SpellCheckerEngine {
private Dictionary engineDictionary;
private Transformation transform = new Transformation();
private Metrics metrics = new LevenshteinDistance();
private Processor processor = new Processor() {
public void process(@Nullable String word) {
final String transformed = transform.transform(word);
if (transformed != null) {
engineDictionary.addToDictionary(transformed);
}
}
};
public BaseSpellChecker() {
ensureEngineDictionary();
}
public void loadDictionary(@NotNull Loader loader) {
loader.load(processor);
}
public Transformation getTransformation() {
return transform;
}
private void ensureEngineDictionary() {
if (engineDictionary == null) {
engineDictionary = new UserDictionary("engine");
}
}
public void addToDictionary(String word) {
final String transformed = transform.transform(word);
if (transformed != null) {
engineDictionary.addToDictionary(transformed);
}
}
public boolean isCorrect(@NotNull String word) {
final String transformed = transform.transform(word);
return transformed != null && engineDictionary.contains(transformed);
}
@NotNull
public List<String> getSuggestions(final @NotNull String word, int threshold, int quality) {
final List<Suggestion> suggestions = new ArrayList<Suggestion>();
suggestions.clear();
engineDictionary.traverse(new Action() {
public void run(Map.Entry<? extends String, ? extends String> entry) {
if (word.charAt(0) == entry.getKey().charAt(0)/* && Math.abs(mpw.length() - entry.getKey().length()) <= 1*/) {
final int distance = metrics.calculateMetrics(word, entry.getKey());
suggestions.add(new Suggestion(entry.getKey(), distance));
}
}
});
List<String> result = new ArrayList<String>();
if (suggestions.isEmpty()){
return result;
}
Collections.sort(suggestions);
int bestMetrics = suggestions.get(0).getMetrics();
for (int i = 0; i < threshold; i++) {
if (suggestions.size()<i || bestMetrics-suggestions.get(i).getMetrics()>quality){
break;
}
result.add(i,suggestions.get(i).getWord());
}
return result;
}
@NotNull
public List<String> getVariants(@NotNull String prefix) {
return null;
}
public void reset() {
engineDictionary = null;
ensureEngineDictionary();
}
}
@@ -1,286 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
import com.swabunga.spell.engine.SpellDictionaryHashMap;
import com.swabunga.spell.engine.Word;
import com.intellij.psi.codeStyle.NameUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.*;
/**
* Jazzy implementation of Spell Checker.
*/
final class JazzySpellChecker implements SpellChecker {
private final SpellCheckerWrapper delegate = new SpellCheckerWrapper();
private final Map<SpellDictionaryImpl, Set<Character>> dictionaries = new HashMap<SpellDictionaryImpl, Set<Character>>();
private final Set<Character> allowed = new HashSet<Character>();
private SpellDictionaryImpl userDictionary;
JazzySpellChecker() {
setUserDictionary();
}
public void addDictionary(@NotNull InputStream is, @NonNls String encoding, @NotNull Locale locale) throws IOException {
SpellDictionaryImpl spellDictionary = new SpellDictionaryImpl(new InputStreamReader(is, encoding), locale);
Set<Character> indexedChars = spellDictionary.getIndexedChars();
dictionaries.put(spellDictionary, indexedChars);
allowed.addAll(indexedChars);
delegate.addDictionary(spellDictionary);
}
public void addToDictionary(@NotNull String word) {
delegate.addToDictionary(word);
indexWord(word);
}
private void indexWord(CharSequence word) {
indexWord(word, allowed);
}
private static void indexWord(CharSequence word, Set<Character> index) {
for (int i = 0; i < word.length(); i++) {
index.add(word.charAt(i));
}
}
public void ignoreAll(@NotNull String word) {
delegate.ignoreAll(word);
}
public boolean isIgnored(@NotNull String word) {
return !isEntireWordAllowed(word, allowed) || delegate.isIgnored(word);
}
public boolean isCorrect(@NotNull String word) {
return !isEntireWordAllowed(word, allowed) || delegate.isCorrect(word);
}
private static boolean isEntireWordAllowed(CharSequence word, Set<Character> index) {
for (int i = 0; i < word.length(); i++) {
if (!index.contains(word.charAt(i))) {
return false;
}
}
return true;
}
private Set<Character> findDictionaryIndex(String word) {
Set<Character> commonIndex = null;
Set<Character> lastIndex = null;
Collection<Set<Character>> indexes = dictionaries.values();
for (Set<Character> index : indexes) {
if (isEntireWordAllowed(word, index)) {
if (lastIndex != null && commonIndex == null) {
commonIndex = new HashSet<Character>(lastIndex.size() + index.size());
commonIndex.addAll(lastIndex);
lastIndex = commonIndex;
}
if (commonIndex != null) {
commonIndex.addAll(index);
} else {
lastIndex = index;
}
}
}
return lastIndex;
}
@NotNull
@SuppressWarnings({"unchecked"})
public List<String> getSuggestions(@NotNull String word, int threshold) {
List<Word> words = delegate.getSuggestions(word, threshold);
Set<Character> index = findDictionaryIndex(word);
List<String> strings = new ArrayList<String>(words.size());
for (Word w : words) {
String suggestion = w.getWord();
if (index == null || isEntireWordAllowed(suggestion, index)) {
strings.add(suggestion);
}
}
return strings;
}
@NotNull
public List<String> getSuggestionsExt(@NotNull String text, int threshold) {
String[] words = NameUtil.nameToWords(text);
List<String> result = new ArrayList<String>();
int index = 0;
List[] res = new List[words.length];
int i = 0;
for (String word : words) {
int start = text.indexOf(word, index);
int end = start + word.length();
if (!isCorrect(word)) {
List<String> variants = new ArrayList<String>();
variants.add(word);
res[i++] = variants;
} else {
List<String> variants = getSuggestions(word, threshold);
res[i++] = variants;
}
index = end;
}
int counter[] = new int[i];
int size = 1;
for (int j = 0; j < i; j++) {
size *= res[j].size();
}
String[] all = new String[size];
for (int k = 0; k < size; k++) {
for (int j = 0; j < i; j++) {
if (all[k] == null) {
all[k] = "";
}
all[k] += res[j].get(counter[j]);
counter[j]++;
if (counter[j] >= res[j].size()) {
counter[j] = 0;
}
}
}
result.addAll(Arrays.asList(all));
return result;
}
@NotNull
public List<String> getVariants(@NotNull String prefix) {
if (prefix.length() > 0) {
List<String> variants = new ArrayList<String>();
userDictionary.appendWordsStartsWith(prefix, variants);
Set<Character> index = new HashSet<Character>();
indexWord(prefix, index);
for (SpellDictionaryImpl dictionary : dictionaries.keySet()) {
Set<Character> dictionaryIndex = dictionaries.get(dictionary);
if (isSame(index, dictionaryIndex)) {
dictionary.appendWordsStartsWith(prefix, variants);
}
}
Collections.sort(variants);
return variants;
}
return Collections.emptyList();
}
private static boolean isSame(@NotNull Set<Character> i1, @NotNull Set<Character> i2) {
if (i1.equals(i2)) {
return true;
}
for (Character c : i1) {
if (!i2.contains(c)) {
return false;
}
}
return true;
}
public void reset() {
delegate.reset();
allowed.clear();
Collection<Set<Character>> sets = dictionaries.values();
for (Set<Character> set : sets) {
allowed.addAll(set);
}
setUserDictionary();
}
private void setUserDictionary() {
try {
userDictionary = new SpellDictionaryImpl(Locale.getDefault());
delegate.setUserDictionary(userDictionary);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
private static class SpellDictionaryImpl extends SpellDictionaryHashMap {
private final Locale locale;
public SpellDictionaryImpl(Locale locale) throws IOException {
this.locale = locale;
}
private SpellDictionaryImpl(Reader wordList, Locale locale) throws IOException {
super(wordList);
this.locale = locale;
}
@SuppressWarnings({"unchecked"})
public Set<Character> getIndexedChars() {
Set<Character> index = new HashSet<Character>(64);
Collection<List<String>> values = mainDictionary.values();
for (List<String> wordList : values) {
if (wordList != null) {
for (String word : wordList) {
if (word != null) {
indexWord(word, index);
}
}
}
}
return Collections.unmodifiableSet(index);
}
@SuppressWarnings({"unchecked"})
public void appendWordsStartsWith(@NotNull String prefix, @NotNull Collection<String> buffer) {
String prefixLowerCase = prefix.toLowerCase(locale);
Collection<List<String>> values = mainDictionary.values();
int prefixLength = prefix.length();
StringBuilder builder = new StringBuilder();
for (List<String> wordList : values) {
if (wordList != null) {
for (String word : wordList) {
if (word != null) {
String lowerCased = word.toLowerCase(locale);
int length = lowerCased.length();
if (lowerCased.startsWith(prefixLowerCase) && length > prefixLength) {
builder.setLength(0);
builder.append(prefix);
builder.append(lowerCased, prefixLength, length);
String value = builder.toString();
if (!buffer.contains(value)) {
buffer.add(value);
}
}
}
}
}
}
}
}
private static final class SpellCheckerWrapper extends com.swabunga.spell.event.SpellChecker {
private SpellCheckerWrapper() {
// Disable caching
setCache(0);
}
public List getSuggestions(String word, int threshold) {
return super.getSuggestions(word, threshold);
}
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
public class LevenshteinDistance implements Metrics {
private static int minimum(int a, int b, int c) {
return Math.min(Math.min(a, b), c);
}
public int calculateMetrics(CharSequence str1, CharSequence str2) {
int[][] distance = new int[str1.length() + 1][str2.length() + 1];
for (int i = 0; i <= str1.length(); i++) {
distance[i][0] = i;
}
for (int j = 0; j <= str2.length(); j++) {
distance[0][j] = j;
}
for (int i = 1; i <= str1.length(); i++) {
for (int j = 1; j <= str2.length(); j++) {
distance[i][j] = minimum(distance[i - 1][j] + 1, distance[i][j - 1] + 1,
distance[i - 1][j - 1] + ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1));
}
}
return distance[str1.length()][str2.length()];
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
public interface Metrics {
int calculateMetrics(CharSequence str1, CharSequence str2);
}
@@ -1,53 +1,46 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
/**
* Spell checker.
*/
public interface SpellChecker {
void addDictionary(@NotNull InputStream is, @NonNls String encoding, @NotNull Locale locale) throws IOException;
void addToDictionary(@NotNull String word);
void ignoreAll(@NotNull String word);
boolean isIgnored(@NotNull String word);
boolean isCorrect(@NotNull String word);
@NotNull
List<String> getSuggestions(@NotNull String word, int threshold);
@NotNull
List<String> getSuggestionsExt(@NotNull String word, int threshold);
@NotNull
List<String> getVariants(@NotNull String prefix);
/**
* This method must clean up user dictionary words and ignored words.
*/
void reset();
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
import com.intellij.spellchecker.dictionary.Loader;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface SpellCheckerEngine {
void loadDictionary(@NotNull Loader loader);
Transformation getTransformation();
boolean isCorrect(@NotNull String word);
void addToDictionary(String word);
@NotNull
List<String> getSuggestions(@NotNull String word, int threshold, int quality);
@NotNull
List<String> getVariants(@NotNull String prefix);
/**
* This method must clean up user dictionary words and ignored words.
*/
void reset();
}
@@ -1,28 +1,25 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
/**
* Spell checker factory.
*/
public final class SpellCheckerFactory {
private SpellCheckerFactory() {
}
public static SpellChecker create() {
return new JazzySpellChecker();
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
public final class SpellCheckerFactory {
private SpellCheckerFactory() {
}
public static SpellCheckerEngine create() {
return new BaseSpellChecker();
}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
public class Suggestion implements Comparable{
private String word;
private int metrics;
public Suggestion(String word, int metrics) {
this.word = word;
this.metrics = metrics;
}
public String getWord() {
return word;
}
public int getMetrics() {
return metrics;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Suggestion result = (Suggestion)o;
if (metrics != result.metrics) return false;
if (word != null ? !word.equals(result.word) : result.word != null) return false;
return true;
}
@Override
public int hashCode() {
int result = word != null ? word.hashCode() : 0;
result = 31 * result + metrics;
return result;
}
public int compareTo(Object o) {
if (!(o instanceof Suggestion)) throw new IllegalArgumentException();
Suggestion r = (Suggestion)o;
return new Integer(getMetrics()).compareTo(r.getMetrics());
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.engine;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Set;
public class Transformation {
@Nullable
public String transform(@Nullable String word) {
if (word == null || word.trim().length() < 3) {
return null;
}
return word.trim().toLowerCase();
}
@Nullable
public Set<String> transform(@Nullable Collection<String> words) {
if (words == null || words.isEmpty()) {
return null;
}
Set<String> result = new HashSet<String>();
for (String word : words) {
String transformed = transform(word);
if (transformed != null) {
result.add(transformed);
}
}
return result;
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.spellchecker;
package com.intellij.spellchecker.inspections;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.Nullable;
@@ -39,17 +39,11 @@ public class CheckArea {
return textRange;
}
public void setTextRange(TextRange textRange) {
this.textRange = textRange;
}
public boolean isIgnored() {
return ignored;
}
public void setIgnored(boolean ignored) {
this.ignored = ignored;
}
@Nullable
public String getWord() {
@@ -59,6 +53,6 @@ public class CheckArea {
@Override
public String toString() {
return "CheckArea{range = " + textRange + ", ignored=" + ignored + ", word=" + (getWord()!=null?getWord():"") +'}';
return "CheckArea{range = " + textRange + ", ignored=" + ignored + ", word=" + (getWord() != null ? getWord() : "") + '}';
}
}
@@ -26,9 +26,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.tree.IElementType;
import com.intellij.spellchecker.CheckArea;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.TextSplitter;
import com.intellij.spellchecker.quickfixes.AcceptWordAsCorrect;
import com.intellij.spellchecker.quickfixes.ChangeTo;
import com.intellij.spellchecker.quickfixes.RenameTo;
@@ -180,7 +178,7 @@ public class SpellCheckingInspection extends LocalInspectionTool {
fixes.add(new ChangeTo(textRange, word, token.getElement().getProject()));
}
else {
fixes.add(new RenameTo());
fixes.add(new RenameTo(textRange, word, token.getElement().getProject()));
}
}
@@ -201,6 +199,7 @@ public class SpellCheckingInspection extends LocalInspectionTool {
final String description = tokenDescription == null ? defaultDescription : tokenDescription;
final TextRange highlightRange = TextRange.from(token.getOffset() + textRange.getStartOffset(), textRange.getLength());
final LocalQuickFix[] quickFixes = fixes.size() > 0 ? fixes.toArray(new LocalQuickFix[fixes.size()]) : null;
return holder.getManager()
.createProblemDescriptor(token.getElement(), highlightRange, description, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, quickFixes);
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.spellchecker;
package com.intellij.spellchecker.inspections;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
@@ -41,7 +41,7 @@ public class TextSplitter {
@NonNls
/*private static final Pattern WORD = Pattern.compile("\\b\\p{L}+'?\\p{L}*\\b");*/
private static final Pattern WORD = Pattern.compile("\\b\\p{Alpha}*'?\\p{Alpha}");
private static final Pattern WORD = Pattern.compile("\\b\\p{Alpha}*'?\\p{Alpha}*");
private static final Pattern EXTENDED_WORD = Pattern.compile("\\b\\p{Alpha}*'?\\p{Alpha}(_*\\p{Alpha})*");
@@ -1,75 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.spellchecker.dictionary.UserDictionary;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.dictionary.ProjectDictionary;
import java.util.ArrayList;
import java.util.List;
@State(
name = "ProjectDictionaryState",
storages = {@Storage(
id = "other",
file = "$PROJECT_FILE$"), @Storage(
id = "dir",
file = "$PROJECT_CONFIG_DIR$/dictionaries/",
scheme = StorageScheme.DIRECTORY_BASED, stateSplitter = ProjectDictionarySplitter.class)})
public class ProjectDictionaryState implements PersistentStateComponent<ProjectDictionaryState> {
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false,elementTypes = UserDictionary.class)
public List<Dictionary> dictionaries = new ArrayList<Dictionary>();
private ProjectDictionary projectDictionary;
public ProjectDictionaryState getState() {
return this;
}
public void loadState(ProjectDictionaryState state) {
XmlSerializerUtil.copyBean(state, this);
createProjectDictionary();
}
private void createProjectDictionary() {
projectDictionary = new ProjectDictionary("project");
projectDictionary.setDictionaries(dictionaries);
projectDictionary.getUserDictionary();
}
public ProjectDictionary getDictionary() {
if (projectDictionary == null) {
createProjectDictionary();
}
return projectDictionary;
}
}
@@ -1,120 +1,102 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Set;
public final class SpellCheckerConfigurable implements Configurable {
private SpellCheckerManager manager;
private final Project myProject;
private final SpellCheckerConfiguration configuration;
private SpellCheckerOptions options;
public SpellCheckerConfigurable(Project project, SpellCheckerConfiguration configuration) {
myProject = project;
this.configuration = configuration;
}
@Nls
public String getDisplayName() {
return SpellCheckerBundle.message("spelling");
}
@Nullable
public Icon getIcon() {
return null;
}
@Nullable
@NonNls
public String getHelpTopic() {
return "reference.settings.ide.settings.spelling";
}
public JComponent createComponent() {
manager = SpellCheckerManager.getInstance(myProject);
if (options == null) {
options = new SpellCheckerOptions(configuration, manager);
}
return options.getRoot();
}
public boolean isModified() {
if (options != null) {
if (dictionaryListWasChanged()) {
return true;
}
}
return false;
}
private boolean dictionaryListWasChanged() {
return !same(options.getUserDictionaryWordsSet(), options.getShownDictionary().getWords());
}
private static boolean same(Set<String> modified, Set<String> original) {
if (original.size() != modified.size()) {
return false;
}
modified.removeAll(original);
return modified.size() == 0;
}
public void apply() throws ConfigurationException {
if (options != null) {
boolean reload = false;
if (dictionaryListWasChanged()) {
options.getShownDictionary().replaceAllWords(options.getUserDictionaryWordsSet());
reload = true;
}
/***replaceAll(configuration.activeDictionary.dictionaryWords, options.getUserDictionaryWords());
replaceAll(configuration.activeDictionary.ignoredWords, options.getIgnoredWords());*//**//*
manager.restartInspections();*/
if (reload) {
manager.applyConfiguration();
manager.restartInspections();
}
}
}
public void reset() {
}
public void disposeUIResources() {
if (options != null) {
options.dispose();
options = null;
}
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
import java.util.Set;
public final class SpellCheckerConfigurable implements Configurable {
private SpellCheckerOptions options;
private SpellCheckerManager manager;
private final Project myProject;
public SpellCheckerConfigurable(Project project) {
myProject = project;
}
@Nls
public String getDisplayName() {
return SpellCheckerBundle.message("spelling");
}
@Nullable
public Icon getIcon() {
return null;
}
@Nullable
@NonNls
public String getHelpTopic() {
return "reference.settings.ide.settings.spelling";
}
public JComponent createComponent() {
manager = SpellCheckerManager.getInstance(myProject);
if (options == null) {
options = new SpellCheckerOptions(manager);
}
return options.getRoot();
}
public boolean isModified() {
if (options != null) {
return wordsListIsModified();
}
return false;
}
private boolean wordsListIsModified() {
assert options != null;
List<String> newWords = options.getWords();
Set<String> words = manager.getUserDictionary().getWords();
if (words == null && newWords == null) {
return false;
}
if (words == null || newWords == null || newWords.size() != words.size()) {
return true;
}
return words.containsAll(newWords) && newWords.containsAll(words);
}
public void apply() throws ConfigurationException {
manager.updateUserWords(options.getWords());
}
public void reset() {
}
public void disposeUIResources() {
if (options != null) {
options.dispose();
options = null;
}
}
}
@@ -1,45 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.util.xmlb.XmlSerializerUtil;
@State(
name = "spellchecker-configuration",
storages = {
@Storage(
id = "other",
file = "$PROJECT_FILE$"),
@Storage(
id = "dir",
file = "$PROJECT_CONFIG_DIR$/spellchecker.xml",
scheme = StorageScheme.DIRECTORY_BASED)})
public final class SpellCheckerConfiguration implements PersistentStateComponent<SpellCheckerConfiguration> {
public SpellCheckerConfiguration getState() {
return this;
}
public void loadState(SpellCheckerConfiguration state) {
XmlSerializerUtil.copyBean(state, this);
}
}
@@ -1,70 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.spellchecker.options.SpellCheckerOptions">
<grid id="27dc6" binding="root" default-binding="true" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="344" height="458"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="76b15" class="javax.swing.JRadioButton" binding="projectRB">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="shared in project "/>
</properties>
</component>
<component id="4ba70" class="javax.swing.JRadioButton" binding="localRB">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="locally cached"/>
</properties>
</component>
<component id="db28" class="javax.swing.JLabel" binding="globalDictionaries">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Global dictionaries: &lt;not found&gt;"/>
</properties>
</component>
<component id="c933e" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="User's word lists:"/>
</properties>
</component>
<grid id="abbb6" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="250" height="350"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="85252" class="com.intellij.spellchecker.options.SpellCheckerOptions$WordsPanel" binding="userDictionaryWords" custom-create="true">
<constraints border-constraint="Center"/>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
<buttonGroups>
<group name="additionalDic">
<member id="76b15"/>
<member id="4ba70"/>
</group>
</buttonGroups>
<inspectionSuppressions>
<suppress inspection="NoLabelFor" id="253a1"/>
<suppress inspection="NoLabelFor" id="32995"/>
</inspectionSuppressions>
</form>
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.spellchecker.options.SpellCheckerOptions">
<grid id="27dc6" binding="root" default-binding="true" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="387" height="285"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<hspacer id="f0925">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<grid id="37249" binding="wordPanelHolder" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="dda13" class="com.intellij.spellchecker.options.SpellCheckerOptions$WordsPanel" binding="wordsPanel" custom-create="true" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
</children>
</grid>
</children>
</grid>
<buttonGroups>
<group name="additionalDic">
<member id="76b15"/>
<member id="4ba70"/>
</group>
</buttonGroups>
<inspectionSuppressions>
<suppress inspection="NoLabelFor" id="253a1"/>
<suppress inspection="NoLabelFor" id="32995"/>
</inspectionSuppressions>
</form>
@@ -1,187 +1,169 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.Messages;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import com.intellij.spellchecker.util.Strings;
import com.intellij.ui.AddDeleteListPanel;
import com.intellij.util.containers.HashSet;
import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class SpellCheckerOptions implements Disposable {
private final SpellCheckerConfiguration configuration;
private final SpellCheckerManager manager;
private JPanel root;
private WordsPanel userDictionaryWords;
/*private WordsPanel ignoredWords;*/
private JRadioButton projectRB;
private JRadioButton localRB;
private JLabel globalDictionaries;
private Dictionary shownDictionary;
public Dictionary getShownDictionary() {
return shownDictionary;
}
public SpellCheckerOptions(SpellCheckerConfiguration configuration, SpellCheckerManager manager) {
this.configuration = configuration;
this.manager = manager;
}
private void createUIComponents() {
userDictionaryWords = new WordsPanel(manager.getProjectWordList().getWords(), manager);
/*ignoredWords = new WordsPanel(manager.getProjectWordList().getIgnoredWords(), manager);*/
shownDictionary = manager.getProjectWordList();
}
public Set<String> getUserDictionaryWordsSet() {
return getWords(userDictionaryWords);
}
public boolean useProjectDictionary() {
return projectRB.isSelected();
}
public void setUserDictionaryWords(Set<String> words) {
userDictionaryWords.replaceAll(words);
}
/*public Set<String> getIgnoredWords() {
return getWords(ignoredWords);
}*/
/* public void setIgnoredWords(Set<String> dictionary) {
ignoredWords.replaceAll(dictionary);
}*/
public JPanel getRoot() {
projectRB.setSelected(true);
projectRB.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (projectRB.isSelected()) {
shownDictionary = manager.getProjectWordList();
userDictionaryWords.replaceAll(shownDictionary.getWords());
/*ignoredWords.replaceAll(shownDictionary.getIgnoredWords());*/
}
}
});
localRB.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (localRB.isSelected()) {
shownDictionary = manager.getCachedWordList();
userDictionaryWords.replaceAll(shownDictionary.getWords());
/*ignoredWords.replaceAll(shownDictionary.getIgnoredWords());*/
}
}
});
if (manager.getDictionaries() != null) {
String label = "Global dictionaries: ";
for (String dic : manager.getDictionaries()) {
label += dic + "; ";
}
globalDictionaries.setText(label);
}
return root;
}
private static Set<String> getWords(AddDeleteListPanel panel) {
Set<String> words = new HashSet<String>();
Object[] objects = panel.getListItems();
for (Object object : objects) {
words.add((String)object);
}
return words;
}
public void dispose() {
userDictionaryWords.dispose();
/*ignoredWords.dispose();*/
}
private static final class WordsPanel extends AddDeleteListPanel implements Disposable {
private SpellCheckerManager manager;
private WordsPanel(Set<String> words, SpellCheckerManager manager) {
super(null, sort(words));
this.manager = manager;
}
private static List<String> sort(Set<String> words) {
List<String> arrayList = new ArrayList<String>(words);
Collections.sort(arrayList);
return arrayList;
}
protected Object findItemToAdd() {
String word =
Messages.showInputDialog(SpellCheckerBundle.message("enter.simple.word"), SpellCheckerBundle.message("add.new.word"), null);
if (word == null) {
return null;
}
else {
word = word.trim();
}
if (Strings.isMixedCase(word)) {
Messages.showWarningDialog(SpellCheckerBundle.message("entered.word.0.is.mixed.cased.you.must.enter.simple.word", word),
SpellCheckerBundle.message("add.new.word"));
return null;
}
if (!manager.hasProblem(word)) {
Messages.showWarningDialog(SpellCheckerBundle.message("entered.word.0.is.correct.you.no.need.to.add.this.in.list", word),
SpellCheckerBundle.message("add.new.word"));
return null;
}
return word;
}
public void replaceAll(Set<String> words) {
myList.clearSelection();
myListModel.removeAllElements();
for (String word : sort(words)) {
myListModel.addElement(word);
}
}
public void dispose() {
myListModel.removeAllElements();
}
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.Messages;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import com.intellij.spellchecker.util.Strings;
import com.intellij.ui.AddDeleteListPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class SpellCheckerOptions implements Disposable {
private final SpellCheckerManager manager;
private JPanel root;
private JPanel wordPanelHolder;
private WordsPanel wordsPanel;
public SpellCheckerOptions(SpellCheckerManager manager) {
this.manager = manager;
}
public void createUIComponents() {
wordsPanel = new WordsPanel(manager);
}
public JPanel getRoot() {
return root;
}
@Nullable
public List<String> getWords(){
Object[] pairs = wordsPanel.getListItems();
if (pairs==null){
return null;
}
List<String> words = new ArrayList<String>();
for (Object pair : pairs) {
words.add(pair.toString());
}
return words;
}
public void dispose() {
wordsPanel.dispose();
}
public static final class WordDescriber {
private Dictionary dictionary;
public WordDescriber(Dictionary dictionary) {
this.dictionary = dictionary;
}
@NotNull
public List<Pair> process() {
if (this.dictionary == null) {
return new ArrayList<Pair>();
}
Set<String> words = this.dictionary.getEditableWords();
if (words == null) {
return new ArrayList<Pair>();
}
List<Pair> result = new ArrayList<Pair>();
for (String word : words) {
result.add(new Pair(word, ""));
}
Collections.sort(result);
return result;
}
}
public static final class Pair implements Comparable {
private String word;
private String description;
public Pair(@NotNull String word, String description) {
this.word = word;
this.description = description;
}
public String getWord() {
return word;
}
public String getDescription() {
return description;
}
public int compareTo(Object o) {
if (!(o instanceof Pair)) {
throw new IllegalArgumentException();
}
return word.compareTo(((Pair)o).getWord());
}
@Override
public String toString() {
return word + (description!=null && description.trim().length()>0?"("+description+")":"");
}
}
private static final class WordsPanel extends AddDeleteListPanel implements Disposable {
private SpellCheckerManager manager;
private WordsPanel(SpellCheckerManager manager) {
super(null, new WordDescriber(manager.getUserDictionary()).process());
this.manager = manager;
}
protected Object findItemToAdd() {
String word = Messages.showInputDialog(com.intellij.spellchecker.util.SpellCheckerBundle.message("enter.simple.word"),
SpellCheckerBundle.message("add.new.word"), null);
if (word == null) {
return null;
}
else {
word = word.trim();
}
if (Strings.isMixedCase(word)) {
Messages.showWarningDialog(SpellCheckerBundle.message("entered.word.0.is.mixed.cased.you.must.enter.simple.word", word),
SpellCheckerBundle.message("add.new.word"));
return null;
}
if (!manager.hasProblem(word)) {
Messages.showWarningDialog(SpellCheckerBundle.message("entered.word.0.is.correct.you.no.need.to.add.this.in.list", word),
SpellCheckerBundle.message("add.new.word"));
return null;
}
return word;
}
public void dispose() {
myListModel.removeAllElements();
}
}
}
@@ -19,7 +19,7 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.actionSystem.Anchor;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.quickfixes.SpellCheckerQuickFix;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import org.jetbrains.annotations.NotNull;
@@ -50,4 +50,5 @@ public class AcceptWordAsCorrect implements SpellCheckerQuickFix {
SpellCheckerManager spellCheckerManager = SpellCheckerManager.getInstance(project);
spellCheckerManager.acceptWordAsCorrect(word);
}
}
@@ -26,25 +26,19 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class ChangeTo implements SpellCheckerQuickFix {
private TextRange textRange;
private String word;
private Project project;
public class ChangeTo extends ShowSuggestions implements SpellCheckerQuickFix {
public ChangeTo(@NotNull TextRange textRange, @NotNull String word, @NotNull Project project) {
this.textRange = textRange;
this.word = word;
this.project = project;
super(textRange, word, project);
}
@NotNull
public String getName() {
return SpellCheckerBundle.message("change.to");
@@ -60,7 +54,7 @@ public class ChangeTo implements SpellCheckerQuickFix {
return Anchor.FIRST;
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext());
@@ -78,11 +72,8 @@ public class ChangeTo implements SpellCheckerQuickFix {
return;
}
SpellCheckerManager manager = SpellCheckerManager.getInstance(project);
List<String> variants = manager.getSuggestions(word);
List<LookupElement> lookupItems = new ArrayList<LookupElement>();
for (String variant : variants) {
for (String variant : getSuggestions()) {
lookupItems.add(LookupElementBuilder.create(variant));
}
LookupElement[] items = new LookupElement[lookupItems.size()];
@@ -90,7 +81,6 @@ public class ChangeTo implements SpellCheckerQuickFix {
LookupManager lookupManager = LookupManager.getInstance(project);
lookupManager.showLookup(editor, items);
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.spellchecker;
package com.intellij.spellchecker.quickfixes;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.PsiElement;
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.refactoring.rename.NameSuggestionProvider;
import com.intellij.spellchecker.SpellCheckerManager;
import java.util.*;
@@ -20,10 +20,10 @@ import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.refactoring.actions.RenameElementAction;
import com.intellij.refactoring.rename.NameSuggestionProvider;
import com.intellij.spellchecker.DictionarySuggestionProvider;
import com.intellij.spellchecker.quickfixes.SpellCheckerQuickFix;
import com.intellij.spellchecker.quickfixes.DictionarySuggestionProvider;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,7 +31,11 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class RenameTo implements SpellCheckerQuickFix {
public class RenameTo extends ShowSuggestions implements SpellCheckerQuickFix {
public RenameTo(@NotNull TextRange textRange, @NotNull String word, @NotNull Project project) {
super(textRange, word, project);
}
@NotNull
public String getName() {
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.quickfixes;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.spellchecker.SpellCheckerManager;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public abstract class ShowSuggestions implements LocalQuickFix {
protected TextRange textRange;
protected String word;
protected Project project;
private List<String> suggestions;
private boolean processed;
public ShowSuggestions(@NotNull TextRange textRange, @NotNull String word, @NotNull Project project) {
this.textRange = textRange;
this.word = word;
this.project = project;
}
@NotNull
public List<String> getSuggestions(){
if (!processed){
calculateSuggestions();
processed=true;
}
return suggestions;
}
private void calculateSuggestions(){
SpellCheckerManager manager = SpellCheckerManager.getInstance(project);
suggestions = manager.getSuggestions(word);
}
}
@@ -19,16 +19,8 @@ import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.openapi.actionSystem.Anchor;
import org.jetbrains.annotations.NotNull;
/**
* Spell checker quick fix.
*/
public interface SpellCheckerQuickFix extends LocalQuickFix {
/**
* Return anchor for actions. Basically return {@link com.intellij.openapi.actionSystem.Anchor#FIRST} for common
* suggest words, and {@link com.intellij.openapi.actionSystem.Anchor#LAST} for 'Add to ...' actions.
*
* @return Action anchor
*/
@NotNull
Anchor getPopupActionAnchor();
}
@@ -0,0 +1,84 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.dictionary.AggregatedDictionary;
import com.intellij.spellchecker.dictionary.ProjectDictionary;
import com.intellij.spellchecker.dictionary.UserDictionary;
import org.jetbrains.annotations.NotNull;
public class AggregatedDictionaryState {
private ProjectDictionaryState projectDictionaryState;
private CachedDictionaryState cachedDictionaryState;
private AggregatedDictionary dictionary;
private String currentUser;
private Project project;
public AggregatedDictionaryState() {
}
public AggregatedDictionaryState(@NotNull AggregatedDictionary dictionary) {
setDictionary(dictionary);
}
public void setProject(Project project) {
this.project = project;
}
public void setCurrentUser(String currentUser) {
this.currentUser = currentUser;
}
public void setDictionary(AggregatedDictionary dictionary) {
this.dictionary = dictionary;
cachedDictionaryState.setDictionary(dictionary.getCachedDictionary());
projectDictionaryState.setProjectDictionary(dictionary.getProjectDictionary());
}
public AggregatedDictionary getDictionary() {
return dictionary;
}
public void loadState() {
assert project != null;
cachedDictionaryState = ServiceManager.getService(project, CachedDictionaryState.class);
projectDictionaryState = ServiceManager.getService(project, ProjectDictionaryState.class);
currentUser = System.getProperty("user.name");
retrieveDictionaries();
}
private void retrieveDictionaries() {
ProjectDictionary projectDictionary = projectDictionaryState.getProjectDictionary();
projectDictionary.setActiveName(currentUser);
if (cachedDictionaryState.getDictionary() == null) {
cachedDictionaryState.setDictionary(new UserDictionary(CachedDictionaryState.DEFAULT_NAME));
}
dictionary = new AggregatedDictionary(projectDictionary, cachedDictionaryState.getDictionary());
setDictionary(dictionary);
}
@Override
public String toString() {
return "AggregatedDictionaryState{" + "dictionary=" + dictionary + '}';
}
}
@@ -1,45 +1,47 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.options;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.spellchecker.dictionary.UserDictionary;
import com.intellij.spellchecker.dictionary.Dictionary;
@State(
name = "CachedDictionaryState",
storages = {@Storage(
id = "spellchecker",
file = "$APP_CONFIG$/cachedDictionary.xml")})
public class CachedDictionaryState implements PersistentStateComponent<CachedDictionaryState> {
public UserDictionary dictionary = new UserDictionary("cached");
public CachedDictionaryState getState() {
return this;
}
public void loadState(CachedDictionaryState state) {
XmlSerializerUtil.copyBean(state, this);
}
public Dictionary getDictionary(){
return dictionary;
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.spellchecker.dictionary.Dictionary;
@State(
name = "CachedDictionaryState",
storages = {@Storage(
id = "spellchecker",
file = "$APP_CONFIG$/cachedDictionary.xml")})
public class CachedDictionaryState extends DictionaryState implements PersistentStateComponent<DictionaryState>{
public static final String DEFAULT_NAME = "cached";
public CachedDictionaryState() {
name = DEFAULT_NAME;
}
public CachedDictionaryState(Dictionary dictionary) {
super(dictionary);
name = DEFAULT_NAME;
}
@Override
public void loadState(DictionaryState state) {
if (state.name==null){
state.name= DEFAULT_NAME;
}
super.loadState(state);
}
}
@@ -0,0 +1,97 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.dictionary.UserDictionary;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.util.xmlb.annotations.Transient;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
@Tag("dictionary")
public class DictionaryState implements PersistentStateComponent<DictionaryState> {
public static final String NAME_ATTRIBUTE = "name";
@Tag("words") @AbstractCollection(surroundWithTag = false, elementTag = "w", elementValueAttribute = "")
public Set<String> words = new HashSet<String>();
@Attribute(NAME_ATTRIBUTE)
public String name;
@Transient
private Dictionary dictionary;
public DictionaryState() {
}
public DictionaryState(@NotNull Dictionary dictionary) {
setDictionary(dictionary);
}
@Transient
public void setDictionary(@NotNull Dictionary dictionary) {
this.dictionary = dictionary;
this.name = dictionary.getName();
synchronizeWords();
}
@Transient
public Dictionary getDictionary() {
return dictionary;
}
public DictionaryState getState() {
synchronizeWords();
return this;
}
private void synchronizeWords() {
if (dictionary != null) {
Set<String> words = new HashSet<String>();
words.addAll(dictionary.getWords());
this.words = words;
}
}
public void loadState(DictionaryState state) {
if (state != null && state.name != null) {
name = state.name;
words = state.words;
}
retrieveDictionary();
}
private void retrieveDictionary() {
assert name != null;
dictionary = new UserDictionary(name);
dictionary.addToDictionary(words);
}
@Override
public String toString() {
return "DictionaryState{" + "dictionary=" + dictionary + '}';
}
}
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.spellchecker.options;
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.StateSplitter;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.spellchecker.state.DictionaryState;
import com.intellij.util.text.UniqueNameGenerator;
import org.jdom.Element;
@@ -36,8 +37,9 @@ public class ProjectDictionarySplitter implements StateSplitter {
final UniqueNameGenerator generator = new UniqueNameGenerator();
List<Pair<Element, String>> result = new ArrayList<Pair<Element, String>>();
for (Element element : JDOMUtil.getElements(e)) {
final String name = generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue("name"))) + ".xml";
for (Element element : JDOMUtil.getElements(e)) {
final String name = generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue(DictionaryState.NAME_ATTRIBUTE))) + ".xml";
result.add(new Pair<Element, String>(element, name));
}
return result;
@@ -0,0 +1,118 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.dictionary.ProjectDictionary;
import com.intellij.spellchecker.state.ProjectDictionarySplitter;
import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Transient;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@State(
name = "ProjectDictionaryState",
storages = {@Storage(
id = "other",
file = "$PROJECT_FILE$"),
@Storage(
id = "dir",
file = "$PROJECT_CONFIG_DIR$/dictionaries/",
scheme = StorageScheme.DIRECTORY_BASED, stateSplitter = ProjectDictionarySplitter.class)})
public class ProjectDictionaryState implements PersistentStateComponent<ProjectDictionaryState>{
@Property(surroundWithTag = false) @AbstractCollection(surroundWithTag = false, elementTypes = DictionaryState.class)
public List<DictionaryState> dictionaryStates = new ArrayList<DictionaryState>();
private ProjectDictionary projectDictionary;
private String currentUser;
private Project project;
public ProjectDictionaryState() {
}
public void setProject(Project project) {
this.project = project;
}
public void setCurrentUser(String currentUser) {
this.currentUser = currentUser;
}
@Transient
public void setProjectDictionary(ProjectDictionary projectDictionary) {
currentUser = projectDictionary.getActiveName();
dictionaryStates.clear();
Set<Dictionary> projectDictionaries = projectDictionary.getDictionaries();
if (projectDictionaries != null) {
for (Dictionary dic : projectDictionary.getDictionaries()) {
dictionaryStates.add(new DictionaryState(dic));
}
}
}
@Transient
public ProjectDictionary getProjectDictionary() {
if (projectDictionary==null){
projectDictionary = new ProjectDictionary();
}
return projectDictionary;
}
public ProjectDictionaryState getState() {
if (projectDictionary!=null){
//ensure all dictionaries within project dictionary will be stored
setProjectDictionary(projectDictionary);
}
return this;
}
public void loadState(ProjectDictionaryState state) {
if (state != null) {
this.dictionaryStates = state.dictionaryStates;
}
retrieveProjectDictionaries();
}
private void retrieveProjectDictionaries() {
Set<Dictionary> dictionaries = new HashSet<Dictionary>();
if (dictionaryStates != null) {
for (DictionaryState dictionaryState : dictionaryStates) {
dictionaryState.loadState(dictionaryState);
dictionaries.add(dictionaryState.getDictionary());
}
}
projectDictionary = new ProjectDictionary(dictionaries);
}
@Override
public String toString() {
return "ProjectDictionaryState{" + "projectDictionary=" + projectDictionary + '}';
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.state;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.dictionary.Dictionary;
import com.intellij.spellchecker.dictionary.Loader;
import com.intellij.spellchecker.dictionary.Processor;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public class StateLoader implements Loader {
private Project project;
private Dictionary dictionary;
public StateLoader(Project project) {
this.project = project;
}
public void load(@NotNull Processor processor) {
AggregatedDictionaryState state = ServiceManager.getService(project, AggregatedDictionaryState.class);
state.setProject(project);
state.loadState();
dictionary = state.getDictionary();
final Set<String> storedWords = dictionary.getWords();
if (storedWords!=null){
for (String word : storedWords) {
processor.process(word);
}
}
}
public Dictionary getDictionary() {
return dictionary;
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.trie;
import java.util.Map;
public interface Action {
void run(Map.Entry<? extends String,? extends String> entry);
}
@@ -0,0 +1,144 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.trie;
/**
* Analyzes <code>CharSequence</code> keys with case sensitivity. With
* <code>CharSequenceKeyAnalyzer</code> you can
* compare, check prefix, and determine the index of a bit.
* <p>
* A typical use case for a <code>CharSequenceKeyAnalyzer</code> is with a
* {@link PatriciaTrie}.
* <pre>
PatriciaTrie&lt;String, String&gt; trie = new PatriciaTrie&lt;String, String&gt;(new CharSequenceKeyAnalyzer());
trie.put("Lime", "Lime");
trie.put("LimeWire", "LimeWire");
trie.put("LimeRadio", "LimeRadio");
trie.put("Lax", "Lax");
trie.put("Lake", "Lake");
trie.put("Lovely", "Lovely");
System.out.println(trie.select("Lo"));
System.out.println(trie.select("Lime"));
System.out.println(trie.getPrefixedBy("La").toString());
Output:
Lovely
Lime
{Lake=Lake, Lax=Lax}
* </pre>
*
* @author Sam Berlin
* @author Roger Kapsi
*/
public class CharSequenceKeyAnalyzer implements PatriciaTrie.KeyAnalyzer<CharSequence> {
private static final long serialVersionUID = -7032449491269434877L;
private static final int[] BITS = createIntBitMask(16);
public static final int[] createIntBitMask(int bitCount) {
int[] bits = new int[bitCount];
for(int i = 0; i < bitCount; i++) {
bits[i] = 1 << (bitCount - i - 1);
}
return bits;
}
public int length(CharSequence key) {
return (key != null ? key.length() * 16 : 0);
}
public int bitIndex(CharSequence key, int keyOff, int keyLength,
CharSequence found, int foundOff, int foundKeyLength) {
boolean allNull = true;
if(keyOff % 16 != 0 || foundOff % 16 != 0 ||
keyLength % 16 != 0 || foundKeyLength % 16 != 0)
throw new IllegalArgumentException("offsets & lengths must be at character boundaries");
int off1 = keyOff / 16;
int off2 = foundOff / 16;
int len1 = keyLength / 16 + off1;
int len2 = foundKeyLength / 16 + off2;
int length = Math.max(len1, len2);
// Look at each character, and if they're different
// then figure out which bit makes the difference
// and return it.
char k = 0, f = 0;
for(int i = 0; i < length; i++) {
int kOff = i + off1;
int fOff = i + off2;
if(kOff >= len1)
k = 0;
else
k = key.charAt(kOff);
if(found == null || fOff >= len2)
f = 0;
else
f = found.charAt(fOff);
if(k != f) {
int x = k ^ f;
return i * 16 + (Integer.numberOfLeadingZeros(x) - 16);
}
if(k != 0)
allNull = false;
}
if (allNull) {
return PatriciaTrie.KeyAnalyzer.NULL_BIT_KEY;
}
return PatriciaTrie.KeyAnalyzer.EQUAL_BIT_KEY;
}
public boolean isBitSet(CharSequence key, int keyLength, int bitIndex) {
if (key == null || bitIndex >= keyLength) {
return false;
}
int index = bitIndex / BITS.length;
int bit = bitIndex - index * BITS.length;
return (key.charAt(index) & BITS[bit]) != 0;
}
public int compare(CharSequence o1, CharSequence o2) {
return o1.toString().compareTo(o2.toString());
}
public int bitsPerElement() {
return 16;
}
public boolean isPrefix(CharSequence prefix, int offset, int length, CharSequence key) {
if(offset % 16 != 0 || length % 16 != 0)
throw new IllegalArgumentException("Cannot determine prefix outside of character boundaries");
String s1 = prefix.subSequence(offset / 16, length / 16).toString();
String s2 = key.toString();
return s2.startsWith(s1);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,172 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.trie;
import java.util.Map;
import java.util.SortedMap;
/**
* Defines the interface for a prefix tree, an ordered tree data structure. For
* more information, see <a href= "http://en.wikipedia.org/wiki/Trie">Tries</a>.
*
* @author Roger Kapsi
* @author Sam Berlin
*/
public interface Trie<K, V> extends SortedMap<K, V> {
/**
* Returns a view of this Trie of all elements that are
* prefixed by the given key.
* <p>
* In a fixed-keysize Trie, this is essentially a 'get' operation.
* <p>
* For example, if the Trie contains 'Lime', 'LimeWire',
* 'LimeRadio', 'Lax', 'Later', 'Lake', and 'Lovely', then
* a lookup of 'Lime' would return 'Lime', 'LimeRadio', and 'LimeWire'.
*/
public SortedMap<K, V> getPrefixedBy(K key);
/**
* Returns a view of this Trie of all elements that are
* prefixed by the length of the key.
* <p>
* Fixed-keysize Tries will not support this operation
* (because all keys will be the same length).
* <p>
* For example, if the Trie contains 'Lime', 'LimeWire',
* 'LimeRadio', 'Lax', 'Later', 'Lake', and 'Lovely', then
* a lookup of 'LimePlastics' with a length of 4 would
* return 'Lime', 'LimeRadio', and 'LimeWire'.
*/
public SortedMap<K, V> getPrefixedBy(K key, int length);
/**
* Returns a view of this Trie of all elements that are prefixed
* by the key, starting at the given offset and for the given length.
* <p>
* Fixed-keysize Tries will not support this operation
* (because all keys are the same length).
* <p>
* For example, if the Trie contains 'Lime', 'LimeWire',
* 'LimeRadio', 'Lax', 'Later', 'Lake', and 'Lovely', then
* a lookup of 'The Lime Plastics' with an offset of 4 and a
* length of 4 would return 'Lime', 'LimeRadio', and 'LimeWire'.
*/
public SortedMap<K, V> getPrefixedBy(K key, int offset, int length);
/**
* Returns a view of this Trie of all elements that are prefixed
* by the number of bits in the given Key.
* <p>
* Fixed-keysize Tries can support this operation as a way to do
* lookups of partial keys. That is, if the Trie is storing IP
* addresses, you can lookup all addresses that begin with
* '192.168' by providing the key '192.168.X.X' and a length of 16
* would return all addresses that begin with '192.168'.
*/
public SortedMap<K, V> getPrefixedByBits(K key, int bitLength);
/**
* Returns the value for the entry whose key is closest in a bitwise
* XOR metric to the given key. This is NOT lexicographic closeness.
* For example, given the keys:<br>
* D = 1000100 <br>
* H = 1001000 <br>
* L = 1001100 <br>
* <p>
* If the Trie contained 'H' and 'L', a lookup of 'D' would return 'L',
* because the XOR distance between D & L is smaller than the XOR distance
* between D & H.
*/
public V select(K key);
/**
* Iterates through the Trie, starting with the entry whose bitwise
* value is closest in an XOR metric to the given key. After the closest
* entry is found, the Trie will call select on that entry and continue
* calling select for each entry (traversing in order of XOR closeness,
* NOT lexicographically) until the cursor returns
* <code>Cursor.SelectStatus.EXIT</code>.<br>
* The cursor can return <code>Cursor.SelectStatus.CONTINUE</code> to
* continue traversing.<br>
* <code>Cursor.SelectStatus.REMOVE_AND_EXIT</code> is used to remove the current element
* and stop traversing.
* <p>
* Note: The {@link Cursor.SelectStatus#REMOVE} operation is not supported.
*
* @return The entry the cursor returned EXIT on, or null if it continued
* till the end.
*/
public Map.Entry<K,V> select(K key, Cursor<? super K, ? super V> cursor);
/**
* Traverses the Trie in lexicographical order. <code>Cursor.select</code>
* will be called on each entry.<p>
* The traversal will stop when the cursor returns <code>Cursor.SelectStatus.EXIT</code>.<br>
* <code>Cursor.SelectStatus.CONTINUE</code> is used to continue traversing.<br>
* <code>Cursor.SelectStatus.REMOVE</code> is used to remove the element that was
* selected and continue traversing.<br>
* <code>Cursor.SelectStatus.REMOVE_AND_EXIT</code> is used to remove the current element
* and stop traversing.
*
* @return The entry the cursor returned EXIT on, or null if it continued
* till the end.
*/
public Map.Entry<K,V> traverse(Cursor<? super K, ? super V> cursor);
/**
* An interface used by a {@link Trie}. A {@link Trie} selects items by
* closeness and passes the items to the <code>Cursor</code>. You can then
* decide what to do with the key-value pair and the return value
* from {@link #select(java.util.Map.Entry)} tells the <code>Trie</code>
* what to do next.
* <p>
* <code>Cursor</code> returns status/selection status might be:
* <table cellspace="5">
* <tr><td><b>Return Value</b></td><td><b>Status</b></td></tr>
* <tr><td>EXIT</td><td>Finish the Trie operation</td></tr>
* <tr><td>CONTINUE</td><td>Look at the next element in the traversal</td></tr>
* <tr><td>REMOVE_AND_EXIT</td><td>Remove the entry and stop iterating</td></tr>
* <tr><td>REMOVE</td><td>Remove the entry and continue iterating</td></tr>
* </table>
* Note: {@link Trie#select(Object, org.limewire.collection.Trie.Cursor)} does
* not support <code>REMOVE</code>.
*
* @param <K> Key Type
* @param <V> Key Value
*/
public static interface Cursor<K, V> {
/**
* Notification that the Trie is currently looking at the given entry.
* Return <code>EXIT</code> to finish the Trie operation,
* <code>CONTINUE</code> to look at the next entry, <code>REMOVE</code>
* to remove the entry and continue iterating, or
* <code>REMOVE_AND_EXIT</code> to remove the entry and stop iterating.
* Not all operations support <code>REMOVE</code>.
*
*/
public SelectStatus select(Map.Entry<? extends K, ? extends V> entry);
/** The mode during selection. */
public static enum SelectStatus {
EXIT, CONTINUE, REMOVE, REMOVE_AND_EXIT;
}
}
}
@@ -1,36 +1,37 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.util;
import com.intellij.CommonBundle;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.PropertyKey;
import java.util.ResourceBundle;
public final class SpellCheckerBundle {
@NonNls
private static final String BUNDLE_NAME = "com.intellij.spellchecker.util.SpellCheckerBundle";
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
private SpellCheckerBundle() {
}
public static String message(@PropertyKey(resourceBundle = BUNDLE_NAME) String key, Object... params) {
return CommonBundle.message(BUNDLE, key, params);
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.util;
import com.intellij.CommonBundle;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.PropertyKey;
import java.util.ResourceBundle;
public final class SpellCheckerBundle {
@NonNls
private static final String BUNDLE_NAME = "com.intellij.spellchecker.util.SpellCheckerBundle";
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
private SpellCheckerBundle() {
}
public static String message(@PropertyKey(resourceBundle = BUNDLE_NAME) String key, Object... params) {
return CommonBundle.message(BUNDLE, key, params);
}
}
@@ -1,28 +1,27 @@
change.to.0=Change to ''{0}''
change.to=Change to...
rename.to.0=Rename to ''{0}''
rename.to=Rename to...
spelling=Spelling
spellchecking.inspection.name=Typo
comments.with.mistakes=Comments with mistakes
word.0.1.is.misspelled=Word ''{0}'' is misspelled
add.0.to.dictionary=Accept ''{0}'' as correct
class.name.with.mistakes=Class name with mistakes
method.name.with.mistakes=Method name with mistakes
field.name.with.mistakes=Field name with mistakes
xml.with.mistakes=XML with mistakes
property.value.with.mistakes=Property value with mistakes
string.value.with.mistakes=Literal expression with mistakes
local.variable.name.with.mistakes=Local variable name with mistakes
doccomment.with.mistakes=Doc comment with mistake
user.dictionary=User Dictionary
ignored.words=Ignored Words
enter.simple.word=Enter simple word:
add.new.word=Add new word
entered.word.0.is.mixed.cased.you.must.enter.simple.word=Entered word {0} is mixed cased. You must enter simple word
entered.word.0.is.correct.you.no.need.to.add.this.in.list=Entered word {0} is correct. You no need to add this in list.
no.suggestions=<no suggestion>
process.code=Process code
process.literals=Process literals
process.comments=Process comments
change.to.0=Typo: Change to ''{0}''
change.to=Typo: Change to...
rename.to.0=Typo: Rename to ''{0}''
rename.to=Typo: Rename to...
spelling=Spelling
spellchecking.inspection.name=Typo
comments.with.mistakes=Comments with mistakes
word.0.1.is.misspelled=Typo: In word ''{0}''
add.0.to.dictionary=Typo: Accept ''{0}'' as correct
class.name.with.mistakes=Class name with mistakes
method.name.with.mistakes=Method name with mistakes
field.name.with.mistakes=Field name with mistakes
xml.with.mistakes=XML with mistakes
property.value.with.mistakes=Property value with mistakes
string.value.with.mistakes=Literal expression with mistakes
local.variable.name.with.mistakes=Local variable name with mistakes
doccomment.with.mistakes=Doc comment with mistake
user.dictionary=User Dictionary
ignored.words=Ignored Words
enter.simple.word=Enter simple word:
add.new.word=Add new word
entered.word.0.is.mixed.cased.you.must.enter.simple.word=Entered word {0} is mixed cased. You must enter simple word
entered.word.0.is.correct.you.no.need.to.add.this.in.list=Entered word {0} is correct. You no need to add this in list.
no.suggestions=<no suggestion>
process.code=Process code
process.literals=Process literals
process.comments=Process comments
@@ -1,76 +1,76 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.util;
import java.util.List;
/**
* Text utility.
*/
public final class Strings {
private Strings() {
}
public static boolean isCapitalized(String word) {
if (word.length() == 0) return false;
boolean lowCase = true;
for (int i = 1; i < word.length() && lowCase; i++) {
lowCase = Character.isLowerCase(word.charAt(i));
}
return Character.isUpperCase(word.charAt(0)) && lowCase;
}
public static boolean isUpperCase(String word) {
boolean upperCase = true;
for (int i = 0; i < word.length() && upperCase; i++) {
upperCase = Character.isUpperCase(word.charAt(i));
}
return upperCase;
}
public static boolean isMixedCase(String word) {
if (word.length() < 2) return false;
String tail = word.substring(1);
String lowerCase = tail.toLowerCase();
return !tail.equals(lowerCase) && !isUpperCase(word);
}
public static String capitalize(String word) {
if (word.length() == 0) return word;
StringBuffer buf = new StringBuffer(word);
buf.setCharAt(0, Character.toUpperCase(buf.charAt(0)));
return buf.toString();
}
public static void capitalize(List<String> words) {
for (int i = 0; i < words.size(); i++) {
words.set(i, capitalize(words.get(i)));
}
}
public static void upperCase(List<String> words) {
for (int i = 0; i < words.size(); i++) {
words.set(i, words.get(i).toUpperCase());
}
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.spellchecker.util;
import java.util.List;
/**
* Text utility.
*/
public final class Strings {
private Strings() {
}
public static boolean isCapitalized(String word) {
if (word.length() == 0) return false;
boolean lowCase = true;
for (int i = 1; i < word.length() && lowCase; i++) {
lowCase = Character.isLowerCase(word.charAt(i));
}
return Character.isUpperCase(word.charAt(0)) && lowCase;
}
public static boolean isUpperCase(String word) {
boolean upperCase = true;
for (int i = 0; i < word.length() && upperCase; i++) {
upperCase = Character.isUpperCase(word.charAt(i));
}
return upperCase;
}
public static boolean isMixedCase(String word) {
if (word.length() < 2) return false;
String tail = word.substring(1);
String lowerCase = tail.toLowerCase();
return !tail.equals(lowerCase) && !isUpperCase(word);
}
public static String capitalize(String word) {
if (word.length() == 0) return word;
StringBuffer buf = new StringBuffer(word);
buf.setCharAt(0, Character.toUpperCase(buf.charAt(0)));
return buf.toString();
}
public static void capitalize(List<String> words) {
for (int i = 0; i < words.size(); i++) {
words.set(i, capitalize(words.get(i)));
}
}
public static void upperCase(List<String> words) {
for (int i = 0; i < words.size(); i++) {
words.set(i, words.get(i).toUpperCase());
}
}
}
@@ -15,5 +15,5 @@
*/
package testData.inspection.classNameWithMistakes;
class Test<TYPO descr="Word 'Upgade' is misspelled">Upgade</TYPO> {
class Test<TYPO descr="Typo: In word 'Upgade'">Upgade</TYPO> {
}
@@ -1,6 +1,6 @@
<xml>
<!--<TYPO descr="Word 'commments' is misspelled">commments</TYPO> in xml-->
<a>tag value <!--<TYPO descr="Word 'commments' is misspelled">commments</TYPO> in xml-->
<!--<TYPO descr="Typo: In word 'commments'">commments</TYPO> in xml-->
<a>tag value <!--<TYPO descr="Typo: In word 'commments'">commments</TYPO> in xml-->
plain text
</a>
</xml>
@@ -21,13 +21,13 @@ package testData.inspection.commentsWithMistakes.data.java.src;
*/
class SPITest1 {
/* boolean is Java keyword
<TYPO descr="Word 'commment' is misspelled">commment</TYPO>
<TYPO descr="Typo: In word 'commment'">commment</TYPO>
*/
// single line <TYPO descr="Word 'upgade' is misspelled">upgade</TYPO>
// single line <TYPO descr="Typo: In word 'upgade'">upgade</TYPO>
void method() {
/*
<TYPO descr="Word 'werty' is misspelled">werty</TYPO> within method
<TYPO descr="Typo: In word 'werty'">werty</TYPO> within method
*/
// single line <TYPO descr="Word 'newss' is misspelled">newss</TYPO> within method
// single line <TYPO descr="Typo: In word 'newss'">newss</TYPO> within method
}
}
@@ -1,5 +1,5 @@
<html>
<body>
<h1><!--Some content goes <TYPO descr="Word 'hrere' is misspelled">hrere</TYPO>--></h1>
<h1><!--Some content goes <TYPO descr="Typo: In word 'hrere'">hrere</TYPO>--></h1>
</body>
</html>
@@ -1 +1 @@
simple <TYPO descr="Word 'ttest' is misspelled">ttest</TYPO> file (just plain text)
simple <TYPO descr="Typo: In word 'ttest'">ttest</TYPO> file (just plain text)
@@ -16,7 +16,7 @@
package testData.inspection.docCommentWithMistakes.data.java.src;
/**
* doc <TYPO descr="Word 'commment' is misspelled">commment</TYPO>
* doc <TYPO descr="Typo: In word 'commment'">commment</TYPO>
*
* @author Test Test
*/
@@ -16,7 +16,7 @@
package testData.inspection.fieldNameWithMistakes.data.java.src;
class SPITest2 {
private static final String TEST_<TYPO descr="Word 'CONASTANT' is misspelled">CONASTANT</TYPO> = "Test Constant Value";
private String <TYPO descr="Word 'ttest' is misspelled">ttest</TYPO>;
private String camelCase<TYPO descr="Word 'Ttest' is misspelled">Ttest</TYPO>;
private static final String TEST_<TYPO descr="Typo: In word 'CONASTANT'">CONASTANT</TYPO> = "Test Constant Value";
private String <TYPO descr="Typo: In word 'ttest'">ttest</TYPO>;
private String camelCase<TYPO descr="Typo: In word 'Ttest'">Ttest</TYPO>;
}
@@ -1,2 +1,2 @@
def abc(String <TYPO descr="Word 'dddd' is misspelled">dddd</TYPO>) {
def abc(String <TYPO descr="Typo: In word 'dddd'">dddd</TYPO>) {
}
@@ -14,14 +14,14 @@
* limitations under the License.
*/
/*some <TYPO descr="Word 'commments' is misspelled">commments</TYPO> */
function test<TYPO descr="Word 'Fuunction' is misspelled">Fuunction</TYPO>(){
var <TYPO descr="Word 'upddate' is misspelled">upddate</TYPO> = "test variable";
/*some <TYPO descr="Typo: In word 'commments'">commments</TYPO> */
function test<TYPO descr="Typo: In word 'Fuunction'">Fuunction</TYPO>(){
var <TYPO descr="Typo: In word 'upddate'">upddate</TYPO> = "test variable";
}
var obj = {
};
obj.<TYPO descr="Word 'ttest' is misspelled">ttest</TYPO> = function(){
obj.<TYPO descr="Typo: In word 'ttest'">ttest</TYPO> = function(){
};
@@ -17,7 +17,7 @@ package testData.inspection.localVariableNameWithMistakes.data.java.src;
class SPITest3 {
public void method() {
String camelCase<TYPO descr="Word 'Ttest' is misspelled">Ttest</TYPO> = "she is reading";
String <TYPO descr="Word 'ttest' is misspelled">ttest</TYPO> = "she is reading";
String camelCase<TYPO descr="Typo: In word 'Ttest'">Ttest</TYPO> = "she is reading";
String <TYPO descr="Typo: In word 'ttest'">ttest</TYPO> = "she is reading";
}
}
@@ -16,8 +16,8 @@
package testData.inspection.methodNameWithMistakes.data.java.src;
class SPITest4 {
public void method<TYPO descr="Word 'Ttest' is misspelled">Ttest</TYPO>WithMistake() {
public void method<TYPO descr="Typo: In word 'Ttest'">Ttest</TYPO>WithMistake() {
}
public void <TYPO descr="Word 'methad' is misspelled">methad</TYPO>() {
public void <TYPO descr="Typo: In word 'methad'">methad</TYPO>() {
}
}
@@ -1,5 +1,5 @@
<?php
class /*Test<TYPO descr="Word 'Classs' is misspelled">Classs</TYPO>*/ Test<TYPO descr="Word 'Classs' is misspelled">Classs</TYPO> {
class /*Test<TYPO descr="Typo: In word 'Classs'">Classs</TYPO>*/ Test<TYPO descr="Typo: In word 'Classs'">Classs</TYPO> {
}
?>
@@ -16,5 +16,5 @@
package testData.inspection.stringWithMistakes.data.java.src;
class SPITest5 {
public final static String test = "<TYPO descr="Word 'upgrdae' is misspelled">upgrdae</TYPO>";
public final static String test = "<TYPO descr="Typo: In word 'upgrdae'">upgrdae</TYPO>";
}
@@ -17,10 +17,10 @@
--%>
<html>
<head>
<title>Test <TYPO descr="Word 'ttitle' is misspelled">ttitle</TYPO></title>
<title>Test <TYPO descr="Typo: In word 'ttitle'">ttitle</TYPO></title>
</head>
<body>
<div title="div <TYPO descr="Word 'ttitle' is misspelled">ttitle</TYPO>">Test <TYPO descr="Word 'ccontent' is misspelled">ccontent</TYPO> goes here</div>
<div title="div <TYPO descr="Typo: In word 'ttitle'">ttitle</TYPO>">Test <TYPO descr="Typo: In word 'ccontent'">ccontent</TYPO> goes here</div>
<a href="#">test link</a>
</body>
</html>
@@ -1,3 +1,3 @@
<a attribute="<TYPO descr="Word 'ttest' is misspelled">ttest</TYPO> attribute">
plain text <TYPO descr="Word 'gooes' is misspelled">gooes</TYPO> here
<a attribute="<TYPO descr="Typo: In word 'ttest'">ttest</TYPO> attribute">
plain text <TYPO descr="Typo: In word 'gooes'">gooes</TYPO> here
</a>
@@ -15,8 +15,8 @@
*/
package com.intellij.spellchecker.inspector;
import com.intellij.spellchecker.CheckArea;
import com.intellij.spellchecker.TextSplitter;
import com.intellij.spellchecker.inspections.CheckArea;
import com.intellij.spellchecker.inspections.TextSplitter;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
@@ -80,7 +80,20 @@ public class SplitterTest extends TestCase {
correctIgnored(checkAreas, text, new String[]{});
}
public void testWordWithApostrophe4() {
String text = "we'll";
List<CheckArea> checkAreas = TextSplitter.splitText(text);
correctListToCheck(checkAreas, text, new String[]{"we'll"});
correctIgnored(checkAreas, text, new String[]{});
}
public void testWordWithApostrophe5() {
String text = "I'm you're we'll";
List<CheckArea> checkAreas = TextSplitter.splitText(text);
correctListToCheck(checkAreas, text, new String[]{"you're","we'll"});
correctIgnored(checkAreas, text, new String[]{"I'm"});
}
public void testConstantName() {
String text = "TEST_CONSTANT";