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

This commit is contained in:
Dmitry Avdeev
2010-10-07 11:20:41 +04:00
41 changed files with 712 additions and 622 deletions
@@ -550,6 +550,9 @@ public class CompilerTask extends Task.Backgroundable {
public boolean canCloseProject(final Project project) {
assert project != null;
if (!project.equals(myProject)) {
return true;
}
if (shouldAskUser()) {
int result = Messages.showOkCancelDialog(
myProject,
@@ -627,13 +630,15 @@ public class CompilerTask extends Task.Backgroundable {
}
public void projectClosed(Project project) {
if (myContent != null) {
if (project.equals(myProject) && myContent != null) {
myContentManager.removeContent(myContent, true);
}
}
public void projectClosing(Project project) {
myIsApplicationExitingOrProjectClosing = true;
if (project.equals(myProject)) {
myIsApplicationExitingOrProjectClosing = true;
}
}
}
}
@@ -143,10 +143,14 @@ public class ExportDialog extends DialogWrapper {
}
public static String getExportThreadsText(VirtualMachineProxyImpl vmProxy) {
StringBuffer buffer = new StringBuffer(512);
final StringBuffer buffer = new StringBuffer(512);
List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads();
for (ThreadReference threadReference : threads) {
buffer.append(threadName(threadReference));
final String name = threadName(threadReference);
if (name == null) {
continue;
}
buffer.append(name);
ReferenceType referenceType = threadReference.referenceType();
if (referenceType != null) {
//noinspection HardCodedStringLiteral
@@ -181,7 +185,10 @@ public class ExportDialog extends DialogWrapper {
for (ObjectReference reference : list) {
final List<ThreadReference> waiting = reference.waitingThreads();
for (ThreadReference thread : waiting) {
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.blocks.thread", threadName(thread)));
final String waitingThreadName = threadName(thread);
if (waitingThreadName != null) {
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.blocks.thread", waitingThreadName));
}
}
}
}
@@ -191,8 +198,10 @@ public class ExportDialog extends DialogWrapper {
if (vmProxy.canGetMonitorInfo()) {
ThreadReference waitedThread = waitedMonitor.owningThread();
if (waitedThread != null) {
buffer.append("\n\t ")
.append(DebuggerBundle.message("threads.export.attribute.label.waiting.for.thread", threadName(waitedThread)));
final String waitedThreadName = threadName(waitedThread);
if (waitedThreadName != null) {
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.waiting.for.thread", waitedThreadName));
}
}
}
}
@@ -228,7 +237,12 @@ public class ExportDialog extends DialogWrapper {
}
private static String threadName(ThreadReference threadReference) {
return threadReference.name() + "@" + threadReference.uniqueID();
try {
return threadReference.name() + "@" + threadReference.uniqueID();
}
catch (ObjectCollectedException e) {
return null;
}
}
private class CopyToClipboardAction extends AbstractAction {
@@ -1,41 +0,0 @@
/*
* Copyright 2000-2009 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.completion;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.editor.Editor;
/**
*
*/
public class JavadocAutoLookupHandler extends CodeCompletionHandlerBase {
public JavadocAutoLookupHandler() {
super(CompletionType.BASIC, false, false);
}
protected void doComplete(final int offset1, final int offset2, final CompletionContext context, final FileCopyPatcher dummyIdentifier,
final Editor editor, final int invocationCount) {
PsiFile file = context.file;
int offset = context.getStartOffset();
PsiElement lastElement = file.findElementAt(offset - 1);
if (lastElement == null || !StringUtil.endsWithChar(lastElement.getText(), '@')) return;
super.doComplete(offset1, offset2, context, dummyIdentifier, editor, invocationCount);
}
}
@@ -17,10 +17,6 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.JavadocAutoLookupHandler;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ScrollType;
@@ -30,6 +26,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.filters.ClassFilter;
@@ -39,7 +36,6 @@ import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiUtilBase;
import org.jetbrains.annotations.Nullable;
/**
@@ -54,13 +50,45 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
return Result.STOP;
}
if (charTyped == '#' || charTyped == '.') {
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new MemberAutoLookupCondition());
autoPopupMemberLookup(project, editor);
return Result.STOP;
}
return Result.CONTINUE;
}
private static void autoPopupMemberLookup(Project project, final Editor editor) {
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new Condition<PsiFile>() {
public boolean value(final PsiFile file) {
int offset = editor.getCaretModel().getOffset();
PsiElement lastElement = file.findElementAt(offset - 1);
if (lastElement == null) {
return false;
}
//do not show lookup when typing varargs ellipsis
final PsiElement prevSibling = lastElement.getPrevSibling();
if (prevSibling == null || ".".equals(prevSibling.getText())) return false;
PsiElement parent = prevSibling;
do {
parent = parent.getParent();
} while(parent instanceof PsiJavaCodeReferenceElement || parent instanceof PsiTypeElement);
if (parent instanceof PsiParameterList) return false;
if (!".".equals(lastElement.getText()) && !"#".equals(lastElement.getText())) {
return false;
}
else{
final PsiElement element = file.findElementAt(offset);
return element == null ||
!"#".equals(lastElement.getText()) ||
new SuperParentFilter(new ClassFilter(PsiDocComment.class)).isAcceptable(element, element.getParent());
}
}
});
}
public Result beforeCharTyped(final char c, final Project project, final Editor editor, final PsiFile file, final FileType fileType) {
final FileType originalFileType = getOriginalFileType(file);
@@ -217,27 +245,15 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
}
private static void autoPopupJavadocLookup(final Project project, final Editor editor) {
if (ApplicationManager.getApplication().isUnitTestMode()) return;
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new Condition<PsiFile>() {
@Override
public boolean value(PsiFile file) {
int offset = editor.getCaretModel().getOffset();
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
if (settings.AUTO_POPUP_COMPLETION_LOOKUP) {
final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project);
if (file == null) return;
final Runnable request = new Runnable(){
public void run(){
PsiDocumentManager.getInstance(project).commitAllDocuments();
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
public void run(){
new JavadocAutoLookupHandler().invoke(project, editor, file);
}
},
"",
null, UndoConfirmationPolicy.DEFAULT, editor.getDocument()
);
}
};
AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, settings.AUTO_LOOKUP_DELAY);
}
PsiElement lastElement = file.findElementAt(offset - 1);
return lastElement != null && StringUtil.endsWithChar(lastElement.getText(), '@');
}
});
}
public static boolean isAfterClassLikeIdentifierOrDot(final int offset, final Editor editor) {
@@ -259,38 +275,4 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
return false;
}
private static class MemberAutoLookupCondition implements Condition<Editor> {
public boolean value(final Editor editor) {
final Project project = editor.getProject();
if (project == null) return false;
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
if (file == null) return false;
int offset = editor.getCaretModel().getOffset();
PsiElement lastElement = file.findElementAt(offset - 1);
if (lastElement == null) {
return false;
}
//do not show lookup when typing varargs ellipsis
final PsiElement prevSibling = lastElement.getPrevSibling();
if (prevSibling == null || ".".equals(prevSibling.getText())) return false;
PsiElement parent = prevSibling;
do {
parent = parent.getParent();
} while(parent instanceof PsiJavaCodeReferenceElement || parent instanceof PsiTypeElement);
if (parent instanceof PsiParameterList) return false;
if (!".".equals(lastElement.getText()) && !"#".equals(lastElement.getText())) {
return false;
}
else{
final PsiElement element = file.findElementAt(offset);
return element == null ||
!"#".equals(lastElement.getText()) ||
new SuperParentFilter(new ClassFilter(PsiDocComment.class)).isAcceptable(element, element.getParent());
}
}
}
}
@@ -185,6 +185,9 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myRole2 == ChildRole.ARGUMENT_LIST) {
createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES);
}
else if (myRole1 == ChildRole.LBRACKET || myRole2 == ChildRole.RBRACKET) {
createSpaceInCode(mySettings.SPACE_WITHIN_BRACKETS);
}
}
@Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
@@ -20,7 +20,6 @@ import com.intellij.pom.PomTarget;
import com.intellij.pom.PomTargetPsiElement;
import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiTarget;
import com.intellij.psi.targets.AliasingPsiTarget;
import com.intellij.psi.targets.AliasingPsiTargetMapper;
import org.jetbrains.annotations.Nullable;
@@ -31,15 +30,32 @@ public class RenameAliasingPomTargetProcessor extends RenamePsiElementProcessor
@Override
public boolean canProcessElement(@Nullable PsiElement element) {
return element instanceof PomTargetPsiElement;
return element instanceof PomTarget || element instanceof PomTargetPsiElement;
}
@Override
public void prepareRenaming(PsiElement element, String newName, Map<PsiElement, String> allRenames) {
PomTarget target = null;
if (element instanceof PomTargetPsiElement) {
target = ((PomTargetPsiElement)element).getTarget();
}
else if (element instanceof PomTarget) {
target = (PomTarget)element;
}
if (target != null) {
for (AliasingPsiTargetMapper mapper : Extensions.getExtensions(AliasingPsiTargetMapper.EP_NAME)) {
for (AliasingPsiTarget psiTarget : mapper.getTargets(((PomTargetPsiElement)element).getTarget())) {
allRenames.put(PomService.convertToPsi(psiTarget), psiTarget.getNameAlias(newName));
for (AliasingPsiTarget psiTarget : mapper.getTargets(target)) {
PsiElement psiElement = PomService.convertToPsi(psiTarget);
String name = psiTarget.getNameAlias(newName);
String definedName = allRenames.put(psiElement, name);
if (definedName != null) {
assert definedName.equals(name);
}
else {
prepareRenaming(psiElement, name, allRenames);
}
}
}
}
@@ -81,8 +81,16 @@ public class TestIntegrationUtils {
public static PsiClass findOuterClass(PsiElement element) {
PsiClass result = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
if (result == null) {
final PsiFile containingFile = element.getContainingFile();
if (containingFile instanceof PsiClassOwner){
final PsiClass[] classes = ((PsiClassOwner)containingFile).getClasses();
if (classes.length == 1) {
result = classes[0];
}
}
}
if (result == null) return null;
do {
PsiClass nextParent = PsiTreeUtil.getParentOfType(result, PsiClass.class, true);
if (nextParent == null) return result;
@@ -39,6 +39,7 @@ import com.intellij.testIntegration.TestFramework;
import com.intellij.testIntegration.TestIntegrationUtils;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -60,17 +61,18 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
PsiClass psiClass = getContainingClass(element);
assert psiClass != null;
PsiJavaToken leftBrace = psiClass.getLBrace();
if (leftBrace == null) return false;
if (element.getTextOffset() >= leftBrace.getTextOffset()) return false;
TextRange declarationRange = HighlightNamesUtil.getClassDeclarationTextRange(psiClass);
if (!declarationRange.contains(element.getTextRange())) return false;
//TextRange declarationRange = HighlightNamesUtil.getClassDeclarationTextRange(psiClass);
//if (!declarationRange.contains(element.getTextRange())) return false;
return true;
}
public boolean isAvailableForElement(PsiElement element) {
public static boolean isAvailableForElement(PsiElement element) {
if (element == null) return false;
PsiClass psiClass = getContainingClass(element);
@@ -91,7 +93,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
return true;
}
private boolean isUnderTestSources(PsiClass c) {
private static boolean isUnderTestSources(PsiClass c) {
ProjectRootManager rm = ProjectRootManager.getInstance(c.getProject());
VirtualFile f = c.getContainingFile().getVirtualFile();
if (f == null) return false;
@@ -144,7 +146,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
});
}
private void showErrorLater(final Project project, final String targetClassName) {
private static void showErrorLater(final Project project, final String targetClassName) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Messages.showErrorDialog(project,
@@ -154,7 +156,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
});
}
private void addSuperClass(PsiClass targetClass, Project project, String superClassName) throws IncorrectOperationException {
private static void addSuperClass(PsiClass targetClass, Project project, String superClassName) throws IncorrectOperationException {
if (superClassName == null) return;
PsiElementFactory ef = JavaPsiFacade.getInstance(project).getElementFactory();
@@ -170,12 +172,13 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
targetClass.getExtendsList().add(superClassRef);
}
private PsiClass findClass(Project project, String fqName) {
@Nullable
private static PsiClass findClass(Project project, String fqName) {
GlobalSearchScope scope = GlobalSearchScope.allScope(project);
return JavaPsiFacade.getInstance(project).findClass(fqName, scope);
}
private void addTestMethods(Editor editor,
private static void addTestMethods(Editor editor,
PsiClass targetClass,
TestFramework descriptor,
Collection<MemberInfo> methods,
@@ -192,14 +195,25 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
}
}
private void generateMethod(TestIntegrationUtils.MethodKind methodKind, TestFramework descriptor, PsiClass targetClass, Editor editor, String name) {
private static void generateMethod(TestIntegrationUtils.MethodKind methodKind, TestFramework descriptor, PsiClass targetClass, Editor editor, String name) {
PsiMethod method = (PsiMethod)targetClass.add(TestIntegrationUtils.createDummyMethod(targetClass.getProject()));
PsiDocumentManager.getInstance(targetClass.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument());
TestIntegrationUtils.runTestMethodTemplate(methodKind, descriptor, editor, targetClass, method, name, true);
}
private PsiClass getContainingClass(PsiElement element) {
return PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
@Nullable
private static PsiClass getContainingClass(PsiElement element) {
final PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
if (psiClass == null) {
final PsiFile containingFile = element.getContainingFile();
if (containingFile instanceof PsiClassOwner){
final PsiClass[] classes = ((PsiClassOwner)containingFile).getClasses();
if (classes.length == 1) {
return classes[0];
}
}
}
return psiClass;
}
public boolean startInWriteAction() {
@@ -3,10 +3,12 @@
*/
package com.intellij.psi;
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
@@ -16,10 +18,10 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.PsiTestCase;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.indexing.StorageException;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class PsiConcurrencyStressTest extends PsiTestCase {
@@ -47,9 +49,10 @@ public class PsiConcurrencyStressTest extends PsiTestCase {
}
private PsiJavaFile myFile;
private volatile boolean writeActionInProgress;
public void testStress() throws Exception {
int numOfThreads = 10;
final int readIterations = 50000;
final int readIterations = 100;
final int writeIterations = 30;
synchronized (this) {
@@ -71,12 +74,8 @@ public class PsiConcurrencyStressTest extends PsiTestCase {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
try {
readStep(random);
}
catch (StorageException e) {
LOG.error(e);
}
assertFalse(writeActionInProgress);
readStep(random);
}
});
}
@@ -93,15 +92,17 @@ public class PsiConcurrencyStressTest extends PsiTestCase {
new WriteCommandAction(myProject, myFile) {
@Override
protected void run(final Result result) throws Throwable {
writeActionInProgress = true;
documentManager.commitAllDocuments();
writeStep(random);
documentManager.commitAllDocuments();
assertEquals(document.getText(), myFile.getText());
writeActionInProgress = false;
}
}.execute();
}
reads.await();
reads.await(5, TimeUnit.MINUTES);
}
private static void mark(final String s) {
@@ -132,62 +133,46 @@ public class PsiConcurrencyStressTest extends PsiTestCase {
}
}
private void readStep(final Random random) throws StorageException {
private void readStep(final Random random) {
PsiClass aClass = getPsiClass();
switch (random.nextInt(5)) {
case 0 :
switch (random.nextInt(4)) {
case 0:
mark("v");
aClass.getContainingFile().accept(new PsiRecursiveElementVisitor() {}); break;
aClass.getContainingFile().accept(new PsiRecursiveElementVisitor() {
});
break;
case 1 :
case 1:
mark("m");
aClass.getMethods();
for (int offset=0; offset<myFile.getTextLength();offset++) {
myFile.findElementAt(offset);
}
break;
//case 2 : {
// mark("h");
// psiFile.accept(new PsiRecursiveElementVisitor() {
// @Override public void visitElement(final PsiElement element) {
// super.visitElement(element);
//
// final HighlightInfoHolder infoHolder = new HighlightInfoHolder(psiFile, HighlightInfoFilter.EMPTY_ARRAY);
// infoHolder.setWritable(true);
// new HighlightVisitorImpl(getPsiManager()).visit(element, infoHolder);
// }
// });
// break;
//}
case 2:
mark("h");
aClass.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(final PsiElement element) {
super.visitElement(element);
case 3 :
final HighlightInfoHolder infoHolder = new HighlightInfoHolder(myFile, HighlightInfoFilter.EMPTY_ARRAY);
new HighlightVisitorImpl(getProject()).visit(element, infoHolder);
}
});
break;
case 3:
mark("u");
//FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID);
for (PsiMethod method : aClass.getMethods()) {
method.getName();
}
break;
case 4 :
mark("\n");
break;
}
}
@Override
protected void invokeTestRunnable(final Runnable runnable) throws Exception {
final Exception[] e = new Exception[1];
Runnable runnable1 = new Runnable() {
@Override
public void run() {
runnable.run();
}
};
if (myRunCommandForTest) {
CommandProcessor.getInstance().executeCommand(myProject, runnable1, "", null);
}
else {
runnable1.run();
}
if (e[0] != null) {
throw e[0];
}
runnable.run();
}
}
@@ -163,4 +163,15 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest {
" }\n" +
"}");
}
public void testSpaceWithArrayBrackets() throws Exception {
// Inspired by IDEA-58510
getSettings().SPACE_WITHIN_BRACKETS = true;
doMethodTest(
"int[] i = new int[1]\n" +
"i[0] = 1;",
"int[] i = new int[ 1 ]\n" +
"i[ 0 ] = 1;"
);
}
}
@@ -223,7 +223,7 @@ public class ClassloaderUtil {
final File libFolder = new File(aFolderPath + File.separator + "lib");
addLibraries(classPath, libFolder, selfRootUrl);
final File extLib = new File(new File(libFolder, "ext"), "lib");
final File extLib = new File(libFolder, "ext");
addLibraries(classPath, extLib, selfRootUrl);
final File antLib = new File(new File(libFolder, "ant"), "lib");
@@ -823,27 +823,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
public boolean equals(Object other) {
if (other instanceof TypeToNameMap) {
TypeToNameMap otherMap = (TypeToNameMap)other;
if (myPatterns.size() != otherMap.myPatterns.size()) {
return false;
}
if (myNames.size() != otherMap.myNames.size()) {
return false;
}
for (int i = 0; i < myPatterns.size(); i++) {
String s1 = myPatterns.get(i);
String s2 = otherMap.myPatterns.get(i);
if (!Comparing.equal(s1, s2)) {
return false;
}
}
for (int i = 0; i < myNames.size(); i++) {
String s1 = myNames.get(i);
String s2 = otherMap.myNames.get(i);
if (!Comparing.equal(s1, s2)) {
return false;
}
}
return true;
return myPatterns.equals(otherMap.myPatterns) && myNames.equals(otherMap.myNames);
}
return false;
}
@@ -858,13 +838,12 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
}
return code;
}
}
private void registerAdditionalIndentOptions(FileType fileType, IndentOptions options) {
boolean exist = false;
for (final FileType existing : myAdditionalIndentOptions.keySet()) {
if (existing.getDefaultExtension() == fileType.getDefaultExtension()) {
if (Comparing.strEqual(existing.getDefaultExtension(), fileType.getDefaultExtension())) {
exist = true;
break;
}
@@ -883,11 +862,13 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
}
private void loadAdditionalIndentOptions() {
myLoadedAdditionalIndentOptions = true;
final FileTypeIndentOptionsProvider[] providers = Extensions.getExtensions(FileTypeIndentOptionsProvider.EP_NAME);
for (final FileTypeIndentOptionsProvider provider : providers) {
if (!myAdditionalIndentOptions.containsKey(provider.getFileType())) {
registerAdditionalIndentOptions(provider.getFileType(), provider.createIndentOptions());
synchronized (myAdditionalIndentOptions) {
myLoadedAdditionalIndentOptions = true;
final FileTypeIndentOptionsProvider[] providers = Extensions.getExtensions(FileTypeIndentOptionsProvider.EP_NAME);
for (final FileTypeIndentOptionsProvider provider : providers) {
if (!myAdditionalIndentOptions.containsKey(provider.getFileType())) {
registerAdditionalIndentOptions(provider.getFileType(), provider.createIndentOptions());
}
}
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.FilteringIterator;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.*;
@@ -67,8 +68,9 @@ public class PathsList {
addAllLast(chooseFirstTimeItems(path), myPath);
}
public void remove(String path) {
public void remove(@NotNull String path) {
myPath.remove(path);
myPathTail.remove(path);
myPathSet.remove(path);
}
@@ -79,7 +79,7 @@ public class AutoPopupController implements Disposable {
}, this);
}
public void autoPopupMemberLookup(final Editor editor, @Nullable final Condition<Editor> condition){
public void autoPopupMemberLookup(final Editor editor, @Nullable final Condition<PsiFile> condition){
if (ApplicationManager.getApplication().isUnitTestMode()) return;
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
@@ -92,7 +92,9 @@ public class AutoPopupController implements Disposable {
if (editor.isDisposed()) return;
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
if (condition != null && !condition.value(editor)) return;
if (!file.isValid()) return;
if (condition != null && !condition.value(file)) return;
new CodeCompletionHandlerBase(CompletionType.BASIC, false, false).invoke(myProject, editor, file);
}
};
@@ -31,6 +31,11 @@ public class ComboEditorCompletionContributor extends CompletionContributor{
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
if (process != null && process.isAutopopupCompletion()) {
return;
}
final PsiFile file = parameters.getOriginalFile();
final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
if (document != null) {
@@ -42,6 +42,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ProgressWrapper;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Pair;
@@ -49,6 +50,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.profile.codeInspection.SeverityProvider;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.ConcurrencyUtil;
@@ -101,9 +103,9 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
else {
myShortcutText = "";
}
mySeverityRegistrar = SeverityRegistrar.getInstance(myProject);
InspectionProfileWrapper customProfile = file.getUserData(InspectionProfileWrapper.KEY);
myProfileWrapper = customProfile == null ? InspectionProjectProfileManager.getInstance(myProject).getProfileWrapper() : customProfile;
mySeverityRegistrar = ((SeverityProvider)myProfileWrapper.getInspectionProfile().getProfileManager()).getSeverityRegistrar();
// initial guess
setProgressLimit(300 * 2);
@@ -324,16 +326,17 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
return highlights;
}
private static HighlightInfo highlightInfoFromDescriptor(final ProblemDescriptor problemDescriptor,
final HighlightInfoType highlightInfoType,
final String message,
final String toolTip) {
private HighlightInfo highlightInfoFromDescriptor(final ProblemDescriptor problemDescriptor,
final HighlightInfoType highlightInfoType,
final String message,
final String toolTip) {
TextRange textRange = ((ProblemDescriptorImpl)problemDescriptor).getTextRange();
PsiElement element = problemDescriptor.getPsiElement();
boolean isFileLevel = element instanceof PsiFile && textRange.equals(element.getTextRange());
return new HighlightInfo(null, highlightInfoType, textRange.getStartOffset(), textRange.getEndOffset(), message, toolTip,
highlightInfoType.getSeverity(element), problemDescriptor.isAfterEndOfLine(), null, isFileLevel);
final HighlightSeverity severity = highlightInfoType.getSeverity(element);
return new HighlightInfo(mySeverityRegistrar.getTextAttributesBySeverity(severity), highlightInfoType, textRange.getStartOffset(), textRange.getEndOffset(), message, toolTip,
severity, problemDescriptor.isAfterEndOfLine(), null, isFileLevel);
}
private final AtomicBoolean haveInfosToProcess = new AtomicBoolean();
@@ -158,9 +158,15 @@ public class AutoHardWrapHandler {
}
final int[] wrapIntroducedSymbolsNumber = new int[1];
final int[] caretOffsetDiff = new int[1];
final int baseCaretOffset = caretModel.getOffset();
DocumentListener listener = new DocumentListener() {
@Override
public void beforeDocumentChange(DocumentEvent event) {
if (event.getOffset() <= baseCaretOffset + caretOffsetDiff[0]) {
caretOffsetDiff[0] += event.getNewLength() - event.getOldLength();
}
if (event.getNewLength() <= 0) {
// There is a possible case that document fragment is removed because of auto-formatting. We don't want to process such events.
return;
@@ -188,12 +194,7 @@ public class AutoHardWrapHandler {
change.change.setStart(wrapOffset);
change.change.setEnd(wrapOffset + wrapIntroducedSymbolsNumber[0]);
int newCaretOffset = caretOffset;
if (wrapOffset <= caretOffset && newCaretOffset + wrapIntroducedSymbolsNumber[0] < document.getTextLength()) {
newCaretOffset += wrapIntroducedSymbolsNumber[0];
}
newCaretOffset = Math.min(document.getLineEndOffset(line + 1), newCaretOffset);
caretModel.moveToOffset(newCaretOffset);
caretModel.moveToOffset(baseCaretOffset + caretOffsetDiff[0]);
}
private static class AutoWrapChange {
@@ -4,6 +4,7 @@ import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.util.Key;
import org.apache.commons.lang.text.StrBuilder;
import org.jetbrains.annotations.NotNull;
/**
@@ -13,6 +14,11 @@ public class OutputListener extends ProcessAdapter {
private final StringBuilder out;
private final StringBuilder err;
public OutputListener() {
out = new StringBuilder();
err = new StringBuilder();
}
public OutputListener(@NotNull final StringBuilder out, @NotNull final StringBuilder err) {
this.out = out;
this.err = err;
@@ -26,4 +32,8 @@ public class OutputListener extends ProcessAdapter {
err.append(event.getText());
}
}
public Output getOutput() {
return new Output(out.toString(), err.toString());
}
}
@@ -16,26 +16,17 @@
package com.intellij.ide.actions;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Trinity;
import com.intellij.psi.PsiElement;
import com.intellij.ui.ComboboxSpeedSearch;
import com.intellij.util.Icons;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Map;
/**
* @author peter
@@ -49,7 +40,7 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
private ElementCreator myCreator;
private CreateFileFromTemplateDialog(@NotNull Project project) {
protected CreateFileFromTemplateDialog(@NotNull Project project) {
super(project, true);
myKindLabel.setLabelFor(myKindCombo);
@@ -58,8 +49,16 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
init();
}
protected JTextField getNameField() {
return myNameField;
}
protected TemplateKindCombo getKindCombo() {
return myKindCombo;
}
private String getEnteredName() {
return myNameField.getText();
return getNameField().getText();
}
@Override
@@ -77,57 +76,72 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
@Override
public JComponent getPreferredFocusedComponent() {
return myNameField;
return getNameField();
}
public static <T extends PsiElement> Builder createDialog(@NotNull final Project project) {
public static Builder createDialog(@NotNull final Project project) {
final CreateFileFromTemplateDialog dialog = new CreateFileFromTemplateDialog(project);
return new BuilderImpl(dialog, project);
}
return new Builder() {
protected static class BuilderImpl implements Builder {
@Override
public Builder setTitle(String title) {
dialog.setTitle(title);
return this;
}
private final CreateFileFromTemplateDialog myDialog;
private final Project myProject;
public Builder addKind(@NotNull String name, @Nullable Icon icon, @NotNull String templateName) {
dialog.myKindCombo.addItem(name, icon, templateName);
return this;
}
public BuilderImpl(CreateFileFromTemplateDialog dialog, Project project) {
myDialog = dialog;
myProject = project;
}
public <T extends PsiElement> T show(@NotNull String errorTitle, @Nullable String selectedTemplateName,
@NotNull final FileCreator<T> creator) {
final Ref<T> created = Ref.create(null);
dialog.myKindCombo.setSelectedName(selectedTemplateName);
dialog.myCreator = new ElementCreator(project, errorTitle) {
@Override
protected void checkBeforeCreate(String newName) throws IncorrectOperationException {
creator.checkBeforeCreate(newName, dialog.myKindCombo.getSelectedName());
}
@Override
public Builder setTitle(String title) {
myDialog.setTitle(title);
return this;
}
@Override
protected PsiElement[] create(String newName) throws Exception {
final T element = creator.createFile(dialog.getEnteredName(), dialog.myKindCombo.getSelectedName());
created.set(element);
if (element != null) {
return new PsiElement[]{element};
}
return PsiElement.EMPTY_ARRAY;
}
public Builder addKind(@NotNull String name, @Nullable Icon icon, @NotNull String templateName) {
myDialog.getKindCombo().addItem(name, icon, templateName);
return this;
}
@Override
protected String getActionName(String newName) {
return creator.getActionName(newName, dialog.myKindCombo.getSelectedName());
}
};
dialog.show();
if (dialog.getExitCode() == OK_EXIT_CODE) {
return created.get();
public <T extends PsiElement> T show(@NotNull String errorTitle, @Nullable String selectedTemplateName,
@NotNull final FileCreator<T> creator) {
final Ref<T> created = Ref.create(null);
myDialog.getKindCombo().setSelectedName(selectedTemplateName);
myDialog.myCreator = new ElementCreator(myProject, errorTitle) {
@Override
protected void checkBeforeCreate(String newName) throws IncorrectOperationException {
creator.checkBeforeCreate(newName, myDialog.getKindCombo().getSelectedName());
}
return null;
@Override
protected PsiElement[] create(String newName) throws Exception {
final T element = creator.createFile(myDialog.getEnteredName(), myDialog.getKindCombo().getSelectedName());
created.set(element);
if (element != null) {
return new PsiElement[]{element};
}
return PsiElement.EMPTY_ARRAY;
}
@Override
protected String getActionName(String newName) {
return creator.getActionName(newName, myDialog.getKindCombo().getSelectedName());
}
};
myDialog.show();
if (myDialog.getExitCode() == OK_EXIT_CODE) {
return created.get();
}
};
return null;
}
@Nullable
@Override
public Map<String,String> getCustomProperties() {
return null;
}
}
public interface Builder {
@@ -135,6 +149,8 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
Builder addKind(@NotNull String kind, @Nullable Icon icon, @NotNull String templateName);
@Nullable
<T extends PsiElement> T show(@NotNull String errorTitle, @Nullable String selectedItem, @NotNull FileCreator<T> creator);
@Nullable
Map<String,String> getCustomProperties();
}
public interface FileCreator<T> {
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Map;
/**
* @author Eugene.Kudelevsky
@@ -74,11 +75,11 @@ public abstract class CreateFromTemplateAction<T extends PsiElement> extends AnA
});
if (createdElement != null) {
view.selectElement(createdElement);
postProcess(createdElement, selectedTemplateName.get());
postProcess(createdElement, selectedTemplateName.get(), builder.getCustomProperties());
}
}
protected void postProcess(T createdElement, String templateName) {
protected void postProcess(T createdElement, String templateName, Map<String,String> customProperties) {
}
@Nullable
@@ -24,18 +24,18 @@ import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Trinity;
import com.intellij.ui.ComboboxSpeedSearch;
import com.intellij.ui.ComboboxWithBrowseButton;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class TemplateKindCombo extends JComboBox {
public class TemplateKindCombo extends ComboboxWithBrowseButton {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.TemplateKindCombo");
public TemplateKindCombo() {
super();
setRenderer(new ListCellRendererWrapper(getRenderer()) {
getComboBox().setRenderer(new ListCellRendererWrapper(getComboBox().getRenderer()) {
@Override
public void customize(final JList list, final Object value, final int index, final boolean selected, final boolean cellHasFocus) {
if (value instanceof Trinity) {
@@ -45,7 +45,7 @@ public class TemplateKindCombo extends JComboBox {
}
});
new ComboboxSpeedSearch(this) {
new ComboboxSpeedSearch(getComboBox()) {
@Override
protected String getElementText(Object element) {
if (element instanceof Trinity) {
@@ -54,28 +54,30 @@ public class TemplateKindCombo extends JComboBox {
return null;
}
};
setButtonListener(null);
}
public void addItem(String presentableName, Icon icon, String templateName) {
addItem(new Trinity<String, Icon, String>(presentableName, icon, templateName));
getComboBox().addItem(new Trinity<String, Icon, String>(presentableName, icon, templateName));
}
public String getSelectedName() {
//noinspection unchecked
final Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)getSelectedItem();
final Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)getComboBox().getSelectedItem();
if (trinity == null) {
LOG.error("Model: " + getModel());
// design time
return null;
}
return trinity.third;
}
public void setSelectedName(@Nullable String name) {
if (name == null) return;
ComboBoxModel model = getModel();
ComboBoxModel model = getComboBox().getModel();
for (int i = 0, n = model.getSize(); i < n; i++) {
Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)model.getElementAt(i);
if (name.equals(trinity.third)) {
setSelectedItem(trinity);
getComboBox().setSelectedItem(trinity);
return;
}
}
@@ -97,15 +99,29 @@ public class TemplateKindCombo extends JComboBox {
}
private void scrollBy(int delta) {
final int size = getModel().getSize();
int next = getSelectedIndex() + delta;
if (delta == 0) return;
final int size = getComboBox().getModel().getSize();
int next = getComboBox().getSelectedIndex() + delta;
if (next < 0 || next >= size) {
if (!UISettings.getInstance().CYCLE_SCROLLING) {
return;
}
next = (next + size) % size;
}
setSelectedIndex(next);
getComboBox().setSelectedIndex(next);
}
/**
* @param listener pass <code>null</code> to hide browse button
*/
public void setButtonListener(@Nullable ActionListener listener) {
getButton().setVisible(listener != null);
if (listener != null) {
addActionListener(listener);
}
}
public void clear() {
getComboBox().removeAllItems();
}
}
@@ -21,12 +21,14 @@
package com.intellij.ide.navigationToolbar;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.wm.impl.IdeRootPaneNorthExtension;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.panels.OpaquePanel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
@@ -37,51 +39,100 @@ import java.awt.event.MouseEvent;
public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
private static final Icon CROSS_ICON = IconLoader.getIcon("/actions/cross.png");
private JComponent myPanel;
private JComponent myWrapperPanel;
@NonNls public static final String NAV_BAR = "NavBar";
private final Project myProject;
private NavBarPanel myNavigationBar;
private JPanel myRunPanel;
public NavBarRootPaneExtension(Project project) {
myProject = project;
UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings source) {
toggleRunPanel(!source.SHOW_MAIN_TOOLBAR);
}
}, project);
}
public JComponent getComponent() {
if (myPanel == null) {
myPanel = new OpaquePanel.List(new BorderLayout());
myNavigationBar = new NavBarPanel(myProject);
JScrollPane scroller = ScrollPaneFactory.createScrollPane(myNavigationBar);
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scroller.setHorizontalScrollBar(null);
scroller.setBorder(null);
myPanel.add(scroller, BorderLayout.CENTER);
JLabel closeLabel = new JLabel(CROSS_ICON);
closeLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
uiSettingsChanged(UISettings.getInstance());
}
});
myPanel.add(closeLabel, BorderLayout.EAST);
myPanel.putClientProperty("NavBarPanel", myNavigationBar);
myNavigationBar.installBorder(0, true);
myPanel.setBorder(myNavigationBar.getBorder());
myNavigationBar.setBorder(null);
if (myWrapperPanel == null) {
myWrapperPanel = new JPanel(new BorderLayout());
myWrapperPanel.add(buildNavBarPanel(), BorderLayout.CENTER);
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
toggleRunPanel(!UISettings.getInstance().SHOW_MAIN_TOOLBAR);
}
return myPanel;
return myWrapperPanel;
}
private void toggleRunPanel(final boolean show) {
if (show && myRunPanel == null) {
final ActionManager manager = ActionManager.getInstance();
final AnAction toolbarRunGroup = manager.getAction("ToolbarRunGroup");
if (toolbarRunGroup instanceof DefaultActionGroup) {
final DefaultActionGroup group = (DefaultActionGroup)toolbarRunGroup;
boolean needsGap = false;
int i = 0;
for (final AnAction action : group.getChildActionsOrStubs()) {
if (action instanceof ComboBoxAction) {
needsGap = i == 0;
break;
} else if (!(action instanceof Separator)) {
i++;
}
}
final ActionToolbar actionToolbar = manager.createActionToolbar(ActionPlaces.UNKNOWN, group, true);
final JComponent component = actionToolbar.getComponent();
component.setBackground(Color.WHITE);
myRunPanel = new JPanel(new BorderLayout());
final Color color = myRunPanel.getBackground() != null ? myRunPanel.getBackground().darker() : Color.darkGray;
myRunPanel.setBackground(Color.WHITE);
myRunPanel.add(component);
myRunPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 1, 1, 0, color),
BorderFactory.createEmptyBorder(1, needsGap ? 5 : 1, 0, 0)));
myWrapperPanel.add(myRunPanel, BorderLayout.EAST);
}
}
else if (!show && myRunPanel != null) {
myWrapperPanel.remove(myRunPanel);
myRunPanel = null;
}
}
private JComponent buildNavBarPanel() {
final JComponent result = new OpaquePanel.List(new BorderLayout());
myNavigationBar = new NavBarPanel(myProject);
JScrollPane scroller = ScrollPaneFactory.createScrollPane(myNavigationBar);
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scroller.setHorizontalScrollBar(null);
scroller.setBorder(null);
result.add(scroller, BorderLayout.CENTER);
JLabel closeLabel = new JLabel(CROSS_ICON);
closeLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
uiSettingsChanged(UISettings.getInstance());
}
});
result.add(closeLabel, BorderLayout.EAST);
myNavigationBar.installBorder(0, true);
result.setBorder(myNavigationBar.getBorder());
myNavigationBar.setBorder(null);
return result;
}
public void uiSettingsChanged(final UISettings settings) {
if (myNavigationBar != null) {
myNavigationBar.updateState(settings.SHOW_NAVIGATION_BAR);
myPanel.setVisible(settings.SHOW_NAVIGATION_BAR);
myWrapperPanel.setVisible(settings.SHOW_NAVIGATION_BAR);
}
}
@@ -90,9 +141,11 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
return NAV_BAR;
}
public void dispose() {
myPanel.setVisible(false);
myPanel = null;
myWrapperPanel.setVisible(false);
myWrapperPanel = null;
myRunPanel = null;
myNavigationBar = null;
}
}
@@ -33,14 +33,13 @@ import javax.swing.*;
public class LangScriptingContextConfigurable implements Configurable {
private ScriptingLibrariesPanel myPanel;
private LangScriptingContextProvider myProvider;
private ModifiableRootModel myRootModel;
private ScriptingLibraryManager myLibManager;
public LangScriptingContextConfigurable(ModifiableRootModel rootModel, LangScriptingContextProvider provider) {
LibraryTable libTable = rootModel != null ?
rootModel.getModuleLibraryTable() : null;
public LangScriptingContextConfigurable(ScriptingLibraryManager libManager, LangScriptingContextProvider provider) {
LibraryTable libTable = libManager.getLibraryTable();
myPanel = new ScriptingLibrariesPanel(libTable);
myProvider = provider;
myRootModel = rootModel;
myLibManager = libManager;
}
@Nls
@@ -71,19 +70,19 @@ public class LangScriptingContextConfigurable implements Configurable {
@Override
public void apply() throws ConfigurationException {
if (myRootModel != null) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myRootModel.commit();
}
});
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myLibManager.commitModel();
myPanel.resetTable(myLibManager.getLibraryTable());
}
});
}
@Override
public void reset() {
//To change body of implemented methods use File | Settings | File Templates.
myLibManager.resetModel();
myPanel.resetTable(myLibManager.getLibraryTable());
}
@Override
@@ -33,14 +33,12 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
private MainScriptingContextsPanel myPanel;
private String myLangNames;
private Project myProject;
private ModifiableRootModel myRootModel;
private ScriptingLibraryManager myLibManager;
public ScriptingContextsConfigurable(Project project) {
myPanel = new MainScriptingContextsPanel();
myLangNames = getLangNames();
myProject = project;
myRootModel = ScriptingLibraryManager.getRootModel(project);
myLibManager = new ScriptingLibraryManager(project);
}
@Nls
@@ -71,9 +69,7 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
@Override
public void apply() throws ConfigurationException {
if (myRootModel != null) {
myRootModel.commit();
}
myLibManager.commitModel();
}
@Override
@@ -83,14 +79,14 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
@Override
public void disposeUIResources() {
disposeModel();
myLibManager.disposeModel();
}
@Override
public Configurable[] getConfigurables() {
ArrayList<LangScriptingContextConfigurable> configurables = new ArrayList<LangScriptingContextConfigurable>();
for (LangScriptingContextProvider provider : LangScriptingContextProvider.getProviders()) {
configurables.add(new LangScriptingContextConfigurable(myRootModel, provider));
configurables.add(new LangScriptingContextConfigurable(myLibManager, provider));
}
return configurables.toArray(new LangScriptingContextConfigurable[configurables.size()]);
}
@@ -104,9 +100,4 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
return result.substring(0, result.length() - 1);
}
public void disposeModel() {
if (myRootModel != null && !myRootModel.isDisposed()) {
myRootModel.dispose();
}
}
}
@@ -32,8 +32,16 @@ public class ScriptingLibraryManager {
public static final String WEB_MODULE_TYPE = "WEB_MODULE";
private ModifiableRootModel myRootModel;
private Project myProject;
public ScriptingLibraryManager(Project project) {
myProject = project;
myRootModel = getRootModel(project);
}
@Nullable
public static ModifiableRootModel getRootModel(Project project) {
private static ModifiableRootModel getRootModel(Project project) {
for (Module module : ModuleManager.getInstance(project).getModules()) {
if (WEB_MODULE_TYPE.equals(module.getModuleType().getId())) {
return ModuleRootManager.getInstance(module).getModifiableModel();
@@ -41,4 +49,30 @@ public class ScriptingLibraryManager {
}
return null;
}
public void disposeModel() {
if (myRootModel != null && !myRootModel.isDisposed()) {
myRootModel.dispose();
myRootModel = null;
}
}
public void commitModel() {
if (myRootModel != null && !myRootModel.isDisposed()) {
myRootModel.commit();
}
}
public void resetModel() {
disposeModel();
myRootModel = getRootModel(myProject);
}
@Nullable
public LibraryTable getLibraryTable() {
if (myRootModel != null) {
return myRootModel.getModuleLibraryTable();
}
return null;
}
}
@@ -74,4 +74,10 @@ public class ScriptingLibrariesPanel {
return myModified;
}
public void resetTable(LibraryTable libTable) {
myLibTableModel.resetTable(libTable);
myModified = false;
myLibraryTable.repaint();
}
}
@@ -36,6 +36,10 @@ public class ScriptingLibraryTableModel extends AbstractTableModel {
myLibTable = libTable;
}
public void resetTable(LibraryTable libTable) {
myLibTable = libTable;
}
@Override
public int getRowCount() {
if (myLibTable != null) {
@@ -16,8 +16,6 @@
package com.intellij.refactoring.rename;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
@@ -45,11 +43,9 @@ import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.*;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
public class RenameDialog extends RefactoringDialog {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameDialog");
@@ -126,11 +122,6 @@ public class RenameDialog extends RefactoringDialog {
};
myNameSuggestionsField.addDataChangedListener(myNameChangedListener);
myNameSuggestionsField.getComponent().registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
completeVariable(myNameSuggestionsField.getEditor());
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
}
public String[] getSuggestedNames() {
@@ -146,21 +137,6 @@ public class RenameDialog extends RefactoringDialog {
return ArrayUtil.toStringArray(result);
}
private void completeVariable(Editor editor) {
final String prefix = myNameSuggestionsField.getEnteredName();
Collection<LookupElement> items = null;
for(NameSuggestionProvider provider: Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) {
items = provider.completeName(myPsiElement, myNameSuggestionContext, prefix);
if (items != null) break;
}
if (items != null) {
final LookupElement[] lookupItems = items.toArray(new LookupElement[items.size()]);
editor.getCaretModel().moveToOffset(prefix.length());
editor.getSelectionModel().removeSelection();
LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix);
}
}
public String getNewName() {
return myNameSuggestionsField.getEnteredName().trim();
@@ -210,18 +210,29 @@ public class HintManagerImpl extends HintManager implements Disposable {
((ScrollAwareHint)hint.getComponent()).editorScrolled();
}
if (!hint.isVisible()) {
return;
}
Editor editor = e.getEditor();
if (!editor.getComponent().isShowing() || editor.isOneLineMode()) return;
Rectangle newRectangle = e.getOldRectangle();
Rectangle oldRectangle = e.getNewRectangle();
Rectangle bounds = hint.getBounds();
Point location = bounds.getLocation();
Point location;
location = SwingUtilities.convertPoint(
editor.getComponent().getRootPane().getLayeredPane(),
location,
editor.getContentComponent()
);
final Window window = SwingUtilities.getWindowAncestor(hint.getComponent());
final boolean realPopup = window != null && window != SwingUtilities.getWindowAncestor(editor.getComponent());
if (realPopup) {
location = window.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(location, editor.getContentComponent());
} else {
location = SwingUtilities.convertPoint(
editor.getComponent().getRootPane().getLayeredPane(),
bounds.getLocation(),
editor.getContentComponent()
);
}
int xOffset = location.x - oldRectangle.x;
@@ -232,13 +243,18 @@ public class HintManagerImpl extends HintManager implements Disposable {
final boolean valid = hideIfOutOfEditor ? oldRectangle.contains(newBounds) : oldRectangle.intersects(newBounds);
if (valid) {
location = SwingUtilities.convertPoint(
editor.getContentComponent(),
location,
editor.getComponent().getRootPane().getLayeredPane()
);
if (!realPopup) {
location = SwingUtilities.convertPoint(
editor.getContentComponent(),
location,
editor.getComponent().getRootPane().getLayeredPane()
);
hint.updateBounds(location.x, location.y);
} else {
SwingUtilities.convertPointToScreen(location, editor.getContentComponent());
window.setLocation(location);
}
hint.updateBounds(location.x, location.y);
}
else {
hint.hide();
@@ -363,11 +363,14 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
if (myOrientation == SwingConstants.HORIZONTAL) {
int eachX = 0;
int eachY = 0;
int maxHeight = 0;
for (int i = 0; i < componentCount; i++) {
final Component eachComp = getComponent(i);
final boolean isLast = i == componentCount - 1;
final Rectangle eachBound = new Rectangle(eachComp.getPreferredSize());
maxHeight = Math.max(eachBound.height, maxHeight);
if (!full) {
boolean inside;
if (isLast) {
@@ -408,6 +411,13 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
bounds.get(i).setBounds(eachBound);
}
for (final Rectangle r : bounds) {
if (r.height < maxHeight && r.y == 0) {
r.y = (maxHeight - r.height) / 2;
}
}
}
else {
int eachX = 0;
@@ -468,7 +468,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
return null; // suppress events in shutdown hook
}
DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, wholeTextReplaced);
//System.out.printf("%nbefore change: offset=%d, old text='%s', new text='%s', document modification stamp=%d%nDocument:'%s'%n",
// event.getOffset(), event.getOldFragment(), event.getNewFragment(), event.getDocument().getModificationStamp(),
// event.getDocument().getText());
for (int i = myDocumentListeners.size() - 1; i >= 0; i--) {
try {
myDocumentListeners.get(i).beforeDocumentChange(event);
@@ -484,6 +486,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
@SuppressWarnings({"ForLoopReplaceableByForEach"})
private void changedUpdate(DocumentEvent event, long newModificationStamp) {
//System.out.printf("after change: new modification stamp=%d%ndocument='%s'%n", event.getDocument().getModificationStamp(),
// event.getDocument().getText());
if (ShutDownTracker.isShutdownHookRunning()) {
return; // suppress events in shutdown hook
}
@@ -116,11 +116,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
}
Rectangle visibleArea = myEditor.getScrollingModel().getVisibleArea();
if (visibleArea.width <= 0 || visibleArea.height <= 0) {
return false;
}
if (!ApplicationManager.getApplication().isUnitTestMode() && myEditor.getScrollingModel().getVisibleArea().width <= 0) {
if (!ApplicationManager.getApplication().isUnitTestMode() && (visibleArea.width <= 0 || visibleArea.height <= 0)) {
return false;
}
@@ -25,7 +25,7 @@ public class ShutDownTracker implements Runnable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.ShutDownTracker");
private static ShutDownTracker ourInstance;
private final List<Thread> myThreads = new ArrayList<Thread>();
private final List<Thread> myShutdownThreads = new ArrayList<Thread>();
private final LinkedList<Thread> myShutdownThreads = new LinkedList<Thread>();
private final LinkedList<Runnable> myShutdownTasks = new LinkedList<Runnable>();
private volatile boolean myIsShutdownHookRunning = false;
@@ -48,17 +48,6 @@ public class ShutDownTracker implements Runnable {
public void run() {
myIsShutdownHookRunning = true;
while (!myShutdownTasks.isEmpty()) {
// task can change myShutdownTasks
final Runnable task = myShutdownTasks.removeLast();
try {
task.run();
}
catch (Throwable e) {
LOG.error(e);
}
}
Thread[] threads = getStopperThreads();
while (threads.length > 0) {
Thread thread = threads[0];
@@ -77,14 +66,27 @@ public class ShutDownTracker implements Runnable {
}
threads = getStopperThreads();
}
for (int idx = myShutdownThreads.size() - 1; idx >= 0; idx--) {
final Thread thread = myShutdownThreads.remove(idx);
thread.start();
while (!myShutdownTasks.isEmpty()) {
// task can change myShutdownTasks
final Runnable task = myShutdownTasks.removeLast();
try {
thread.join();
task.run();
}
catch (Throwable e) {
LOG.error(e);
}
}
if (!myShutdownThreads.isEmpty()) {
for (Thread thread = myShutdownThreads.removeLast(); thread != null; thread = myShutdownThreads.removeLast()) {
thread.start();
try {
thread.join();
}
catch (InterruptedException ignored) {
}
}
catch (InterruptedException e) { }
}
}
@@ -105,7 +107,7 @@ public class ShutDownTracker implements Runnable {
}
public void registerShutdownThread(final Thread thread) {
myShutdownThreads.add(thread);
myShutdownThreads.addLast(thread);
}
public void registerShutdownThread(int index, final Thread thread) {
@@ -19,7 +19,6 @@ package com.intellij.openapi.util.io;
import com.intellij.CommonBundle;
import com.intellij.Patches;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Processor;
@@ -429,14 +428,14 @@ public class FileUtil {
public void run() {
final Thread currentThread = Thread.currentThread();
currentThread.setPriority(Thread.MIN_PRIORITY);
ShutDownTracker.getInstance().registerStopperThread(currentThread);
//ShutDownTracker.getInstance().registerStopperThread(currentThread);
try {
for (File tempFile : tempFiles) {
delete(tempFile);
}
}
finally {
ShutDownTracker.getInstance().unregisterStopperThread(currentThread);
//ShutDownTracker.getInstance().unregisterStopperThread(currentThread);
currentThread.setPriority(Thread.NORM_PRIORITY);
}
}
@@ -18,6 +18,7 @@ package com.intellij.util.containers;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
@@ -69,7 +70,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
/* ---------------- Public operations -------------- */
public StripedLockConcurrentHashMap(TObjectHashingStrategy<K> hashingStrategy) {
public StripedLockConcurrentHashMap(@Nullable TObjectHashingStrategy<K> hashingStrategy) {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, hashingStrategy);
}
@@ -90,7 +91,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
this(initialCapacity, loadFactor, null);
}
public StripedLockConcurrentHashMap(int initialCapacity, float loadFactor, TObjectHashingStrategy<K> hashingStrategy) {
public StripedLockConcurrentHashMap(int initialCapacity, float loadFactor, @Nullable TObjectHashingStrategy<K> hashingStrategy) {
super(getInitCap(initialCapacity, loadFactor), loadFactor, hashingStrategy);
}
@@ -138,7 +139,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
*
* @param t the map
*/
public StripedLockConcurrentHashMap(Map<? extends K, ? extends V> t) {
public StripedLockConcurrentHashMap(@NotNull Map<? extends K, ? extends V> t) {
this(Math.max((int)(t.size() / DEFAULT_LOAD_FACTOR) + 1, 11), DEFAULT_LOAD_FACTOR);
putAll(t);
}
@@ -166,7 +167,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
* @throws NullPointerException if the key is
* <tt>null</tt>.
*/
public V get(Object key) {
public V get(@NotNull Object key) {
K kKey = (K)key;
int hash = myHashingStrategy.computeHashCode(kKey); // throws NullPointerException if key null
return get(kKey, hash);
@@ -182,7 +183,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
* @throws NullPointerException if the key is
* <tt>null</tt>.
*/
public boolean containsKey(Object key) {
public boolean containsKey(@NotNull Object key) {
K kKey = (K)key;
int hash = myHashingStrategy.computeHashCode(kKey); // throws NullPointerException if key null
return containsKey(kKey, hash);
@@ -203,7 +204,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
* <tt>false</tt> otherwise.
* @throws NullPointerException if the value is <tt>null</tt>.
*/
public boolean contains(Object value) {
public boolean contains(@NotNull Object value) {
return containsValue(value);
}
@@ -262,7 +263,10 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
*/
public void putAll(@NotNull Map<? extends K, ? extends V> t) {
for (Entry<? extends K, ? extends V> e : t.entrySet()) {
put(e.getKey(), e.getValue());
V value = e.getValue();
if (value != null) { // null is possible if the entry has just been removed
put(e.getKey(), value);
}
}
}
@@ -507,20 +511,24 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
}
final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
@NotNull
public K next() {
return nextEntry().key;
}
@NotNull
public K nextElement() {
return nextEntry().key;
}
}
final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
@NotNull
public V next() {
return nextEntry().value;
}
@NotNull
public V nextElement() {
return nextEntry().value;
}
@@ -534,11 +542,13 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
* itself acts as a forwarding pseudo-entry.
*/
final class EntryIterator extends HashIterator implements Entry<K, V>, Iterator<Entry<K, V>> {
@NotNull
public Entry<K, V> next() {
nextEntry();
return this;
}
@NotNull
public K getKey() {
if (lastReturned == null) {
throw new IllegalStateException("Entry was removed");
@@ -546,6 +556,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
return lastReturned.key;
}
@Nullable("null means the entry has just been removed")
public V getValue() {
if (lastReturned == null) {
throw new IllegalStateException("Entry was removed");
@@ -553,7 +564,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
return get(lastReturned.key);
}
public V setValue(V value) {
public V setValue(@NotNull V value) {
if (lastReturned == null) {
throw new IllegalStateException("Entry was removed");
}
@@ -571,7 +582,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
Entry e = (Entry)o;
K o1 = getKey();
K o2 = (K)e.getKey();
return (o1 == null ? o2 == null : myHashingStrategy.equals(o1, o2)) && eq(getValue(), e.getValue());
return myHashingStrategy.equals(o1, o2) && getValue().equals(e.getValue());
}
public int hashCode() {
@@ -582,8 +593,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
Object k = getKey();
Object v = getValue();
return (k == null ? 0 : k.hashCode()) ^
(v == null ? 0 : v.hashCode());
return k.hashCode() ^ v.hashCode();
}
public String toString() {
@@ -591,15 +601,8 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
if (lastReturned == null) {
return super.toString();
}
else {
return getKey() + "=" + getValue();
}
return getKey() + "=" + getValue();
}
boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
}
final class KeySet extends AbstractSet<K> {
@@ -728,23 +731,25 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
* is made accessible.
*/
final class SimpleEntry implements Entry<K, V> {
K key;
final K key;
V value;
public SimpleEntry(Entry<K, V> e) {
public SimpleEntry(@NotNull Entry<K, V> e) {
key = e.getKey();
value = e.getValue();
}
@NotNull
public K getKey() {
return key;
}
@NotNull
public V getValue() {
return value;
}
public V setValue(V value) {
public V setValue(@NotNull V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
@@ -756,21 +761,16 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
}
Entry e = (Entry)o;
K o2 = (K)e.getKey();
return (key == null ? o2 == null : myHashingStrategy.equals(key, o2)) && eq(value, e.getValue());
return myHashingStrategy.equals(key, o2) && value.equals(e.getValue());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
return key.hashCode() ^ value.hashCode();
}
public String toString() {
return key + "=" + value;
}
boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
}
static class CanonicalHashingStrategy<K> implements TObjectHashingStrategy<K> {
@@ -790,7 +790,7 @@ public class StripedLockConcurrentHashMap<K, V> extends _CHMSegment<K, V> implem
return h;
}
public boolean equals(final K o1, final K o2) {
public boolean equals(@NotNull K o1, @NotNull K o2) {
return o1.equals(o2);
}
}
@@ -964,9 +964,7 @@ class _CHMSegment<K, V> {
HashEntry[] tab = table;
int len = tab.length;
for (int i = 0; i < len; i++) {
for (HashEntry<K, V> e = tab[i];
e != null;
e = e.next) {
for (HashEntry<K, V> e = tab[i]; e != null; e = e.next) {
V v = e.value;
if (v == null) // recheck
{
@@ -1124,7 +1122,7 @@ class _CHMSegment<K, V> {
/*
* Remove; match on key only if value null, else match both.
*/
V remove(K key, int hash, Object value) {
V remove(@NotNull K key, int hash, @Nullable("null means don't care") Object value) {
try {
lock();
int c = count - 1;
@@ -1188,9 +1186,9 @@ class _CHMSegment<K, V> {
* an unsynchronized access method.
*/
static final class HashEntry<K, V> {
final K key;
@NotNull final K key;
final int hash;
volatile V value;
@NotNull volatile V value;
final HashEntry<K, V> next;
HashEntry(@NotNull K key, int hash, HashEntry<K, V> next, @NotNull V value) {
@@ -276,24 +276,29 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
}
private VcsDirtyScopeManagerImpl getVcsManager() {
try {
return ((VcsDirtyScopeManagerImpl) VcsDirtyScopeManager.getInstance(myProject));
}
catch(ProcessCanceledException ex) {
return null;
}
catch(Exception ex) {
LOG.error(ex);
return null;
}
}
private void updateImmediately(final AtomicSectionsAware atomicSectionsAware) {
FileHolderComposite composite;
ChangeListWorker changeListWorker;
final FileHolderComposite composite;
final ChangeListWorker changeListWorker;
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
if (! vcsManager.hasActiveVcss()) return;
final VcsDirtyScopeManagerImpl dirtyScopeManager;
try {
dirtyScopeManager = ((VcsDirtyScopeManagerImpl) VcsDirtyScopeManager.getInstanceChecked(myProject));
}
catch(ProcessCanceledException ex) {
return;
}
catch(Exception ex) {
LOG.error(ex);
return;
}
final VcsDirtyScopeManagerImpl dirtyScopeManager = getVcsManager();
if (dirtyScopeManager == null) return;
final VcsInvalidated invalidated = dirtyScopeManager.retrieveScopes();
if (invalidated == null || invalidated.isEmpty()) {
// a hack here; but otherwise everything here should be refactored ;)
@@ -305,6 +310,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final boolean wasEverythingDirty = invalidated.isEverythingDirty();
final List<VcsDirtyScope> scopes = invalidated.getScopes();
try {
checkIfDisposed();
@@ -22,7 +22,8 @@ import com.intellij.openapi.project.ProjectLocator;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.util.containers.HashMap;
@@ -71,13 +72,15 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
// collect files and directories - sources of events
for (VFileEvent event : events) {
final VirtualFile file = getFileForEvent(event);
if (file == null) { continue; }
if (file == null) {
continue;
}
if (event instanceof VFileDeleteEvent) {
if (!file.isInLocalFileSystem()) { continue; }
dirtyFilesAndDirs.add(file);
dirtyFilesAndDirs.add(file, true);
} else if (event instanceof VFileMoveEvent || event instanceof VFilePropertyChangeEvent) {
dirtyFilesAndDirs.addToFiles(file);
dirtyFilesAndDirs.addToFiles(file, false); // todo ?
}
}
// and notify VCSDirtyScopeManager
@@ -90,20 +93,22 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
// collect files and directories - sources of events
for (VFileEvent event : events) {
final VirtualFile file = getFileForEvent(event);
if (file == null) { continue; }
if (file == null) {
continue;
}
if (event instanceof VFileContentChangeEvent || event instanceof VFileCopyEvent || event instanceof VFileCreateEvent) {
dirtyFilesAndDirs.addToFiles(file);
dirtyFilesAndDirs.add(file, false);
} else if (event instanceof VFilePropertyChangeEvent) {
final VFilePropertyChangeEvent pce = (VFilePropertyChangeEvent) event;
if (pce.getPropertyName().equals(VirtualFile.PROP_NAME)) {
// if a file was renamed, then the file is dirty and its parent directory is dirty too;
// if a directory was renamed, all its children are recursively dirty, the parent dir is also dirty but not recursively.
dirtyFilesAndDirs.add(file); // the file is dirty recursively
dirtyFilesAndDirs.addToFiles(file.getParent()); // directory is dirty alone. if parent is null - is checked in the method
dirtyFilesAndDirs.add(file, false); // the file is dirty recursively
dirtyFilesAndDirs.addToFiles(file.getParent(), false); // directory is dirty alone. if parent is null - is checked in the method
} else {
dirtyFilesAndDirs.addToFiles(file);
dirtyFilesAndDirs.addToFiles(file, false);
}
}
}
@@ -133,11 +138,12 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
* @param file file which path is to be added.
* @param addToFiles If true, then add to dirty files even if it is a directory. Otherwise add to the proper set.
*/
private void add(VirtualFile file, boolean addToFiles) {
public void add(VirtualFile file, boolean addToFiles, final boolean forDelete) {
if (file == null) { return; }
final boolean isDirectory = file.isDirectory();
// need to create FilePath explicitly without referring to VirtualFile because the path of VirtualFile may change
final FilePathImpl path = new FilePathImpl(new File(file.getPath()), isDirectory);
final FilePathImpl path = forDelete ? new FilePathImpl(new File(file.getPath()), isDirectory) :
new FilePathImpl(file);
final Collection<VcsDirtyScopeManager> managers = getManagers(file);
for (VcsDirtyScopeManager manager : managers) {
@@ -158,16 +164,16 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
/**
* Adds files to the collection of files and directories - to the collection of directories (which are handled recursively).
*/
void add(VirtualFile file) {
add(file, false);
void add(VirtualFile file, final boolean forDelete) {
add(file, false, forDelete);
}
/**
* Adds to the collection of files. A file (even if it is a directory) is marked dirty alone (not recursively).
* Use this method, when you want directory not to be marked dirty recursively.
*/
void addToFiles(VirtualFile file) {
add(file, true);
void addToFiles(VirtualFile file, final boolean forDelete) {
add(file, true, forDelete);
}
void markDirty() {
@@ -562,11 +562,15 @@ public class PsiUtil {
@Nullable
public static PsiClass getContextClass(PsiElement context) {
GroovyPsiElement parent = PsiTreeUtil.getParentOfType(context, GrTypeDefinition.class, GroovyFileBase.class);
if (parent instanceof GrTypeDefinition) {
return (PsiClass)parent;
} else if (parent instanceof GroovyFileBase) {
return ((GroovyFileBase)parent).getScriptClass();
while (context != null) {
if (context instanceof GrTypeDefinition) {
return (PsiClass)context;
}
else if (context instanceof GroovyFileBase) {
return ((GroovyFileBase)context).getScriptClass();
}
context = context.getContext();
}
return null;
}
@@ -4,16 +4,22 @@ import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.IgnoredBeanFactory;
import com.intellij.openapi.vcs.changes.IgnoredFileBean;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.AbstractVcsTestCase;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
@@ -46,7 +52,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase {
myVcs = SvnVcs.getInstance(myProject);
myVcsManager = (ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myProject);
myVcsManager.registerVcs(myVcs);
myVcsManager.setDirectoryMapping("", myVcs.getName());
myVcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), myVcs.getName());
((ProjectComponent) myChangeListManager).projectOpened();
myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
@@ -72,7 +78,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase {
}
// they all blink now
/*
@Test
public void testFileIsIgnored() throws Exception {
final String filePath1 = myClientRoot.getPath() + "/a";
@@ -97,8 +103,8 @@ public class IgnoredFilesTest extends AbstractVcsTestCase {
@Test
public void testDirIsIgnored() throws Exception {
final String dirPath1 = myClientRoot.getPath() + "/a";
final File dir = new File(dirPath1);
//final String dirPath1 = myClientRoot.getPath() + "/a";
final File dir = new File(myClientRoot, "a");
dir.mkdir();
final File innerDir = new File(dir, "innerDir");
innerDir.mkdir();
@@ -111,7 +117,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase {
final VirtualFile vf1 = myLocalFileSystem.refreshAndFindFileByIoFile(file1);
final VirtualFile vf2 = myLocalFileSystem.refreshAndFindFileByIoFile(file2);
final IgnoredFileBean ignoredFileBean = IgnoredBeanFactory.ignoreUnderDirectory(dirPath1, myProject);
final IgnoredFileBean ignoredFileBean = IgnoredBeanFactory.ignoreUnderDirectory(FileUtil.toSystemIndependentName(dir.getPath()), myProject);
myChangeListManager.addFilesToIgnore(ignoredFileBean);
dirty();
@@ -124,7 +130,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase {
@Test
public void testPatternIsIgnored() throws Exception {
final String dirPath1 = myClientRoot.getPath() + "/a";
final File dir = new File(dirPath1);
final File dir = new File(myClientRoot, "a");
dir.mkdir();
final File innerDir = new File(dir, "innerDir");
innerDir.mkdir();
@@ -155,5 +161,5 @@ public class IgnoredFilesTest extends AbstractVcsTestCase {
Assert.assertNotNull(vf);
Assert.assertTrue(myChangeListManager.isIgnoredFile(vf));
Assert.assertEquals(FileStatus.IGNORED, myChangeListManager.getStatus(vf));
} */
}
}
@@ -1,107 +0,0 @@
/*
* Copyright 2000-2009 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.completion;
import com.intellij.lang.Language;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
import com.intellij.xml.util.XmlUtil;
/**
*
*/
public class XmlAutoLookupHandler extends CodeCompletionHandlerBase {
public XmlAutoLookupHandler() {
super(CompletionType.BASIC, false, false);
}
protected void doComplete(final int offset1, final int offset2, final CompletionContext context, final FileCopyPatcher dummyIdentifier, Editor editor,
final int invocationCount) {
PsiFile file = context.file;
int offset = context.getStartOffset();
PsiElement lastElement = InjectedLanguageUtil.findElementAtNoCommit(file, offset - 1);
if (lastElement instanceof PsiFile) { //the very end of an injected file
lastElement = file.findElementAt(offset - 1);
}
if (lastElement == null) return;
if(!doCompleteIfNeeded(offset1, offset2, context, dummyIdentifier, editor, invocationCount, file, lastElement)) {
// In template language based file we need to check element from template data language tree, not from base language
FileViewProvider fileViewProvider = file.getViewProvider();
Language templateDataLanguage;
final PsiElement parent = lastElement.getParent();
if (fileViewProvider instanceof TemplateLanguageFileViewProvider &&
(templateDataLanguage = ((TemplateLanguageFileViewProvider)fileViewProvider).getTemplateDataLanguage()) != parent.getLanguage()) {
lastElement = fileViewProvider.findElementAt(offset - 1, templateDataLanguage);
if (lastElement == null) return;
doCompleteIfNeeded(offset1, offset2, context, dummyIdentifier, editor, invocationCount, file, lastElement);
}
}
}
private boolean doCompleteIfNeeded(int offset1,
int offset2,
CompletionContext context,
FileCopyPatcher dummyIdentifier,
Editor editor,
int invocationCount, PsiFile file, PsiElement lastElement) {
final Ref<Boolean> isRelevantLanguage = new Ref<Boolean>();
final Ref<Boolean> isAnt = new Ref<Boolean>();
String text = lastElement.getText();
final int len = context.getStartOffset() - lastElement.getTextRange().getStartOffset();
if (len < text.length()) {
text = text.substring(0, len);
}
if (text.equals("<") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) ||
text.equals(" ") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) ||
text.endsWith("${") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() ||
text.endsWith("@{") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() ||
text.endsWith("</") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt)) {
super.doComplete(offset1, offset2, context, dummyIdentifier, editor, invocationCount);
return true;
}
return false;
}
private static boolean isLanguageRelevant(final PsiElement element,
final PsiFile file,
final Ref<Boolean> isRelevantLanguage,
final Ref<Boolean> isAnt) {
Boolean isAntFile = isAnt.get();
if (isAntFile == null) {
isAntFile = XmlUtil.isAntFile(file);
isAnt.set(isAntFile);
}
Boolean result = isRelevantLanguage.get();
if (result == null) {
Language language = element.getLanguage();
if (element instanceof PsiWhiteSpace) language = element.getParent().getLanguage();
result = language instanceof XMLLanguage || isAntFile.booleanValue();
isRelevantLanguage.set(result);
}
return result.booleanValue();
}
}
@@ -16,17 +16,20 @@
package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.XmlAutoLookupHandler;
import com.intellij.lang.Language;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
import com.intellij.psi.xml.XmlTag;
import com.intellij.xml.util.XmlUtil;
public class XmlAutoPopupHandler extends TypedHandlerDelegate {
public Result checkAutoPopup(final char charTyped, final Project project, final Editor editor, final PsiFile file) {
@@ -53,24 +56,73 @@ public class XmlAutoPopupHandler extends TypedHandlerDelegate {
}
public static void autoPopupXmlLookup(final Project project, final Editor editor){
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
if (settings.AUTO_POPUP_COMPLETION_LOOKUP) {
final Runnable request = new Runnable(){
public void run(){
PsiDocumentManager.getInstance(project).commitAllDocuments();
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new Condition<PsiFile>() {
@Override
public boolean value(PsiFile file) {
int offset = editor.getCaretModel().getOffset();
final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project);
if (file == null) return;
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
public void run() {
new XmlAutoLookupHandler().invoke(project, editor, file);
}
}, null, null);
PsiElement lastElement = InjectedLanguageUtil.findElementAtNoCommit(file, offset - 1);
if (lastElement instanceof PsiFile) { //the very end of an injected file
lastElement = file.findElementAt(offset - 1);
}
};
AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, settings.AUTO_LOOKUP_DELAY);
}
if (lastElement == null) return false;
if (doCompleteIfNeeded(offset, file, lastElement)) {
return true;
}
FileViewProvider fileViewProvider = file.getViewProvider();
Language templateDataLanguage;
final PsiElement parent = lastElement.getParent();
if (fileViewProvider instanceof TemplateLanguageFileViewProvider &&
(templateDataLanguage = ((TemplateLanguageFileViewProvider)fileViewProvider).getTemplateDataLanguage()) != parent.getLanguage()) {
lastElement = fileViewProvider.findElementAt(offset - 1, templateDataLanguage);
if (lastElement == null) return false;
return doCompleteIfNeeded(offset, file, lastElement);
}
return false;
}
});
}
private static boolean doCompleteIfNeeded(int offset, PsiFile file, PsiElement lastElement) {
final Ref<Boolean> isRelevantLanguage = new Ref<Boolean>();
final Ref<Boolean> isAnt = new Ref<Boolean>();
String text = lastElement.getText();
final int len = offset - lastElement.getTextRange().getStartOffset();
if (len < text.length()) {
text = text.substring(0, len);
}
if (text.equals("<") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) ||
text.equals(" ") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) ||
text.endsWith("${") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() ||
text.endsWith("@{") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() ||
text.endsWith("</") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt)) {
return true;
}
return false;
}
private static boolean isLanguageRelevant(final PsiElement element,
final PsiFile file,
final Ref<Boolean> isRelevantLanguage,
final Ref<Boolean> isAnt) {
Boolean isAntFile = isAnt.get();
if (isAntFile == null) {
isAntFile = XmlUtil.isAntFile(file);
isAnt.set(isAntFile);
}
Boolean result = isRelevantLanguage.get();
if (result == null) {
Language language = element.getLanguage();
if (element instanceof PsiWhiteSpace) language = element.getParent().getLanguage();
result = language instanceof XMLLanguage || isAntFile.booleanValue();
isRelevantLanguage.set(result);
}
return result.booleanValue();
}
}