Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Dmitry Jemerov
2010-11-23 21:18:11 +03:00
113 changed files with 1062 additions and 460 deletions
@@ -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<SourceState, OutputState> data = cache.getState(targetId, key);
SourceState sourceState = data != null ? data.mySourceState : null;
final OutputState outputState = data != null ? data.myOutputState : null;
@@ -34,4 +34,8 @@ public abstract class CompileItem<Key, SourceState, OutputState> {
@NotNull
public abstract OutputState computeOutputState();
public boolean isExcluded() {
return false;
}
}
@@ -38,6 +38,10 @@ public class DisableGC implements Evaluator{
return result;
}
public Evaluator getDelegate() {
return myDelegate;
}
public Modifier getModifier() {
return myDelegate.getModifier();
}
@@ -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);
@@ -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);
}
}
});
}
@@ -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;
@@ -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<T extends PsiElement & PsiReference> implements HintAction {
public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> implements HintAction, HighPriorityAction {
private final T myRef;
protected ImportClassFixBase(T ref) {
@@ -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();
@@ -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();
@@ -170,7 +170,7 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{
Collection<CommonProblemDescriptor> 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();
}
@@ -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<String> targetList = new ArrayList<String>();
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) {
@@ -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<PsiDirectory> result = new ArrayList<PsiDirectory>();
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));
}
@@ -115,4 +115,11 @@ class AnchorElementInfo implements SmartPointerElementInfo {
return null;
}
}
@Override
public void dispose() {
if (myMarker != null) {
myMarker.dispose();
}
}
}
@@ -43,6 +43,10 @@ public class ImplicitVariableElementInfoFactory implements SmartPointerElementIn
return null;
}
@Override
public void dispose() {
}
@Nullable
public Document getDocumentToSynchronize() {
return null;
@@ -42,6 +42,10 @@ public class ImportListElementInfoFactory implements SmartPointerElementInfoFact
return myFile.getImportList();
}
@Override
public void dispose() {
}
public Document getDocumentToSynchronize() {
return null;
}
@@ -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;
}
@@ -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);
@@ -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) {
@@ -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) {
@@ -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);
@@ -174,8 +174,7 @@ public class ProblemsHolder {
@Nullable
public ProblemDescriptor[] getResultsArray() {
final List<ProblemDescriptor> problems = myProblems;
myProblems = null;
final List<ProblemDescriptor> problems = getResults();
return problems == null ? null : problems.toArray(new ProblemDescriptor[problems.size()]);
}
@@ -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 extends PsiElement> T findParentOfType (PsiFile file, int offset, Class<T> parentClass) {
public static @Nullable <T extends PsiElement> T findParentOfType (PsiFile file, int offset, Class<T> 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) {
@@ -74,6 +74,14 @@ public class VirtualFilePattern extends TreeElementPattern<VirtualFile, VirtualF
});
}
public VirtualFilePattern withPath(final ElementPattern<String> pathPattern) {
return with(new PatternCondition<VirtualFile>("withName") {
public boolean accepts(@NotNull final VirtualFile virtualFile, final ProcessingContext context) {
return pathPattern.accepts(virtualFile.getPath(), context);
}
});
}
public VirtualFilePattern xmlWithRootTag(final ElementPattern<String> tagNamePattern) {
return with(new PatternCondition<VirtualFile>("xmlWithRootTag") {
public boolean accepts(@NotNull final VirtualFile virtualFile, final ProcessingContext context) {
@@ -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<TextEditorHighlightingPass> 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);
}
@@ -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 {
@@ -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;
@@ -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<LocalInspectionTool> 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<LocalInspectionTool> tools = DumbService.getInstance(myProject).filterByDumbAwareness(getInspectionTools(profile));
inspect(tools, iManager, true, true, true, progress);
}
finally {
disposeDescriptors();
}
}
private void disposeDescriptors() {
for (List<InspectionResult> list : result.values()) {
for (InspectionResult inspectionResult : list) {
for (ProblemDescriptor pd: inspectionResult.foundProblems) {
((ProblemDescriptorImpl)pd).dispose();
}
}
}
result.clear();
}
public void doInspectInBatch(final InspectionManagerEx iManager, List<InspectionProfileEntry> toolWrappers, boolean ignoreSuppressed) {
@@ -202,8 +218,26 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
final LocalInspectionToolSession session = new LocalInspectionToolSession(myFile, myStartOffset, myEndOffset);
List<Trinity<LocalInspectionTool, ProblemsHolder, PsiElementVisitor>> init = new ArrayList<Trinity<LocalInspectionTool, ProblemsHolder, PsiElementVisitor>>();
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<LocalInspectionTool, ProblemsHolder, PsiElementVisitor> trinity : init) {
List<ProblemDescriptor> 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<TextRange> emptyActionRegistered) {
private static void registerQuickFixes(final LocalInspectionTool tool,
final ProblemDescriptor descriptor,
final HighlightInfo highlightInfo,
final Set<TextRange> 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());
@@ -209,6 +209,7 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass {
if (place != null) {
List<IntentionAction> enableDisableIntentionAction = new ArrayList<IntentionAction>();
enableDisableIntentionAction.add(new IntentionHintComponent.EnableDisableIntentionAction(action));
enableDisableIntentionAction.add(new IntentionHintComponent.EditIntentionSettingsAction(action));
intentions.intentionsToShow.add(new HighlightInfo.IntentionActionDescriptor(action, enableDisableIntentionAction, null));
}
}
@@ -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);
}
});
}
@@ -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<FoldRegion, SmartPsiElementPointer<?>> myFoldRegionToSmartPointerMap
= new THashMap<FoldRegion, SmartPsiElementPointer<?>>();
@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);
}
@@ -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;
}
}
}
@@ -103,4 +103,7 @@ public class IntentionSettingsConfigurable extends BaseConfigurable implements S
return HELP_ID;
}
public void selectIntention(String familyName) {
myPanel.selectIntention(familyName);
}
}
@@ -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<Set<String>> keySetList, final HashSet<String> quoted) {
if (StringUtil.containsIgnoreCase(metaData.getFamily(), filter)) {
@@ -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<IntentionActionMetaData> sort(final List<IntentionActionMetaData> intentionsToShow) {
List<IntentionActionMetaData> copy = new ArrayList<IntentionActionMetaData>(intentionsToShow);
Collections.sort(copy, new Comparator<IntentionActionMetaData>() {
@@ -244,6 +252,28 @@ public abstract class IntentionSettingsTree {
return found.get();
}
private static CheckedTreeNode findChildRecursively(CheckedTreeNode node, final String name) {
final Ref<CheckedTreeNode> found = new Ref<CheckedTreeNode>();
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;
@@ -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<InspectionProfileEntry> toolsInGroup = myGroupNames.get(groupName);
@@ -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
@@ -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");
@@ -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());
}
}
}
@@ -196,4 +196,8 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti
}
return super.getSuppressActions();
}
public boolean isUnfair() {
return myTool instanceof UnfairLocalInspectionTool;
}
}
@@ -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();
}
}
@@ -152,6 +152,7 @@ public class SuppressActionWrapper extends ActionGroup {
for (GlobalInspectionContextImpl context : globalInspectionContexts) {
context.refreshViews();
}
CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject);
}
}, getTemplatePresentation().getText(), null);
}
@@ -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) {
@@ -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);
@@ -91,18 +91,27 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings<ScriptingL
}
@Override
@Nullable
public ScriptingLibraryTable.LibraryModel chosenToStored(VirtualFile file, ScriptingLibraryTable.LibraryModel value) {
if (value instanceof CompoundLibrary) return value;
CompoundLibrary compoundLib = file == null ? myProjectLibs : myCompoundLibMap.get(file);
if (compoundLib == null) {
compoundLib = new CompoundLibrary();
myCompoundLibMap.put(file, compoundLib);
}
if (value == null) {
compoundLib.clearLibraries();
if (compoundLib != null) {
compoundLib.clearLibraries();
myCompoundLibMap.remove(file);
compoundLib = null;
}
}
else {
if (compoundLib == null) {
compoundLib = new CompoundLibrary();
myCompoundLibMap.put(file, compoundLib);
}
compoundLib.toggleLibrary(value);
if (compoundLib.isEmpty()) {
myCompoundLibMap.remove(file);
compoundLib = null;
}
}
return compoundLib;
}
@@ -47,7 +47,7 @@
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Attach..."/>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.attach"/>
</properties>
</component>
<scrollpane id="2fb19" class="com.intellij.ui.components.JBScrollPane">
@@ -76,19 +76,11 @@
</constraints>
</vspacer>
<component id="1dade" class="javax.swing.JButton" binding="myRemoveFileButton">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Detach"/>
</properties>
</component>
<component id="ec28f" class="javax.swing.JButton" binding="myAttachFromButton">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Attach From..."/>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.detach"/>
</properties>
</component>
</children>
@@ -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<rv> 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<rv> 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<rv> Move to resources
case FILE_TYPE_COL: //TODO<rv> 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<rv> Move to resources
Messages.showErrorDialog(myProject, IdeBundle.message("scripting.lib.invalid.name"), "Error");
return;
}
super.doOKAction();
@@ -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<S
public ScriptingContextsConfigurable(final Project project, final ScriptingLibraryMappings mappings) {
super(project, ScriptingLibraryTable.LibraryModel.class, mappings,
"Specify which libraries are used in specific files and/or directories.", "Library",
"Override library settings for child directories and files?", "Override Library Settings");
IdeBundle.message("scripting.lib.usageScope.caption"),
IdeBundle.message("scripting.lib.usageScope.tableTitle"),
IdeBundle.message("scripting.lib.usageScope.override.question"),
IdeBundle.message("scripting.lib.usageScope.override.title"));
myScriptingLibraryMappings = mappings;
}
@@ -57,7 +60,7 @@ public class ScriptingContextsConfigurable extends LanguagePerFileConfigurable<S
@Nls
@Override
public String getDisplayName() {
return "Usage Scope";
return IdeBundle.message("scripting.lib.usageScope");
}
@Override
@@ -34,7 +34,7 @@
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Add..."/>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.add"/>
</properties>
</component>
<component id="ae881" class="javax.swing.JButton" binding="myRemoveLibraryButton">
@@ -42,7 +42,7 @@
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Remove"/>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.remove"/>
</properties>
</component>
<component id="7d17d" class="javax.swing.JButton" binding="myEditLibraryButton">
@@ -50,7 +50,7 @@
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Edit..."/>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.edit"/>
</properties>
</component>
<vspacer id="dea58">
@@ -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()) {
@@ -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();
}
}
}
@@ -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);
@@ -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() {
}
}
@@ -110,4 +110,8 @@ public class LazyPointerImpl<E extends PsiElement> implements SmartPointerEx<E>
return null;
}
@Override
public void dispose() {
if (myPointer != null) ((SmartPointerEx)myPointer).dispose();
}
}
@@ -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;
@@ -28,4 +28,6 @@ interface SmartPointerElementInfo {
@Nullable
PsiElement restoreElement();
void dispose();
}
@@ -21,4 +21,5 @@ import com.intellij.psi.SmartPsiElementPointer;
public interface SmartPointerEx<E extends PsiElement> extends SmartPsiElementPointer<E> {
void fastenBelt();
void documentAndPsiInSync();
void dispose();
}
@@ -149,6 +149,15 @@ class SmartPsiElementPointerImpl<E extends PsiElement> 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<E extends PsiElement> implements SmartPointerEx
myElementInfo = createElementInfo();
}
}
}
@@ -262,7 +262,8 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
private void switchFromStubToAST(ASTNode root, final Iterator<StubElement<?>> 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();
@@ -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) {
@@ -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<PsiReference> allReferences =
settings.isOnlyOneReferenceToInline() ? Collections.singleton(invocationReference) : ReferencesSearch.search(element).findAll();
final Collection<PsiReference> allReferences;
if (settings.isOnlyOneReferenceToInline()) {
allReferences = Collections.singleton(invocationReference);
} else {
final Ref<Collection<PsiReference>> usagesRef = new Ref<Collection<PsiReference>>();
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<Language, InlineHandler.Inliner> inliners = new HashMap<Language, InlineHandler.Inliner>();
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
@@ -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();
@@ -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<String, StringPattern> {
private static final Logger LOG = Logger.getInstance("#com.intellij.patterns.StringPattern");
private static final InitialPatternCondition<String> CONDITION = new InitialPatternCondition<String>(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<String, StringPattern> {
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<String>("neverMatches") {
@Override
public boolean accepts(@NotNull String s, ProcessingContext context) {
return false;
}
});
}
return with(new ValuePatternCondition<String>("matches") {
public boolean accepts(@NotNull final String str, final ProcessingContext context) {
@@ -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) {
@@ -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++) {
@@ -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<? extends SoftWrap> 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();
@@ -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<DocumentListener> myDocumentListeners = new ArrayList<DocumentListener>();
private final List<FoldingListener> myFoldListeners = new ArrayList<FoldingListener>();
@@ -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
* <p/>
* 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 <code>'soft wraps aware'</code> and
* <code>'soft wraps unaware'</code> modes.
*/
private interface SoftWrapAwareMappingTask {
private interface SoftWrapAwareTask {
/**
* Asks current task to perform the mapping.
* Asks current task to do the job.
* <p/>
* 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";
}
}
}
@@ -65,7 +65,6 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
private final List<SoftWrapAwareDocumentParsingListener> myListeners = new ArrayList<SoftWrapAwareDocumentParsingListener>();
private final List<IncrementalCacheUpdateEvent> myCacheUpdateEvents = new ArrayList<IncrementalCacheUpdateEvent>();
private final List<SoftWrapApplianceStrategy> myApplianceStrategies = new ArrayList<SoftWrapApplianceStrategy>();
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<IncrementalCacheUpdateEvent> events = new ArrayList<IncrementalCacheUpdateEvent>(myCacheUpdateEvents);
@@ -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();
@@ -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);
}
@@ -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 {
@@ -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
@@ -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<Module> 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);
}
@@ -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) {
@@ -17,6 +17,7 @@ package com.intellij.openapi.progress;
public class ProcessCanceledException extends RuntimeException {
public ProcessCanceledException() {
int i = 0;
}
public ProcessCanceledException(Throwable cause) {
@@ -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;
}
}
@@ -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<File> processor) {
final LinkedList<File> queue = new LinkedList<File>();
queue.add(root);
@@ -782,7 +782,7 @@ public class ContainerUtil {
@NotNull
public static <T, V> List<V> map(@NotNull T[] arr, @NotNull Function<T, V> mapping) {
List<V> result = new ArrayList<V>();
List<V> result = new ArrayList<V>(arr.length);
for (T t : arr) {
result.add(mapping.fun(t));
}
@@ -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<Key, Value> extends PersistentEnumerator<Key>{
private static class AppendStream extends DataOutputStream {
private AppendStream() {
super(new ByteArrayOutputStream());
super(new BufferExposingByteArrayOutputStream());
}
public int getBufferSize() {
@@ -73,6 +75,11 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumerator<Key>{
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<AppendStream> myStreamPool = new LimitedPool<AppendStream>(10, new LimitedPool.ObjectFactory<AppendStream>() {
@@ -96,9 +103,9 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumerator<Key>{
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<Key, Value> extends PersistentEnumerator<Key>{
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<Key, Value> extends PersistentEnumerator<Key>{
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<Key, Value> extends PersistentEnumerator<Key>{
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;
@@ -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<DataOutputStream> 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;
@@ -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()));
}
}
}
@@ -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) {
@@ -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);
}
}
@@ -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;
}
@@ -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<K,V> 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<KeyWrapper<K>, 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 {
@@ -96,7 +96,7 @@ public class PatchApplier<BinaryType extends FilePatch> {
final ApplyPatchStatus patchStatus = nonWriteActionPreCheck();
if (ApplyPatchStatus.FAILURE.equals(patchStatus)) return patchStatus;
final ApplyPatchStatus applyStatus = ApplicationManager.getApplication().runWriteAction(new Computable<ApplyPatchStatus>() {
final ApplyPatchStatus applyStatus = ApplicationManager.getApplication().runReadAction(new Computable<ApplyPatchStatus>() {
public ApplyPatchStatus compute() {
final Ref<ApplyPatchStatus> refStatus = new Ref<ApplyPatchStatus>(ApplyPatchStatus.FAILURE);
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@@ -172,21 +172,28 @@ public class PatchApplier<BinaryType extends FilePatch> {
}
protected ApplyPatchStatus executeWritable() {
return ApplicationManager.getApplication().runWriteAction(new Computable<ApplyPatchStatus>() {
final Application application = ApplicationManager.getApplication();
return application.runReadAction(new Computable<ApplyPatchStatus>() {
public ApplyPatchStatus compute() {
final Ref<ApplyPatchStatus> refStatus = new Ref<ApplyPatchStatus>(ApplyPatchStatus.FAILURE);
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
if (! myVerifier.execute()) {
final Boolean result = application.runWriteAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
return myVerifier.execute();
}
});
if (! result) {
return;
}
if (! makeWritable(myVerifier.getWritableFiles())) {
if (!makeWritable(myVerifier.getWritableFiles())) {
return;
}
final List<Pair<VirtualFile, ApplyTextFilePatch>> textPatches = myVerifier.getTextPatches();
if (! fileTypesAreOk(textPatches)) {
if (!fileTypesAreOk(textPatches)) {
return;
}
@@ -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<BinaryType extends FilePatch> {
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];
}
}
}
@@ -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();
}
}
@@ -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<T extends FilePatch> ApplyPatchStatus applyOnly(final Project project, final ApplyFilePatchBase<T> patch, final ApplyPatchContext context, final VirtualFile file) {
public static<T extends FilePatch> ApplyPatchStatus applyOnly(final Project project, final ApplyFilePatchBase<T> 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<ApplyPatchStatus>() {
@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<ApplyPatchStatus>() {
@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;
@@ -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());
@@ -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);
@@ -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<ProcessHandler, XDebugSessionData> mySessionData;
private final Map<ProcessHandler, XDebugSessionTab> mySessionTabs;
private final List<XDebugSessionImpl> mySessions;
private final Map<ProcessHandler, XDebugSessionImpl> 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<ProcessHandler, XDebugSessionData>();
mySessions = new ArrayList<XDebugSessionImpl>();
mySessions = new LinkedHashMap<ProcessHandler, XDebugSessionImpl>();
myExecutionPointHighlighter = new ExecutionPointHighlighter(project);
mySessionTabs = new HashMap<ProcessHandler, XDebugSessionTab>();
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<XDebugSessionImpl> sessions = mySessions.values();
return sessions.toArray(new XDebugSessionImpl[sessions.size()]);
}
@Override
@@ -220,7 +226,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom
@Override
public <T extends XDebugProcess> Collection<? extends T> getDebugProcesses(Class<T> processClass) {
final List<T> list = new ArrayList<T>();
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() {
@@ -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<String>() {
@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
@@ -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();
+2 -1
View File
@@ -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;
@@ -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;
}
@@ -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<GitBranch> allBranches = new ArrayList<GitBranch>();
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;
}
@@ -34,6 +34,14 @@ public class SymbolicRefs {
myRemoteBranches = new TreeSet<String>();
}
public void addRemote(final String branch) {
myRemoteBranches.add(branch);
}
public void addLocal(final String branch) {
myLocalBranches.add(branch);
}
public void addTags(final Collection<String> value) {
myTags.addAll(value);
}
@@ -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);
@@ -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"
@@ -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<GrImportStatement> 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);
}
}

Some files were not shown because too many files have changed in this diff Show More