diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java index 341f8a7eef1a..b6c1067f8615 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java @@ -192,6 +192,8 @@ public class GenericCompilerRunner { for (Item item : items) { final Key key = item.getKey(); keySet.add(key); + if (item.isExcluded()) continue; + final GenericCompilerCache.PersistentStateData data = cache.getState(targetId, key); SourceState sourceState = data != null ? data.mySourceState : null; final OutputState outputState = data != null ? data.myOutputState : null; diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java index 3e5f19883a5e..3bd9972c1465 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java @@ -34,4 +34,8 @@ public abstract class CompileItem { @NotNull public abstract OutputState computeOutputState(); + + public boolean isExcluded() { + return false; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DisableGC.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DisableGC.java index ff9194c4b2b7..1c5e7182c6ad 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DisableGC.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DisableGC.java @@ -38,6 +38,10 @@ public class DisableGC implements Evaluator{ return result; } + public Evaluator getDelegate() { + return myDelegate; + } + public Modifier getModifier() { return myDelegate.getModifier(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java index 94875d7f44d3..257bad282949 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java @@ -61,7 +61,11 @@ public class MethodEvaluator implements Evaluator { public Object evaluate(EvaluationContextImpl context) throws EvaluateException { if(!context.getDebugProcess().isAttached()) return null; DebugProcessImpl debugProcess = context.getDebugProcess(); - final boolean requiresSuperObject = myObjectEvaluator instanceof SuperEvaluator; + + final boolean requiresSuperObject = + myObjectEvaluator instanceof SuperEvaluator || + (myObjectEvaluator instanceof DisableGC && ((DisableGC)myObjectEvaluator).getDelegate() instanceof SuperEvaluator); + final Object object = myObjectEvaluator.evaluate(context); if (LOG.isDebugEnabled()) { LOG.debug("MethodEvaluator: object = " + object); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java index 042abef112cd..5ce90c6956bb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java @@ -49,6 +49,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; @@ -172,29 +173,32 @@ public class PostHighlightingPass extends TextEditorHighlightingPass { private void optimizeImportsOnTheFly(@NotNull final Editor editor) { if (myHasRedundantImports || myHasMissortedImports) { - invokeOnTheFlyImportOptimizer(new Runnable() { - public void run() { - if (myProject.isDisposed() || editor.isDisposed()) { - return; - } - OptimizeImportsFix optimizeImportsFix = new OptimizeImportsFix(); - if (optimizeImportsFix.isAvailable(myProject, editor, myFile) && myFile.isWritable()) { - PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + final OptimizeImportsFix optimizeImportsFix = new OptimizeImportsFix(); + if (optimizeImportsFix.isAvailable(myProject, editor, myFile) && myFile.isWritable()) { + invokeOnTheFlyImportOptimizer(new Runnable() { + public void run() { optimizeImportsFix.invoke(myProject, editor, myFile); } - } - }); + }, myFile, editor); + } } } - public static void invokeOnTheFlyImportOptimizer(final Runnable runnable) { + public static void invokeOnTheFlyImportOptimizer(@NotNull final Runnable runnable, @NotNull final PsiFile file, @NotNull final Editor editor) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { + if (file.getProject().isDisposed() || editor.isDisposed()) return; + PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); + String beforeText = file.getText(); CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { public void run() { ApplicationManager.getApplication().runWriteAction(runnable); } }); + String afterText = file.getText(); + if (Comparing.strEqual(beforeText, afterText)) { + LOG.error("Import optimizer for the '"+file.getVirtualFile().getPath()+"' hasn't optimized any imports. Text:\n"+afterText); + } } }); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java index 88c0599ea364..5c78831bda8a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.CodeInsightUtilBase; +import com.intellij.codeInsight.intention.LowPriorityAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; @@ -32,7 +33,7 @@ import org.jetbrains.annotations.NotNull; /** * @author ven */ -public class CreateGetterOrSetterFix implements IntentionAction{ +public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityAction { private final boolean myCreateGetter; private final boolean myCreateSetter; private final PsiField myField; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java index 8dc94cc9f5cd..815ee1d4f9da 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java @@ -16,45 +16,43 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightSettings; -import com.intellij.codeInsight.daemon.QuickFixBundle; -import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; -import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; -import com.intellij.codeInsight.daemon.impl.actions.AddImportAction; -import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; -import com.intellij.codeInsight.daemon.impl.ShowAutoImportPass; -import com.intellij.codeInsight.completion.JavaCompletionUtil; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.codeInsight.CodeInsightUtilBase; -import com.intellij.codeInsight.hint.HintManagerImpl; -import com.intellij.codeInsight.hint.QuestionAction; +import com.intellij.codeInsight.completion.JavaCompletionUtil; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; +import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; +import com.intellij.codeInsight.daemon.impl.ShowAutoImportPass; +import com.intellij.codeInsight.daemon.impl.actions.AddImportAction; import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.QuestionAction; +import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInspection.HintAction; -import com.intellij.psi.*; -import com.intellij.psi.search.PsiShortNamesCache; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.packageDependencies.DependencyRule; -import com.intellij.ui.HintHint; +import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.*; -import java.util.List; -import java.util.Collections; import java.util.ArrayList; -import java.util.regex.Pattern; +import java.util.Collections; +import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; /** * @author peter */ -public abstract class ImportClassFixBase implements HintAction { +public abstract class ImportClassFixBase implements HintAction, HighPriorityAction { private final T myRef; protected ImportClassFixBase(T ref) { diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java index dbbe7f9a22a1..1dfae7e1bf14 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java @@ -39,6 +39,7 @@ import com.intellij.ui.ReferenceEditorComboWithBrowseButton; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -175,9 +176,8 @@ public class CreateClassDialog extends DialogWrapper { CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { try { - final PsiDirectory baseDir = myModule == null? null : PackageUtil.findPossiblePackageDirectoryInModule(myModule, packageName); - myTargetDirectory = myModule == null? PackageUtil.findOrCreateDirectoryForPackage(myProject, packageName, baseDir, true) - : PackageUtil.findOrCreateDirectoryForPackage(myModule, packageName, baseDir, true); + myTargetDirectory = myModule == null? PackageUtil.findOrCreateDirectoryForPackage(myProject, packageName, getBaseDir(packageName), true) + : PackageUtil.findOrCreateDirectoryForPackage(myModule, packageName, getBaseDir(packageName), true, true); if (myTargetDirectory == null) { errorString[0] = ""; // message already reported by PackageUtil return; @@ -199,6 +199,11 @@ public class CreateClassDialog extends DialogWrapper { super.doOKAction(); } + @Nullable + protected PsiDirectory getBaseDir(String packageName) { + return myModule == null? null : PackageUtil.findPossiblePackageDirectoryInModule(myModule, packageName); + } + public String getClassName() { if (myClassNameEditable) { return myTfClassName.getText(); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java index 9fa6b411e4cb..6a7b8f519479 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java @@ -26,14 +26,12 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.CodeInsightUtil; -import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.daemon.impl.analysis.HighlightNamesUtil; import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind; import com.intellij.codeInsight.daemon.impl.quickfix.CreateConstructorMatchingSuperFix; import com.intellij.codeInsight.generation.OverrideImplementUtil; import com.intellij.codeInsight.generation.PsiMethodMember; import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction; -import com.intellij.ide.util.MemberChooser; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -118,14 +116,19 @@ public class CreateSubclassAction extends PsiElementBaseIntentionAction { @Nullable public static CreateClassDialog chooseSubclassToCreate(PsiClass psiClass) { - PsiDirectory sourceDir = psiClass.getContainingFile().getContainingDirectory(); + final PsiDirectory sourceDir = psiClass.getContainingFile().getContainingDirectory(); final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(sourceDir); final CreateClassDialog dialog = new CreateClassDialog( psiClass.getProject(), getTitle(psiClass), psiClass.getName() + IMPL_SUFFIX, aPackage != null ? aPackage.getQualifiedName() : "", - CreateClassKind.CLASS, true, ModuleUtil.findModuleForPsiElement(psiClass)); + CreateClassKind.CLASS, true, ModuleUtil.findModuleForPsiElement(psiClass)){ + @Override + protected PsiDirectory getBaseDir(String packageName) { + return sourceDir; + } + }; dialog.show(); if (!dialog.isOK()) return null; final PsiDirectory targetDirectory = dialog.getTargetDirectory(); diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java index c4bc71b35a30..6ed51c4992d8 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java @@ -170,7 +170,7 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{ Collection descriptors; if (tool instanceof LocalInspectionToolWrapper) { LocalInspectionToolWrapper local = (LocalInspectionToolWrapper)tool; - if (local.getTool() instanceof UnfairLocalInspectionTool) continue; //cant't work with passes other than LocalInspectionPass + if (local.isUnfair()) continue; //cant't work with passes other than LocalInspectionPass local.processFile(psiElement.getContainingFile(), false, manager); descriptors = local.getProblemDescriptors(); } diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java index 74560cdc1e27..4ede61a08dbc 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java @@ -16,35 +16,20 @@ package com.intellij.codeInspection.unusedSymbol; -import com.intellij.ExtensionPoints; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.BaseJavaLocalInspectionTool; -import com.intellij.codeInspection.ex.EntryPointsManager; import com.intellij.codeInspection.ex.EntryPointsManagerImpl; import com.intellij.codeInspection.ex.UnfairLocalInspectionTool; -import com.intellij.codeInspection.reference.EntryPoint; import com.intellij.codeInspection.util.SpecialAnnotationsUtil; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.extensions.ExtensionPoint; -import com.intellij.openapi.extensions.ExtensionPointListener; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.util.JDOMExternalizableStringList; -import com.intellij.profile.codeInspection.InspectionProfileManager; -import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifierListOwner; -import com.intellij.psi.util.PropertyUtil; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.UIUtil; -import gnu.trove.THashSet; import org.intellij.lang.annotations.Pattern; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -54,8 +39,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.*; -import java.util.List; /** * User: anna @@ -170,13 +153,10 @@ public class UnusedSymbolLocalInspection extends BaseJavaLocalInspectionTool imp public static IntentionAction createQuickFix(final String qualifiedName, String element, Project project) { final EntryPointsManagerImpl entryPointsManager = EntryPointsManagerImpl.getInstance(project); - final ArrayList targetList = new ArrayList(); - targetList.addAll(entryPointsManager.ADDITIONAL_ANNOTATIONS); - targetList.addAll(entryPointsManager.getAdditionalAnnotations()); return SpecialAnnotationsUtil.createAddToSpecialAnnotationsListIntentionAction( QuickFixBundle.message("fix.unused.symbol.injection.text", element, qualifiedName), QuickFixBundle.message("fix.unused.symbol.injection.family"), - targetList, qualifiedName); + entryPointsManager.ADDITIONAL_ANNOTATIONS, qualifiedName); } public static boolean isInjected(final PsiModifierListOwner modifierListOwner) { diff --git a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java index 15a806d6ace4..a8c2d63fc02c 100644 --- a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java +++ b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java @@ -26,6 +26,8 @@ import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.impl.ProjectRootUtil; import com.intellij.openapi.roots.ModulePackageIndex; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.CommonContentEntriesEditor; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.ui.Messages; @@ -162,6 +164,14 @@ public class PackageUtil { String packageName, PsiDirectory baseDir, boolean askUserToCreate) throws IncorrectOperationException { + return findOrCreateDirectoryForPackage(module, packageName, baseDir, askUserToCreate, false); + } + + public static PsiDirectory findOrCreateDirectoryForPackage(@NotNull Module module, + String packageName, + PsiDirectory baseDir, + boolean askUserToCreate, + boolean filterSourceDirsForBaseTestDirectory) throws IncorrectOperationException { final Project project = module.getProject(); PsiDirectory psiDirectory = null; if (!"".equals(packageName)) { @@ -174,6 +184,9 @@ public class PackageUtil { postfixToShow = File.separatorChar + postfixToShow; } PsiDirectory[] moduleDirectories = getPackageDirectoriesInModule(rootPackage, module); + if (filterSourceDirsForBaseTestDirectory) { + moduleDirectories = filterSourceDirectories(baseDir, project, moduleDirectories); + } psiDirectory = DirectoryChooserUtil.selectDirectory(project, moduleDirectories, baseDir, postfixToShow); if (psiDirectory == null) return null; } @@ -240,6 +253,20 @@ public class PackageUtil { return psiDirectory; } + private static PsiDirectory[] filterSourceDirectories(PsiDirectory baseDir, Project project, PsiDirectory[] moduleDirectories) { + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + if (fileIndex.isInTestSourceContent(baseDir.getVirtualFile())) { + List result = new ArrayList(); + for (PsiDirectory moduleDirectory : moduleDirectories) { + if (fileIndex.isInTestSourceContent(moduleDirectory.getVirtualFile())) { + result.add(moduleDirectory); + } + } + moduleDirectories = result.toArray(new PsiDirectory[result.size()]); + } + return moduleDirectories; + } + private static PsiDirectory[] getPackageDirectoriesInModule(PsiPackage rootPackage, Module module) { return rootPackage.getDirectories(GlobalSearchScope.moduleScope(module)); } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java index 6cdf6b4d49aa..efaf4626a856 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java @@ -115,4 +115,11 @@ class AnchorElementInfo implements SmartPointerElementInfo { return null; } } + + @Override + public void dispose() { + if (myMarker != null) { + myMarker.dispose(); + } + } } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java index e6a6f36bfb42..ad95e90b3b6e 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java @@ -43,6 +43,10 @@ public class ImplicitVariableElementInfoFactory implements SmartPointerElementIn return null; } + @Override + public void dispose() { + } + @Nullable public Document getDocumentToSynchronize() { return null; diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java index f798857e0346..853a82691117 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java @@ -42,6 +42,10 @@ public class ImportListElementInfoFactory implements SmartPointerElementInfoFact return myFile.getImportList(); } + @Override + public void dispose() { + } + public Document getDocumentToSynchronize() { return null; } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java index e1373dcb0556..de4fd131035d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionStatementImpl.java @@ -36,7 +36,7 @@ public class PsiExpressionStatementImpl extends CompositePsiElement implements P public PsiExpression getExpression() { PsiExpression expression = (PsiExpression)SourceTreeToPsiMap.treeElementToPsi(findChildByType(ElementType.EXPRESSION_BIT_SET)); if (expression != null) return expression; - LOG.error("Illegal PSI. Children: " + DebugUtil.psiToString(this, false)); + LOG.error("Illegal PSI: \n" + DebugUtil.psiToString(getParent(), false)); return null; } diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java index b163cbbadfb7..f834fb0292b4 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java @@ -689,7 +689,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor { final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); final Module module = ModuleUtil.findModuleForPsiElement(containingFile); assert module != null; - final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false); + final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false, true); if (directory != null) { final PsiFile newFile = PsiFileFactory.getInstance(project).createFileFromText(newClassName + ".java", classString); final PsiElement addedFile = directory.add(newFile); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java index 542bcafc8bb8..2b5749a0eef2 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java @@ -275,7 +275,7 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP final PsiFile containingFile = method.getContainingFile(); final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); final Module module = ModuleUtil.findModuleForPsiElement(containingFile); - final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true); + final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true); if (directory != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java index f6b4b5e6463e..493e8a5227af 100644 --- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java @@ -110,7 +110,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); final Module module = ModuleUtil.findModuleForPsiElement(containingFile); assert module != null; - final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true); + final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true, true); if (directory != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java index 0b59f205de74..98c39e504645 100644 --- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java @@ -269,7 +269,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); final Module module = ModuleUtil.findModuleForPsiElement(containingFile); - final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true); + final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true); if (directory != null) { final PsiElement shortenedFile = JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiFile); diff --git a/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java b/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java index 42c38ab7626f..801d47e345a8 100644 --- a/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java +++ b/platform/lang-api/src/com/intellij/codeInspection/ProblemsHolder.java @@ -174,8 +174,7 @@ public class ProblemsHolder { @Nullable public ProblemDescriptor[] getResultsArray() { - final List problems = myProblems; - myProblems = null; + final List problems = getResults(); return problems == null ? null : problems.toArray(new ProblemDescriptor[problems.size()]); } diff --git a/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUtils.java b/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUtils.java index 38461c9dcf82..4b570cb3c2a7 100644 --- a/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUtils.java +++ b/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoUtils.java @@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.text.CharArrayUtil; @@ -34,10 +35,15 @@ import java.util.Set; public class ParameterInfoUtils { public static final String DEFAULT_PARAMETER_CLOSE_CHARS = ",){}"; - public static T findParentOfType (PsiFile file, int offset, Class parentClass) { + public static @Nullable T findParentOfType (PsiFile file, int offset, Class parentClass) { PsiElement element = file.findElementAt(offset); if (element == null) return null; - return PsiTreeUtil.getParentOfType(element, parentClass); + + T parentOfType = PsiTreeUtil.getParentOfType(element, parentClass); + if (element instanceof PsiWhiteSpace) { + parentOfType = PsiTreeUtil.getParentOfType(PsiTreeUtil.prevLeaf(element), parentClass); + } + return parentOfType; } public static int getCurrentParameterIndex(ASTNode argList, int offset, IElementType delimiterType) { diff --git a/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java b/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java index 3b26feb8e9c1..4515c6eb4a7f 100644 --- a/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java +++ b/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java @@ -74,6 +74,14 @@ public class VirtualFilePattern extends TreeElementPattern pathPattern) { + return with(new PatternCondition("withName") { + public boolean accepts(@NotNull final VirtualFile virtualFile, final ProcessingContext context) { + return pathPattern.accepts(virtualFile.getPath(), context); + } + }); + } + public VirtualFilePattern xmlWithRootTag(final ElementPattern tagNamePattern) { return with(new PatternCondition("xmlWithRootTag") { public boolean accepts(@NotNull final VirtualFile virtualFile, final ProcessingContext context) { 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 99364f20f93d..475cce0629b2 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 @@ -170,7 +170,8 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx @NotNull Document document, @NotNull TextEditor textEditor, @NotNull int[] toIgnore, - boolean canChangeDocument) { + boolean canChangeDocument, + @Nullable Runnable callbackWhileWaiting) { Application application = ApplicationManager.getApplication(); application.assertIsDispatchThread(); assert !application.isWriteAccessAllowed(); @@ -191,16 +192,18 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx final List passes = highlighter.getPasses(toIgnore); HighlightingPass[] array = passes.toArray(new HighlightingPass[passes.size()]); - final DaemonProgressIndicator progress = new DaemonProgressIndicator(); + final DaemonProgressIndicator progress = createUpdateProgress(); progress.setDebug(true); - progress.start(); myPassExecutorService.submitPasses(Collections.singletonMap((FileEditor)textEditor, array), progress, Job.DEFAULT_PRIORITY); try { while (progress.isRunning()) { if (progress.isCanceled() && progress.isRunning()) { // write action sneaked in the AWT. restart waitForTermination(); - return runPasses(file, document, textEditor, toIgnore, canChangeDocument); + return runPasses(file, document, textEditor, toIgnore, canChangeDocument,callbackWhileWaiting); + } + if (callbackWhileWaiting != null) { + callbackWhileWaiting.run(); } progress.waitFor(100); try { @@ -678,23 +681,25 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx // cancel all after calling createPasses() since there are perverts {@link com.intellij.util.xml.ui.DomUIFactoryImpl} who are changing PSI there cancelUpdateProgress(true, "Cancel by alarm"); myAlarm.cancelAllRequests(); - DaemonProgressIndicator progress; - synchronized (DaemonCodeAnalyzerImpl.this) { - progress = new DaemonProgressIndicator() { - @Override - public void stopIfRunning() { - super.stopIfRunning(); - myProject.getMessageBus().syncPublisher(DAEMON_EVENT_TOPIC).daemonFinished(); - } - }; - progress.start(); - myUpdateProgress = progress; - } + DaemonProgressIndicator progress = createUpdateProgress(); myPassExecutorService.submitPasses(passes, progress, Job.DEFAULT_PRIORITY); } }; } + private synchronized DaemonProgressIndicator createUpdateProgress() { + DaemonProgressIndicator progress = new DaemonProgressIndicator() { + @Override + public void stopIfRunning() { + super.stopIfRunning(); + myProject.getMessageBus().syncPublisher(DAEMON_EVENT_TOPIC).daemonFinished(); + } + }; + progress.start(); + myUpdateProgress = progress; + return progress; + } + public boolean canChangeFileSilently(PsiFileSystemItem file) { return myDaemonListeners.canChangeFileSilently(file); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index 7c020d84aa7d..dbe80edbfb88 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -328,30 +328,19 @@ class DaemonListeners implements Disposable { } private class MyApplicationListener extends ApplicationAdapter { + private boolean myDaemonWasRunning; + public void beforeWriteActionStart(Object action) { - if (!myDaemonCodeAnalyzer.isRunning()) return; // we'll restart in writeActionFinished() - if (LOG.isDebugEnabled()) { - LOG.debug("cancelling code highlighting by write action:" + action); - } - if (containsDocumentWorthBothering(action)) { - stopDaemon(true); - } + myDaemonWasRunning = myDaemonCodeAnalyzer.isRunning(); + if (!myDaemonWasRunning) return; // we'll restart in writeActionFinished() + stopDaemon(true); } public void writeActionFinished(Object action) { - if (containsDocumentWorthBothering(action)) { + if (myDaemonWasRunning) { stopDaemon(true); } } - - private boolean containsDocumentWorthBothering(Object action) { - if (isUnderIgnoredAction(action)) return false; - DocumentRunnable currentWriteAction = action instanceof DocumentRunnable ? (DocumentRunnable)action - : ApplicationManager.getApplication().getCurrentWriteAction(DocumentRunnable.class); - if (currentWriteAction == null) return true; - Document document = currentWriteAction.getDocument(); - return worthBothering(document, currentWriteAction.getProject()); - } } private class MyCommandListener extends CommandAdapter { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java index d89fb0377d99..c67285dcf5bb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java @@ -26,7 +26,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.editor.ex.RangeMarkerEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; 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 ab001ac96da3..8b670d4abea0 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 @@ -112,11 +112,27 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } protected void collectInformationWithProgress(final ProgressIndicator progress) { - if (!HighlightLevelUtil.shouldInspect(myFile)) return; - final InspectionManagerEx iManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); - final InspectionProfileWrapper profile = myProfileWrapper; - final List tools = DumbService.getInstance(myProject).filterByDumbAwareness(getInspectionTools(profile)); - inspect(tools, iManager, true, true, true, progress); + try { + if (!HighlightLevelUtil.shouldInspect(myFile)) return; + final InspectionManagerEx iManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); + final InspectionProfileWrapper profile = myProfileWrapper; + final List tools = DumbService.getInstance(myProject).filterByDumbAwareness(getInspectionTools(profile)); + inspect(tools, iManager, true, true, true, progress); + } + finally { + disposeDescriptors(); + } + } + + private void disposeDescriptors() { + for (List list : result.values()) { + for (InspectionResult inspectionResult : list) { + for (ProblemDescriptor pd: inspectionResult.foundProblems) { + ((ProblemDescriptorImpl)pd).dispose(); + } + } + } + result.clear(); } public void doInspectInBatch(final InspectionManagerEx iManager, List toolWrappers, boolean ignoreSuppressed) { @@ -202,8 +218,26 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass final LocalInspectionToolSession session = new LocalInspectionToolSession(myFile, myStartOffset, myEndOffset); List> init = new ArrayList>(); - visitPriorityElementsAndInit(tools, iManager, isOnTheFly, ignoreSuppressed, indicator, inside, session, init); - visitRestElementsAndCleanup(tools,iManager,isOnTheFly,ignoreSuppressed, indicator, outside, session, init); + boolean finished = false; + try { + visitPriorityElementsAndInit(tools, iManager, isOnTheFly, ignoreSuppressed, indicator, inside, session, init); + visitRestElementsAndCleanup(tools,iManager,isOnTheFly,ignoreSuppressed, indicator, outside, session, init); + finished = true; + } + finally { + if (!finished) { + synchronized (init) { + for (Trinity trinity : init) { + List results = trinity.second.getResults(); + if (results != null) { + for (ProblemDescriptor pd : results) { + ((ProblemDescriptorImpl)pd).dispose(); + } + } + } + } + } + } indicator.checkCanceled(); @@ -553,8 +587,10 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass return highlightInfo; } - private static void registerQuickFixes(final LocalInspectionTool tool, final ProblemDescriptor descriptor, - final HighlightInfo highlightInfo, final Set emptyActionRegistered) { + private static void registerQuickFixes(final LocalInspectionTool tool, + final ProblemDescriptor descriptor, + final HighlightInfo highlightInfo, + final Set emptyActionRegistered) { final HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName()); boolean needEmptyAction = true; final QuickFix[] fixes = descriptor.getFixes(); @@ -572,7 +608,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass needEmptyAction = false; } if (((ProblemDescriptorImpl)descriptor).getEnforcedTextAttributes() != null) { - needEmptyAction = false; + needEmptyAction = false; } if (needEmptyAction && emptyActionRegistered.add(new TextRange(highlightInfo.fixStartOffset, highlightInfo.fixEndOffset))) { EmptyIntentionAction emptyIntentionAction = new EmptyIntentionAction(tool.getDisplayName()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java index bce7959a8501..1ee2b413a854 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java @@ -209,6 +209,7 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { if (place != null) { List enableDisableIntentionAction = new ArrayList(); enableDisableIntentionAction.add(new IntentionHintComponent.EnableDisableIntentionAction(action)); + enableDisableIntentionAction.add(new IntentionHintComponent.EditIntentionSettingsAction(action)); intentions.intentionsToShow.add(new HighlightInfo.IntentionActionDescriptor(action, enableDisableIntentionAction, null)); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java index 890e15da0981..2cd30bfbe867 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java @@ -61,7 +61,7 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec myProject = project; project.getMessageBus().connect().subscribe(DocumentBulkUpdateListener.TOPIC, new DocumentBulkUpdateListener.Adapter() { public void updateStarted(final Document doc) { - resetFoldingInfo(doc); //TODO RangeMarkers tree convert + resetFoldingInfo(doc); } }); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java index f5e9f16a1052..e7460e1abe13 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.SmartPsiElementPointer; +import com.intellij.psi.impl.smartPointers.SmartPointerEx; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -36,6 +37,7 @@ public class EditorFoldingInfo { private final Map> myFoldRegionToSmartPointerMap = new THashMap>(); + @NotNull public static EditorFoldingInfo get(@NotNull Editor editor) { EditorFoldingInfo info = editor.getUserData(KEY); if (info == null){ @@ -82,15 +84,18 @@ public class EditorFoldingInfo { } public void dispose() { + for(FoldRegion region:myFoldRegionToSmartPointerMap.keySet()) { + SmartPsiElementPointer pointer = myFoldRegionToSmartPointerMap.get(region); + ((SmartPointerEx)pointer).dispose(); + region.dispose(); + } myFoldRegionToSmartPointerMap.clear(); } public static void resetInfo(final Editor editor) { EditorFoldingInfo info = editor.getUserData(KEY); if (info != null) { - for(FoldRegion region:info.myFoldRegionToSmartPointerMap.keySet()) { - region.dispose(); - } + info.dispose(); } editor.putUserData(KEY, null); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java index ddf8ab8d7d85..9e8b2c3a1f89 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java @@ -25,6 +25,7 @@ import com.intellij.codeInsight.hint.PriorityQuestionAction; import com.intellij.codeInsight.hint.ScrollAwareHint; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; +import com.intellij.codeInsight.intention.impl.config.IntentionSettingsConfigurable; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.IdeActions; @@ -33,6 +34,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.VisualPosition; import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.JBPopupListener; @@ -489,4 +491,49 @@ public class IntentionHintComponent extends JPanel implements Disposable, Scroll return getText(); } } + + public static class EditIntentionSettingsAction implements IntentionAction { + private String myFamilyName; + + public EditIntentionSettingsAction(IntentionAction action) { + myFamilyName = action.getFamilyName(); + } + + @NotNull + @Override + public String getText() { + return "Edit intention settings"; + } + + @NotNull + @Override + public String getFamilyName() { + return getText(); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + final IntentionSettingsConfigurable configurable = new IntentionSettingsConfigurable(); + ShowSettingsUtil.getInstance().editConfigurable(project, configurable, new Runnable() { + @Override + public void run() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + configurable.selectIntention(myFamilyName); + } + }); + } + }); + } + + @Override + public boolean startInWriteAction() { + return false; + } + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java index d49c42b3994a..f9ebfb90b722 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java @@ -103,4 +103,7 @@ public class IntentionSettingsConfigurable extends BaseConfigurable implements S return HELP_ID; } + public void selectIntention(String familyName) { + myPanel.selectIntention(familyName); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsPanel.java index 70fbf86759a4..ecf39f78ba11 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsPanel.java @@ -147,6 +147,10 @@ public class IntentionSettingsPanel implements MasterDetails { myIntentionDescriptionPanel.dispose(); } + public void selectIntention(String familyName) { + myIntentionSettingsTree.selectIntention(familyName); + } + private static boolean isIntentionAccepted(IntentionActionMetaData metaData, @NonNls String filter, boolean forceInclude, final List> keySetList, final HashSet quoted) { if (StringUtil.containsIgnoreCase(metaData.getFamily(), filter)) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsTree.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsTree.java index 33c42af31fa1..a3a674d7b80a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsTree.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsTree.java @@ -189,6 +189,14 @@ public abstract class IntentionSettingsTree { treeModel.nodeChanged(root); } + public void selectIntention(String familyName) { + final CheckedTreeNode child = findChildRecursively(getRoot(), familyName); + if (child != null) { + final TreePath path = new TreePath(child.getPath()); + TreeUtil.selectPath(myTree, path); + } + } + private static List sort(final List intentionsToShow) { List copy = new ArrayList(intentionsToShow); Collections.sort(copy, new Comparator() { @@ -244,6 +252,28 @@ public abstract class IntentionSettingsTree { return found.get(); } + private static CheckedTreeNode findChildRecursively(CheckedTreeNode node, final String name) { + final Ref found = new Ref(); + visitChildren(node, new CheckedNodeVisitor() { + public void visit(CheckedTreeNode node) { + if (found.get() != null) return; + final Object userObject = node.getUserObject(); + if (userObject instanceof IntentionActionMetaData) { + String text = getNodeText(node); + if (name.equals(text)) { + found.set(node); + } + } else { + final CheckedTreeNode child = findChildRecursively(node, name); + if (child != null) { + found.set(child); + } + } + } + }); + return found.get(); + } + private static String getNodeText(CheckedTreeNode node) { final Object userObject = node.getUserObject(); String text; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java index f3acc5d8ab8f..a7e878941c44 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java @@ -17,6 +17,7 @@ package com.intellij.codeInspection.actions; import com.intellij.codeInspection.InspectionProfileEntry; import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.codeInspection.ex.ScopeToolState; import com.intellij.ide.IdeBundle; import com.intellij.ide.util.gotoByName.SimpleChooseByNameModel; @@ -51,6 +52,9 @@ public class GotoInspectionModel extends SimpleChooseByNameModel {//implements C final InspectionProfileImpl rootProfile = (InspectionProfileImpl)InspectionProfileManager.getInstance().getRootProfile(); for (ScopeToolState state : rootProfile.getAllTools()) { final InspectionProfileEntry tool = state.getTool(); + if (tool instanceof LocalInspectionToolWrapper && ((LocalInspectionToolWrapper)tool).isUnfair()) { + continue; + } myToolNames.put(tool.getDisplayName(), tool); final String groupName = tool.getGroupDisplayName(); Set toolsInGroup = myGroupNames.get(groupName); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionAction.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionAction.java index cacec609a9a9..b5dbefcb4d96 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionAction.java @@ -44,7 +44,6 @@ import com.intellij.psi.PsiManager; import org.jdom.Element; import org.jetbrains.annotations.NotNull; -import java.awt.*; import java.util.Arrays; /** @@ -58,7 +57,6 @@ public class RunInspectionAction extends GotoActionBase { @Override protected void gotoActionPerformed(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - final Component component = e.getData(PlatformDataKeys.CONTEXT_COMPONENT); final PsiElement psiElement = LangDataKeys.PSI_ELEMENT.getData(e.getDataContext()); final PsiFile psiFile = LangDataKeys.PSI_FILE.getData(e.getDataContext()); final VirtualFile virtualFile = LangDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); @@ -85,7 +83,6 @@ public class RunInspectionAction extends GotoActionBase { @NotNull InspectionProfileEntry profileEntry, @NotNull VirtualFile virtualFile, PsiElement psiElement, PsiFile psiFile) { - final String shortName = profileEntry.getShortName(); final InspectionManagerEx managerEx = (InspectionManagerEx)InspectionManagerEx.getInstance(project); final Module module = ModuleUtil.findModuleForFile(virtualFile, project); @@ -120,15 +117,12 @@ public class RunInspectionAction extends GotoActionBase { final InspectionProfileImpl profile = new InspectionProfileImpl(profileEntry.getDisplayName()); final InspectionProfileImpl model = (InspectionProfileImpl)profile.getModifiableModel(); - final InspectionProfileEntry[] profileEntries = model.getInspectionTools(null); - for (InspectionProfileEntry entry : profileEntries) { - model.disableTool(entry.getShortName()); - } - model.enableTool(shortName); + model.disableAllTools(); + model.enableTool(profileEntry.getShortName()); try { Element element = new Element("toCopy"); profileEntry.writeSettings(element); - model.getInspectionTool(shortName).readSettings(element); + model.getInspectionTool(profileEntry.getShortName()).readSettings(element); } catch (Exception e) { //skip diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionIntention.java index 8c603fb9786a..7a898a5ceb38 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionIntention.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionIntention.java @@ -65,10 +65,9 @@ public class RunInspectionIntention implements IntentionAction { } public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - final InspectionProfileEntry inspectionTool = + final InspectionProfileEntry tool = InspectionProjectProfileManager.getInstance(project).getInspectionProfile().getInspectionTool(myShortName, file); - if (inspectionTool instanceof LocalInspectionToolWrapper && - ((LocalInspectionToolWrapper)inspectionTool).getTool() instanceof UnfairLocalInspectionTool) { + if (tool instanceof LocalInspectionToolWrapper && ((LocalInspectionToolWrapper)tool).isUnfair()) { return false; } return true; @@ -97,10 +96,7 @@ public class RunInspectionIntention implements IntentionAction { PsiElement psiElement) { final InspectionProfileImpl profile = new InspectionProfileImpl(baseTool.getDisplayName()); final InspectionProfileImpl model = (InspectionProfileImpl)profile.getModifiableModel(); - final InspectionProfileEntry[] profileEntries = model.getInspectionTools(null); - for (InspectionProfileEntry entry : profileEntries) { - model.disableTool(entry.getShortName()); - } + model.disableAllTools(); model.enableTool(baseTool.getShortName()); try { Element element = new Element("toCopy"); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java index d8cfc2bad03c..be45473e79b5 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java @@ -784,4 +784,10 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel, initInspectionTools(); return myTools.get(toolId); } + + public void disableAllTools() { + for (InspectionProfileEntry entry : getInspectionTools(null)) { + disableTool(entry.getShortName()); + } + } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java index 25729c1dbcff..46529d04842e 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java @@ -196,4 +196,8 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti } return super.getSuppressActions(); } + + public boolean isUnfair() { + return myTool instanceof UnfairLocalInspectionTool; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java index 52ffb45c8a74..b9e746fa4d4e 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/ProblemDescriptorImpl.java @@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.pom.Navigatable; import com.intellij.psi.*; +import com.intellij.psi.impl.smartPointers.SmartPointerEx; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @@ -40,7 +41,6 @@ public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implement @NotNull private final SmartPsiElementPointer myStartSmartPointer; @Nullable private final SmartPsiElementPointer myEndSmartPointer; - private final ProblemHighlightType myHighlightType; private Navigatable myNavigatable; private final boolean myAfterEndOfLine; @@ -66,7 +66,10 @@ public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implement this(startElement, endElement, descriptionTemplate, fixes, highlightType, isAfterEndOfLine, rangeInElement, true, hintAction, onTheFly); } - public ProblemDescriptorImpl(@NotNull PsiElement startElement, @NotNull PsiElement endElement, String descriptionTemplate, LocalQuickFix[] fixes, + public ProblemDescriptorImpl(@NotNull PsiElement startElement, + @NotNull PsiElement endElement, + String descriptionTemplate, + LocalQuickFix[] fixes, ProblemHighlightType highlightType, boolean isAfterEndOfLine, final TextRange rangeInElement, @@ -191,4 +194,9 @@ public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implement public boolean showTooltip() { return myShowTooltip; } + + public void dispose() { + ((SmartPointerEx)myStartSmartPointer).dispose(); + if (myEndSmartPointer != null) ((SmartPointerEx)myEndSmartPointer).dispose(); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java index 674e563a8a32..3dd00ee20988 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java @@ -152,6 +152,7 @@ public class SuppressActionWrapper extends ActionGroup { for (GlobalInspectionContextImpl context : globalInspectionContexts) { context.refreshViews(); } + CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject); } }, getTemplatePresentation().getText(), null); } diff --git a/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java b/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java index 5843bbf7c885..af9ce1aed324 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java @@ -129,7 +129,8 @@ public class CreateAction extends BaseRunConfigurationAction { private static class CreateAndEditPolicy extends CreatePolicy { protected void updateText(final Presentation presentation, final String actionText) { - presentation.setText(ExecutionBundle.message("create.run.configuration.for.item.action.name", actionText) + "...", false); + presentation.setText(actionText.length() > 0 ? ExecutionBundle.message("create.run.configuration.for.item.action.name", actionText) + "..." + : ExecutionBundle.message("create.run.configuration.action.name"), false); } public void perform(final ConfigurationContext context) { diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java index 1e5117c5ceff..ce06c71c35b6 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java @@ -99,7 +99,8 @@ public class BookmarksAction extends AnAction implements DumbAware { final Font font = pathLabel.getFont(); pathLabel.setFont(font.deriveFont((float)10)); - final JList list = new JBList(model); + final JBList list = new JBList(model); + list.getEmptyText().setText("No Bookmarks"); final PreviewPanel previewPanel = new PreviewPanel(project); diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index c796667b7a03..6cd16ced5954 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -91,18 +91,27 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings - + @@ -76,19 +76,11 @@ - - - - - - - - - + diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java index 7e2d139a31e9..182a0561cc31 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.scriptingContext.ui; +import com.intellij.ide.IdeBundle; import com.intellij.ide.scriptingContext.LangScriptingContextProvider; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; @@ -51,7 +52,6 @@ public class EditLibraryDialog extends DialogWrapper { private JButton myAddFileButton; private JButton myRemoveFileButton; private JBTable myFileTable; - private JButton myAttachFromButton; private Project myProject; private FileTableModel myFileTableModel; private VirtualFile mySelectedFile; @@ -70,13 +70,6 @@ public class EditLibraryDialog extends DialogWrapper { } }); - myAttachFromButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - attachFromDirectory(); - } - }); - myFileTableModel = new FileTableModel(); myFileTable.setModel(myFileTableModel); @@ -147,19 +140,15 @@ public class EditLibraryDialog extends DialogWrapper { FileChooserDescriptor chooserDescriptor = new LibFileChooserDescriptor(); VirtualFile[] files = FileChooser.chooseFiles(myProject, chooserDescriptor); if (files.length == 1 && files[0] != null) { - myFileTableModel.addFile(files[0]); - } - } - - private void attachFromDirectory() { - FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); - chooserDescriptor.setTitle("Select a directory to attach files from"); //TODO Move to resources - VirtualFile[] files = FileChooser.chooseFiles(myProject, chooserDescriptor); - if (files.length == 1 && files[0] != null) { - VirtualFile chosenDir = files[0]; - if (chosenDir.isDirectory() && chosenDir.isValid()) { - if (myLibName.getText().isEmpty()) myLibName.setText(chosenDir.getName()); - addRecursively(chosenDir); + VirtualFile selectedFile = files[0]; + if (selectedFile.isValid()) { + if (selectedFile.isDirectory()) { + if (myLibName.getText().isEmpty()) myLibName.setText(selectedFile.getName()); + addRecursively(selectedFile); + } + else { + myFileTableModel.addFile(selectedFile); + } } } } @@ -181,13 +170,13 @@ public class EditLibraryDialog extends DialogWrapper { private class LibFileChooserDescriptor extends FileChooserDescriptor { public LibFileChooserDescriptor() { - super (true, false, false, true, false, false); - setTitle("Select library file"); //TODO Move to resources + super (true, true, false, true, false, false); + setTitle(IdeBundle.message("scripting.lib.select.root")); } @Override public boolean isFileSelectable(VirtualFile file) { - if (!myProvider.acceptsExtension(file.getExtension())) return false; + if (!file.isDirectory() && !myProvider.acceptsExtension(file.getExtension())) return false; return super.isFileSelectable(file); } @@ -204,9 +193,9 @@ public class EditLibraryDialog extends DialogWrapper { public String getColumnName(int column) { switch(column) { case FILE_LOCATION_COL: - return "Location"; //TODO Move to resources - case FILE_TYPE_COL: //TODO Move to resources - return "Type"; + return IdeBundle.message("scripting.lib.file.location"); + case FILE_TYPE_COL: + return IdeBundle.message("scripting.lib.file.type"); } return ""; } @@ -326,7 +315,7 @@ public class EditLibraryDialog extends DialogWrapper { @Override protected void doOKAction() { if (!isLibNameValid(myLibName.getText())) { - Messages.showErrorDialog(myProject, "Invalid library name", "Error"); //TODO Move to resources + Messages.showErrorDialog(myProject, IdeBundle.message("scripting.lib.invalid.name"), "Error"); return; } super.doOKAction(); diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java index 44da63392e45..fd8aad467a05 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.scriptingContext.ui; +import com.intellij.ide.IdeBundle; import com.intellij.ide.scriptingContext.ScriptingLibraryMappings; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.scripting.ScriptingLibraryTable; @@ -34,8 +35,10 @@ public class ScriptingContextsConfigurable extends LanguagePerFileConfigurable - + @@ -42,7 +42,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java b/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java index c4cb198940af..9fb87784388c 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java @@ -27,7 +27,10 @@ import com.intellij.openapi.editor.ex.*; import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.ProperTextRange; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -53,6 +56,8 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable private final int myPrefixLineCount; private final int mySuffixLineCount; + private CachedText myCachedText = null; + public DocumentWindowImpl(@NotNull DocumentEx delegate, boolean oneLine, Place shreds) { myDelegate = delegate; myOneLine = oneLine; @@ -61,6 +66,25 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable mySuffixLineCount = Math.max(1, 1 + StringUtil.countNewLines(myShreds.get(shreds.size()- 1).suffix)); } + private static class CachedText { + private final String text; + private final long modstamp; + + private CachedText(String text, long modstamp) { + this.text = text; + this.modstamp = modstamp; + } + + public String getText() { + return text; + } + + public long getModstamp() { + return modstamp; + } + } + + public int getLineCount() { return 1 + StringUtil.countNewLines(getText()); } @@ -122,8 +146,20 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable } public String getText() { + if (myCachedText != null && myCachedText.getModstamp() != myDelegate.getModificationStamp()) { + myCachedText = null; + } + + if (myCachedText == null) { + myCachedText = new CachedText(calcText(), myDelegate.getModificationStamp()); + } + + return myCachedText.getText(); + } + + private String calcText() { StringBuilder text = new StringBuilder(); - String hostText = myDelegate.getText(); + CharSequence hostText = myDelegate.getCharsSequence(); for (PsiLanguageInjectionHost.Shred shred : myShreds) { RangeMarker hostRange = shred.getHostRangeMarker(); if (hostRange.isValid()) { diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java b/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java index 88cbc3339233..15897a46b278 100644 --- a/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java +++ b/platform/lang-impl/src/com/intellij/openapi/editor/ex/util/LayeredLexerEditorHighlighter.java @@ -350,13 +350,13 @@ public class LayeredLexerEditorHighlighter extends LexerEditorHighlighter { final int newEnd = start + tokenText.length(); if (oldMapping.range.getStartOffset() != start || - oldMapping.range.getEndOffset() != newEnd - ) { + oldMapping.range.getEndOffset() != newEnd) { + oldMapping.range.dispose(); oldMapping.range = doc.createRangeMarker(start, newEnd); } } - public MappedRange insertMapping(int tokenIndex, IElementType outerToken) { + private MappedRange insertMapping(int tokenIndex, IElementType outerToken) { CharSequence tokenText = getTokenText(tokenIndex); final int length = tokenText.length(); @@ -367,7 +367,8 @@ public class LayeredLexerEditorHighlighter extends LexerEditorHighlighter { doc.insertString(insertOffset, new MergingCharSequence(mySeparator, tokenText)); insertOffset += mySeparator.length(); - return new MappedRange(this, doc.createRangeMarker(insertOffset, insertOffset + length), outerToken); + RangeMarker marker = doc.createRangeMarker(insertOffset, insertOffset + length); + return new MappedRange(this, marker, outerToken); } private CharSequence getTokenText(final int tokenIndex) { @@ -386,12 +387,13 @@ public class LayeredLexerEditorHighlighter extends LexerEditorHighlighter { return null; } - public void removeMapping(MappedRange mapping) { + private void removeMapping(MappedRange mapping) { RangeMarker rangeMarker = mapping.range; if (rangeMarker.isValid()) { final int start = rangeMarker.getStartOffset(); final int end = rangeMarker.getEndOffset(); doc.deleteString(start - mySeparator.length(), end); + rangeMarker.dispose(); } } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index ed82047b391b..7dcd48d7a11d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -652,7 +652,7 @@ public class FileManagerImpl implements FileManager { if (!vFile.isDirectory()) { PsiFile psiFile = findFile(vFile); - if (psiFile != null) { + if (psiFile != null && psiFile.getProject() == myManager.getProject()) { PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setParent(parentDir); myManager.beforeChildAddition(treeEvent); @@ -662,7 +662,7 @@ public class FileManagerImpl implements FileManager { } else { PsiDirectory psiDir = findDirectory(vFile); - if (psiDir != null) { + if (psiDir != null && psiDir.getProject() == myManager.getProject()) { PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setParent(parentDir); myManager.beforeChildAddition(treeEvent); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java index 0047cd5683da..c825b9ec7302 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java @@ -18,10 +18,8 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; /** @@ -50,4 +48,8 @@ class FileElementInfo implements SmartPointerElementInfo { myFile = SelfElementInfo.restoreFile(myFile, myProject); return myFile; } + + @Override + public void dispose() { + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java index 95f0c04401b8..b091bc7de1b2 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/LazyPointerImpl.java @@ -110,4 +110,8 @@ public class LazyPointerImpl implements SmartPointerEx return null; } + @Override + public void dispose() { + if (myPointer != null) ((SmartPointerEx)myPointer).dispose(); + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 03cb478976a2..8f338691024f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -113,6 +113,13 @@ class SelfElementInfo implements SmartPointerElementInfo { return null; } + @Override + public void dispose() { + if (myMarker != null) { + myMarker.dispose(); + } + } + @Nullable public static PsiFile restoreFile(PsiFile file,@NotNull Project project) { if (file == null) return null; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java index 9c85e8082473..98435ed3f3ca 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java @@ -28,4 +28,6 @@ interface SmartPointerElementInfo { @Nullable PsiElement restoreElement(); + + void dispose(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java index 8133f292798a..4ab980b7ef08 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerEx.java @@ -21,4 +21,5 @@ import com.intellij.psi.SmartPsiElementPointer; public interface SmartPointerEx extends SmartPsiElementPointer { void fastenBelt(); void documentAndPsiInSync(); + void dispose(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java index 507b4fe0856f..da8b80f07d38 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -149,6 +149,15 @@ class SmartPsiElementPointerImpl implements SmartPointerEx } } + @Override + public void dispose() { + if (myElementInfo != null) { + myElementInfo.dispose(); + myElementInfo = null; + myElement = null; + } + } + public void fastenBelt() { if (myElementInfo != null && myElement != null && myElement.isValid()) return; @@ -156,5 +165,4 @@ class SmartPsiElementPointerImpl implements SmartPointerEx myElementInfo = createElementInfo(); } } - } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index c139c4157a18..29a406621db0 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -262,7 +262,8 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF private void switchFromStubToAST(ASTNode root, final Iterator> stubs) { final IElementType contentElementType = getContentElementType(); if (!(contentElementType instanceof IStubFileElementType)) { - throw new AssertionError("Invalid content element type: " + contentElementType + "; elementType=" + myElementType + "; file=" + getClass() + "; viewProvider=" + getViewProvider()); + throw new AssertionError("Invalid content element type: " + contentElementType + " of " + contentElementType.getLanguage() + + "; elementType=" + myElementType + " of " + myElementType.getLanguage() + "; file=" + getClass() + "; viewProvider=" + getViewProvider()); } ((TreeElement)root).acceptTree(new RecursiveTreeElementWalkingVisitor() { final StubBuilder builder = ((IStubFileElementType)contentElementType).getBuilder(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java index beb4c62c1e73..a74ccd064db5 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java @@ -61,8 +61,8 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio @Override protected final RefactoringActionHandler getHandler(DataContext dataContext) { - PsiElement element; + PsiElement element = null; Editor editor = LangDataKeys.EDITOR.getData(dataContext); PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); if (editor != null && file != null) { @@ -75,14 +75,18 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio } } - element = LangDataKeys.PSI_ELEMENT.getData(dataContext); - if (element != null) { - RefactoringActionHandler handler = getHandler(element.getLanguage(), element); + PsiElement referenced = LangDataKeys.PSI_ELEMENT.getData(dataContext); + if (referenced != null) { + RefactoringActionHandler handler = getHandler(referenced.getLanguage(), referenced); if (handler != null) { return handler; } } + if (element == null) { + element = referenced; + } + final Language[] languages = LangDataKeys.CONTEXT_LANGUAGES.getData(dataContext); if (languages != null) { for (Language language : languages) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java b/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java index 8e75a6c8d106..bbc2945dac1a 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java @@ -17,14 +17,15 @@ package com.intellij.refactoring.inline; import com.intellij.codeInsight.TargetElementUtilBase; -import com.intellij.codeInsight.hint.HintManager; import com.intellij.lang.Language; import com.intellij.lang.refactoring.InlineHandler; import com.intellij.lang.refactoring.InlineHandlers; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReference; @@ -53,8 +54,21 @@ public class GenericInlineHandler { return settings != null; } - final Collection allReferences = - settings.isOnlyOneReferenceToInline() ? Collections.singleton(invocationReference) : ReferencesSearch.search(element).findAll(); + final Collection allReferences; + + if (settings.isOnlyOneReferenceToInline()) { + allReferences = Collections.singleton(invocationReference); + } else { + final Ref> usagesRef = new Ref>(); + ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + @Override + public void run() { + usagesRef.set(ReferencesSearch.search(element).findAll()); + } + }, "Find Usages", false, editor.getProject()); + allReferences = usagesRef.get(); + } + final Map inliners = new HashMap(); final MultiMap conflicts = new MultiMap(); diff --git a/platform/lang-impl/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java b/platform/lang-impl/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java index 4a4c74884170..cd06228cc62b 100644 --- a/platform/lang-impl/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java +++ b/platform/lang-impl/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java @@ -151,14 +151,12 @@ public abstract class ChooseLibrariesDialogBase extends DialogWrapper { myBuilder.initRootNode(); myTree.setDragEnabled(false); - myTree.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); myTree.setRowHeight(Icons.CLASS_ICON.getIconHeight()); myTree.setShowsRootHandles(true); UIUtil.setLineStyleAngled(myTree); myTree.setRootVisible(false); - myTree.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); myTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(final TreeSelectionEvent e) { updateOKAction(); diff --git a/platform/platform-api/src/com/intellij/patterns/StringPattern.java b/platform/platform-api/src/com/intellij/patterns/StringPattern.java index 43459f96a7f6..aded18ec8c40 100644 --- a/platform/platform-api/src/com/intellij/patterns/StringPattern.java +++ b/platform/platform-api/src/com/intellij/patterns/StringPattern.java @@ -15,6 +15,7 @@ */ package com.intellij.patterns; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ProcessingContext; import dk.brics.automaton.Automaton; @@ -28,11 +29,13 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; /** * @author peter */ public class StringPattern extends ObjectPattern { + private static final Logger LOG = Logger.getInstance("#com.intellij.patterns.StringPattern"); private static final InitialPatternCondition CONDITION = new InitialPatternCondition(String.class) { public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return o instanceof String; @@ -94,7 +97,19 @@ public class StringPattern extends ObjectPattern { if (escaped.equals(s)) { return equalTo(s); } - final Pattern pattern = Pattern.compile(s); + final Pattern pattern; + try { + pattern = Pattern.compile(s); + } + catch (PatternSyntaxException e) { + LOG.error(e); + return with(new PatternCondition("neverMatches") { + @Override + public boolean accepts(@NotNull String s, ProcessingContext context) { + return false; + } + }); + } return with(new ValuePatternCondition("matches") { public boolean accepts(@NotNull final String str, final ProcessingContext context) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java index 11cb4b0f3ca3..0125d61de1bc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java @@ -151,6 +151,10 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex for (String placeName : placeNames) { try { SoftWrapAppliancePlaces place = SoftWrapAppliancePlaces.valueOf(placeName); + if (place == SoftWrapAppliancePlaces.VCS_DIFF) { + // Don't keep separate setting for vcs diff window for now and let it share the value for main editor. + continue; + } myPlacesToUseSoftWraps.add(place); } catch (IllegalArgumentException e) { @@ -258,7 +262,15 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex } public boolean isUseSoftWraps(@NotNull SoftWrapAppliancePlaces place) { - return myPlacesToUseSoftWraps.contains(place); + if (myPlacesToUseSoftWraps.contains(place)) { + return true; + } + + // For now use soft wraps at vcs diff if they are enabled for the main editors. + if (place == SoftWrapAppliancePlaces.VCS_DIFF) { + return myPlacesToUseSoftWraps.contains(SoftWrapAppliancePlaces.MAIN_EDITOR); + } + return false; } public void setUseSoftWraps(boolean use) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java index 5414fa8641e9..0c7b8f44a788 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java @@ -44,12 +44,10 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen * This is performance-related optimization because profiling shows that it's rather expensive to call * {@link Editor#getColorsScheme()} often due to contention in 'assert read access'. */ - private final EditorColorsScheme myColorsScheme; private final Editor myEditor; public DefaultEditorTextRepresentationHelper(Editor editor) { myEditor = editor; - myColorsScheme = myEditor.getColorsScheme(); } @Override @@ -61,8 +59,9 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen public int charWidth(char c, int fontType) { // Symbol width retrieval is detected to be a bottleneck, hence, we perform a caching here in assumption that every representation // helper is editor-bound and cache size is not too big. - mySharedKey.fontName = myColorsScheme.getEditorFontName(); - mySharedKey.fontSize = myColorsScheme.getEditorFontSize(); + EditorColorsScheme colorsScheme = myEditor.getColorsScheme(); + mySharedKey.fontName = colorsScheme.getEditorFontName(); + mySharedKey.fontSize = colorsScheme.getEditorFontSize(); mySharedKey.fontType = fontType; mySharedKey.c = c; @@ -83,8 +82,9 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen // Symbol width retrieval is detected to be a bottleneck, hence, we perform a caching here in assumption that every representation // helper is editor-bound and cache size is not too big. - mySharedKey.fontName = myColorsScheme.getEditorFontName(); - mySharedKey.fontSize = myColorsScheme.getEditorFontSize(); + EditorColorsScheme colorsScheme = myEditor.getColorsScheme(); + mySharedKey.fontName = colorsScheme.getEditorFontName(); + mySharedKey.fontSize = colorsScheme.getEditorFontSize(); mySharedKey.fontType = fontType; for (int i = startToUse; i < end; i++) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 372874e7967f..67d4cd713ea5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -1043,7 +1043,24 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi // optimization: do not do column calculations here since we are interested in line number only public int offsetToVisualLine(int offset) { int line = calcLogicalLineNumber(offset); - return logicalToVisualLine(line); + int lineStartOffset = myDocument.getLineStartOffset(line); + int result = logicalToVisualLine(line); + + // There is a possible case that logical line that contains target offset is soft-wrapped (represented in more than one visual + // line). Hence, we need to perform necessary adjustments to the visual line that is used to show logical line start if necessary. + int i = getSoftWrapModel().getSoftWrapIndex(lineStartOffset); + if (i < 0) { + i = -i - 1; + } + List softWraps = getSoftWrapModel().getRegisteredSoftWraps(); + for (; i < softWraps.size(); i++) { + SoftWrap softWrap = softWraps.get(i); + if (softWrap.getStart() > offset) { + break; + } + result++; // Assuming that every soft wrap contains only one virtual line feed symbol + } + return result; } private int logicalToVisualLine(int line) { assertReadAccess(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index cdf5839c0291..baadc1294d23 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -58,9 +58,10 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi /** Upper boundary of time interval to check editor settings. */ private static final long EDITOR_SETTINGS_CHECK_PERIOD_MILLIS = 10000; - private final OffsetToLogicalTask myOffsetToLogicalTask = new OffsetToLogicalTask(); - private final VisualToLogicalTask myVisualToLogicalTask = new VisualToLogicalTask(); - private final LogicalToVisualTask myLogicalToVisualTask = new LogicalToVisualTask(); + private final OffsetToLogicalTask myOffsetToLogicalTask = new OffsetToLogicalTask(); + private final VisualToLogicalTask myVisualToLogicalTask = new VisualToLogicalTask(); + private final LogicalToVisualTask myLogicalToVisualTask = new LogicalToVisualTask(); + private final FoldProcessingEndTask myFoldProcessingEndTask = new FoldProcessingEndTask(); private final List myDocumentListeners = new ArrayList(); private final List myFoldListeners = new ArrayList(); @@ -284,7 +285,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myActive++; try { myVisualToLogicalTask.input = visual; - performMapping(myVisualToLogicalTask); + executeSafely(myVisualToLogicalTask); return myVisualToLogicalTask.output; } finally { myActive--; @@ -300,7 +301,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myActive++; try { myOffsetToLogicalTask.input = offset; - performMapping(myOffsetToLogicalTask); + executeSafely(myOffsetToLogicalTask); return myOffsetToLogicalTask.output; } finally { myActive--; @@ -316,7 +317,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myActive++; try { myOffsetToLogicalTask.input = offset; - performMapping(myOffsetToLogicalTask); + executeSafely(myOffsetToLogicalTask); return myOffsetToLogicalTask.output; } finally { myActive--; @@ -333,7 +334,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi try { myLogicalToVisualTask.input = logical; myLogicalToVisualTask.defaultOutput = defaultVisual; - performMapping(myLogicalToVisualTask); + executeSafely(myLogicalToVisualTask); return myLogicalToVisualTask.output; } finally { @@ -510,9 +511,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi if (!isSoftWrappingEnabled()) { return; } - for (FoldingListener listener : myFoldListeners) { - listener.onFoldProcessingEnd(); - } + executeSafely(myFoldProcessingEndTask); } @Override @@ -538,60 +537,61 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi *

* Current method encapsulates the logic mentioned above. * - * @param task object that encapsulates data and entry point for document dimension mapping algorithm + * @param task command object that which execution may trigger incremental update of update soft wraps cache */ @SuppressWarnings({"UseOfArchaicSystemPropertyAccessors"}) - private void performMapping(SoftWrapAwareMappingTask task) { + private void executeSafely(SoftWrapAwareTask task) { try { - task.performMapping(true); - } catch (Exception e) { + task.run(true); + } catch (Throwable e) { if (Boolean.getBoolean(DEBUG_PROPERTY_NAME)) { LOG.error(String.format( - "Unexpected exception occurred during performing document dimension mapping '%s'. Current soft wraps cache: %n" + "Unexpected exception occurred during performing '%s'. Current soft wraps cache: %n" + "%s%nDocument:%n%s%nFold regions: %s", task, myDataMapper, myEditor.getDocument().getText(), Arrays.toString(myEditor.getFoldingModel().fetchTopLevel())), e); } myDataMapper.release(); myApplianceManager.release(); try { - task.performMapping(true); + task.run(true); } - catch (Exception e1) { + catch (Throwable e1) { LOG.error(String.format( - "Can't perform document dimension mapping %s even with complete soft wraps cache re-parsing. Current soft wraps cache: %n" + "Can't perform %s even with complete soft wraps cache re-parsing. Current soft wraps cache: %n" + "%s. Document:%n%s%nFold regions: %s", task, myDataMapper, myEditor.getDocument().getText(), Arrays.toString(myEditor.getFoldingModel().fetchTopLevel())), e1 ); myEditor.getSettings().setUseSoftWraps(false); - task.performMapping(false); + task.run(false); } } } /** - * Defines generic interface to encapsulate task of mapping one document dimension to another. + * Defines generic interface for the command that may be proceeded in both 'soft wraps aware' and + * 'soft wraps unaware' modes. */ - private interface SoftWrapAwareMappingTask { + private interface SoftWrapAwareTask { /** - * Asks current task to perform the mapping. + * Asks current task to do the job. *

- * It's assumed that input data is already stored at the task object. Mapping result is assumed to be stored there as well - * for further retrieval for task in implementation-specific manner. + * It's assumed that input data (if any) is already stored at the task object. Processing result (if any) is assumed + * to be stored there as well for further retrieval in implementation-specific manner. * - * @param softWrapAware flag that indicates if soft wraps-aware mapping should be performed - * @throws IllegalStateException in case of inability to perform the mapping + * @param softWrapAware flag that indicates if soft wraps-aware processing should be performed + * @throws IllegalStateException in case of inability to do the job */ - void performMapping(boolean softWrapAware) throws IllegalStateException; + void run(boolean softWrapAware) throws IllegalStateException; } - private class OffsetToLogicalTask implements SoftWrapAwareMappingTask { + private class OffsetToLogicalTask implements SoftWrapAwareTask { public int input; public LogicalPosition output; @Override - public void performMapping(boolean softWrapAware) throws IllegalStateException { + public void run(boolean softWrapAware) throws IllegalStateException { if (softWrapAware) { output = myDataMapper.offsetToLogicalPosition(input); } @@ -599,15 +599,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi output = myEditor.offsetToLogicalPosition(input, false); } } + + @Override + public String toString() { + return "mapping from offset (" + input + ") to logical position"; + } } - private class VisualToLogicalTask implements SoftWrapAwareMappingTask { + private class VisualToLogicalTask implements SoftWrapAwareTask { public VisualPosition input; public LogicalPosition output; @Override - public void performMapping(boolean softWrapAware) throws IllegalStateException { + public void run(boolean softWrapAware) throws IllegalStateException { if (softWrapAware) { output = myDataMapper.visualToLogical(input); } @@ -615,17 +620,44 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi output = myEditor.visualToLogicalPosition(input, false); } } + + @Override + public String toString() { + return "mapping from visual position (" + input + ") to logical position"; + } } - private class LogicalToVisualTask implements SoftWrapAwareMappingTask { + private class LogicalToVisualTask implements SoftWrapAwareTask { public LogicalPosition input; public VisualPosition defaultOutput; public VisualPosition output; @Override - public void performMapping(boolean softWrapAware) throws IllegalStateException { + public void run(boolean softWrapAware) throws IllegalStateException { output = softWrapAware ? myDataMapper.logicalToVisualPosition(input, defaultOutput) : defaultOutput; } + + @Override + public String toString() { + return "mapping from logical position (" + input + ") to visual position"; + } + } + + private class FoldProcessingEndTask implements SoftWrapAwareTask { + @Override + public void run(boolean softWrapAware) { + if (!softWrapAware) { + return; + } + for (FoldingListener listener : myFoldListeners) { + listener.onFoldProcessingEnd(); + } + } + + @Override + public String toString() { + return "fold regions state change processing"; + } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java index c13bfa93ff5c..42ae65b17331 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java @@ -65,7 +65,6 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen private final List myListeners = new ArrayList(); private final List myCacheUpdateEvents = new ArrayList(); - private final List myApplianceStrategies = new ArrayList(); private final ProcessingContext myContext = new ProcessingContext(); private final FontTypesStorage myOffset2fontType = new FontTypesStorage(); @@ -110,28 +109,12 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen myLineWrapPositionStrategy = null; } - /** - * Registers given strategy to use within the current manager. - * - * @param strategy strategy to use during deciding if soft wraps should be recalculated for particular document region. - */ - public void addApplianceStrategy(@NotNull SoftWrapApplianceStrategy strategy) { - myApplianceStrategies.add(strategy); - } - @SuppressWarnings({"ForLoopReplaceableByForEach"}) private void recalculateSoftWraps() { if (myVisibleAreaWidth <= 0 || myCacheUpdateEvents.isEmpty()) { return; } - // Counter-based loop is preferred to for-each in order to avoid unnecessary performance degradation. - for (int i = 0; i < myApplianceStrategies.size(); i++) { - if (!myApplianceStrategies.get(i).processSoftWraps()) { - return; - } - } - myLastDocumentStamp = myEditor.getDocument().getModificationStamp(); // There is a possible case that new dirty regions are encountered during processing, hence, we iterate on regions snapshot here. List events = new ArrayList(myCacheUpdateEvents); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index dcf7f2ac5413..312ba258a2f9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -24,6 +24,8 @@ import com.intellij.openapi.Forceable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.IntArrayList; @@ -1046,7 +1048,7 @@ public class FSRecords implements Forceable { return new ContentOutputStream(fileId, readOnly); } - public void writeContent(int fileId, byte[] bytes, boolean readOnly) throws IOException { + public void writeContent(int fileId, ByteSequence bytes, boolean readOnly) throws IOException { new ContentOutputStream(fileId, readOnly).writeBytes(bytes, fileId); } @@ -1116,7 +1118,7 @@ public class FSRecords implements Forceable { protected final boolean myFixedSize; private BaseOutputStream(final int fileId, boolean fixedSize) { - super(new ByteArrayOutputStream()); + super(new BufferExposingByteArrayOutputStream()); myFileId = fileId; myFixedSize = fixedSize; } @@ -1133,10 +1135,11 @@ public class FSRecords implements Forceable { } protected void doFlush() throws IOException { - writeBytes(((ByteArrayOutputStream)out).toByteArray(), myFileId); + final BufferExposingByteArrayOutputStream _out = (BufferExposingByteArrayOutputStream)out; + writeBytes(new ByteSequence(_out.getInternalBuffer(), 0, _out.size()), myFileId); } - public void writeBytes(byte[] bytes, int fileId) throws IOException { + public void writeBytes(ByteSequence bytes, int fileId) throws IOException { final int page; synchronized (lock) { DbConnection.markDirty(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java index 6a2722fde9c9..e7f521c1ef18 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java @@ -24,6 +24,8 @@ import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.ShutDownTracker; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.*; @@ -232,7 +234,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { return myRecords.writeContent(getFileId(file), readOnly); } - private void writeContent(VirtualFile file, byte[] content, boolean readOnly) throws IOException { + private void writeContent(VirtualFile file, ByteSequence content, boolean readOnly) throws IOException { myRecords.writeContent(getFileId(file), content, readOnly); } @@ -436,7 +438,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { if ((!delegate.isReadOnly() || (!application.isInternal() && !application.isUnitTestMode())) && !noCaching && content.length <= FILE_LENGTH_TO_CACHE_THRESHOLD) { synchronized (INPUT_LOCK) { - writeContent(file, content, delegate.isReadOnly()); + writeContent(file, new ByteSequence(content), delegate.isReadOnly()); myRecords.setLength(getFileId(file), content.length); setFlag(file, MUST_RELOAD_CONTENT, false); @@ -479,14 +481,14 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } private ReplicatorInputStream createReplicator(final VirtualFile file, final InputStream nativeStream, final long len, final boolean readOnly) { - final ByteArrayOutputStream cache = new ByteArrayOutputStream((int)len); + final BufferExposingByteArrayOutputStream cache = new BufferExposingByteArrayOutputStream((int)len); return new ReplicatorInputStream(nativeStream, cache) { public void close() throws IOException { super.close(); synchronized (INPUT_LOCK) { if (getBytesRead() == len) { - writeContent(file, cache.toByteArray(), readOnly); + writeContent(file, new ByteSequence(cache.getInternalBuffer(), 0, cache.size()), readOnly); myRecords.setLength(getFileId(file), len); setFlag(file, MUST_RELOAD_CONTENT, false); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 41bc5b261fe6..9a8f59fe02e8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -79,7 +79,10 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } } }; - private boolean myFlushWasDelayedToFixFocus; + private boolean myFlushWasDelayedToFixFocusByDefaultRequest; + + private FocusCommand myRestoreFocusOnFlushCmd; + private ActionCallback myRestoreFocusOnFlushCallback; private boolean canFlushIdleRequests() { return isFocusTransferReady() && !isIdleQueueEmpty(); @@ -173,6 +176,12 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { if (forced) { myForcedFocusRequestsAlarm.cancelAllRequests(); setLastEffectiveForcedRequest(command); + + if (myRestoreFocusOnFlushCmd != null) { + rejectCommand(myRestoreFocusOnFlushCmd, myRestoreFocusOnFlushCallback, false); + myRestoreFocusOnFlushCmd = null; + myRestoreFocusOnFlushCallback = null; + } } SwingUtilities.invokeLater(new Runnable() { @@ -221,7 +230,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { }).notify(focusTimeout); } else { - rejectCommand(command, result); + rejectCommand(command, result, false); } } }); @@ -229,7 +238,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private boolean checkForRejectOrByPass(final FocusCommand cmd, final boolean forced, final ActionCallback result) { if (cmd.isExpired()) { - rejectCommand(cmd, result); + rejectCommand(cmd, result, false); return true; } @@ -241,14 +250,14 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { result.setDone(); } else { - rejectCommand(cmd, result); + rejectCommand(cmd, result, true); } return true; } if (lastRequest != null && lastRequest.dominatesOver(cmd)) { - rejectCommand(cmd, result); + rejectCommand(cmd, result, false); return true; } @@ -423,15 +432,28 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { if (isPendingKeyEventsRedispatched()) { - boolean focusOk = getFocusOwner() != null || myFlushWasDelayedToFixFocus; - if (!focusOk) { - IdeEventQueue.getInstance().fixStickyFocusedComponents(null); - myFlushWasDelayedToFixFocus = true; - } + boolean focusOk = getFocusOwner() != null; - if (canFlushIdleRequests() && getFlushingIdleRequests() <= 1 && (focusOk || !myFlushWasDelayedToFixFocus)) { - myFlushWasDelayedToFixFocus = false; - flushNow(); + if (!focusOk && myRestoreFocusOnFlushCmd != null) { + FocusCommand cmd = myRestoreFocusOnFlushCmd; + ActionCallback cb = myRestoreFocusOnFlushCallback; + + myRestoreFocusOnFlushCmd = null; + myRestoreFocusOnFlushCallback = null; + + requestFocus(cmd, true).notify(cb); + } else { + boolean noNeedToFixFocus = focusOk || myFlushWasDelayedToFixFocusByDefaultRequest; + + if (!noNeedToFixFocus) { + IdeEventQueue.getInstance().fixStickyFocusedComponents(null); + myFlushWasDelayedToFixFocusByDefaultRequest = true; + } + + if (canFlushIdleRequests() && getFlushingIdleRequests() <= 1 && (noNeedToFixFocus || !myFlushWasDelayedToFixFocusByDefaultRequest)) { + myFlushWasDelayedToFixFocusByDefaultRequest = false; + flushNow(); + } } } } @@ -654,15 +676,25 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } private void forceFinishFocusSettledown(FocusCommand cmd, ActionCallback cmdCallback) { - rejectCommand(cmd, cmdCallback); + rejectCommand(cmd, cmdCallback, false); } - private void rejectCommand(FocusCommand cmd, ActionCallback callback) { - resetCommand(cmd, true); + private void rejectCommand(FocusCommand cmd, ActionCallback callback, boolean canBeUseToFixNullFocusOnFlush) { + resetCommand(cmd, !canBeUseToFixNullFocusOnFlush); resetUnforcedCommand(cmd); - callback.setRejected(); + + if (canBeUseToFixNullFocusOnFlush) { + if (myRestoreFocusOnFlushCmd != null) { + rejectCommand(myRestoreFocusOnFlushCmd, myRestoreFocusOnFlushCallback, false); + } + + myRestoreFocusOnFlushCmd = cmd; + myRestoreFocusOnFlushCallback = callback; + } else { + callback.setRejected(); + } } private class AppListener extends ApplicationAdapter { diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 481d96ea5b45..94f6c57750c2 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -1077,3 +1077,19 @@ use.sun.jdk.prompt=Java version is not supported, please use Sun/Oracle JDK rath prompt.goto.inspection.enter.name=Enter inspection name: goto.inspection.action.text=&Run Inspection by Name... label.no.inspections.found=No inspections found + +#Scripting library management +scripting.lib.file.location=Location +scripting.lib.file.type=Type +scripting.lib.select.root=Select library file or directory +scripting.lib.invalid.name=Invalid library name +scripting.lib.attach=&Attach... +scripting.lib.detach=&Detach +scripting.lib.add=&Add... +scripting.lib.edit=&Edit... +scripting.lib.remove=&Remove +scripting.lib.usageScope=Usage Scope +scripting.lib.usageScope.caption=Specify which libraries are used in specific files and/or directories. +scripting.lib.usageScope.tableTitle=Library +scripting.lib.usageScope.override.question=Override library settings for child directories and files? +scripting.lib.usageScope.override.title=Override Library Settings \ No newline at end of file diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 30828d22d16b..29f104eb3926 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -73,6 +73,7 @@ import com.intellij.util.indexing.IndexableSetContributor; import com.intellij.util.indexing.IndexedRootsProvider; import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -198,7 +199,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro runStartupActivities(); } - @Nullable + @NotNull public static Project createProject(File projectFile, String creationPlace) { try { Project project = @@ -251,7 +252,11 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } protected Module doCreateRealModule(final String moduleName) { - final VirtualFile baseDir = myProject.getBaseDir(); + return doCreateRealModuleIn(moduleName, myProject, getModuleType()); + } + + protected static Module doCreateRealModuleIn(String moduleName, final Project project, final ModuleType moduleType) { + final VirtualFile baseDir = project.getBaseDir(); assertNotNull(baseDir); final File moduleFile = new File(baseDir.getPath().replace('/', File.separatorChar), moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION); @@ -261,7 +266,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @Override protected void run(Result result) throws Throwable { final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleFile); - Module module = ModuleManager.getInstance(myProject).newModule(virtualFile.getPath(), getModuleType()); + Module module = ModuleManager.getInstance(project).newModule(virtualFile.getPath(), moduleType); module.getModuleFile(); result.setResult(module); } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 96a5d4f03457..53bf15ddb2d1 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1303,7 +1303,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig ensureIndexesUpToDate(project); DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project); TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor); - return codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, toIgnore, canChangeDocument); + return codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, toIgnore, canChangeDocument,null); } public static void ensureIndexesUpToDate(Project project) { diff --git a/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java b/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java index 6f322791f3b3..b7c95c87d4c4 100644 --- a/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java +++ b/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java @@ -17,6 +17,7 @@ package com.intellij.openapi.progress; public class ProcessCanceledException extends RuntimeException { public ProcessCanceledException() { + int i = 0; } public ProcessCanceledException(Throwable cause) { diff --git a/platform/util/src/com/intellij/openapi/util/io/ByteSequence.java b/platform/util/src/com/intellij/openapi/util/io/ByteSequence.java new file mode 100644 index 000000000000..38a27ad0bfb7 --- /dev/null +++ b/platform/util/src/com/intellij/openapi/util/io/ByteSequence.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2010 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.openapi.util.io; + +/** + * @author Eugene Zhuravlev + * Date: 11/23/10 + */ +public class ByteSequence { + private final byte[] myBytes; + private final int myOffset; + private final int myLen; + + public ByteSequence(byte[] bytes) { + this(bytes, 0, bytes.length); + } + + public ByteSequence(byte[] bytes, int offset, int len) { + myBytes = bytes; + myOffset = offset; + myLen = len; + } + + public byte[] getBytes() { + return myBytes; + } + + public int getOffset() { + return myOffset; + } + + public int getLength() { + return myLen; + } +} diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index b140c9ba17de..734b4d13a612 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -932,19 +932,25 @@ public class FileUtil { writeToFile(file, text, false); } + public static void writeToFile(final File file, final byte[] text, int off, int len) throws IOException { + writeToFile(file, text, off, len, false); + } + public static void writeToFile(final File file, final byte[] text, boolean append) throws IOException { + writeToFile(file, text, 0, text.length, append); + } + + private static void writeToFile(File file, byte[] text, final int off, final int len, boolean append) throws IOException { createParentDirs(file); OutputStream stream = new BufferedOutputStream(new FileOutputStream(file, append)); try { - stream.write(text); + stream.write(text, off, len); } finally { stream.close(); } } - - public static boolean processFilesRecursively(final File root, final Processor processor) { final LinkedList queue = new LinkedList(); queue.add(root); diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index f93ee99c1d88..cffa2990143a 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -782,7 +782,7 @@ public class ContainerUtil { @NotNull public static List map(@NotNull T[] arr, @NotNull Function mapping) { - List result = new ArrayList(); + List result = new ArrayList(arr.length); for (T t : arr) { result.add(mapping.fun(t)); } diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMap.java b/platform/util/src/com/intellij/util/io/PersistentHashMap.java index 846da09a3c0a..2c8edb64005a 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMap.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMap.java @@ -17,6 +17,8 @@ package com.intellij.util.io; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.LowMemoryWatcher; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; @@ -55,7 +57,7 @@ public class PersistentHashMap extends PersistentEnumerator{ private static class AppendStream extends DataOutputStream { private AppendStream() { - super(new ByteArrayOutputStream()); + super(new BufferExposingByteArrayOutputStream()); } public int getBufferSize() { @@ -73,6 +75,11 @@ public class PersistentHashMap extends PersistentEnumerator{ public byte[] toByteArray() { return ((ByteArrayOutputStream)out).toByteArray(); } + + public ByteSequence getInternalBuffer() { + final BufferExposingByteArrayOutputStream _out = (BufferExposingByteArrayOutputStream)out; + return new ByteSequence(_out.getInternalBuffer(), 0, _out.size()); + } } private final LimitedPool myStreamPool = new LimitedPool(10, new LimitedPool.ObjectFactory() { @@ -96,9 +103,9 @@ public class PersistentHashMap extends PersistentEnumerator{ final int id = enumerate(key); HeaderRecord headerRecord = readValueId(id); - final byte[] bytes = value.toByteArray(); + final ByteSequence bytes = value.getInternalBuffer(); - headerRecord.size += bytes.length; + headerRecord.size += bytes.getLength(); headerRecord.address = myValueStorage.appendBytes(bytes, headerRecord.address); updateValueId(id, headerRecord); @@ -187,9 +194,9 @@ public class PersistentHashMap extends PersistentEnumerator{ myAppendCache.remove(key); final int id = enumerate(key); - AppendStream record = new AppendStream(); + final AppendStream record = new AppendStream(); myValueExternalizer.save(record, value); - byte[] bytes = record.toByteArray(); + final ByteSequence bytes = record.getInternalBuffer(); HeaderRecord header = readValueId(id); if (header != null) { @@ -199,7 +206,7 @@ public class PersistentHashMap extends PersistentEnumerator{ header = new HeaderRecord(); } - header.size = bytes.length; + header.size = bytes.getLength(); header.address = myValueStorage.appendBytes(bytes, 0); updateValueId(id, header); @@ -362,9 +369,9 @@ public class PersistentHashMap extends PersistentEnumerator{ public boolean process(final int keyId) throws IOException { final HeaderRecord record = readValueId(keyId); if (record.address != NULL_ADDR) { - byte[] bytes = new byte[record.size]; + final byte[] bytes = new byte[record.size]; myValueStorage.readBytes(record.address, bytes); - record.address = newStorage.appendBytes(bytes, 0); + record.address = newStorage.appendBytes(new ByteSequence(bytes), 0); updateValueId(keyId, record); } return true; diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java b/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java index 625c1dcbbd48..a86e150da7f8 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java @@ -19,6 +19,7 @@ */ package com.intellij.util.io; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.util.containers.SLRUCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,23 +63,23 @@ public class PersistentHashMapValueStorage { mySize = myFile.length(); if (mySize == 0) { - appendBytes("Header Record For PersistentHashMapValuStorage".getBytes(), 0); + appendBytes(new ByteSequence("Header Record For PersistentHashMapValuStorage".getBytes()), 0); } } - public long appendBytes(byte[] data, long prevChunkAddress) throws IOException { + public long appendBytes(ByteSequence data, long prevChunkAddress) throws IOException { assert !myCompactionMode; long result = mySize; final CacheValue appender = ourAppendersCache.get(myPath); try { appender.get().writeLong(prevChunkAddress); - appender.get().writeInt(data.length); - appender.get().write(data); + appender.get().writeInt(data.getLength()); + appender.get().write(data.getBytes(), data.getOffset(), data.getLength()); } finally { appender.release(); } - mySize += data.length + 8 + 4; + mySize += data.getLength() + 8 + 4; return result; } @@ -131,7 +132,7 @@ public class PersistentHashMapValueStorage { } if (chunkCount > 1 && !myCompactionMode) { - return appendBytes(result, 0); + return appendBytes(new ByteSequence(result), 0); } return tailChunkAddress; diff --git a/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java b/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java index 37ee234390e1..157e2888f5c7 100644 --- a/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java +++ b/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java @@ -22,6 +22,8 @@ package com.intellij.util.io.storage; import com.intellij.openapi.Disposable; import com.intellij.openapi.Forceable; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.io.PagePool; @@ -240,8 +242,8 @@ public abstract class AbstractStorage implements Disposable, Forceable { } } - protected void appendBytes(int record, byte[] bytes) throws IOException { - int delta = bytes.length; + protected void appendBytes(int record, ByteSequence bytes) throws IOException { + final int delta = bytes.getLength(); if (delta == 0) return; synchronized (myLock) { @@ -250,10 +252,10 @@ public abstract class AbstractStorage implements Disposable, Forceable { int newSize = oldSize + delta; if (newSize > capacity) { if (oldSize > 0) { - byte[] newbytes = new byte[newSize]; + final byte[] newbytes = new byte[newSize]; System.arraycopy(readBytes(record), 0, newbytes, 0, oldSize); - System.arraycopy(bytes, 0, newbytes, oldSize, delta); - writeBytes(record, newbytes, false); + System.arraycopy(bytes.getBytes(), bytes.getOffset(), newbytes, oldSize, delta); + writeBytes(record, new ByteSequence(newbytes), false); } else { writeBytes(record, bytes, false); @@ -261,15 +263,15 @@ public abstract class AbstractStorage implements Disposable, Forceable { } else { long address = myRecordsTable.getAddress(record) + oldSize; - myDataTable.writeBytes(address, bytes); + myDataTable.writeBytes(address, bytes.getBytes(), bytes.getOffset(), bytes.getLength()); myRecordsTable.setSize(record, newSize); } } } - public void writeBytes(int record, byte[] bytes, boolean fixedSize) throws IOException { + public void writeBytes(int record, ByteSequence bytes, boolean fixedSize) throws IOException { synchronized (myLock) { - final int requiredLength = bytes.length; + final int requiredLength = bytes.getLength(); final int currentCapacity = myRecordsTable.getCapacity(record); final int currentSize = myRecordsTable.getSize(record); @@ -292,7 +294,7 @@ public abstract class AbstractStorage implements Disposable, Forceable { myRecordsTable.setCapacity(record, newCapacity); } - myDataTable.writeBytes(address, bytes); + myDataTable.writeBytes(address, bytes.getBytes(), bytes.getOffset(), bytes.getLength()); myRecordsTable.setSize(record, requiredLength); } } @@ -324,7 +326,7 @@ public abstract class AbstractStorage implements Disposable, Forceable { private final int myRecordId; public StorageDataOutput(AbstractStorage storage, int recordId) { - this(storage, recordId, new ByteArrayOutputStream()); + this(storage, recordId, new BufferExposingByteArrayOutputStream()); } protected StorageDataOutput(AbstractStorage storage, int recordId, OutputStream stream) { @@ -335,11 +337,12 @@ public abstract class AbstractStorage implements Disposable, Forceable { public void close() throws IOException { super.close(); - myStorage.writeBytes(myRecordId, getByteStream().toByteArray(), false); + final BufferExposingByteArrayOutputStream byteStream = getByteStream(); + myStorage.writeBytes(myRecordId, new ByteSequence(byteStream.getInternalBuffer(), 0, byteStream.size()), false); } - protected ByteArrayOutputStream getByteStream() { - return ((ByteArrayOutputStream)out); + protected BufferExposingByteArrayOutputStream getByteStream() { + return ((BufferExposingByteArrayOutputStream)out); } public int getRecordId() { @@ -351,13 +354,14 @@ public abstract class AbstractStorage implements Disposable, Forceable { private final int myRecordId; public AppenderStream(int recordId) { - super(new ByteArrayOutputStream()); + super(new BufferExposingByteArrayOutputStream()); myRecordId = recordId; } public void close() throws IOException { super.close(); - appendBytes(myRecordId, ((ByteArrayOutputStream)out).toByteArray()); + final BufferExposingByteArrayOutputStream _out = (BufferExposingByteArrayOutputStream)out; + appendBytes(myRecordId, new ByteSequence(_out.getInternalBuffer(), 0, _out.size())); } } } diff --git a/platform/util/src/com/intellij/util/io/storage/DataTable.java b/platform/util/src/com/intellij/util/io/storage/DataTable.java index d4414f4fa6bc..d4532eda7494 100644 --- a/platform/util/src/com/intellij/util/io/storage/DataTable.java +++ b/platform/util/src/com/intellij/util/io/storage/DataTable.java @@ -73,8 +73,12 @@ class DataTable implements Disposable, Forceable { } public void writeBytes(long address, byte[] bytes) { + writeBytes(address, bytes, 0, bytes.length); + } + + public void writeBytes(long address, byte[] bytes, int off, int len) { markDirty(); - myFile.put(address, bytes, 0, bytes.length); + myFile.put(address, bytes, off, len); } public long allocateSpace(int len) { diff --git a/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java b/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java index 689a4246080b..6903bbaf47ad 100644 --- a/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java +++ b/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java @@ -19,12 +19,13 @@ */ package com.intellij.util.io.storage; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.io.PagePool; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.zip.DeflaterOutputStream; @@ -57,12 +58,12 @@ public class RefCountingStorage extends AbstractStorage { } @Override - protected void appendBytes(int record, byte[] bytes) throws IOException { + protected void appendBytes(int record, ByteSequence bytes) throws IOException { throw new IncorrectOperationException("Appending is not supported"); } @Override - public void writeBytes(int record, byte[] bytes, boolean fixedSize) throws IOException { + public void writeBytes(int record, ByteSequence bytes, boolean fixedSize) throws IOException { if (myDoNotZipCaches) { super.writeBytes(record, bytes, fixedSize); @@ -70,15 +71,15 @@ public class RefCountingStorage extends AbstractStorage { } synchronized (myLock) { - ByteArrayOutputStream s = new ByteArrayOutputStream(); + BufferExposingByteArrayOutputStream s = new BufferExposingByteArrayOutputStream(); DeflaterOutputStream out = new DeflaterOutputStream(s); try { - out.write(bytes); + out.write(bytes.getBytes(), bytes.getOffset(), bytes.getLength()); } finally { out.close(); } - super.writeBytes(record, s.toByteArray(), fixedSize); + super.writeBytes(record, new ByteSequence(s.getInternalBuffer(), 0, s.size()), fixedSize); } } diff --git a/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java b/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java index 92b062d9e715..afedc0c1a79c 100644 --- a/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java +++ b/platform/util/testSrc/com/intellij/util/io/storage/StorageTest.java @@ -20,6 +20,7 @@ package com.intellij.util.io.storage; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import junit.framework.TestCase; @@ -50,7 +51,7 @@ public class StorageTest extends TestCase { public void testSmoke() throws Exception { final int record = myStorage.createNewRecord(); - myStorage.writeBytes(record, "Hello".getBytes(), false); + myStorage.writeBytes(record, new ByteSequence("Hello".getBytes()), false); assertEquals("Hello", new String(myStorage.readBytes(record))); } @@ -67,7 +68,7 @@ public class StorageTest extends TestCase { for (int i = 0; i < count; i++) { final int record = myStorage.createNewRecord(); - myStorage.writeBytes(record, hello.getBytes(), true); // fixed size optimization is mor than 50 percents here! + myStorage.writeBytes(record, new ByteSequence(hello.getBytes()), true); // fixed size optimization is mor than 50 percents here! records[i] = record; } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/persistent/SmallMapSerializer.java b/platform/vcs-api/src/com/intellij/openapi/vcs/persistent/SmallMapSerializer.java index b87aa5de69d1..004dee277a1b 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/persistent/SmallMapSerializer.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/persistent/SmallMapSerializer.java @@ -17,6 +17,7 @@ package com.intellij.openapi.vcs.persistent; import com.intellij.openapi.Forceable; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.KeyDescriptor; @@ -76,14 +77,14 @@ public class SmallMapSerializer implements Forceable { public void force() { if (! myDirty) return; try{ - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + final BufferExposingByteArrayOutputStream bos = new BufferExposingByteArrayOutputStream(); final DataOutput out = new DataOutputStream(bos); out.writeInt(myMap.size()); for (Map.Entry, V> entry : myMap.entrySet()) { myKeyDescriptor.save(out, entry.getKey().myKey); myValueExternalizer.save(out, entry.getValue()); } - FileUtil.writeToFile(myFile, bos.toByteArray()); + FileUtil.writeToFile(myFile, bos.getInternalBuffer(), 0, bos.size()); } catch (IOException e) { LOG.error(e); } finally { diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java index 1ae3557eb2f3..b32fdd7340d8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java @@ -96,7 +96,7 @@ public class PatchApplier { final ApplyPatchStatus patchStatus = nonWriteActionPreCheck(); if (ApplyPatchStatus.FAILURE.equals(patchStatus)) return patchStatus; - final ApplyPatchStatus applyStatus = ApplicationManager.getApplication().runWriteAction(new Computable() { + final ApplyPatchStatus applyStatus = ApplicationManager.getApplication().runReadAction(new Computable() { public ApplyPatchStatus compute() { final Ref refStatus = new Ref(ApplyPatchStatus.FAILURE); CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { @@ -172,21 +172,28 @@ public class PatchApplier { } protected ApplyPatchStatus executeWritable() { - return ApplicationManager.getApplication().runWriteAction(new Computable() { + final Application application = ApplicationManager.getApplication(); + return application.runReadAction(new Computable() { public ApplyPatchStatus compute() { final Ref refStatus = new Ref(ApplyPatchStatus.FAILURE); CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { - if (! myVerifier.execute()) { + final Boolean result = application.runWriteAction(new Computable() { + @Override + public Boolean compute() { + return myVerifier.execute(); + } + }); + if (! result) { return; } - if (! makeWritable(myVerifier.getWritableFiles())) { + if (!makeWritable(myVerifier.getWritableFiles())) { return; } final List> textPatches = myVerifier.getTextPatches(); - if (! fileTypesAreOk(textPatches)) { + if (!fileTypesAreOk(textPatches)) { return; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java index 039337c18fdf..e9c5632cfd54 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.diff.impl.patch.formove; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.impl.patch.BinaryFilePatch; import com.intellij.openapi.diff.impl.patch.FilePatch; import com.intellij.openapi.diff.impl.patch.TextFilePatch; @@ -463,7 +464,21 @@ public class PathsVerifier { final MovedFileData movedFile = myMovedFiles.get(file); if (movedFile != null) { myBeforePaths.add(new FilePathImpl(file.getParent(), file.getName(), file.isDirectory())); - final VirtualFile moveResult = movedFile.doMove(); + final IOException[] exc = new IOException[1]; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + final VirtualFile moveResult = movedFile.doMove(); + } + catch (IOException e) { + exc[0] = e; + } + } + }); + if (exc[0] != null) { + throw exc[0]; + } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RevertCommittedStuffAbstractAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RevertCommittedStuffAbstractAction.java index 705c34846b88..637a298d68ab 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RevertCommittedStuffAbstractAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RevertCommittedStuffAbstractAction.java @@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.impl.patch.BinaryFilePatch; import com.intellij.openapi.diff.impl.patch.FilePatch; import com.intellij.openapi.diff.impl.patch.IdeaTextPatchBuilder; @@ -82,8 +83,14 @@ abstract class RevertCommittedStuffAbstractAction extends AnAction implements Du try { patches.addAll(IdeaTextPatchBuilder.buildPatch(project, changesList, baseDir.getPresentableUrl(), true)); } - catch (VcsException ex) { - Messages.showErrorDialog(project, "Failed to revert changes: " + ex.getMessage(), VcsBundle.message("revert.changes.title")); + catch (final VcsException ex) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Messages.showErrorDialog(project, "Failed to revert changes: " + ex.getMessage(), VcsBundle.message("revert.changes.title")); + } + }); + indicator.cancel(); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java index a5b06db4ec4f..2074f6990d36 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java @@ -25,6 +25,8 @@ package com.intellij.openapi.vcs.changes.patch; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.ActionButtonPresentation; import com.intellij.openapi.diff.DiffManager; @@ -40,14 +42,17 @@ import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; +import com.intellij.vcsUtil.Rethrow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -113,13 +118,29 @@ public class ApplyPatchAction extends DumbAwareAction { return sb.toString(); } - public static ApplyPatchStatus applyOnly(final Project project, final ApplyFilePatchBase patch, final ApplyPatchContext context, final VirtualFile file) { + public static ApplyPatchStatus applyOnly(final Project project, final ApplyFilePatchBase patch, + final ApplyPatchContext context, final VirtualFile file) { final T patchBase = patch.getPatch(); - try { - return patch.apply(file, context, project); - } - catch(ApplyPatchException ex) { - if (!patchBase.isNewFile() && !patchBase.isDeletedFile() && patchBase instanceof TextFilePatch) { + final Application application = ApplicationManager.getApplication(); + final ApplyPatchException[] exc = new ApplyPatchException[1]; + final ApplyPatchStatus applyPatchStatus = application.runWriteAction(new Computable() { + @Override + public ApplyPatchStatus compute() { + try { + return patch.apply(file, context, project); + } + catch (IOException e) { + LOG.error(e); + return ApplyPatchStatus.FAILURE; + } + catch (ApplyPatchException e) { + exc[0] = e; + } + return ApplyPatchStatus.FAILURE; + } + }); + if (exc[0] != null) { + if (! patchBase.isNewFile() && ! patchBase.isDeletedFile() && patchBase instanceof TextFilePatch) { //final VirtualFile beforeRename = (pathBeforeRename == null) ? file : pathBeforeRename; ApplyPatchStatus mergeStatus = mergeAgainstBaseVersion(project, file, new FilePathImpl(file), (TextFilePatch) patchBase, ApplyPatchMergeRequestFactory.INSTANCE); @@ -127,21 +148,11 @@ public class ApplyPatchAction extends DumbAwareAction { return mergeStatus; } } - Messages.showErrorDialog(project, VcsBundle.message("patch.apply.error", patchBase.getBeforeName(), ex.getMessage()), + Messages.showErrorDialog(project, VcsBundle.message("patch.apply.error", patchBase.getBeforeName(), exc[0].getMessage()), VcsBundle.message("patch.apply.dialog.title")); + return ApplyPatchStatus.FAILURE; } - catch (Exception ex) { - LOG.error(ex); - } - return ApplyPatchStatus.FAILURE; - } - - @Nullable - public static ApplyPatchStatus mergeAgainstBaseVersion(Project project, VirtualFile file, ApplyPatchContext context, - final TextFilePatch patch, - final PatchMergeRequestFactory mergeRequestFactory) { - final FilePath pathBeforeRename = context.getPathBeforeRename(file); - return mergeAgainstBaseVersion(project, file, pathBeforeRename, patch, mergeRequestFactory); + return applyPatchStatus; } @Nullable @@ -159,7 +170,12 @@ public class ApplyPatchAction extends DumbAwareAction { return status; } if (status != ApplyPatchStatus.ALREADY_APPLIED) { - return showMergeDialog(project, file, threeTexts.getBase(), threeTexts.getPatched(), mergeRequestFactory); + return ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public ApplyPatchStatus compute() { + return showMergeDialog(project, file, threeTexts.getBase(), threeTexts.getPatched(), mergeRequestFactory); + } + }); } else { return status; @@ -173,7 +189,7 @@ public class ApplyPatchAction extends DumbAwareAction { return ApplyPatchStatus.FAILURE; } final MergeRequest request = mergeRequestFactory.createMergeRequest(fileContent.toString(), patchedContent, content.toString(), file, - project); + project); DiffManager.getInstance().getDiffTool().show(request); if (request.getResult() == DialogWrapper.OK_EXIT_CODE) { return ApplyPatchStatus.SUCCESS; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java index 015cca865b12..ac4f6e9ee8eb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java @@ -16,15 +16,18 @@ package com.intellij.openapi.vcs.ui; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.ui.EditorCustomization; import com.intellij.ui.EditorTextField; -import com.intellij.ui.SeparatorFactory; import com.intellij.ui.EditorTextFieldProvider; +import com.intellij.ui.SeparatorFactory; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -37,6 +40,11 @@ public class CommitMessage extends JPanel implements Disposable { public CommitMessage(Project project) { super(new BorderLayout()); myEditorField = createEditorField(project); + + // Note that we assume here that editor used for commit message processing uses font family implied by LAF (in contrast, + // IJ code editor uses monospaced font). Hence, we don't need any special actions here + // (myEditorField.setFontInheritedFromLAF(true) should be used instead). + add(myEditorField, BorderLayout.CENTER); JPanel labelPanel = new JPanel(new BorderLayout()); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 50a8228f81eb..b4765e42e86e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -336,7 +336,7 @@ public class XDebugSessionImpl implements XDebugSession { private void doResume() { myDispatcher.getMulticaster().beforeSessionResume(); - myDebuggerManager.updateExecutionPosition(this, null, false); + myDebuggerManager.setActiveSession(this, null, false); mySuspendContext = null; myCurrentStackFrame = null; myCurrentPosition = null; @@ -362,18 +362,25 @@ public class XDebugSessionImpl implements XDebugSession { boolean frameChanged = myCurrentStackFrame != frame; myCurrentStackFrame = frame; - XSourcePosition position = frame.getSourcePosition(); - if (position != null) { - XExecutionStack activeExecutionStack = mySuspendContext.getActiveExecutionStack(); - boolean isTopFrame = activeExecutionStack != null && activeExecutionStack.getTopFrame() == frame; - myDebuggerManager.updateExecutionPosition(this, position, !isTopFrame); - } + activateSession(); if (frameChanged) { myDispatcher.getMulticaster().stackFrameChanged(); } } + public void activateSession() { + XSourcePosition position = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null; + if (position != null) { + XExecutionStack activeExecutionStack = mySuspendContext.getActiveExecutionStack(); + boolean isTopFrame = activeExecutionStack != null && activeExecutionStack.getTopFrame() == myCurrentStackFrame; + myDebuggerManager.setActiveSession(this, position, !isTopFrame); + } + else { + myDebuggerManager.setActiveSession(this, null, false); + } + } + public void updateBreakpointPresentation(@NotNull final XLineBreakpoint breakpoint, @Nullable final Icon icon, @Nullable final String errorMessage) { CustomizedBreakpointPresentation presentation; synchronized (myRegisteredBreakpoints) { @@ -484,7 +491,7 @@ public class XDebugSessionImpl implements XDebugSession { myPaused = true; if (myCurrentPosition != null) { - myDebuggerManager.updateExecutionPosition(this, myCurrentPosition, false); + myDebuggerManager.setActiveSession(this, myCurrentPosition, false); } UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { @@ -516,7 +523,7 @@ public class XDebugSessionImpl implements XDebugSession { myCurrentPosition = null; myCurrentStackFrame = null; mySuspendContext = null; - myDebuggerManager.updateExecutionPosition(this, null, false); + myDebuggerManager.setActiveSession(this, null, false); XBreakpointManagerImpl breakpointManager = myDebuggerManager.getBreakpointManager(); breakpointManager.removeBreakpointListener(myBreakpointListener); breakpointManager.getDependentBreakpointManager().removeListener(myDependentBreakpointListener); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java index 08e80cc97d3a..3dc3c8af5c73 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java @@ -38,7 +38,6 @@ import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; -import com.intellij.util.containers.HashMap; import com.intellij.util.messages.MessageBus; import com.intellij.util.xmlb.annotations.Property; import com.intellij.xdebugger.*; @@ -65,19 +64,17 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom private final Project myProject; private final XBreakpointManagerImpl myBreakpointManager; private final Map mySessionData; - private final Map mySessionTabs; - private final List mySessions; + private final Map mySessions; private final ExecutionPointHighlighter myExecutionPointHighlighter; - private XDebugSessionImpl myLastActiveSession; + private XDebugSessionImpl myActiveSession; public XDebuggerManagerImpl(final Project project, final StartupManager startupManager, MessageBus messageBus) { myProject = project; myBreakpointManager = new XBreakpointManagerImpl(project, this, startupManager); mySessionData = new LinkedHashMap(); - mySessions = new ArrayList(); + mySessions = new LinkedHashMap(); myExecutionPointHighlighter = new ExecutionPointHighlighter(project); - mySessionTabs = new HashMap(); messageBus.connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { @Override public void fileOpened(final FileEditorManager source, final VirtualFile file) { @@ -90,14 +87,23 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom messageBus.connect().subscribe(RunContentManagerImpl.RUN_CONTENT_TOPIC, new RunContentWithExecutorListener() { @Override public void contentSelected(RunContentDescriptor descriptor, @NotNull Executor executor) { + if (executor.equals(DefaultDebugExecutor.getDebugExecutorInstance())) { + final XDebugSessionImpl session = mySessions.get(descriptor.getProcessHandler()); + if (session != null) { + session.activateSession(); + } + else { + setActiveSession(null, null, false); + } + } } @Override public void contentRemoved(RunContentDescriptor descriptor, @NotNull Executor executor) { if (executor.equals(DefaultDebugExecutor.getDebugExecutorInstance())) { - XDebugSessionTab sessionTab = mySessionTabs.remove(descriptor.getProcessHandler()); - if (sessionTab != null) { - Disposer.dispose(sessionTab); + XDebugSessionImpl session = mySessions.remove(descriptor.getProcessHandler()); + if (session != null) { + Disposer.dispose(session.getSessionTab()); } } } @@ -164,9 +170,8 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom if (oldSessionData == null) { oldSessionData = new XDebugSessionData(); } - final XDebugSessionTab sessionTab = session.init(process, oldSessionData); - mySessions.add(session); - mySessionTabs.put(session.getDebugProcess().getProcessHandler(), sessionTab); + session.init(process, oldSessionData); + mySessions.put(session.getDebugProcess().getProcessHandler(), session); return session; } @@ -176,15 +181,15 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom XDebugSessionData data = sessionTab.saveData(); mySessions.remove(session); mySessionData.put(session.getDebugProcess().getProcessHandler(), data); - if (myLastActiveSession == session) { - myLastActiveSession = null; + if (myActiveSession == session) { + myActiveSession = null; onActiveSessionChanged(); } } - public void updateExecutionPosition(@NotNull XDebugSessionImpl session, @Nullable XSourcePosition position, boolean useSelection) { - boolean sessionChanged = myLastActiveSession != session; - myLastActiveSession = session; + public void setActiveSession(@Nullable XDebugSessionImpl session, @Nullable XSourcePosition position, boolean useSelection) { + boolean sessionChanged = myActiveSession != session; + myActiveSession = session; if (position != null) { myExecutionPointHighlighter.show(position, useSelection); } @@ -202,7 +207,8 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom @NotNull public XDebugSession[] getDebugSessions() { - return mySessions.toArray(new XDebugSession[mySessions.size()]); + final Collection sessions = mySessions.values(); + return sessions.toArray(new XDebugSessionImpl[sessions.size()]); } @Override @@ -220,7 +226,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom @Override public Collection getDebugProcesses(Class processClass) { final List list = new ArrayList(); - for (XDebugSessionImpl session : mySessions) { + for (XDebugSessionImpl session : mySessions.values()) { final XDebugProcess process = session.getDebugProcess(); if (processClass.isInstance(process)) { list.add(processClass.cast(process)); @@ -231,10 +237,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom @Nullable public XDebugSessionImpl getCurrentSession() { - if (myLastActiveSession != null) { - return myLastActiveSession; - } - return !mySessions.isEmpty() ? mySessions.get(0) : null; + return myActiveSession; } public XDebuggerState getState() { diff --git a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java index 2faaaac0478d..7cfb26b7259a 100644 --- a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java +++ b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java @@ -204,16 +204,22 @@ public abstract class ResourceManager { } @Nullable - public String getFileResourceType(@NotNull PsiFile file) { - PsiDirectory dir = file.getContainingDirectory(); - if (dir == null) return null; - PsiDirectory possibleResDir = dir.getParentDirectory(); - if (possibleResDir == null || !isResourceDir(possibleResDir.getVirtualFile())) { - return null; - } - String type = getResourceTypeByDirName(dir.getName()); - if (type == null) return null; - return isCorrectFileName(type, file.getName()) ? type : null; + public String getFileResourceType(@NotNull final PsiFile file) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Nullable + @Override + public String compute() { + PsiDirectory dir = file.getContainingDirectory(); + if (dir == null) return null; + PsiDirectory possibleResDir = dir.getParentDirectory(); + if (possibleResDir == null || !isResourceDir(possibleResDir.getVirtualFile())) { + return null; + } + String type = getResourceTypeByDirName(dir.getName()); + if (type == null) return null; + return isCorrectFileName(type, file.getName()) ? type : null; + } + }); } @NotNull diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdatePsiFileCopyright.java b/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdatePsiFileCopyright.java index 1ee15cc08c09..3498d6ea7fce 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdatePsiFileCopyright.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdatePsiFileCopyright.java @@ -306,6 +306,7 @@ public abstract class UpdatePsiFileCopyright extends AbstractUpdateCopyright { app.runWriteAction(new Runnable() { public void run() { Document doc = FileDocumentManager.getInstance().getDocument(getRoot()); + PsiDocumentManager.getInstance(file.getProject()).doPostponedOperationsAndUnblockDocument(doc); for (CommentAction action : actions) { int start = action.getStart(); int end = action.getEnd(); diff --git a/plugins/git4idea/src/git4idea/GitBranch.java b/plugins/git4idea/src/git4idea/GitBranch.java index 6bfb164b6f3e..fde11cdeeb1f 100644 --- a/plugins/git4idea/src/git4idea/GitBranch.java +++ b/plugins/git4idea/src/git4idea/GitBranch.java @@ -178,7 +178,8 @@ public class GitBranch extends GitReference { b = b.substring(2).trim(); if (b.equals(NO_BRANCH_NAME)) { continue; } - boolean isRemote = (! localWanted) || b.startsWith("remotes"); + boolean isRemote = b.startsWith("remotes/") || b.startsWith(REFS_REMOTES_PREFIX); +// boolean isRemote = (! localWanted) || b.startsWith("remotes"); final GitBranch branch = new GitBranch(b, current, isRemote); if (current) { currentBranch = branch; diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index adfa2617628b..3a312558518e 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -430,7 +430,10 @@ public class GitHistoryUtils { } //if (line.charAt(line.length() - 1) != '\u0003') { if ((! line.startsWith("\u0001")) || skipFirst.get()) { - sb.append("\n").append(line); + if (sb.length() > 0) { + sb.append("\n"); + } + sb.append(line); skipFirst.set(false); return; } diff --git a/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java b/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java index 8ae99a46a331..28fdeb0924fb 100644 --- a/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java +++ b/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java @@ -93,11 +93,21 @@ public class LowLevelAccessImpl implements LowLevelAccess { public SymbolicRefs getRefs() throws VcsException { final SymbolicRefs refs = new SymbolicRefs(); loadAllTags(refs.getTags()); - final GitBranch localBranch = loadLocalBranches(refs.getLocalBranches()); - final GitBranch remoteBranch = loadRemoteBranches(refs.getRemoteBranches()); - final GitBranch current = localBranch == null ? remoteBranch : localBranch; + final List allBranches = new ArrayList(); + final GitBranch current = GitBranch.list(myProject, myRoot, true, true, allBranches, null); + for (GitBranch branch : allBranches) { + if (branch.isRemote()) { + String name = branch.getName(); + name = name.startsWith("remotes/") ? name.substring("remotes/".length()) : name; + refs.addRemote(name); + } else { + refs.addLocal(branch.getName()); + } + } refs.setCurrent(current); - refs.setTrackedRemote(current.getTrackedRemoteName(myProject, myRoot)); + if (current != null) { + refs.setTrackedRemote(current.getTrackedRemoteName(myProject, myRoot)); + } return refs; } diff --git a/plugins/git4idea/src/git4idea/history/browser/SymbolicRefs.java b/plugins/git4idea/src/git4idea/history/browser/SymbolicRefs.java index 74681ca2096d..0868aa585bbc 100644 --- a/plugins/git4idea/src/git4idea/history/browser/SymbolicRefs.java +++ b/plugins/git4idea/src/git4idea/history/browser/SymbolicRefs.java @@ -34,6 +34,14 @@ public class SymbolicRefs { myRemoteBranches = new TreeSet(); } + public void addRemote(final String branch) { + myRemoteBranches.add(branch); + } + + public void addLocal(final String branch) { + myLocalBranches.add(branch); + } + public void addTags(final Collection value) { myTags.addAll(value); } diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java index f4a483bf9268..b676e313dac0 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java @@ -392,7 +392,7 @@ public class GitLogUI implements Disposable { @Override public void run() { final int[] afterRows = myJBTable.getSelectedRows(); - if (myDetails.isMissingBranchesInfo() && afterRows.length == 1) { + if (myDetails.isMissingBranchesInfo() && afterRows.length == 1 && afterRows[0] == rows[0]) { final CommitI afterCommit = myTableModel.getCommitAt(rows[0]); if (afterCommit.holdsDecoration() || (! afterCommit.equals(commit))) return; myDetails.putBranches(gitCommit, branches); diff --git a/plugins/groovy/resources/standardDsls/gantScript.gdsl b/plugins/groovy/resources/standardDsls/gantScript.gdsl index 35648d9e665b..98760c63c949 100644 --- a/plugins/groovy/resources/standardDsls/gantScript.gdsl +++ b/plugins/groovy/resources/standardDsls/gantScript.gdsl @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -def ctx = context(scope: scriptScope(), scripttype : ["gant"]) +def ctx = context(scope: scriptScope(), scriptType : "gant") contributor ([ctx], { property name:"ant", type:"org.codehaus.gant.GantBuilder" diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/local/GroovyUnusedImportPass.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/local/GroovyUnusedImportPass.java index 019dcb7bf06b..01fc6ec4b8ea 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/local/GroovyUnusedImportPass.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/local/GroovyUnusedImportPass.java @@ -34,7 +34,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; @@ -54,6 +53,7 @@ import java.util.Set; */ public class GroovyUnusedImportPass extends TextEditorHighlightingPass { private final GroovyFile myFile; + private final Editor myEditor; public static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.codeInspection.local.GroovyUnusedImportsPass"); private volatile Set myUnusedImports = Collections.emptySet(); private volatile Runnable myOptimizeRunnable; @@ -61,6 +61,7 @@ public class GroovyUnusedImportPass extends TextEditorHighlightingPass { public GroovyUnusedImportPass(GroovyFile file, Editor editor) { super(file.getProject(), editor.getDocument(), true); myFile = file; + myEditor = editor; } public void doCollectInformation(ProgressIndicator progress) { @@ -124,10 +125,9 @@ public class GroovyUnusedImportPass extends TextEditorHighlightingPass { PostHighlightingPass.invokeOnTheFlyImportOptimizer(new Runnable() { @Override public void run() { - PsiDocumentManager.getInstance(myProject).commitAllDocuments(); optimize.run(); } - }); + },myFile,myEditor); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy index 3a4ba24cc0dd..bdfce4c779b4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy @@ -2,15 +2,12 @@ package org.jetbrains.plugins.groovy.dsl.toplevel import com.intellij.openapi.util.text.StringUtil import com.intellij.patterns.ElementPattern +import com.intellij.patterns.StandardPatterns import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.Scope import static com.intellij.patterns.PlatformPatterns.psiFile import static com.intellij.patterns.PlatformPatterns.virtualFile -import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor -import com.intellij.util.ProcessingContext -import org.jetbrains.plugins.groovy.lang.psi.GroovyFile -import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector -/** + /** * @author ilyas */ class Context { @@ -28,19 +25,14 @@ class Context { addFilter new FileContextFilter(psiFile().withVirtualFile(vfilePattern)) } - List scripttype = args.scripttype - if (scripttype) { - addFilter(new ContextFilter() { - @Override - boolean isApplicable(GroovyClassDescriptor descriptor, ProcessingContext ctx) { - def file = descriptor.placeFile - if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) { - def scripTypeId = GroovyScriptTypeDetector.getScriptType((GroovyFile)file).getId() - return scripttype.contains(scripTypeId) - } - return false - } - }) + String scriptType = args.scriptType + if (scriptType) { + addFilter(new ScriptTypeFilter(scriptType)) + } + + String pathRegexp = args.pathRegexp + if (pathRegexp) { + addFilter new FileContextFilter(psiFile().withVirtualFile(virtualFile().withPath(StandardPatterns.string().matches(pathRegexp)))) } // filter by scope first, then by ctype diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ScriptTypeFilter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ScriptTypeFilter.java new file mode 100644 index 000000000000..ff6923bd2398 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ScriptTypeFilter.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2010 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.plugins.groovy.dsl.toplevel; + +import com.intellij.psi.PsiFile; +import com.intellij.util.ProcessingContext; +import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor; +import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; + +/** + * @author peter + */ +public class ScriptTypeFilter implements ContextFilter { + private final String myScriptType; + + public ScriptTypeFilter(String scriptType) { + myScriptType = scriptType; + } + + public boolean isApplicable(GroovyClassDescriptor descriptor, ProcessingContext ctx) { + PsiFile file = descriptor.getPlaceFile(); + if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) { + return myScriptType.contains(GroovyScriptTypeDetector.getScriptType((GroovyFile)file).getId()); + } + return false; + } + +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy index d8bd3e6b71b6..54fab61016b2 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy @@ -137,4 +137,17 @@ contributor([:]){category 'MyCategory'}"""); myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + "_after.groovy") } + + public void testPathRegexp() { + final PsiFile file = myFixture.addFileToProject("a.gdsl", "contributor(pathRegexp: '.*aaa.*') { property name:'fffooo', type:'int' }"); + GroovyDslFileIndex.activateUntilModification(file.virtualFile) + + myFixture.configureFromExistingVirtualFile myFixture.addFileToProject("aaa/foo.groovy", "fffx").virtualFile + myFixture.completeBasic() + assertOrderedEquals myFixture.lookupElementStrings, 'fffooo' + + myFixture.configureFromExistingVirtualFile myFixture.addFileToProject("bbb/foo.groovy", "fffx").virtualFile + myFixture.completeBasic() + assertEmpty myFixture.lookupElementStrings + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java index ef110ef1f51f..f3c255df5e53 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java @@ -223,11 +223,13 @@ public class RepositoryBrowserDialog extends DialogWrapper { public JComponent createCenterPanel() { JPanel parentPanel = new JPanel(new BorderLayout()); - JPanel top = new JPanel(new BorderLayout()); + JPanel top = new JPanel(); + final BoxLayout layout = new BoxLayout(top, BoxLayout.X_AXIS); + top.setLayout(layout); myRepositoriesLabel = new JLabel(myRepositoriesLabelText); - top.add(myRepositoriesLabel, BorderLayout.WEST); - top.add(createToolbar(true, null), BorderLayout.EAST); + top.add(myRepositoriesLabel); + top.add(createToolbar(true, null)); parentPanel.add(top, BorderLayout.NORTH); JComponent panel = createBrowserComponent(false); @@ -305,6 +307,7 @@ public class RepositoryBrowserDialog extends DialogWrapper { protected RepositoryBrowserComponent getRepositoryBrowser() { if (myRepositoryBrowser == null) { myRepositoryBrowser = new RepositoryBrowserComponent(SvnVcs.getInstance(myProject)); + myRepositoryBrowser.setPreferredSize(new Dimension(300, 300)); } return myRepositoryBrowser; } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index 11be9e716651..cc4f83d992e7 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -43,11 +43,11 @@ import java.util.regex.Pattern; */ public class TestProxy extends AbstractTestProxy { @NonNls public static final Pattern COMPARISION_PATTERN = - Pattern.compile("([^\\<\\>]*)expected[^\\<\\>]*\\<([^\\<\\>]*)\\>[^\\<\\>]*\\<([^\\<\\>]*)\\>[^\\<\\>]*"); + Pattern.compile("(.*)expected same with:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL); @NonNls public static final Pattern EXPECTED_BUT_WAS_PATTERN = Pattern.compile("(.*)expected:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL); @NonNls public static final Pattern EXPECTED_NOT_SAME_BUT_WAS_PATTERN = - Pattern.compile("(.*)expected not same with:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL); + Pattern.compile("(.*)expected not same with:\\<(.*)\\> but was same:\\<(.*)\\>.*", Pattern.DOTALL); private final List results = new ArrayList(); private TestResultMessage resultMessage; private String name; diff --git a/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java b/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java index 5be551653479..dc6dafe87453 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java @@ -115,9 +115,12 @@ public class ExtendedTagInsertHandler extends XmlTagInsertHandler { } protected boolean isNamespaceBound(PsiElement psiElement) { - final XmlTag tag = (XmlTag)psiElement.getParent(); + PsiElement parent = psiElement.getParent(); + if (!(parent instanceof XmlTag)) return false; + final XmlTag tag = (XmlTag)parent; final XmlElementDescriptor tagDescriptor = tag.getDescriptor(); final String tagNamespace = tag.getNamespace(); + assert myNamespace != null; return tagDescriptor != null && !(tagDescriptor instanceof AnyXmlElementDescriptor) && myNamespace.equals(tagNamespace); } diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java index b2f7936299eb..6781c1c22dd1 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java @@ -43,6 +43,7 @@ public class XmlSmartCompletionProvider { final XmlTag tag = (XmlTag)element.getParent(); final XmlTag parentTag = tag.getParentTag(); + if (parentTag == null) return; final XmlContentDFA dfa = XmlContentDFA.getContentDFA(parentTag); if (dfa == null) return; ApplicationManager.getApplication().runReadAction(new Runnable() { diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java index 448ce5214f3c..cf49e5ae339c 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java @@ -32,7 +32,7 @@ public abstract class XmlContentDFA { public abstract void transition(XmlTag xmlTag); @Nullable - public static XmlContentDFA getContentDFA(XmlTag parentTag) { + public static XmlContentDFA getContentDFA(@NotNull XmlTag parentTag) { XmlContentDFA contentDFA = XsContentDFA.createContentDFA(parentTag); if (contentDFA != null) return contentDFA; return XmlContentDFAImpl.createContentDFA(parentTag); diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java index 8fc66ab1361d..11fefd140226 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java @@ -63,7 +63,7 @@ class XsContentDFA extends XmlContentDFA { private final XmlElementDescriptor[] myElementDescriptors; @Nullable - public static XmlContentDFA createContentDFA(XmlTag parentTag) { + public static XmlContentDFA createContentDFA(@NotNull XmlTag parentTag) { final PsiFile file = parentTag.getContainingFile().getOriginalFile(); if (!(file instanceof XmlFile)) return null; XSModel xsModel = ApplicationManager.getApplication().runReadAction(new NullableComputable() { diff --git a/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java b/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java index 303015b731ed..6bfddfd9f708 100644 --- a/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java +++ b/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java @@ -141,7 +141,7 @@ public class GenerateXmlTagAction extends SimpleCodeInsightAction { } @Nullable - private static XmlTag getAnchor(XmlTag contextTag, Editor editor, XmlElementDescriptor selected) { + private static XmlTag getAnchor(@NotNull XmlTag contextTag, Editor editor, XmlElementDescriptor selected) { XmlContentDFA contentDFA = XmlContentDFA.getContentDFA(contextTag); int offset = editor.getCaretModel().getOffset(); if (contentDFA == null) { diff --git a/xml/impl/src/com/intellij/xml/index/XmlIndex.java b/xml/impl/src/com/intellij/xml/index/XmlIndex.java index 6482bdd920fa..d466188c5ca0 100644 --- a/xml/impl/src/com/intellij/xml/index/XmlIndex.java +++ b/xml/impl/src/com/intellij/xml/index/XmlIndex.java @@ -60,8 +60,7 @@ public abstract class XmlIndex extends FileBasedIndexExtension { @Override public boolean contains(VirtualFile file) { final VirtualFile parent = file.getParent(); - assert parent != null; - return parent.getName().equals("standardSchemas") || projectScope.contains(file); + return parent != null && (parent.getName().equals("standardSchemas") || projectScope.contains(file)); } @Override diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index dd87449badc8..54c573491f95 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -1282,7 +1282,7 @@ public class XmlUtil { final char ch = unquotedValue.charAt(i); if (!Character.isJavaIdentifierPart(ch) && ch != ':' && ch != '-') { final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class); - if (file != null) return !tagFromTemplateFramework(file.getDocument().getRootTag()); + if (file != null) return !tagFromTemplateFramework(file.getRootTag()); return false; } } diff --git a/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java b/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java index 298b8dd3fb61..f1ce3969dfc2 100644 --- a/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java +++ b/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java @@ -43,7 +43,7 @@ public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider { } public boolean isSuppressedFor(PsiElement element, String inspectionId) { - final XmlTag tag = PsiTreeUtil.getContextOfType(element, XmlTag.class, false); + final XmlTag tag = element instanceof XmlFile ? ((XmlFile)element).getRootTag() : PsiTreeUtil.getContextOfType(element, XmlTag.class, false); return tag != null && findSuppression(tag, inspectionId, element) != null; }