diff --git a/.gitignore b/.gitignore index e1a3e405ef99..3fb1a17163fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/android /config /system .idea/workspace.xml diff --git a/.idea/libraries/asm_tools.xml b/.idea/libraries/asm_tools.xml new file mode 100644 index 000000000000..9435a42f3c35 --- /dev/null +++ b/.idea/libraries/asm_tools.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/bouncy_castle.xml b/.idea/libraries/bouncy_castle.xml new file mode 100644 index 000000000000..4e4673aa939e --- /dev/null +++ b/.idea/libraries/bouncy_castle.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/builder_model.xml b/.idea/libraries/builder_model.xml new file mode 100644 index 000000000000..e50dabd08689 --- /dev/null +++ b/.idea/libraries/builder_model.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/commons_compress.xml b/.idea/libraries/commons_compress.xml new file mode 100644 index 000000000000..a77ee366b254 --- /dev/null +++ b/.idea/libraries/commons_compress.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/easymock_tools.xml b/.idea/libraries/easymock_tools.xml new file mode 100644 index 000000000000..c9963855dbcf --- /dev/null +++ b/.idea/libraries/easymock_tools.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/freemarker_2_3_20.xml b/.idea/libraries/freemarker_2_3_20.xml new file mode 100644 index 000000000000..831297d1baf3 --- /dev/null +++ b/.idea/libraries/freemarker_2_3_20.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/guava_tools.xml b/.idea/libraries/guava_tools.xml new file mode 100644 index 000000000000..b492cf4758e7 --- /dev/null +++ b/.idea/libraries/guava_tools.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/javawriter.xml b/.idea/libraries/javawriter.xml new file mode 100644 index 000000000000..1d73b23855f5 --- /dev/null +++ b/.idea/libraries/javawriter.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/kxml2.xml b/.idea/libraries/kxml2.xml new file mode 100644 index 000000000000..fe007f5f7a9c --- /dev/null +++ b/.idea/libraries/kxml2.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/lombok_ast.xml b/.idea/libraries/lombok_ast.xml new file mode 100644 index 000000000000..9fe1aa4ea9f2 --- /dev/null +++ b/.idea/libraries/lombok_ast.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/mockito.xml b/.idea/libraries/mockito.xml new file mode 100644 index 000000000000..a1ae9af5cc45 --- /dev/null +++ b/.idea/libraries/mockito.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 0322352e9df9..f23cddeafc3c 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -10,18 +10,26 @@ + + + + + + + + @@ -39,6 +47,7 @@ + @@ -46,13 +55,16 @@ + + - + + @@ -66,6 +78,7 @@ + @@ -116,12 +129,17 @@ + + + + + @@ -130,7 +148,9 @@ + + @@ -168,6 +188,8 @@ + + @@ -190,6 +212,7 @@ + @@ -220,8 +243,6 @@ - - diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f82558..a1b9ce94e902 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 7d5698fc9aee..6eb85a76a4ae 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -254,9 +254,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir } public def layoutCommunityPlugins(String home) { - if (isDefined("androidPluginHome")) { - layoutAndroid(p("androidPluginHome")) - } + layoutAndroid("$home/android") dir("plugins") { def simplePlugins = ["commander", "copyright", "java-i18n", "hg4idea", "github"] //, "tasks-time-tracking"] diff --git a/getPlugins.bat b/getPlugins.bat new file mode 100644 index 000000000000..3cd8b977612a --- /dev/null +++ b/getPlugins.bat @@ -0,0 +1,2 @@ +call git clone git://git.jetbrains.org/idea/android.git android +call git clone git://git.jetbrains.org/idea/adt-tools-base.git android/tools-base diff --git a/getPlugins.sh b/getPlugins.sh new file mode 100755 index 000000000000..9afcebda7d70 --- /dev/null +++ b/getPlugins.sh @@ -0,0 +1,2 @@ +git clone git://git.jetbrains.org/idea/android.git android +git clone git://git.jetbrains.org/idea/adt-tools-base.git android/tools-base diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java index 7e0515726610..ef745b3aaa8b 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java @@ -62,8 +62,9 @@ public class ClassesTreeStructureProvider implements SelectableTreeStructureProv if (originalElement instanceof PsiFile) { PsiFile classFile = (PsiFile)originalElement; final VirtualFile virtualClassFile = classFile.getVirtualFile(); - if (virtualClassFile != null && fileIndex.isInLibraryClasses(virtualClassFile) && - classOwner.getManager().areElementsEquivalent(classOwner.getContainingDirectory(), classFile.getContainingDirectory())) { + if (virtualClassFile != null && fileIndex.isInLibraryClasses(virtualClassFile) + && !classOwner.getManager().areElementsEquivalent(classOwner, classFile) + && classOwner.getManager().areElementsEquivalent(classOwner.getContainingDirectory(), classFile.getContainingDirectory())) { continue; } } diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java index 6a3dd82b237e..b1669144551a 100644 --- a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java +++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java @@ -23,17 +23,21 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.HighlighterIterator; -import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.InternalFileType; +import com.intellij.openapi.fileTypes.LanguageFileType; +import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.CustomHighlighterTokenType; -import com.intellij.psi.impl.cache.impl.BaseFilterLexer; import com.intellij.psi.impl.cache.CacheUtil; +import com.intellij.psi.impl.cache.impl.BaseFilterLexer; import com.intellij.psi.impl.cache.impl.IndexPatternUtil; import com.intellij.psi.impl.cache.impl.OccurrenceConsumer; import com.intellij.psi.impl.cache.impl.todo.TodoIndexEntry; import com.intellij.psi.impl.cache.impl.todo.TodoIndexers; +import com.intellij.psi.impl.cache.impl.todo.VersionedTodoIndexer; import com.intellij.psi.search.IndexPattern; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; @@ -116,7 +120,7 @@ public abstract class PlatformIdTableBuilding { return ourTodoIndexers.containsKey(fileType) || TodoIndexers.INSTANCE.forFileType(fileType) != null || fileType instanceof InternalFileType; } - private static class CompositeTodoIndexer implements DataIndexer { + private static class CompositeTodoIndexer extends VersionedTodoIndexer { private final DataIndexer[] indexers; public CompositeTodoIndexer(@NotNull DataIndexer... indexers) { @@ -139,9 +143,18 @@ public abstract class PlatformIdTableBuilding { } return result; } + + @Override + public int getVersion() { + int version = super.getVersion(); + for(DataIndexer dataIndexer:indexers) { + version += dataIndexer instanceof VersionedTodoIndexer ? ((VersionedTodoIndexer)dataIndexer).getVersion() : 0xFF; + } + return version; + } } - private static class TokenSetTodoIndexer implements DataIndexer { + private static class TokenSetTodoIndexer extends VersionedTodoIndexer { @NotNull private final TokenSet myCommentTokens; private final VirtualFile myFile; @@ -201,7 +214,7 @@ public abstract class PlatformIdTableBuilding { } } - public static class PlainTextTodoIndexer implements DataIndexer { + public static class PlainTextTodoIndexer extends VersionedTodoIndexer { @Override @NotNull public Map map(@NotNull final FileContent inputData) { diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java index d955354cca7f..109ec0c3f971 100644 --- a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java +++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java @@ -20,8 +20,10 @@ import com.intellij.lang.Language; import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lang.ParserDefinition; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding; import com.intellij.psi.search.IndexPatternProvider; @@ -39,7 +41,9 @@ import java.beans.PropertyChangeListener; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.Map; /** @@ -49,7 +53,10 @@ import java.util.Map; public class TodoIndex extends FileBasedIndexExtension { @NonNls public static final ID NAME = ID.create("TodoIndex"); - public TodoIndex(MessageBus messageBus) { + private final FileTypeRegistry myFileTypeManager; + + public TodoIndex(MessageBus messageBus, FileTypeRegistry manager) { + myFileTypeManager = manager; messageBus.connect().subscribe(IndexPatternProvider.INDEX_PATTERNS_CHANGED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -127,7 +134,27 @@ public class TodoIndex extends FileBasedIndexExtension @Override public int getVersion() { - return 8; + int version = 8; + FileType[] types = myFileTypeManager.getRegisteredFileTypes(); + Arrays.sort(types, new Comparator() { + @Override + public int compare(FileType o1, FileType o2) { + return Comparing.compare(o1.getName(), o2.getName()); + } + }); + + for(FileType fileType:types) { + DataIndexer indexer = TodoIndexers.INSTANCE.forFileType(fileType); + if (indexer == null) continue; + + if (!(indexer instanceof VersionedTodoIndexer)) { + int a = 1; + } + + int versionFromIndexer = indexer instanceof VersionedTodoIndexer ? (((VersionedTodoIndexer)indexer).getVersion()) : 0xFF; + version = version * 31 + (versionFromIndexer ^ indexer.getClass().getName().hashCode()); + } + return version; } @Override diff --git a/platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java b/platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java index c4a306286708..824202fd0807 100644 --- a/platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java +++ b/platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java @@ -27,7 +27,7 @@ import org.jetbrains.annotations.NotNull; * @author max */ -public class DefaultWordsScanner implements WordsScanner { +public class DefaultWordsScanner extends VersionedWordsScanner { private final Lexer myLexer; private final TokenSet myIdentifierTokenSet; private final TokenSet myCommentTokenSet; diff --git a/platform/indexing-api/src/com/intellij/lang/cacheBuilder/SimpleWordsScanner.java b/platform/indexing-api/src/com/intellij/lang/cacheBuilder/SimpleWordsScanner.java index 6273654982a9..069c8643ae19 100644 --- a/platform/indexing-api/src/com/intellij/lang/cacheBuilder/SimpleWordsScanner.java +++ b/platform/indexing-api/src/com/intellij/lang/cacheBuilder/SimpleWordsScanner.java @@ -25,7 +25,7 @@ import com.intellij.util.text.CharArrayUtil; * * @author max */ -public class SimpleWordsScanner implements WordsScanner { +public class SimpleWordsScanner extends VersionedWordsScanner { public void processWords(CharSequence fileText, Processor processor) { int index = 0; WordOccurrence occurrence = null; diff --git a/platform/indexing-api/src/com/intellij/lang/cacheBuilder/VersionedWordsScanner.java b/platform/indexing-api/src/com/intellij/lang/cacheBuilder/VersionedWordsScanner.java new file mode 100644 index 000000000000..f8d27825d14e --- /dev/null +++ b/platform/indexing-api/src/com/intellij/lang/cacheBuilder/VersionedWordsScanner.java @@ -0,0 +1,22 @@ +/* + * Copyright 2000-2014 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.lang.cacheBuilder; + +public abstract class VersionedWordsScanner implements WordsScanner { + public int getVersion() { + return 1; + } +} diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/FileTypeIdIndexer.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/FileTypeIdIndexer.java index f770ac1d5d97..5c1246c7a50b 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/FileTypeIdIndexer.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/FileTypeIdIndexer.java @@ -24,4 +24,7 @@ import com.intellij.util.indexing.FileContent; * Date: Jan 16, 2008 */ public abstract class FileTypeIdIndexer implements DataIndexer { + public int getVersion() { + return 1; + } } diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java index 8519453e3e6c..c2ea447400cc 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java @@ -161,6 +161,11 @@ public class IdTableBuilding { }); return consumer.getResult(); } + + @Override + public int getVersion() { + return myScanner instanceof VersionedWordsScanner ? ((VersionedWordsScanner)myScanner).getVersion() : -1; + } } public static void scanWords(final ScanWordProcessor processor, final CharSequence chars, final int startOffset, final int endOffset) { diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/LexerBasedTodoIndexer.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/LexerBasedTodoIndexer.java index b05ef6a9853a..04e27e91dc63 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/LexerBasedTodoIndexer.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/LexerBasedTodoIndexer.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.cache.impl.todo; import com.intellij.psi.impl.cache.impl.BaseFilterLexerUtil; import com.intellij.psi.impl.cache.impl.IdAndToDoScannerBasedOnFilterLexer; -import com.intellij.util.indexing.DataIndexer; import com.intellij.util.indexing.FileContent; import org.jetbrains.annotations.NotNull; @@ -28,8 +27,7 @@ import java.util.Map; * @author Eugene Zhuravlev * Date: Jan 20, 2008 */ -public abstract class LexerBasedTodoIndexer implements DataIndexer, - IdAndToDoScannerBasedOnFilterLexer { +public abstract class LexerBasedTodoIndexer extends VersionedTodoIndexer implements IdAndToDoScannerBasedOnFilterLexer { @Override @NotNull public Map map(@NotNull final FileContent inputData) { diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/VersionedTodoIndexer.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/VersionedTodoIndexer.java new file mode 100644 index 000000000000..028c24b77eed --- /dev/null +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/todo/VersionedTodoIndexer.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2014 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.psi.impl.cache.impl.todo; + +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileContent; + +public abstract class VersionedTodoIndexer implements DataIndexer { + public int getVersion() { + return 1; + } +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java new file mode 100644 index 000000000000..457a285a9e9c --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2014 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.psi.codeStyle.autodetect; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import static com.intellij.psi.codeStyle.CommonCodeStyleSettings.*; + +public class IndentOptionsDetector { + private static Logger LOG = Logger.getInstance("#com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptionsDetector"); + + private static final double RATE_THRESHOLD = 0.8; + private static final int MIN_LINES_THRESHOLD = 50; + private static int MAX_INDENT_TO_DETECT = 8; + + private final PsiFile myFile; + private final Project myProject; + private final Document myDocument; + + public IndentOptionsDetector(@NotNull PsiFile file) { + myFile = file; + myProject = file.getProject(); + myDocument = PsiDocumentManager.getInstance(myProject).getDocument(myFile); + } + + @NotNull + public IndentOptions getIndentOptions() { + IndentOptions indentOptions = (IndentOptions)CodeStyleSettingsManager.getSettings(myProject).getIndentOptions(myFile.getFileType()).clone(); + + if (myDocument != null) { + List linesInfo = new LineIndentInfoBuilder(myDocument.getCharsSequence()).build(); + IndentUsageStatistics stats = new IndentUsageStatisticsImpl(linesInfo); + adjustIndentOptions(indentOptions, stats); + } + + return indentOptions; + } + + private void adjustIndentOptions(@NotNull IndentOptions indentOptions, @NotNull IndentUsageStatistics stats) { + int linesWithTabs = stats.getTotalLinesWithLeadingTabs(); + int linesWithWhiteSpaceIndent = stats.getTotalLinesWithLeadingSpaces(); + + int totalLines = linesWithTabs + linesWithWhiteSpaceIndent; + double lineWithTabsRate = (double)linesWithTabs / totalLines; + + if (linesWithTabs > MIN_LINES_THRESHOLD && lineWithTabsRate > RATE_THRESHOLD) { + if (!indentOptions.USE_TAB_CHARACTER) { + indentOptions.USE_TAB_CHARACTER = true; + LOG.info("Detected tab usage in" + myFile); + } + } + else if (linesWithWhiteSpaceIndent > MIN_LINES_THRESHOLD && (1 - lineWithTabsRate) > RATE_THRESHOLD) { + int newIndentSize = getPositiveIndentSize(stats); + if (newIndentSize > 0 && indentOptions.INDENT_SIZE != newIndentSize) { + indentOptions.INDENT_SIZE = newIndentSize; + LOG.info("Detected indent size: " + newIndentSize + " for file " + myFile); + } + } + } + + private static int getPositiveIndentSize(@NotNull IndentUsageStatistics stats) { + int totalIndentSizesDetected = stats.getTotalIndentSizesDetected(); + if (totalIndentSizesDetected == 0) return -1; + + IndentUsageInfo maxUsedIndentInfo = stats.getKMostUsedIndentInfo(0); + int maxUsedIndentSize = maxUsedIndentInfo.getIndentSize(); + + if (maxUsedIndentSize == 0) { + if (totalIndentSizesDetected < 1) return -1; + + maxUsedIndentInfo = stats.getKMostUsedIndentInfo(1); + maxUsedIndentSize = maxUsedIndentInfo.getIndentSize(); + } + + if (maxUsedIndentSize <= MAX_INDENT_TO_DETECT) { + int totalUsagesWithoutZeroIndent = stats.getTotalLinesWithLeadingSpaces() - stats.getTimesIndentUsed(0); + double usageRate = (double)maxUsedIndentInfo.getTimesUsed() / totalUsagesWithoutZeroIndent; + if (usageRate > RATE_THRESHOLD) { + return maxUsedIndentSize; + } + } + + return -1; + } +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java new file mode 100644 index 000000000000..a600483a07a6 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 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.psi.codeStyle.autodetect; + +public class IndentUsageInfo { + private final int indentSize; + private final int timesUsed; + + public IndentUsageInfo(int indentSize, int timesUsed) { + this.indentSize = indentSize; + this.timesUsed = timesUsed; + } + + public int getIndentSize() { + return indentSize; + } + + public int getTimesUsed() { + return timesUsed; + } + + @Override + public String toString() { + return "indent: " + indentSize + ", used " + timesUsed; + } +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java new file mode 100644 index 000000000000..7e3bee7221da --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 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.psi.codeStyle.autodetect; + +public interface IndentUsageStatistics { + + int getTotalLinesWithLeadingTabs(); + + int getTotalLinesWithLeadingSpaces(); + + IndentUsageInfo getKMostUsedIndentInfo(int k); + + int getTotalIndentSizesDetected(); + + int getTimesIndentUsed(int indent); + +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java new file mode 100644 index 000000000000..6578b5faa3e3 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java @@ -0,0 +1,149 @@ +/* + * Copyright 2000-2014 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.psi.codeStyle.autodetect; + +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Stack; +import gnu.trove.TIntIntHashMap; +import gnu.trove.TIntIntIterator; +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; +import java.util.List; + +public class IndentUsageStatisticsImpl implements IndentUsageStatistics { + private static final Comparator DECREASING_ORDER = new Comparator() { + @Override + public int compare(@NotNull IndentUsageInfo o1, @NotNull IndentUsageInfo o2) { + return o1.getTimesUsed() < o2.getTimesUsed() ? 1 : o1.getTimesUsed() == o2.getTimesUsed() ? 0 : -1; + } + }; + + private List myLineInfos; + + private int myPreviousLineIndent; + private int myPreviousRelativeIndent; + + private int myTotalLinesWithTabs = 0; + private int myTotalLinesWithWhiteSpaces = 0; + + private TIntIntHashMap myIndentToUsages = new TIntIntHashMap(); + private List myIndentUsages = ContainerUtil.newArrayList(); + private Stack myParentIndents = ContainerUtil.newStack(new IndentData(0, 0)); + + public IndentUsageStatisticsImpl(@NotNull List lineInfos) { + myLineInfos = lineInfos; + buildIndentToUsagesMap(); + myIndentUsages = toIndentUsageList(myIndentToUsages); + ContainerUtil.sort(myIndentUsages, DECREASING_ORDER); + } + + @NotNull + private static List toIndentUsageList(@NotNull TIntIntHashMap indentToUsages) { + List indentUsageInfos = ContainerUtil.newArrayList(); + TIntIntIterator it = indentToUsages.iterator(); + while (it.hasNext()) { + it.advance(); + indentUsageInfos.add(new IndentUsageInfo(it.key(), it.value())); + } + return indentUsageInfos; + } + + public void buildIndentToUsagesMap() { + myPreviousLineIndent = 0; + myPreviousRelativeIndent = 0; + + for (LineIndentInfo lineInfo : myLineInfos) { + if (lineInfo.isLineWithTabs()) { + myTotalLinesWithTabs++; + } + else if (lineInfo.isLineWithWhiteSpaceIndent()) { + handleWhiteSpaceIndent(lineInfo.getIndentSize()); + } + } + } + + @NotNull + private IndentData findParentIndent(int indent) { + while (myParentIndents.size() != 1 && myParentIndents.peek().indent > indent) { + myParentIndents.pop(); + } + return myParentIndents.peek(); + } + + private void handleWhiteSpaceIndent(int currentIndent) { + int relativeIndent = currentIndent - myPreviousLineIndent; + if (relativeIndent < 0) { + IndentData indentData = findParentIndent(currentIndent); + myPreviousLineIndent = indentData.indent; + myPreviousRelativeIndent = indentData.relativeIndent; + relativeIndent = currentIndent - myPreviousLineIndent; + } + + if (relativeIndent == 0) { + relativeIndent = myPreviousRelativeIndent; + } + else { + myParentIndents.push(new IndentData(currentIndent, relativeIndent)); + } + + increaseIndentUsage(relativeIndent); + + myPreviousRelativeIndent = relativeIndent; + myPreviousLineIndent = currentIndent; + myTotalLinesWithWhiteSpaces++; + } + + private void increaseIndentUsage(int relativeIndent) { + int timesUsed = myIndentToUsages.get(relativeIndent); + myIndentToUsages.put(relativeIndent, ++timesUsed); + } + + @Override + public int getTotalLinesWithLeadingTabs() { + return myTotalLinesWithTabs; + } + + @Override + public int getTotalLinesWithLeadingSpaces() { + return myTotalLinesWithWhiteSpaces; + } + + @Override + public IndentUsageInfo getKMostUsedIndentInfo(int k) { + return myIndentUsages.get(k); + } + + @Override + public int getTimesIndentUsed(int indent) { + return myIndentToUsages.get(indent); + } + + @Override + public int getTotalIndentSizesDetected() { + return myIndentToUsages.size(); + } + + private static class IndentData { + public final int indent; + public final int relativeIndent; + + public IndentData(int indent, int relativeIndent) { + this.indent = indent; + this.relativeIndent = relativeIndent; + } + } +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java new file mode 100644 index 000000000000..67b186504d06 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2014 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.psi.codeStyle.autodetect; + +import org.jetbrains.annotations.NotNull; + +public class LineIndentInfo { + public static LineIndentInfo EMPTY_LINE = new LineIndentInfo(LineType.EMPTY_LINE, -1); + public static LineIndentInfo LINE_WITH_COMMENT = new LineIndentInfo(LineType.LINE_WITH_COMMENT, -1); + public static LineIndentInfo LINE_WITH_TABS = new LineIndentInfo(LineType.LINE_WITH_TABS, -1); + + private final int myIndentSize; + private final LineType myType; + + private LineIndentInfo(@NotNull LineType type, int indentSize) { + myType = type; + myIndentSize = indentSize; + } + + @NotNull + public static LineIndentInfo newWhiteSpaceIndent(int indentSize) { + return new LineIndentInfo(LineType.LINE_WITH_WHITESPACE_INDENT, indentSize); + } + + public int getIndentSize() { + return myIndentSize; + } + + public boolean isLineWithWhiteSpaceIndent() { + return myType == LineType.LINE_WITH_WHITESPACE_INDENT; + } + + public boolean isLineWithTabs() { + return myType == LineType.LINE_WITH_TABS; + } + + private enum LineType { + EMPTY_LINE, + LINE_WITH_COMMENT, + LINE_WITH_TABS, + LINE_WITH_WHITESPACE_INDENT + } +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java new file mode 100644 index 000000000000..8efbbc495750 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2014 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.psi.codeStyle.autodetect; + +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.text.CharArrayUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class LineIndentInfoBuilder { + private static final int MAX_LINES_TO_PROCESS = 500; + + private final CharSequence myText; + private final int myLength; + + public LineIndentInfoBuilder(@NotNull CharSequence text) { + myText = text; + myLength = text.length(); + } + + @NotNull + public List build() { + List lineIndentInfos = ContainerUtil.newArrayList(); + + int lineStartOffset = 0; + int currentLine = 0; + + while (lineStartOffset < myText.length() && currentLine < MAX_LINES_TO_PROCESS) { + int lineEndOffset = getLineEndOffset(lineStartOffset); + int textStartOffset = CharArrayUtil.shiftForward(myText, lineStartOffset, lineEndOffset, " \t"); + + if (textStartOffset != lineEndOffset) { + lineIndentInfos.add(createInfoFromWhiteSpaceRange(lineStartOffset, textStartOffset)); + } else { + lineIndentInfos.add(LineIndentInfo.EMPTY_LINE); + } + + lineStartOffset = lineEndOffset + 1; + currentLine++; + } + + return lineIndentInfos; + } + + @NotNull + private LineIndentInfo createInfoFromWhiteSpaceRange(int lineStartOffset, int textStartOffset) { + if (myText.charAt(textStartOffset) == '*') { + return LineIndentInfo.LINE_WITH_COMMENT; + } + else if (CharArrayUtil.indexOf(myText, "\t", lineStartOffset, textStartOffset) > 0) { + return LineIndentInfo.LINE_WITH_TABS; + } + else { + int indentSize = textStartOffset - lineStartOffset; + return LineIndentInfo.newWhiteSpaceIndent(indentSize); + } + } + + private int getLineEndOffset(int lineStartOffset) { + int lineEndOffset = CharArrayUtil.indexOf(myText, "\n", lineStartOffset, myLength); + if (lineEndOffset < 0) { + lineEndOffset = myText.length(); + } + return lineEndOffset; + } +} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 81d0bf651688..2320d059c146 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -1005,11 +1005,10 @@ public class SingleInspectionProfilePanel extends JPanel { northPanel.add(createTreeToolbarPanel().getComponent(), new GridBagConstraints(1, 0, 1, 1, 0.5, 1, GridBagConstraints.BASELINE_LEADING, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); treePanel.add(northPanel, BorderLayout.NORTH); - myMainSplitter = new Splitter(false); + myMainSplitter = new Splitter(false, myProperties.getFloat(VERTICAL_DIVIDER_PROPORTION, 0.5f), 0.01f, 0.99f); myMainSplitter.setFirstComponent(treePanel); myMainSplitter.setSecondComponent(myRightSplitter); myMainSplitter.setHonorComponentsMinimumSize(false); - myMainSplitter.setProportion(myProperties.getFloat(VERTICAL_DIVIDER_PROPORTION, 0.5f)); final JPanel panel = new JPanel(new BorderLayout()); panel.add(myMainSplitter, BorderLayout.CENTER); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java index 5607816ad13c..fe36408cf61a 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java @@ -220,7 +220,7 @@ public class InspectionsConfigTreeTable extends TreeTable { @Override public void setValueAt(final Object aValue, final Object node, final int column) { LOG.assertTrue(column == IS_ENABLED_COLUMN); - LOG.assertTrue(aValue != null); + LOG.assertTrue(aValue != null, "node = " + node); final boolean doEnable = (Boolean) aValue; for (final InspectionConfigTreeNode aNode : InspectionsAggregationUtil.getInspectionsNodes((InspectionConfigTreeNode) node)) { final String toolId = aNode.getKey().toString(); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndexImpl.java index 537d997e5a50..1773a260a706 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndexImpl.java @@ -15,6 +15,9 @@ */ package com.intellij.psi.impl.cache.impl.id; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeRegistry; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.ThreadLocalCachedIntArray; import com.intellij.util.indexing.CustomInputsIndexFileBasedIndexExtension; import com.intellij.util.io.DataExternalizer; @@ -27,9 +30,35 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; public class IdIndexImpl extends IdIndex implements CustomInputsIndexFileBasedIndexExtension { private static final ThreadLocalCachedIntArray spareBufferLocal = new ThreadLocalCachedIntArray(); + private final FileTypeRegistry myFileTypeManager; + + public IdIndexImpl(FileTypeRegistry manager) { + myFileTypeManager = manager; + } + + @Override + public int getVersion() { + FileType[] types = myFileTypeManager.getRegisteredFileTypes(); + Arrays.sort(types, new Comparator() { + @Override + public int compare(FileType o1, FileType o2) { + return Comparing.compare(o1.getName(), o2.getName()); + } + }); + + int version = super.getVersion(); + for(FileType fileType:types) { + if (!isIndexable(fileType)) continue; + FileTypeIdIndexer indexer = IdIndexers.INSTANCE.forFileType(fileType); + if (indexer == null) continue; + version = version * 31 + (indexer.getVersion() ^ indexer.getClass().getName().hashCode()); + } + return version; + } @NotNull @Override diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java index 411f2d9d93bb..0b696c8f4496 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java @@ -134,12 +134,12 @@ public class CreateLauncherScriptAction extends DumbAwareAction { private static File createLauncherScriptFile() throws IOException, ExecutionException { String runPath = PathManager.getHomePath(); + final String productName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase(); if (!SystemInfo.isMac) { // for Macs just use "*.app" - final String productName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase(); runPath += "/bin/" + productName + ".sh"; } else if (runPath.endsWith(CONTENTS)) { - runPath = runPath.substring(0, runPath.length() - CONTENTS.length()); + runPath += "/MacOS/" + productName; } String launcherContents = ExecUtil.loadTemplate(CreateLauncherScriptAction.class.getClassLoader(), "launcher.py", newHashMap(asList("$CONFIG_PATH$", "$RUN_PATH$"), diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesPanel.form b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesPanel.form index 2cee5d3e03f9..be22623c2142 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesPanel.form +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesPanel.form @@ -25,7 +25,6 @@ - diff --git a/platform/platform-resources/src/launcher.py b/platform/platform-resources/src/launcher.py index f04a26cb2c83..440f716f8ebf 100644 --- a/platform/platform-resources/src/launcher.py +++ b/platform/platform-resources/src/launcher.py @@ -18,30 +18,19 @@ for i, arg in enumerate(sys.argv[1:]): print(('Usage:\n' + \ ' {0} -h |-? | --help\n' + \ ' {0} [-l|--line line] file[:line]\n' + \ - ' {0} diff \n' + \ - ' {0} merge [base] ').format(sys.argv[0])) + ' {0} diff ' + \ + ' {0} merge [base] ').format(sys.argv[0])) exit(0) - elif arg == 'diff' and i == 0: - args.append(arg) - elif arg == 'merge' and i == 0: - args.append(arg) - elif arg == '-l' or arg == '--line': - args.append(arg) - skip_next = True - elif skip_next: - args.append(arg) - skip_next = False - else: - if ':' in arg: - file_path, line_number = arg.rsplit(':', 1) - if line_number.isdigit(): - args.append('-l') - args.append(line_number) - args.append(os.path.abspath(file_path)) - else: - args.append(os.path.abspath(arg)) + elif ':' in arg: + file_path, line_number = arg.rsplit(':', 1) + if line_number.isdigit(): + args.append('-l') + args.append(line_number) + args.append(file_path) else: - args.append(os.path.abspath(arg)) + args.append(arg) + else: + args.append(arg) def launch_with_port(port): found = False @@ -57,7 +46,6 @@ def launch_with_port(port): try: path_len = struct.unpack(">h", s.recv(2))[0] path = s.recv(path_len) - path = os.path.abspath(path) if os.path.abspath(path) == os.path.abspath(CONFIG_PATH): found = True break @@ -90,13 +78,5 @@ if port == -1: else: if launch_with_port(port): exit() -if sys.platform == "darwin": - # Mac OS: RUN_PATH is *.app path - if len(args): - args.insert(0, "--args") - os.execvp("open", ["-a", RUN_PATH] + args) -else: - # unix common - bin_dir, bin_file = os.path.split(RUN_PATH) - os.chdir(bin_dir) - os.execv(bin_file, [bin_file] + args) \ No newline at end of file +bin_dir, bin_file = os.path.split(RUN_PATH) +os.execv(RUN_PATH, [bin_file] + args) \ No newline at end of file diff --git a/platform/platform-tests/testData/codeStyle/autodetect/manyComments.java b/platform/platform-tests/testData/codeStyle/autodetect/manyComments.java new file mode 100644 index 000000000000..7bc7a3a46982 --- /dev/null +++ b/platform/platform-tests/testData/codeStyle/autodetect/manyComments.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2014 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. + */ + + +public interface Doable { + + + /* + * + * + * + * + * + * + * + * + * + * + */ + public void count() { + } + + + /* + * + * + * + * + * + * + * + * + * + * + */ + public void test() { + } +} diff --git a/platform/platform-tests/testData/codeStyle/autodetect/manyZeroRelativeIndent.java b/platform/platform-tests/testData/codeStyle/autodetect/manyZeroRelativeIndent.java new file mode 100644 index 000000000000..2ee4c59848ec --- /dev/null +++ b/platform/platform-tests/testData/codeStyle/autodetect/manyZeroRelativeIndent.java @@ -0,0 +1,31 @@ +class Test { + + public void test() { + // boolean function-available(string) + addFunction(decls, new FunctionImpl("function-available", XPathType.BOOLEAN, + new Parameter(XPathType.STRING, Parameter.Kind.REQUIRED))); + + // node-set current() + addFunction(decls, new FunctionImpl("current", XPathType.NODESET)); + + // EXSLT (http://www.exslt.org) extensions supported by Xalan & Saxon + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("date", XPathType.STRING, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("date-time", XPathType.STRING)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("day-abbreviation", XPathType.STRING, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("day-in-month", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("day-in-week", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("day-in-year", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("day-name", XPathType.STRING, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("day-of-week-in-month", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("hour-in-day", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("leap-year", XPathType.BOOLEAN, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("minute-in-hour", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("month-abbreviation", XPathType.STRING, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("month-in-year", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("month-name", XPathType.STRING, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("second-in-minute", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("time", XPathType.STRING, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("week-in-year", XPathType.NUMBER, optional_string)); + addFunction(decls, EXSLT_DATE_TIME, new FunctionImpl("year", XPathType.NUMBER, optional_string)); + } +} diff --git a/platform/platform-tests/testData/codeStyle/autodetect/simpleIndent.java b/platform/platform-tests/testData/codeStyle/autodetect/simpleIndent.java new file mode 100644 index 000000000000..c4cd369df732 --- /dev/null +++ b/platform/platform-tests/testData/codeStyle/autodetect/simpleIndent.java @@ -0,0 +1,14 @@ +public class A { + + public void test() { + int a = 2; + int c = 2; + int r = 3; + int rq = 3; + int rw = 3; + int re = 3; + } + + public void a() { + } +} diff --git a/platform/platform-tests/testSrc/com/intellij/psi/autodetect/IndentAutoDetectionTest.java b/platform/platform-tests/testSrc/com/intellij/psi/autodetect/IndentAutoDetectionTest.java new file mode 100644 index 000000000000..4b59416de0d9 --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/psi/autodetect/IndentAutoDetectionTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2000-2014 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.psi.autodetect; + +import com.intellij.openapi.editor.Document; +import com.intellij.psi.codeStyle.autodetect.*; +import com.intellij.testFramework.LightPlatformCodeInsightTestCase; +import com.intellij.testFramework.PlatformTestCase; +import com.intellij.testFramework.PlatformTestUtil; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; + +import java.io.File; +import java.util.List; + +public class IndentAutoDetectionTest extends LightPlatformCodeInsightTestCase { + private static final String BASE_PATH = "codeStyle/autodetect/"; + + static { + PlatformTestCase.initPlatformLangPrefix(); + } + + public void testSimpleIndent() { + doTestMaxUsedIndent(2, 6); + } + + public void testManyComments() { + doTestMaxUsedIndent(2, 6); + } + + public void testManyZeroRelativeIndent() { + doTestMaxUsedIndent(2); + } + + public void testSpacesToNumbers() throws Exception { + String text = " i\n" + + " a\n" + + " t\n"; + doTestLineToIndentMapping(text, 5, 4, 10); + } + + public void testEmptyLines() throws Exception { + doTestLineToIndentMapping(" \n\n\n", -1, -1, -1); + } + + public void testSpacesInSimpleClass() { + doTestLineToIndentMapping( + "public class A {\n" + + "\n" + + " public void test() {\n" + + " int a = 2;\n" + + " }\n" + + "\n" + + " public void a() {\n" + + " }\n" + + "}", + 0, -1, 4, 6, 4, -1, 4, 4, 0 + ); + } + + public void testComplexIndents() { + doTestLineToIndentMapping( + "class Test\n" + + "{\n" + + " int a;\n" + + " int b;\n" + + " \n" + + " public void test() {\n" + + " int c;\n" + + " }\n" + + " \n" + + " public void run() {\n" + + " Runnable runnable = new Runnable() {\n" + + " @Override\n" + + " public void run() {\n" + + " System.out.println(\"Hello!\");\n" + + " }\n" + + " };\n" + + " }\n" + + "}", + 0, 0, 2, 2, -1, 2, 4, 2, -1, 2, 4, 6, 6, 8, 6, 4, 2, 0 + ); + } + + public void doTestMaxUsedIndent(int indentExpected, int timesUsedExpected) { + IndentUsageInfo maxIndentExpected = new IndentUsageInfo(indentExpected, timesUsedExpected); + IndentUsageInfo indentInfo = getMaxUsedIndentInfo(); + Assert.assertEquals("Indent size mismatch", maxIndentExpected.getIndentSize(), indentInfo.getIndentSize()); + Assert.assertEquals("Indent size usage number mismatch", maxIndentExpected.getTimesUsed(), indentInfo.getTimesUsed()); + } + + public void doTestMaxUsedIndent(int indentExpected) { + IndentUsageInfo indentInfo = getMaxUsedIndentInfo(); + Assert.assertEquals("Indent size mismatch", indentExpected, indentInfo.getIndentSize()); + } + + @NotNull + private IndentUsageInfo getMaxUsedIndentInfo() { + configureByFile(getTestName(true) + ".java"); + Document document = getDocument(myFile); + List lines = new LineIndentInfoBuilder(document.getCharsSequence()).build(); + IndentUsageStatistics statistics = new IndentUsageStatisticsImpl(lines); + return statistics.getKMostUsedIndentInfo(0); + } + + private static void doTestLineToIndentMapping(@NotNull CharSequence text, int... spacesForLine) { + List list = new LineIndentInfoBuilder(text).build(); + Assert.assertEquals(list.size(), spacesForLine.length); + for (int i = 0; i < spacesForLine.length; i++) { + int indentSize = list.get(i).getIndentSize(); + Assert.assertEquals("Mismatch on line " + i, spacesForLine[i], indentSize); + } + } + + @Override + @NotNull + public String getTestDataPath() { + return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + + "/platform/platform-tests/testData/" + + BASE_PATH; + } +} diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java index 29ef1acdfd78..bf81b8d62502 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java @@ -26,12 +26,12 @@ public class GithubUser { @NotNull private final String myHtmlUrl; - @Nullable private final String myGravatarId; + @Nullable private final String myAvatarUrl; - public GithubUser(@NotNull String login, @NotNull String htmlUrl, @Nullable String gravatarId) { + public GithubUser(@NotNull String login, @NotNull String htmlUrl, @Nullable String avatarUrl) { myLogin = login; myHtmlUrl = htmlUrl; - myGravatarId = gravatarId; + myAvatarUrl = avatarUrl; } @NotNull @@ -45,7 +45,7 @@ public class GithubUser { } @Nullable - public String getGravatarId() { - return myGravatarId; + public String getAvatarUrl() { + return myAvatarUrl; } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java index 2c82c078e339..3940b80f360a 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java @@ -55,13 +55,13 @@ public class GithubUserDetailed extends GithubUser { public GithubUserDetailed(@NotNull String login, @NotNull String htmlUrl, - @Nullable String gravatarId, + @Nullable String avatarUrl, @Nullable String name, @Nullable String email, @Nullable Integer ownedPrivateRepos, @Nullable String type, @Nullable UserPlan plan) { - super(login, htmlUrl, gravatarId); + super(login, htmlUrl, avatarUrl); myName = name; myEmail = email; myOwnedPrivateRepos = ownedPrivateRepos; diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserRaw.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserRaw.java index 04d642f8eb2e..0bc673299847 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserRaw.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserRaw.java @@ -74,14 +74,14 @@ class GithubUserRaw implements DataConstructor { @SuppressWarnings("ConstantConditions") @NotNull public GithubUser createUser() { - return new GithubUser(login, htmlUrl, gravatarId); + return new GithubUser(login, htmlUrl, avatarUrl); } @SuppressWarnings("ConstantConditions") @NotNull public GithubUserDetailed createUserDetailed() { GithubUserDetailed.UserPlan plan = this.plan == null ? null : this.plan.create(); - return new GithubUserDetailed(login, htmlUrl, gravatarId, name, email, ownedPrivateRepos, type, plan); + return new GithubUserDetailed(login, htmlUrl, avatarUrl, name, email, ownedPrivateRepos, type, plan); } @SuppressWarnings("unchecked") diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubComment.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubComment.java index d65a95044a9c..e3115f71975c 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubComment.java +++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubComment.java @@ -26,16 +26,16 @@ import java.util.Date; * @author Dennis.Ushakov */ public class GithubComment extends SimpleComment { - @Nullable private final String myGravatarId; + @Nullable private final String myAvatarUrl; @NotNull private final String myUserHtmlUrl; public GithubComment(@Nullable Date date, @Nullable String author, @NotNull String text, - @Nullable String gravatarId, + @Nullable String avatarUrl, @NotNull String userHtmlUrl) { super(date, author, text); - myGravatarId = gravatarId; + myAvatarUrl = avatarUrl; myUserHtmlUrl = userHtmlUrl; } @@ -43,9 +43,9 @@ public class GithubComment extends SimpleComment { builder.append("
"); builder.append(""); builder.append("
"); - if (myGravatarId != null) { - builder.append("
"); - } + if (myAvatarUrl != null) { + builder.append("
"); + } builder.append("
"); if (getAuthor() != null) { builder.append("Author: ").append(getAuthor()).append("
"); diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java index 39a97184fe72..a8445b7f76ac 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java +++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java @@ -240,7 +240,7 @@ public class GithubRepository extends BaseRepositoryImpl { @Override public Comment fun(GithubIssueComment comment) { return new GithubComment(comment.getCreatedAt(), comment.getUser().getLogin(), comment.getBodyHtml(), - comment.getUser().getGravatarId(), + comment.getUser().getAvatarUrl(), comment.getUser().getHtmlUrl()); } }); diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java index 15e73791f8ea..502d9b4dc499 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java @@ -15,7 +15,6 @@ */ package com.intellij.lang.properties; -import com.intellij.lang.HtmlScriptContentProvider; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.lang.properties.psi.PropertyKeyIndex; import com.intellij.lang.properties.xml.XmlPropertiesFileImpl; @@ -79,7 +78,13 @@ public class PropertiesImplUtil extends PropertiesUtil { private static ResourceBundle getResourceBundle(@NotNull final String baseName, @NotNull final PsiDirectory baseDirectory) { PropertiesFile defaultPropertiesFile = null; final ResourceBundleManager bundleBaseNameManager = ResourceBundleManager.getInstance(baseDirectory.getProject()); - for (final PsiFile psiFile : baseDirectory.getFiles()) { + final PsiFile[] psiFiles = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiFile[] compute() { + return baseDirectory.getFiles(); + } + }); + for (final PsiFile psiFile : psiFiles) { if (baseName.equals(bundleBaseNameManager.getBaseName(psiFile))) { final PropertiesFile propertiesFile = getPropertiesFile(psiFile); if (propertiesFile != null) { @@ -147,4 +152,4 @@ public class PropertiesImplUtil extends PropertiesUtil { } return getResourceBundle(baseName, baseDirectory); } -} +} \ No newline at end of file