diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaChangeLocalityDetector.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaChangeLocalityDetector.java index 6a8f8244faca..1f06435e398a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaChangeLocalityDetector.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaChangeLocalityDetector.java @@ -21,15 +21,20 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.codeInsight.daemon.ChangeLocalityDetector; import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class JavaChangeLocalityDetector implements ChangeLocalityDetector { @Override @Nullable - public PsiElement getChangeHighlightingDirtyScopeFor(final PsiElement element) { + public PsiElement getChangeHighlightingDirtyScopeFor(@NotNull final PsiElement element) { + // optimization PsiElement parent = element.getParent(); - if (element instanceof PsiCodeBlock && parent instanceof PsiMethod && !((PsiMethod)parent).isConstructor() && - parent.getParent() instanceof PsiClass && !(parent.getParent() instanceof PsiAnonymousClass)) { + if (element instanceof PsiCodeBlock + && parent instanceof PsiMethod + && !((PsiMethod)parent).isConstructor() + && parent.getParent() instanceof PsiClass + && !(parent.getParent() instanceof PsiAnonymousClass)) { // for changes inside method, rehighlight codeblock only // do not use this optimization for constructors and class initializers - to update non-initialized fields return parent; diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousConstructorProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousConstructorProcessor.java index 31fbe26be597..b762395a7a2a 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousConstructorProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousConstructorProcessor.java @@ -57,11 +57,11 @@ class InlineToAnonymousConstructorProcessor { psiElement().withText(PsiKeyword.THIS))); private final PsiClass myClass; - private final PsiNewExpression myNewExpression; + private PsiNewExpression myNewExpression; private final PsiType mySuperType; private final Map myFieldInitializers = new HashMap(); private final Map myLocalsForParameters = new HashMap(); - private final PsiStatement myNewStatement; + private PsiStatement myNewStatement; private final PsiElementFactory myElementFactory; private PsiMethod myConstructor; private PsiExpressionList myConstructorArguments; @@ -263,7 +263,23 @@ class InlineToAnonymousConstructorProcessor { final PsiDeclarationStatement declaration = myElementFactory.createVariableDeclarationStatement(localName, type, initializer); PsiVariable variable = (PsiVariable)declaration.getDeclaredElements()[0]; PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, true); - myNewStatement.getParent().addBefore(declaration, myNewStatement); + final PsiElement parent = myNewStatement.getParent(); + if (parent instanceof PsiCodeBlock) { + variable = (PsiVariable)((PsiDeclarationStatement)parent.addBefore(declaration, myNewStatement)).getDeclaredElements()[0]; + } + else { + final int offsetInStatement = myNewExpression.getTextRange().getStartOffset() - myNewStatement.getTextRange().getStartOffset(); + final PsiBlockStatement blockStatement = (PsiBlockStatement)myElementFactory.createStatementFromText("{}", null); + PsiCodeBlock block = blockStatement.getCodeBlock(); + block.add(declaration); + block.add(myNewStatement); + block = ((PsiBlockStatement)myNewStatement.replace(blockStatement)).getCodeBlock(); + + variable = (PsiVariable)((PsiDeclarationStatement)block.getStatements()[0]).getDeclaredElements()[0]; + myNewStatement = block.getStatements()[1]; + myNewExpression = PsiTreeUtil.getParentOfType(myNewStatement.findElementAt(offsetInStatement), PsiNewExpression.class); + } + return variable; } catch (IncorrectOperationException e) { diff --git a/java/java-tests/testData/refactoring/inlineToAnonymousClass/Braces.java b/java/java-tests/testData/refactoring/inlineToAnonymousClass/Braces.java new file mode 100644 index 000000000000..fc3eddbb1b9c --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineToAnonymousClass/Braces.java @@ -0,0 +1,26 @@ +public class Demo { + + static class MyParent { + private final String value; + + MyParent(String value) { + this.value = value; + } + } + + static class MyChild extends MyParent { + MyChild(String value) { + super(value); + } + } + + public static void main(String[] args) { + + String value = "something"; + final MyParent p; + if (true) + p = new MyChild(value); + else + p = new MyParent("value"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineToAnonymousClass/Braces.java.after b/java/java-tests/testData/refactoring/inlineToAnonymousClass/Braces.java.after new file mode 100644 index 000000000000..8a2d39edbd07 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineToAnonymousClass/Braces.java.after @@ -0,0 +1,22 @@ +public class Demo { + + static class MyParent { + private final String value; + + MyParent(String value) { + this.value = value; + } + } + + public static void main(String[] args) { + + String value = "something"; + final MyParent p; + if (true) { + final String value1 = value; + p = new MyParent(value1); + } + else + p = new MyParent("value"); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java index f9edb4b24490..469acd2a150f 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java @@ -226,6 +226,10 @@ public class InlineToAnonymousClassTest extends LightRefactoringTestCase { doTest(false, true); } + public void testBraces() throws Exception { + doTest(false, false); + } + public void testNoInlineAbstract() throws Exception { doTestNoInline("Abstract classes cannot be inlined"); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 2c05de57807b..5ba93fd8b982 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -73,6 +73,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF private IElementType myElementType; protected IElementType myContentElementType; + private long myModificationStamp; protected PsiFile myOriginalFile = null; private final FileViewProvider myViewProvider; @@ -354,7 +355,9 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF myStub = null; } - public void clearCaches() {} + public void clearCaches() { + myModificationStamp ++; + } @Override public String getText() { @@ -386,7 +389,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF @Override public long getModificationStamp() { - return getViewProvider().getModificationStamp(); + return myModificationStamp; } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java index 53419feb35f6..f2673843b5b6 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java @@ -180,7 +180,7 @@ public class BlockSupportImpl extends BlockSupport { viewProvider.getLanguages(); FileType fileType = viewProvider.getVirtualFile().getFileType(); final LightVirtualFile lightFile = new LightVirtualFile(fileImpl.getName(), fileType, newFileText, viewProvider.getVirtualFile().getCharset(), - fileImpl.getModificationStamp()); + fileImpl.getViewProvider().getModificationStamp()); lightFile.setOriginalFile(viewProvider.getVirtualFile()); FileViewProvider copy = viewProvider.createCopy(lightFile); diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/ChangeLocalityDetector.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/ChangeLocalityDetector.java index b80a4b6fc9be..fedbd19f2f48 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/ChangeLocalityDetector.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/ChangeLocalityDetector.java @@ -20,9 +20,17 @@ package com.intellij.codeInsight.daemon; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface ChangeLocalityDetector { + /** + * @param changedElement + * @return the psi element (ancestor of the changedElement) which should be re-highlighted, or null if unsure. + * e.g. in Java we re-highlight enclosing code block only when element inside has changed. + * Note: do not traverse PSI tree upwards here, + * since this ChangeLocalityDetector will be called for the changed element and all its parents anyway. + */ @Nullable - PsiElement getChangeHighlightingDirtyScopeFor(PsiElement changedElement); + PsiElement getChangeHighlightingDirtyScopeFor(@NotNull PsiElement changedElement); } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/codeInsight/editorActions/moveUpDown/LineRange.java b/platform/lang-api/src/com/intellij/codeInsight/editorActions/moveUpDown/LineRange.java index b9fba8d2bf57..cce3cd8c39e3 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/editorActions/moveUpDown/LineRange.java +++ b/platform/lang-api/src/com/intellij/codeInsight/editorActions/moveUpDown/LineRange.java @@ -33,7 +33,7 @@ public class LineRange { public LineRange(final int startLine, final int endLine) { this.startLine = startLine; this.endLine = endLine; - LOG.assertTrue(startLine > 0, "Negative start line"); + LOG.assertTrue(startLine >= 0, "Negative start line"); if (startLine > endLine) { LOG.error("start > end: start=" + startLine+"; end="+endLine); } diff --git a/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java index d40d70cb1723..fcda8e15f6b2 100644 --- a/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java +++ b/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java @@ -55,6 +55,7 @@ public abstract class TextEditorHighlightingPass implements HighlightingPass { this(project, document, true); } + @Override public final void collectInformation(ProgressIndicator progress) { if (!isValid()) return; //Document has changed. myDumb = DumbService.getInstance(myProject).isDumb(); @@ -88,6 +89,7 @@ public abstract class TextEditorHighlightingPass implements HighlightingPass { return true; } + @Override public final void applyInformationToEditor() { if (!isValid()) return; // Document has changed. if (DumbService.getInstance(myProject).isDumb() && !(this instanceof DumbAware)) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 3214d978bcca..2e1333b0919c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -785,7 +785,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { final Pair pair = reference.get(); if (pair != null && pair.first.isValid() && pair.first.getClass().equals(file.getClass())) { final PsiFile copy = pair.first; - if (copy.getModificationStamp() > file.getModificationStamp()) { + if (copy.getViewProvider().getModificationStamp() > file.getViewProvider().getModificationStamp()) { ((PsiModificationTrackerImpl) file.getManager().getModificationTracker()).incCounter(); } final Document document = pair.second; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/OffsetTranslator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/OffsetTranslator.java index bf21e70a6399..041e2a0f25d3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/OffsetTranslator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/OffsetTranslator.java @@ -59,10 +59,10 @@ public class OffsetTranslator implements Disposable { }); originalFile.getProject().getMessageBus().connect(this).subscribe(PsiModificationTracker.TOPIC, new PsiModificationTracker.Listener() { - long lastModCount = originalFile.getModificationStamp(); + long lastModCount = originalFile.getViewProvider().getModificationStamp(); @Override public void modificationCountChanged() { - if (isUpToDate() && lastModCount != originalFile.getModificationStamp()) { + if (isUpToDate() && lastModCount != originalFile.getViewProvider().getModificationStamp()) { myTranslation.addAll(sinceCommit); sinceCommit.clear(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index b9e0f7d040af..7dc5955bc4d9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -26,6 +26,7 @@ import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.ReferenceImporter; import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.intention.impl.IntentionHintComponent; +import com.intellij.codeInspection.ex.InspectionProfileWrapper; import com.intellij.concurrency.Job; import com.intellij.ide.PowerSaveMode; import com.intellij.lang.annotation.HighlightSeverity; @@ -53,6 +54,7 @@ import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -471,7 +473,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx if (myDisposed) return false; Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file); return document != null && - document.getModificationStamp() == file.getModificationStamp() && + document.getModificationStamp() == file.getViewProvider().getModificationStamp() && myFileStatusMap.allDirtyScopesAreNull(document); } @@ -479,7 +481,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx if (myDisposed) return false; Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file); return document != null && - document.getModificationStamp() == file.getModificationStamp() && + document.getModificationStamp() == file.getViewProvider().getModificationStamp() && myFileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL) == null; } @@ -749,10 +751,31 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx myPassExecutorService.submitPasses(passes, progress, Job.DEFAULT_PRIORITY); } }; + + if (activeEditor == null) { runnable.run(); } else { + final InspectionProfileWrapper profile = InspectionProjectProfileManager.getInstance(myProject).getProfileWrapper(); + final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(activeEditor.getDocument()); + if (psiFile != null && profile != null && !profile.areToolsInstantiated()) { + // optimization: do expensive classloading outside readaction + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + try { + if (!psiFile.getManager().isDisposed() && !profile.areToolsInstantiated()) { + profile.preInstantiateTools(psiFile); + } + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + ((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject)).cancelAndRunWhenAllCommitted( "start daemon when all committed", runnable); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultChangeLocalityDetector.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultChangeLocalityDetector.java new file mode 100644 index 000000000000..a822811aa845 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultChangeLocalityDetector.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 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.codeInsight.daemon.impl; + +import com.intellij.codeInsight.daemon.ChangeLocalityDetector; +import com.intellij.codeInspection.SuppressionUtil; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +import org.jetbrains.annotations.NotNull; + +public class DefaultChangeLocalityDetector implements ChangeLocalityDetector { + @Override + public PsiElement getChangeHighlightingDirtyScopeFor(@NotNull PsiElement changedElement) { + if (changedElement instanceof PsiWhiteSpace || + changedElement instanceof PsiComment + && !changedElement.getText().contains(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) { + return changedElement; + } + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index f17a5504853a..ed110d1bd749 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -709,7 +709,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass return new ArrayList(result); } - List getInspectionTools(InspectionProfileWrapper profile) { + @NotNull + List getInspectionTools(@NotNull InspectionProfileWrapper profile) { final List tools = profile.getHighlightingLocalInspectionTools(myFile); for (Iterator iterator = tools.iterator(); iterator.hasNext(); ) { LocalInspectionToolWrapper tool = iterator.next(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java index f148691cd732..956f39823ba5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.codeInsight.daemon.ChangeLocalityDetector; -import com.intellij.codeInspection.SuppressionUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -214,18 +213,9 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable return; } - // optimization - if (whitespaceOptimizationAllowed && UpdateHighlightersUtil.isWhitespaceOptimizationAllowed(document)) { - if (child instanceof PsiWhiteSpace || - child instanceof PsiComment && !child.getText().contains(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) { - myFileStatusMap.markFileScopeDirty(document, child.getTextRange(), fileLength); - return; - } - } - - PsiElement element = child; + PsiElement element = whitespaceOptimizationAllowed && UpdateHighlightersUtil.isWhitespaceOptimizationAllowed(document) ? child : child.getParent(); while (true) { - if (element instanceof PsiFile || element instanceof PsiDirectory) { + if (element == null || element instanceof PsiFile || element instanceof PsiDirectory) { myFileStatusMap.markAllFilesDirty(); return; } @@ -242,10 +232,18 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable @Nullable private static PsiElement getChangeHighlightingScope(PsiElement element) { + DefaultChangeLocalityDetector defaultDetector = null; for (ChangeLocalityDetector detector : Extensions.getExtensions(EP_NAME)) { + if (detector instanceof DefaultChangeLocalityDetector) { + // run default detector last + assert defaultDetector == null : defaultDetector; + defaultDetector = (DefaultChangeLocalityDetector)detector; + continue; + } final PsiElement scope = detector.getChangeHighlightingDirtyScopeFor(element); if (scope != null) return scope; } - return null; + assert defaultDetector != null : "com.intellij.codeInsight.daemon.impl.DefaultChangeLocalityDetector is unregistered"; + return defaultDetector.getChangeHighlightingDirtyScopeFor(element); } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java index c2052337d83b..35a5ee5873bb 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java @@ -22,8 +22,10 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.util.Function; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -66,9 +68,9 @@ public class InspectionProfileWrapper { return enabled; } - // check whether some inspection got registered twice by accident. Bit only once. + // check whether some inspection got registered twice by accident. 've bit once. private static boolean alreadyChecked; - private static void checkInspectionsDuplicates(InspectionTool[] tools) { + private static void checkInspectionsDuplicates(@NotNull InspectionTool[] tools) { if (alreadyChecked) return; alreadyChecked = true; Set uniqTools = new THashSet(tools.length); @@ -79,6 +81,22 @@ public class InspectionProfileWrapper { } } + private volatile boolean toolsInstantiated; + public void preInstantiateTools(PsiFile psiFile) { + if (toolsInstantiated) return; + toolsInstantiated = true; + InspectionTool[] tools = getInspectionTools(psiFile); + for (InspectionTool tool : tools) { + if (tool instanceof InspectionToolWrapper) { + ((InspectionToolWrapper)tool).getTool(); + } + } + } + + public boolean areToolsInstantiated() { + return toolsInstantiated; + } + public String getName() { return myProfile.getName(); } @@ -105,13 +123,10 @@ public class InspectionProfileWrapper { } public void cleanup(final Project project){ - myProfile.cleanup(project); } public InspectionProfile getInspectionProfile() { return myProfile; } - - } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 7ad24cee508c..fcf4e6d58a65 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -59,7 +59,12 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C private Pattern myCompiledPattern; private final PatternMatcher myMatcher = new Perl5Matcher(); - private Map myActionsMap = new HashMap(); + private Map myActionsMap = new TreeMap(new Comparator() { + @Override + public int compare(AnAction o1, AnAction o2) { + return Comparing.compare(o1.getTemplatePresentation().getText(), o2.getTemplatePresentation().getText()); + } + }); private final SearchableOptionsRegistrar myIndex; @@ -289,6 +294,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C } } final Object[] descriptions = optionDescriptions.toArray(); + Arrays.sort(descriptions); objects = ArrayUtil.mergeArrays(objects, descriptions); } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexComponent.java index bbb30af153ea..bee9deaa4f8f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexComponent.java @@ -117,7 +117,7 @@ public class DirectoryIndexComponent extends DirectoryIndexImpl { VirtualFile f = file.findFileByRelativePath(rel); if (f != null) { if (state == originalState) state = state.copy(); - state.fillMapWithModuleContent(f, eachModule, f); + state.fillMapWithModuleContent(f, eachModule, f, null); } } } @@ -133,29 +133,29 @@ public class DirectoryIndexComponent extends DirectoryIndexImpl { } if (state == originalState) state = state.copy(); - state.fillMapWithModuleContent(file, module, parentInfo.contentRoot); + state.fillMapWithModuleContent(file, module, parentInfo.contentRoot, null); String parentPackage = state.myDirToPackageName.get(parent); if (module != null) { if (parentInfo.isInModuleSource) { String newDirPackageName = getPackageNameForSubdir(parentPackage, file.getName()); - state.fillMapWithModuleSource(file, module, newDirPackageName, parentInfo.sourceRoot, parentInfo.isTestSource); + state.fillMapWithModuleSource(file, module, newDirPackageName, parentInfo.sourceRoot, parentInfo.isTestSource, null); } } if (parentInfo.libraryClassRoot != null) { String newDirPackageName = getPackageNameForSubdir(parentPackage, file.getName()); - state.fillMapWithLibraryClasses(file, newDirPackageName, parentInfo.libraryClassRoot); + state.fillMapWithLibraryClasses(file, newDirPackageName, parentInfo.libraryClassRoot, null); } if (parentInfo.isInLibrarySource) { String newDirPackageName = getPackageNameForSubdir(parentPackage, file.getName()); - state.fillMapWithLibrarySources(file, newDirPackageName, parentInfo.sourceRoot); + state.fillMapWithLibrarySources(file, newDirPackageName, parentInfo.sourceRoot, null); } if (!parentInfo.getOrderEntries().isEmpty()) { - state.fillMapWithOrderEntries(file, parentInfo.getOrderEntries(), null, null, null, parentInfo); + state.fillMapWithOrderEntries(file, parentInfo.getOrderEntries(), null, null, null, parentInfo, null); } return state; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java index 6f84cd1c8266..2ce83f870330 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java @@ -72,14 +72,17 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb myMainPanel = new JPanel(new BorderLayout()); myMainPanel.setOpaque(false); myMainPanel.addMouseListener(new MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { myEventDispatcher.getMulticaster().editingStarted(ContentEntryEditor.this); } + @Override public void mouseEntered(MouseEvent e) { if (!myIsSelected) { highlight(true); } } + @Override public void mouseExited(MouseEvent e) { if (!myIsSelected) { highlight(false); @@ -106,6 +109,7 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb protected abstract ModifiableRootModel getModel(); + @Override public void deleteContentEntry() { final String path = FileUtil.toSystemDependentName(VfsUtil.urlToPath(myContentEntryUrl)); final int answer = Messages.showYesNoDialog(ProjectBundle.message("module.paths.remove.content.prompt", path), @@ -120,6 +124,7 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb } } + @Override public void deleteContentFolder(ContentEntry contentEntry, ContentFolder folder) { if (folder instanceof SourceFolder) { removeSourceFolder((SourceFolder)folder); @@ -132,6 +137,7 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb } + @Override public void navigateFolder(ContentEntry contentEntry, ContentFolder contentFolder) { final VirtualFile file = contentFolder.getFile(); if (file != null) { // file can be deleted externally @@ -139,6 +145,7 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb } } + @Override public void setPackagePrefix(SourceFolder folder, String prefix) { folder.setPackagePrefix(prefix); update(); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java index 89b421d2249c..9cf95dcd0367 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java @@ -96,7 +96,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter { final boolean insideTransaction = myTransactionsMap.containsKey(document); if (!insideTransaction) { - document.setModificationStamp(psiFile.getModificationStamp()); + document.setModificationStamp(psiFile.getViewProvider().getModificationStamp()); if (LOG.isDebugEnabled()) { PsiDocumentManagerImpl.checkConsistency(psiFile, document); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index e2ae3217f0d8..b804aa97bef2 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1384,7 +1384,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { @Override public String getText() { - if (myFile.getModificationStamp() != myDocument.getModificationStamp()) { + if (myFile.getViewProvider().getModificationStamp() != myDocument.getModificationStamp()) { final ASTNode node = myFile.getNode(); assert node != null; return node.getText(); @@ -1394,7 +1394,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { @Override public long getModificationStamp() { - return myFile.getModificationStamp(); + return myFile.getViewProvider().getModificationStamp(); } } @@ -1418,7 +1418,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { final PsiFile dominantContentFile = findDominantPsiForDocument(document, project); final DocumentContent content; - if (dominantContentFile != null && dominantContentFile.getModificationStamp() != document.getModificationStamp()) { + if (dominantContentFile != null && dominantContentFile.getViewProvider().getModificationStamp() != document.getModificationStamp()) { content = new PsiContent(document, dominantContentFile); } else { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java index 73114f7aa0cb..82268d3ef782 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java @@ -197,8 +197,8 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { myStorage.put(new String(option), configs); } - configs.add(new OptionDescription(null, myIdentifierTable.intern(id), hit != null ? myIdentifierTable.intern(hit) : null, - path != null ? myIdentifierTable.intern(path) : null)); + configs.add(new OptionDescription(null, myIdentifierTable.intern(id).trim(), hit != null ? myIdentifierTable.intern(hit).trim() : null, + path != null ? myIdentifierTable.intern(path).trim() : null)); } @NotNull diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java index b4814b14ed62..61dac0c65b3a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java @@ -52,27 +52,31 @@ import java.awt.event.InputEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; @SuppressWarnings({"ConstantConditions"}) public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { + @Override public void notifyByBalloon(@NotNull final String toolWindowId, @NotNull final MessageType type, @NotNull final String htmlBody) { } - public static final ToolWindow HEADLESS_WINDOW = new ToolWindowEx(){ + public static final ToolWindow HEADLESS_WINDOW = new ToolWindowEx() { + @Override public boolean isActive() { return false; } + @Override public void activate(@Nullable Runnable runnable) { } + @Override public boolean isDisposed() { return false; } + @Override public boolean isVisible() { return false; } @@ -82,102 +86,133 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { return new ActionCallback.Done(); } + @Override public void show(@Nullable Runnable runnable) { } + @Override public void hide(@Nullable Runnable runnable) { } + @Override public ToolWindowAnchor getAnchor() { return ToolWindowAnchor.BOTTOM; } + @Override public void setAnchor(ToolWindowAnchor anchor, @Nullable Runnable runnable) { } + @Override public boolean isSplitMode() { return false; } + @Override public void setSplitMode(final boolean isSideTool, @Nullable final Runnable runnable) { } + @Override public boolean isAutoHide() { return false; } + @Override public void setAutoHide(boolean state) { } + @Override public void setToHideOnEmptyContent(final boolean hideOnEmpty) { } + @Override public boolean isToHideOnEmptyContent() { return false; } + @Override public ToolWindowType getType() { return ToolWindowType.SLIDING; } + @Override public void setType(ToolWindowType type, @Nullable Runnable runnable) { } + @Override public Icon getIcon() { return null; } + @Override public void setIcon(Icon icon) { } + @Override public String getTitle() { return ""; } + @Override public void setTitle(String title) { } + @Override public boolean isAvailable() { return false; } + @Override public void setContentUiType(ToolWindowContentUiType type, @Nullable Runnable runnable) { } + @Override public void setDefaultContentUiType(@NotNull ToolWindowContentUiType type) { } + @Override public ToolWindowContentUiType getContentUiType() { return ToolWindowContentUiType.TABBED; } + @Override public void setAvailable(boolean available, @Nullable Runnable runnable) { } + @Override public void installWatcher(ContentManager contentManager) { } + @Override public JComponent getComponent() { return null; } + @Override public ContentManager getContentManager() { return MOCK_CONTENT_MANAGER; } - public void setDefaultState(@Nullable final ToolWindowAnchor anchor, @Nullable final ToolWindowType type, @Nullable final Rectangle floatingBounds) { + @Override + public void setDefaultState(@Nullable final ToolWindowAnchor anchor, + @Nullable final ToolWindowType type, + @Nullable final Rectangle floatingBounds) { } + @Override public void activate(@Nullable final Runnable runnable, final boolean autoFocusContents) { } + @Override public void activate(@Nullable Runnable runnable, boolean autoFocusContents, boolean forced) { } + @Override public void showContentPopup(InputEvent inputEvent) { } + @Override public ActionCallback getActivation() { return new ActionCallback.Done(); } @@ -223,8 +258,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { }; @NonNls private static final ContentManager MOCK_CONTENT_MANAGER = new ContentManager() { - - private final ArrayList myContents = new ArrayList(); + private final List myContents = new ArrayList(); private Content mySelected; @Override @@ -232,20 +266,60 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { return new ActionCallback.Done(); } - public void addContent(@NotNull final Content content) { } + @Override + public void addContent(@NotNull final Content content) { + } + + @Override public void addContent(@NotNull Content content, int order) { myContents.add(order, content); } - public void addContent(@NotNull final Content content, final Object constraints) { } - public void addContentManagerListener(@NotNull final ContentManagerListener l) { } - public void addDataProvider(@NotNull final DataProvider provider) { } - public void addSelectedContent(@NotNull final Content content) { } - public boolean canCloseAllContents() { return false; } - public boolean canCloseContents() { return false; } - public Content findContent(final String displayName) { return null; } - public List getAdditionalPopupActions(@NotNull final Content content) { return Collections.emptyList(); } - public String getCloseActionName() { return "close"; } - public String getCloseAllButThisActionName() { return "closeallbutthis"; } + + @Override + public void addContent(@NotNull final Content content, final Object constraints) { + } + + @Override + public void addContentManagerListener(@NotNull final ContentManagerListener l) { + } + + @Override + public void addDataProvider(@NotNull final DataProvider provider) { + } + + @Override + public void addSelectedContent(@NotNull final Content content) { + } + + @Override + public boolean canCloseAllContents() { + return false; + } + + @Override + public boolean canCloseContents() { + return false; + } + + @Override + public Content findContent(final String displayName) { + return null; + } + + @Override + public List getAdditionalPopupActions(@NotNull final Content content) { + return Collections.emptyList(); + } + + @Override + public String getCloseActionName() { + return "close"; + } + + @Override + public String getCloseAllButThisActionName() { + return "closeallbutthis"; + } @Override public String getPreviousContentActionName() { @@ -257,71 +331,150 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { return "next"; } - public JComponent getComponent() { return new JLabel(); } - public Content getContent(final JComponent component) { return null; } - @Nullable - public Content getContent(final int index) { return null; } - public int getContentCount() { return 0; } - @NotNull - public Content[] getContents() { return myContents.toArray(new Content[myContents.size()]); } - public int getIndexOfContent(final Content content) { return -1; } - @Nullable - public Content getSelectedContent() { return mySelected; } - @NotNull - public Content[] getSelectedContents() { return new Content[0]; } - public boolean isSelected(@NotNull final Content content) { return false; } - public void removeAllContents(final boolean dispose) { - for (Iterator iterator = myContents.iterator(); iterator.hasNext(); ) { - Content content = iterator.next(); - Disposer.dispose(content); - iterator.remove(); - } + @Override + public JComponent getComponent() { + return new JLabel(); } + + @Override + public Content getContent(final JComponent component) { + return null; + } + + @Override + @Nullable + public Content getContent(final int index) { + return null; + } + + @Override + public int getContentCount() { + return 0; + } + + @Override + @NotNull + public Content[] getContents() { + return myContents.toArray(new Content[myContents.size()]); + } + + @Override + public int getIndexOfContent(final Content content) { + return -1; + } + + @Override + @Nullable + public Content getSelectedContent() { + return mySelected; + } + + @Override + @NotNull + public Content[] getSelectedContents() { + return new Content[0]; + } + + @Override + public boolean isSelected(@NotNull final Content content) { + return false; + } + + @Override + public void removeAllContents(final boolean dispose) { + for (int i = myContents.size() - 1; i >= 0; i--) { + Content content = myContents.get(i); + removeContent(content, true); + } + mySelected = null; + } + + @Override public boolean removeContent(@NotNull final Content content, final boolean dispose) { Disposer.dispose(content); + if (mySelected == content) { + mySelected = null; + } return myContents.remove(content); } + @Override public ActionCallback removeContent(@NotNull Content content, boolean dispose, boolean trackFocus, boolean implicitFocus) { return new ActionCallback.Done(); } - public void removeContentManagerListener(@NotNull final ContentManagerListener l) { } - public void removeFromSelection(@NotNull final Content content) { } - public ActionCallback selectNextContent() { return new ActionCallback.Done();} - public ActionCallback selectPreviousContent() { return new ActionCallback.Done();} - public void setSelectedContent(@NotNull final Content content) { mySelected = content; } - public ActionCallback setSelectedContentCB(@NotNull Content content) { return new ActionCallback.Done(); } - public void setSelectedContent(@NotNull final Content content, final boolean requestFocus) { } - public ActionCallback setSelectedContentCB(@NotNull final Content content, final boolean requestFocus) { return new ActionCallback.Done();} + @Override + public void removeContentManagerListener(@NotNull final ContentManagerListener l) { + } + @Override + public void removeFromSelection(@NotNull final Content content) { + } + + @Override + public ActionCallback selectNextContent() { + return new ActionCallback.Done(); + } + + @Override + public ActionCallback selectPreviousContent() { + return new ActionCallback.Done(); + } + + @Override + public void setSelectedContent(@NotNull final Content content) { + mySelected = content; + } + + @Override + public ActionCallback setSelectedContentCB(@NotNull Content content) { + return new ActionCallback.Done(); + } + + @Override + public void setSelectedContent(@NotNull final Content content, final boolean requestFocus) { + } + + @Override + public ActionCallback setSelectedContentCB(@NotNull final Content content, final boolean requestFocus) { + return new ActionCallback.Done(); + } + + @Override public void setSelectedContent(@NotNull Content content, boolean requestFocus, boolean forcedFocus) { } + @Override public ActionCallback setSelectedContentCB(@NotNull final Content content, final boolean requestFocus, final boolean forcedFocus) { return new ActionCallback.Done(); } + @Override public ActionCallback setSelectedContent(@NotNull Content content, boolean requestFocus, boolean forcedFocus, boolean implicit) { return new ActionCallback.Done(); } + @Override public ActionCallback requestFocus(@Nullable final Content content, final boolean forced) { - return new ActionCallback.Done(); + return new ActionCallback.Done(); } + @Override public void dispose() { removeAllContents(true); } + @Override public boolean isDisposed() { return false; } + @Override public boolean isSingleSelection() { return true; } + @Override @NotNull public ContentFactory getFactory() { return ServiceManager.getService(ContentFactory.class); @@ -337,10 +490,12 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { return HEADLESS_WINDOW; } + @Override public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor) { return HEADLESS_WINDOW; } + @Override public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, @@ -350,54 +505,75 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { return HEADLESS_WINDOW; } - public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, Disposable parentDisposable) { + @Override + public ToolWindow registerToolWindow(@NotNull String id, + @NotNull JComponent component, + @NotNull ToolWindowAnchor anchor, + Disposable parentDisposable) { return HEADLESS_WINDOW; } + @Override public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor) { return HEADLESS_WINDOW; } - public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor, final boolean sideTool) { + @Override + public ToolWindow registerToolWindow(@NotNull final String id, + final boolean canCloseContent, + @NotNull final ToolWindowAnchor anchor, + final boolean sideTool) { return HEADLESS_WINDOW; } + @Override public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor, final Disposable parentDisposable, final boolean dumbAware) { return HEADLESS_WINDOW; } + @Override public void unregisterToolWindow(@NotNull String id) { } + @Override public void activateEditorComponent() { } + @Override public boolean isEditorComponentActive() { return false; } + @Override public String[] getToolWindowIds() { return ArrayUtil.EMPTY_STRING_ARRAY; } + @Override public String getActiveToolWindowId() { return null; } + @Override public ToolWindow getToolWindow(String id) { return HEADLESS_WINDOW; } + @Override public void invokeLater(Runnable runnable) { } + @Override public IdeFocusManager getFocusManager() { return IdeFocusManagerHeadless.INSTANCE; } @Override - public void notifyByBalloon(@NotNull final String toolWindowId, @NotNull final MessageType type, @NotNull final String text, @Nullable final Icon icon, + public void notifyByBalloon(@NotNull final String toolWindowId, + @NotNull final MessageType type, + @NotNull final String text, + @Nullable final Icon icon, @Nullable final HyperlinkListener listener) { } @@ -411,41 +587,52 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { } + @Override public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { } + @Override public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { } + @Override public String getLastActiveToolWindowId() { return null; } + @Override public String getLastActiveToolWindowId(Condition condition) { return null; } + @Override public DesktopLayout getLayout() { return new DesktopLayout(); } + @Override public void setLayoutToRestoreLater(DesktopLayout layout) { } + @Override public DesktopLayout getLayoutToRestoreLater() { return new DesktopLayout(); } + @Override public void setLayout(@NotNull DesktopLayout layout) { } + @Override public void clearSideStack() { } + @Override public void hideToolWindow(@NotNull final String id, final boolean hideSide) { } + @Override public List getIdsOn(@NotNull final ToolWindowAnchor anchor) { return new ArrayList(); } diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index 6465f1f168f9..834e6e03ed0c 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -404,7 +404,7 @@ - + + diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java index f022f621164f..07e54aab89dc 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java @@ -71,11 +71,13 @@ public abstract class ContentFolderBaseImpl extends RootModelComponentBase imple return url; } + @Override public VirtualFile getFile() { final VirtualFile file = myFilePointer.getFile(); return file == null || !file.isDirectory() ? null : file; } + @Override @NotNull public ContentEntry getContentEntry() { return myContentEntry; @@ -86,15 +88,18 @@ public abstract class ContentFolderBaseImpl extends RootModelComponentBase imple element.setAttribute(URL_ATTRIBUTE, myFilePointer.getUrl()); } + @Override @NotNull public String getUrl() { return myFilePointer.getUrl(); } + @Override public boolean isSynthetic() { return false; } + @Override public int compareTo(ContentFolderBaseImpl folder) { return getUrl().compareTo(folder.getUrl()); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index 144ce1153619..ddfa00d68104 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -263,12 +263,15 @@ public class DirectoryIndexImpl extends DirectoryIndex { return info; } - void fillMapWithModuleContent(VirtualFile root, final Module module, final VirtualFile contentRoot) { + void fillMapWithModuleContent(VirtualFile root, final Module module, final VirtualFile contentRoot, @Nullable final ProgressIndicator progress) { VfsUtilCore.visitChildrenRecursively(root, new DirectoryVisitor() { @Override protected DirectoryInfo updateInfo(VirtualFile file) { + if (progress != null) { + progress.checkCanceled(); + } if (isExcluded(contentRoot, file)) return null; if (isIgnored(file)) return null; @@ -332,7 +335,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { } for (final VirtualFile contentRoot : contentRoots) { - fillMapWithModuleContent(contentRoot, module, contentRoot); + fillMapWithModuleContent(contentRoot, module, contentRoot, progress); } } @@ -354,7 +357,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { for (SourceFolder sourceFolder : sourceFolders) { VirtualFile dir = sourceFolder.getFile(); if (dir != null) { - fillMapWithModuleSource(dir, module, sourceFolder.getPackagePrefix(), dir, sourceFolder.isTestSource()); + fillMapWithModuleSource(dir, module, sourceFolder.getPackagePrefix(), dir, sourceFolder.isTestSource(), progress); } } } @@ -364,7 +367,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { final Module module, final String packageName, final VirtualFile sourceRoot, - final boolean isTestSource) { + final boolean isTestSource, @Nullable final ProgressIndicator progress) { VfsUtilCore.visitChildrenRecursively(dir, new DirectoryVisitor() { @@ -372,6 +375,9 @@ public class DirectoryIndexImpl extends DirectoryIndex { @Override protected DirectoryInfo updateInfo(VirtualFile file) { + if (progress != null) { + progress.checkCanceled(); + } DirectoryInfo info = myDirToInfoMap.get(file); if (info == null) return null; if (!module.equals(info.module)) return null; @@ -414,13 +420,16 @@ public class DirectoryIndexImpl extends DirectoryIndex { if (isLibrary) { VirtualFile[] sourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); for (final VirtualFile sourceRoot : sourceRoots) { - fillMapWithLibrarySources(sourceRoot, "", sourceRoot); + fillMapWithLibrarySources(sourceRoot, "", sourceRoot, progress); } } } } - protected void fillMapWithLibrarySources(VirtualFile dir, String packageName, VirtualFile sourceRoot) { + protected void fillMapWithLibrarySources(VirtualFile dir, String packageName, VirtualFile sourceRoot, @Nullable ProgressIndicator progress) { + if (progress != null) { + progress.checkCanceled(); + } if (isIgnored(dir)) return; DirectoryInfo info = getOrCreateDirInfo(dir); @@ -438,7 +447,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { for (VirtualFile child : children) { if (child.isDirectory()) { String childPackageName = getPackageNameForSubdir(packageName, child.getName()); - fillMapWithLibrarySources(child, childPackageName, sourceRoot); + fillMapWithLibrarySources(child, childPackageName, sourceRoot, progress); } } } @@ -452,13 +461,16 @@ public class DirectoryIndexImpl extends DirectoryIndex { if (isLibrary) { VirtualFile[] classRoots = orderEntry.getFiles(OrderRootType.CLASSES); for (final VirtualFile classRoot : classRoots) { - fillMapWithLibraryClasses(classRoot, "", classRoot); + fillMapWithLibraryClasses(classRoot, "", classRoot, progress); } } } } - protected void fillMapWithLibraryClasses(VirtualFile dir, String packageName, VirtualFile classRoot) { + protected void fillMapWithLibraryClasses(VirtualFile dir, String packageName, VirtualFile classRoot, @Nullable ProgressIndicator progress) { + if (progress != null) { + progress.checkCanceled(); + } if (isIgnored(dir)) return; DirectoryInfo info = getOrCreateDirInfo(dir); @@ -478,7 +490,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { for (VirtualFile child : children) { if (child.isDirectory()) { String childPackageName = getPackageNameForSubdir(packageName, child.getName()); - fillMapWithLibraryClasses(child, childPackageName, classRoot); + fillMapWithLibraryClasses(child, childPackageName, classRoot, progress); } } } @@ -486,7 +498,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { private void initOrderEntries(Module module, MultiMap depEntries, MultiMap libClassRootEntries, - MultiMap libSourceRootEntries) { + MultiMap libSourceRootEntries, ProgressIndicator progress) { for (OrderEntry orderEntry : getOrderEntries(module)) { if (orderEntry instanceof ModuleOrderEntry) { @@ -509,7 +521,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { VirtualFile[] sourceRoots = orderEntry.getFiles(OrderRootType.SOURCES); for (VirtualFile sourceRoot : sourceRoots) { - fillMapWithOrderEntries(sourceRoot, oneEntryList, entryModule, null, null, null); + fillMapWithOrderEntries(sourceRoot, oneEntryList, entryModule, null, null, null, progress); } } else if (orderEntry instanceof LibraryOrderEntry || orderEntry instanceof JdkOrderEntry) { @@ -527,23 +539,23 @@ public class DirectoryIndexImpl extends DirectoryIndex { private void fillMapWithOrderEntries(MultiMap depEntries, MultiMap libClassRootEntries, - MultiMap libSourceRootEntries) { + MultiMap libSourceRootEntries, ProgressIndicator progress) { for (Map.Entry> mapEntry : depEntries.entrySet()) { final VirtualFile vRoot = mapEntry.getKey(); final Collection entries = mapEntry.getValue(); - fillMapWithOrderEntries(vRoot, entries, null, null, null, null); + fillMapWithOrderEntries(vRoot, entries, null, null, null, null, progress); } for (Map.Entry> mapEntry : libClassRootEntries.entrySet()) { final VirtualFile vRoot = mapEntry.getKey(); final Collection entries = mapEntry.getValue(); - fillMapWithOrderEntries(vRoot, entries, null, vRoot, null, null); + fillMapWithOrderEntries(vRoot, entries, null, vRoot, null, null, progress); } for (Map.Entry> mapEntry : libSourceRootEntries.entrySet()) { final VirtualFile vRoot = mapEntry.getKey(); final Collection entries = mapEntry.getValue(); - fillMapWithOrderEntries(vRoot, entries, null, null, vRoot, null); + fillMapWithOrderEntries(vRoot, entries, null, null, vRoot, null, progress); } } @@ -578,10 +590,10 @@ public class DirectoryIndexImpl extends DirectoryIndex { protected void fillMapWithOrderEntries(final VirtualFile root, final Collection orderEntries, - final Module module, - final VirtualFile libraryClassRoot, - final VirtualFile librarySourceRoot, - final DirectoryInfo parentInfo) { + @Nullable final Module module, + @Nullable final VirtualFile libraryClassRoot, + @Nullable final VirtualFile librarySourceRoot, + @Nullable final DirectoryInfo parentInfo, @Nullable final ProgressIndicator progress) { VfsUtilCore.visitChildrenRecursively(root, new DirectoryVisitor() { @@ -589,6 +601,9 @@ public class DirectoryIndexImpl extends DirectoryIndex { @Override protected DirectoryInfo updateInfo(VirtualFile dir) { + if (progress != null) { + progress.checkCanceled(); + } if (isIgnored(dir)) return null; DirectoryInfo info = myDirToInfoMap.get(dir); // do not create it here! @@ -659,9 +674,9 @@ public class DirectoryIndexImpl extends DirectoryIndex { initOrderEntries(module, depEntries, libClassRootEntries, - libSourceRootEntries); + libSourceRootEntries, progress); } - fillMapWithOrderEntries(depEntries, libClassRootEntries, libSourceRootEntries); + fillMapWithOrderEntries(depEntries, libClassRootEntries, libSourceRootEntries, progress); killOrderEntryArrayDuplicates(); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java index 25a686e6f38f..5dc97011e512 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelComponentBase.java @@ -37,6 +37,7 @@ public abstract class RootModelComponentBase implements Disposable { return myRootModel; } + @Override public void dispose() { myDisposed = true; } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java index d3d272f33429..049e7048b875 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java @@ -31,7 +31,7 @@ import org.jetbrains.annotations.NotNull; */ public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFolder, ClonableContentFolder { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleSourceFolderImpl"); - private boolean myIsTestSource; + private final boolean myIsTestSource; @NonNls public static final String ELEMENT_NAME = "sourceFolder"; @NonNls public static final String TEST_SOURCE_ATTR = "isTestSource"; private String myPackagePrefix; @@ -75,14 +75,17 @@ public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFol myPackagePrefix = that.myPackagePrefix; } + @Override public boolean isTestSource() { return myIsTestSource; } + @Override public String getPackagePrefix() { return myPackagePrefix; } + @Override public void setPackagePrefix(String packagePrefix) { myPackagePrefix = packagePrefix; } @@ -95,10 +98,12 @@ public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFol } } + @Override public ContentFolder cloneFolder(ContentEntry contentEntry) { return new SourceFolderImpl(this, (ContentEntryImpl) contentEntry); } + @Override public int compareTo(ContentFolderBaseImpl folder) { if (!(folder instanceof SourceFolderImpl)) return -1; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index ed42a437fad9..0b5d61152b59 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -89,7 +89,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myRootsWatcher.updateWatchedRoots(); } - LibraryImpl(String name, final @Nullable PersistentLibraryKind kind, LibraryTable table, ModifiableRootModel rootModel) { + LibraryImpl(String name, @Nullable final PersistentLibraryKind kind, LibraryTable table, ModifiableRootModel rootModel) { myName = name; myLibraryTable = table; myRootModel = rootModel; @@ -131,20 +131,24 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myJarDirectories.copyFrom(from.myJarDirectories); } + @Override public void dispose() { assert !isDisposed(); Disposer.dispose(myRootsWatcher); myDisposed = true; } + @Override public boolean isDisposed() { return myDisposed; } + @Override public String getName() { return myName; } + @Override @NotNull public String[] getUrls(@NotNull OrderRootType rootType) { assert !isDisposed(); @@ -152,6 +156,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return result.getUrls(); } + @Override @NotNull public VirtualFile[] getFiles(@NotNull OrderRootType rootType) { assert !isDisposed(); @@ -182,18 +187,21 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { } } + @Override public void setName(String name) { LOG.assertTrue(isWritable()); myName = name; } /* you have to commit modifiable model or dispose it by yourself! */ + @Override @NotNull public ModifiableModel getModifiableModel() { assert !isDisposed(); return new LibraryImpl(this, this, myRootModel); } + @Override public Library cloneLibrary(RootModelImpl rootModel) { LOG.assertTrue(myLibraryTable == null); final LibraryImpl clone = new LibraryImpl(this, null, rootModel); @@ -201,6 +209,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return clone; } + @Override public List getInvalidRootUrls(OrderRootType type) { final List pointers = myRoots.get(type).getList(); List invalidPaths = null; @@ -221,6 +230,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myProperties = properties; } + @Override @NotNull public RootProvider getRootProvider() { return myRootProvider; @@ -241,6 +251,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return result; } + @Override public void readExternal(Element element) throws InvalidDataException { readName(element); readProperties(element); @@ -285,6 +296,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { public static List sortRootTypes(Collection rootTypes) { List allTypes = new ArrayList(rootTypes); Collections.sort(allTypes, new Comparator() { + @Override public int compare(final OrderRootType o1, final OrderRootType o2) { return getSortKey(o1).compareTo(getSortKey(o2)); } @@ -296,12 +308,13 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { if (orderRootType instanceof PersistentOrderRootType) { return ((PersistentOrderRootType)orderRootType).getSdkRootName(); } - else if (orderRootType instanceof OrderRootType.DocumentationRootType) { + if (orderRootType instanceof OrderRootType.DocumentationRootType) { return ((OrderRootType.DocumentationRootType)orderRootType).getSdkRootName(); } return ""; } + @Override public void writeExternal(Element rootElement) throws WriteExternalException { LOG.assertTrue(!isDisposed(), "Already disposed!"); @@ -357,6 +370,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myKind = kind; } + @Override public void addRoot(@NotNull String url, @NotNull OrderRootType rootType) { LOG.assertTrue(isWritable()); assert !isDisposed(); @@ -365,6 +379,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { container.add(url); } + @Override public void addRoot(@NotNull VirtualFile file, @NotNull OrderRootType rootType) { LOG.assertTrue(isWritable()); assert !isDisposed(); @@ -373,14 +388,17 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { container.add(file); } + @Override public void addJarDirectory(@NotNull final String url, final boolean recursive) { addJarDirectory(url, recursive, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE); } + @Override public void addJarDirectory(@NotNull final VirtualFile file, final boolean recursive) { addJarDirectory(file, recursive, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE); } + @Override public void addJarDirectory(@NotNull final String url, final boolean recursive, @NotNull OrderRootType rootType) { assert !isDisposed(); LOG.assertTrue(isWritable()); @@ -389,6 +407,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myJarDirectories.add(rootType, url, recursive); } + @Override public void addJarDirectory(@NotNull final VirtualFile file, final boolean recursive, @NotNull OrderRootType rootType) { assert !isDisposed(); LOG.assertTrue(isWritable()); @@ -397,20 +416,24 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myJarDirectories.add(rootType, file.getUrl(), recursive); } + @Override public boolean isJarDirectory(@NotNull final String url) { return isJarDirectory(url, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE); } + @Override public boolean isJarDirectory(@NotNull final String url, @NotNull final OrderRootType rootType) { return myJarDirectories.contains(rootType, url); } + @Override public boolean isValid(@NotNull final String url, @NotNull final OrderRootType rootType) { final VirtualFilePointerContainer container = myRoots.get(rootType); final VirtualFilePointer fp = container.findByUrl(url); return fp != null && fp.isValid(); } + @Override public boolean removeRoot(@NotNull String url, @NotNull OrderRootType rootType) { assert !isDisposed(); LOG.assertTrue(isWritable()); @@ -424,6 +447,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return false; } + @Override public void moveRootUp(@NotNull String url, @NotNull OrderRootType rootType) { assert !isDisposed(); LOG.assertTrue(isWritable()); @@ -431,6 +455,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { container.moveUp(url); } + @Override public void moveRootDown(@NotNull String url, @NotNull OrderRootType rootType) { assert !isDisposed(); LOG.assertTrue(isWritable()); @@ -438,6 +463,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { container.moveDown(url); } + @Override public boolean isChanged() { return !mySource.equals(this); } @@ -471,6 +497,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return mySource; } + @Override public void commit() { assert !isDisposed(); mySource.commit(this); @@ -517,6 +544,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { } private class MyRootProviderImpl extends RootProviderBaseImpl { + @Override @NotNull public String[] getUrls(@NotNull OrderRootType rootType) { Set originalUrls = new LinkedHashSet(Arrays.asList(LibraryImpl.this.getUrls(rootType))); @@ -526,12 +554,14 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return ArrayUtil.toStringArray(originalUrls); } + @Override @NotNull public VirtualFile[] getFiles(@NotNull final OrderRootType rootType) { return LibraryImpl.this.getFiles(rootType); } } + @Override public LibraryTable getTable() { return myLibraryTable; } @@ -558,6 +588,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return result; } + @NonNls @Override public String toString() { return "Library: name:" + myName + "; jars:" + myJarDirectories + "; roots:" + myRoots.values(); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java index bb03da56ec93..1e67ae55dca6 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java @@ -44,10 +44,12 @@ public abstract class LibraryTableBase implements PersistentStateComponent getLibraryIterator() { return myModel.getLibraryIterator(); } + @Override public Library getLibraryByName(@NotNull String name) { return myModel.getLibraryByName(name); } + @Override public void addListener(Listener listener) { myDispatcher.addListener(listener); } + @Override public void addListener(Listener listener, Disposable parentDisposable) { myDispatcher.addListener(listener, parentDisposable); } + @Override public void removeListener(Listener listener) { myDispatcher.removeListener(listener); } @@ -117,12 +126,14 @@ public abstract class LibraryTableBase implements PersistentStateComponent getLibraryIterator() { return Collections.unmodifiableList(myLibraries).iterator(); } + @Override @Nullable public Library getLibraryByName(@NotNull String name) { for (Library myLibrary : myLibraries) { @@ -229,6 +245,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent thisLibraries = new HashSet(myLibraries); @@ -263,6 +282,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent libraries = new HashMap(); for (Library library : myLibraries) { @@ -288,6 +308,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent libraries = ContainerUtil.findAll(myLibraries, new Condition() { @Override diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 3a37e5b3d100..6e84ee8c0c03 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -407,7 +407,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, private long myModificationStamp; private long getCurrentModificationStamp() { final PsiFile containingFile = getPsiFile(); - return containingFile == null ? -1L : containingFile.getModificationStamp(); + return containingFile == null ? -1L : containingFile.getViewProvider().getModificationStamp(); } @Override diff --git a/platform/util/src/com/intellij/openapi/util/Disposer.java b/platform/util/src/com/intellij/openapi/util/Disposer.java index 65ab06fd114c..7005e1fc3e3a 100644 --- a/platform/util/src/com/intellij/openapi/util/Disposer.java +++ b/platform/util/src/com/intellij/openapi/util/Disposer.java @@ -147,7 +147,7 @@ public class Disposer { } /** - * @return object registered on parentDisposable which is equal to object, or null + * @return object registered on parentDisposable which is equal to object, or null if not found */ @Nullable public static T findRegisteredObject(@NotNull Disposable parentDisposable, @NotNull T object) { diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml index f7bd8c9d1061..1a57d95de8a0 100644 --- a/plugins/devkit/resources/META-INF/plugin.xml +++ b/plugins/devkit/resources/META-INF/plugin.xml @@ -120,6 +120,11 @@ + + + + diff --git a/plugins/devkit/src/actions/ShuffleNamesAction.java b/plugins/devkit/src/actions/ShuffleNamesAction.java new file mode 100644 index 000000000000..5cf7dde89b25 --- /dev/null +++ b/plugins/devkit/src/actions/ShuffleNamesAction.java @@ -0,0 +1,130 @@ +/* + * Copyright 2000-2012 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 org.jetbrains.idea.devkit.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessorEx; +import com.intellij.openapi.command.UndoConfirmationPolicy; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiRecursiveElementWalkingVisitor; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import gnu.trove.THashMap; + +import java.util.*; + +/** + * @author gregsh + */ +public class ShuffleNamesAction extends AnAction { + @Override + public void update(AnActionEvent e) { + Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + e.getPresentation().setEnabled(editor != null && file != null); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final Editor editor = PlatformDataKeys.EDITOR.getData(e.getDataContext()); + PsiFile file = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + if (editor == null || file == null) return; + final Project project = file.getProject(); + CommandProcessorEx commandProcessor = (CommandProcessorEx)CommandProcessorEx.getInstance(); + Object commandToken = commandProcessor.startCommand(project, e.getPresentation().getText(), e.getPresentation().getText(), UndoConfirmationPolicy.DEFAULT); + AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass()); + try { + shuffleIds(file, editor); + } + finally { + token.finish(); + commandProcessor.finishCommand(project, commandToken, null); + } + } + + private static boolean shuffleIds(PsiFile file, Editor editor) { + final Map map = new THashMap(); + final StringBuilder sb = new StringBuilder(); + final StringBuilder quote = new StringBuilder(); + final ArrayList split = new ArrayList(100); + file.acceptChildren(new PsiRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (element instanceof LeafPsiElement) { + String type = ((LeafPsiElement)element).getElementType().toString(); + String text = element.getText(); + if (text.isEmpty()) return; + + for (int i=0, len=text.length(); i 0; + boolean isNumber = false; + if (isQuoted || type.equals("ID") || type.contains("IDENT") && !"ts".equals(text) || + (isNumber = text.matches("[0-9]+"))) { + String replacement = map.get(text); + if (replacement == null) { + split.addAll(Arrays.asList((isQuoted? text.substring(quote.length(), text.length()-quote.length()).replace("''", "") : text).split(""))); + if (!isNumber) { + for (ListIterator it = split.listIterator(); it.hasNext(); ) { + String s = it.next(); + if (s.isEmpty()) { + it.remove(); + continue; + } + int c = s.charAt(0); + int cap = c & 32; + c &= ~cap; + c = (char) ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 7) % 26 + 'A') : c) | cap; + it.set(String.valueOf((char)c)); + } + } + Collections.shuffle(split); + if (isNumber && "0".equals(split.get(0))) { + split.set(0, "1"); + } + replacement = StringUtil.join(split, ""); + if (isQuoted) { + replacement = quote + replacement + quote.reverse(); + } + map.put(text, replacement); + } + text = replacement; + } + sb.append(text); + quote.setLength(0); + split.clear(); + } + super.visitElement(element); + } + }); + editor.getDocument().setText(sb.toString()); + return true; + } +} diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java index ea2034fe7520..e2e67229c90f 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java @@ -39,6 +39,7 @@ import junit.framework.Assert; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.eclipse.config.EclipseClasspathStorageProvider; import org.jetbrains.idea.eclipse.conversion.ConversionException; import org.jetbrains.idea.eclipse.conversion.EclipseClasspathReader; @@ -74,7 +75,7 @@ public class EclipseClasspathTest extends IdeaTestCase { checkModule(path, setUpModule(path, project)); } - static Module setUpModule(final String path, final Project project) + static Module setUpModule(final String path, @NotNull final Project project) throws IOException, JDOMException, ConversionException, ConfigurationException { final File classpathFile = new File(path, EclipseXml.DOT_CLASSPATH_EXT); String fileText = FileUtil.loadFile(classpathFile).replaceAll("\\$ROOT\\$", project.getBaseDir().getPath()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java index b06652ad81b0..529479e02c29 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDescription.java @@ -23,6 +23,7 @@ import com.intellij.openapi.roots.libraries.NewLibraryConfiguration; import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -121,6 +122,7 @@ public class GroovyLibraryDescription extends CustomLibraryDescription { final String path = dir.getPath(); final String sdkVersion = provider.getSDKVersion(path); if (AbstractConfigUtils.UNDEFINED_VERSION.equals(sdkVersion)) { + Messages.showErrorDialog(parentComponent, "Looks like " + myFrameworkName + " distribution in specified path is broken. Cannot determinate version.", "Failed to create library"); return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java index c29a1b3d7a37..e9d453a06822 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java @@ -244,12 +244,17 @@ public class MvcModuleStructureSynchronizer extends AbstractProjectComponent { StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() { @Override public void run() { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - runActions(); - } - }, ModalityState.NON_MODAL); + if (ApplicationManager.getApplication().isUnitTestMode()) { + runActions(); + } + else { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + runActions(); + } + }, ModalityState.NON_MODAL); + } } }); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltChangeLocalityDetector.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltChangeLocalityDetector.java index c72f6ac58eb8..5b7dedcecae3 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltChangeLocalityDetector.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltChangeLocalityDetector.java @@ -22,6 +22,7 @@ import com.intellij.psi.xml.XmlElementType; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlToken; import org.intellij.lang.xpath.xslt.XsltSupport; +import org.jetbrains.annotations.NotNull; /* * Created by IntelliJ IDEA. @@ -30,7 +31,7 @@ import org.intellij.lang.xpath.xslt.XsltSupport; */ public class XsltChangeLocalityDetector implements ChangeLocalityDetector { @Override - public PsiElement getChangeHighlightingDirtyScopeFor(PsiElement changedElement) { + public PsiElement getChangeHighlightingDirtyScopeFor(@NotNull PsiElement changedElement) { try { if (changedElement instanceof XmlToken && changedElement.getNode().getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE_TOKEN) { final PsiElement grandParent = changedElement.getParent().getParent(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index cb3175edc39c..82372a8498d0 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -969,6 +969,7 @@ + diff --git a/xml/impl/src/com/intellij/xml/XmlChangeLocalityDetector.java b/xml/impl/src/com/intellij/xml/XmlChangeLocalityDetector.java new file mode 100644 index 000000000000..fb65aa55965d --- /dev/null +++ b/xml/impl/src/com/intellij/xml/XmlChangeLocalityDetector.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 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.xml; + +import com.intellij.codeInsight.daemon.ChangeLocalityDetector; +import com.intellij.codeInspection.DefaultXmlSuppressionProvider; +import com.intellij.lang.xml.XMLLanguage; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +public class XmlChangeLocalityDetector implements ChangeLocalityDetector { + @Override + public PsiElement getChangeHighlightingDirtyScopeFor(@NotNull PsiElement changedElement) { + // rehighlight everything when inspection suppress comment changed + if (changedElement.getLanguage() instanceof XMLLanguage + && changedElement instanceof PsiComment + && changedElement.getText().contains(DefaultXmlSuppressionProvider.SUPPRESS_MARK)) { + return changedElement.getContainingFile(); + } + return null; + } +} diff --git a/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java b/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java index 2275976cd61a..aa7a8ae8bbd6 100644 --- a/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java +++ b/xml/impl/src/com/intellij/xml/actions/ValidateXmlActionHandler.java @@ -548,7 +548,7 @@ public class ValidateXmlActionHandler { final PsiFile psifile = PsiManager.getInstance(myProject).findFile(file); if (psifile != null && psifile.isValid()) { - timestamp += psifile.getModificationStamp(); + timestamp += psifile.getViewProvider().getModificationStamp(); } else { break; } diff --git a/xml/impl/src/com/intellij/xml/actions/XmlSplitTagAction.java b/xml/impl/src/com/intellij/xml/actions/XmlSplitTagAction.java index 8291ac3d4c9a..77ec93a89a50 100644 --- a/xml/impl/src/com/intellij/xml/actions/XmlSplitTagAction.java +++ b/xml/impl/src/com/intellij/xml/actions/XmlSplitTagAction.java @@ -36,16 +36,19 @@ import org.jetbrains.annotations.NotNull; */ public class XmlSplitTagAction implements IntentionAction { + @Override @NotNull public String getText() { return XmlBundle.message("xml.split.tag.intention.action"); } + @Override @NotNull public String getFamilyName() { return XmlBundle.message("xml.split.tag.intention.action"); } + @Override public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) { if (file instanceof XmlFile) { if (editor != null) { @@ -75,6 +78,7 @@ public class XmlSplitTagAction implements IntentionAction { return "html".equals(name) || "body".equals(name) || "title".equals(name); } + @Override public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { if (!CodeInsightUtilBase.prepareFileForWrite(file)) return; @@ -165,6 +169,7 @@ public class XmlSplitTagAction implements IntentionAction { return sb.toString(); } + @Override public boolean startInWriteAction() { return true; } diff --git a/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java b/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java index f1ce3969dfc2..6aa1a22ad909 100644 --- a/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java +++ b/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java @@ -37,16 +37,20 @@ import org.jetbrains.annotations.Nullable; */ public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider { + public static final String SUPPRESS_MARK = "suppress"; + @Override public boolean isProviderAvailable(PsiFile file) { return true; } + @Override public boolean isSuppressedFor(PsiElement element, String inspectionId) { final XmlTag tag = element instanceof XmlFile ? ((XmlFile)element).getRootTag() : PsiTreeUtil.getContextOfType(element, XmlTag.class, false); return tag != null && findSuppression(tag, inspectionId, element) != null; } + @Override public void suppressForFile(PsiElement element, String inspectionId) { final PsiFile file = element.getContainingFile(); final XmlDocument document = ((XmlFile)file).getDocument(); @@ -55,6 +59,7 @@ public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider { suppress(file, findFileSuppression(anchor, null, element), inspectionId, anchor.getTextRange().getStartOffset()); } + @Override public void suppressForTag(PsiElement element, String inspectionId) { final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class); assert tag != null; @@ -140,7 +145,9 @@ public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider { @NonNls protected String getPrefix() { - return "