Merge remote-tracking branch 'origin/master'

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