diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java index 242e157a705b..f7232701bc4c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java @@ -225,7 +225,7 @@ public class PositionHighlighter { } if (breakpoint instanceof BreakpointWithHighlighter) { - if (((BreakpointWithHighlighter)breakpoint).isVisible()) { + if (((BreakpointWithHighlighter)breakpoint).isVisible() && breakpoint.isValid()) { breakpoint.reload(); final SourcePosition sourcePosition = ((BreakpointWithHighlighter)breakpoint).getSourcePosition(); if (sourcePosition == null || sourcePosition.getLine() != lineIndex) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java index a9f93fdde07b..52e325db6aaf 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java @@ -42,7 +42,7 @@ class CollectionsUtilityMethodsProvider { final PsiType type = parameters.getExpectedType(); final PsiType defaultType = parameters.getDefaultType(); final PsiElement pparent = parent.getParent(); - if (parameters.getInvocationCount() > 1 || + if (parameters.getParameters().getInvocationCount() > 1 || pparent instanceof PsiReturnStatement || pparent instanceof PsiConditionalExpression && pparent.getParent() instanceof PsiReturnStatement) { addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "emptyList", collectionsClass); @@ -50,7 +50,7 @@ class CollectionsUtilityMethodsProvider { addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "emptyMap", collectionsClass); } - if (parameters.getInvocationCount() > 1) { + if (parameters.getParameters().getInvocationCount() > 1) { addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "singletonList", collectionsClass); addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "singleton", collectionsClass); addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "singletonMap", collectionsClass); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 79fe32f1e62b..ed3c07767a2d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -7,6 +7,7 @@ import com.intellij.codeInsight.generation.PsiMethodMember; import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupElementDecorator; import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.util.MemberChooser; import com.intellij.openapi.application.ApplicationManager; @@ -16,6 +17,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; @@ -63,38 +65,67 @@ class ConstructorInsertHandler implements InsertHandler 0) { + TextRange range = paramList.getTextRange(); + context.getDocument().replaceString(range.getStartOffset(), range.getEndOffset(), "<>"); + editor.getCaretModel().moveToOffset(range.getStartOffset() + 1); + } + return; + } + } } } - if (mySmart) { - FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW); + } + + context.setLaterRunnable(generateAnonymousBody(editor, context.getFile())); + } + else { + final PsiNewExpression newExpression = + PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiNewExpression.class, false); + if (newExpression != null) { + final PsiJavaCodeReferenceElement classReference = newExpression.getClassOrAnonymousClassReference(); + if (classReference != null) { + CodeStyleManager.getInstance(context.getProject()).reformat(classReference); } } + if (mySmart) { + FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW); + } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index fcf92f5c8a61..6157ab88a59a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -220,15 +220,14 @@ public class JavaCompletionContributor extends CompletionContributor { addKeywords(parameters, result); - addAllClasses(parameters, result, position, inheritors); + addAllClasses(parameters, result, inheritors); result.stopHere(); } public static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, - PsiElement position, final InheritorsHolder inheritors) { - if (shouldRunClassNameCompletion(result, position)) { + if (shouldRunClassNameCompletion(result, parameters)) { JavaClassNameCompletionContributor.addAllClasses(parameters, result, new Consumer() { @Override public void consume(LookupElement element) { @@ -314,7 +313,8 @@ public class JavaCompletionContributor extends CompletionContributor { } } - private static boolean shouldRunClassNameCompletion(CompletionResultSet result, PsiElement position) { + private static boolean shouldRunClassNameCompletion(CompletionResultSet result, CompletionParameters parameters) { + PsiElement position = parameters.getPosition(); final PsiElement parent = position.getParent(); if (!(parent instanceof PsiJavaCodeReferenceElement)) return false; if (((PsiJavaCodeReferenceElement)parent).getQualifier() != null) return false; @@ -331,7 +331,7 @@ public class JavaCompletionContributor extends CompletionContributor { return false; } - return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix()); + return StringUtil.isCapitalized(result.getPrefixMatcher().getPrefix()) || parameters.relaxMatching(); } private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement, diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java index aea4cc222e4c..abc1425bdac8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java @@ -103,7 +103,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { result.addElement(item); } - JavaCompletionContributor.addAllClasses(parameters, result, position, new InheritorsHolder(position, result)); + JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(position, result)); } } }); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionParameters.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionParameters.java index b3aaf854c9bc..9796a359b44c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionParameters.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionParameters.java @@ -15,17 +15,19 @@ */ package com.intellij.codeInsight.completion; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import com.intellij.codeInsight.ExpectedTypeInfo; /** * @author peter */ -public class JavaSmartCompletionParameters extends CompletionParameters{ +public class JavaSmartCompletionParameters { + private final CompletionParameters myParameters; private final ExpectedTypeInfo myExpectedType; public JavaSmartCompletionParameters(CompletionParameters parameters, final ExpectedTypeInfo expectedType) { - super(parameters.getPosition(), parameters.getOriginalFile(), parameters.getCompletionType(), parameters.getOffset(), parameters.getInvocationCount()); + myParameters = parameters; myExpectedType = expectedType; } @@ -36,4 +38,12 @@ public class JavaSmartCompletionParameters extends CompletionParameters{ public PsiType getDefaultType() { return myExpectedType.getDefaultType(); } + + public PsiElement getPosition() { + return myParameters.getPosition(); + } + + public CompletionParameters getParameters() { + return myParameters; + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index 128fdc78843a..fafdeab63df0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -110,7 +110,7 @@ public class ReferenceExpressionCompletionContributor { final PsiElement element = parameters.getPosition(); if (JavaSmartCompletionContributor.INSIDE_TYPECAST_EXPRESSION.accepts(element)) return; - final int offset = parameters.getOffset(); + final int offset = parameters.getParameters().getOffset(); final PsiReference reference = element.getContainingFile().findReferenceAt(offset); if (reference != null) { final ElementFilter filter = getReferenceFilter(element, false); @@ -118,9 +118,9 @@ public class ReferenceExpressionCompletionContributor { result.consume(item); } - final boolean secondTime = parameters.getInvocationCount() >= 2; + final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2; - for (final LookupElement item : JavaSmartCompletionContributor.completeReference(element, reference, filter, false, parameters)) { + for (final LookupElement item : JavaSmartCompletionContributor.completeReference(element, reference, filter, false, parameters.getParameters())) { addSingleArrayElementAccess(element, item, parameters, result); if (secondTime) { @@ -164,7 +164,7 @@ public class ReferenceExpressionCompletionContributor { public boolean isClassAcceptable(Class hintClass) { return true; } - }), false, parameters); + }), false, parameters.getParameters()); for (LookupElement lookupElement : elements) { if (lookupElement.getObject() instanceof PsiMethod) { final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java index 5bd678959548..af2d3dfd6798 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java @@ -188,9 +188,10 @@ public class PostHighlightingPass extends TextEditorHighlightingPass { } public static void invokeOnTheFlyImportOptimizer(@NotNull final Runnable runnable, @NotNull final PsiFile file, @NotNull final Editor editor) { + final long stamp = editor.getDocument().getModificationStamp(); ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { - if (file.getProject().isDisposed() || editor.isDisposed()) return; + if (file.getProject().isDisposed() || editor.isDisposed() || editor.getDocument().getModificationStamp() != stamp) return; PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); String beforeText = file.getText(); CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java index c446d083b469..76b14c447fa6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java @@ -37,6 +37,7 @@ import com.intellij.find.impl.FindManagerImpl; import com.intellij.ide.util.SuperMethodWarningUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.undo.UndoUtil; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; @@ -68,6 +69,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction { private final boolean myChangeAllUsages; private final int myMinUsagesNumberToShowDialog; private ParameterInfoImpl[] myNewParametersInfo; + private static final Logger LOG = Logger.getInstance("#" + ChangeMethodSignatureFromUsageFix.class.getName()); ChangeMethodSignatureFromUsageFix(@NotNull PsiMethod targetMethod, @NotNull PsiExpression[] expressions, @@ -99,6 +101,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction { if (result.length() != 0) { result += ", "; } + LOG.assertTrue(type != null, "old idx: " + info.getOldIndex() + "; " + info.getClass().getName()); result += type.getPresentableText(); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java index e3aafe432b11..fd62c6b0b77e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java @@ -139,7 +139,10 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction { // do not introduce assignment in chanined constructor if (HighlightControlFlowUtil.getChainedConstructors(constructor) == null) { - AssignFieldFromParameterAction.addFieldAssignmentStatement(project, getField(), parameter, editor); + PsiField field = getField(); + if (field != null) { + AssignFieldFromParameterAction.addFieldAssignmentStatement(project, field, parameter, editor); + } } return true; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java index 13e6e6f4baba..8a3a22b2f791 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddOverrideAnnotationAction.java @@ -20,7 +20,7 @@ import com.intellij.codeInsight.intention.AddAnnotationFix; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -72,7 +72,8 @@ public class AddOverrideAnnotationAction implements IntentionAction { //Not available in method's body PsiCodeBlock body = res.getBody(); if (body == null) return null; - if (body.getTextRange().getStartOffset() <= offset) return null; + TextRange textRange = body.getTextRange(); + if (textRange == null || textRange.getStartOffset() <= offset) return null; return res; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java index c8a9646f2e05..b6989557af17 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java @@ -80,17 +80,17 @@ public class AssignFieldFromParameterAction extends BaseIntentionAction { IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace(); try { PsiField field = findFieldToAssign(myParameter); - addFieldAssignmentStatement(project, field, myParameter, editor); + if (field != null) addFieldAssignmentStatement(project, field, myParameter, editor); } catch (IncorrectOperationException e) { LOG.error(e); } } - public static void addFieldAssignmentStatement(final Project project, - final PsiField field, - final PsiParameter parameter, - final Editor editor) throws IncorrectOperationException { + public static void addFieldAssignmentStatement(@NotNull Project project, + @NotNull PsiField field, + @NotNull PsiParameter parameter, + @NotNull Editor editor) throws IncorrectOperationException { final PsiMethod method = (PsiMethod)parameter.getDeclarationScope(); PsiCodeBlock methodBody = method.getBody(); if (methodBody == null) return; diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaWhileUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaWhileUnwrapper.java index 3910887fb119..4a2b3635c75d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaWhileUnwrapper.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaWhileUnwrapper.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.unwrap; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.java.PsiWhileStatementImpl; import com.intellij.util.IncorrectOperationException; public class JavaWhileUnwrapper extends JavaUnwrapper { @@ -25,7 +26,9 @@ public class JavaWhileUnwrapper extends JavaUnwrapper { } public boolean isApplicableTo(PsiElement e) { - return e instanceof PsiWhileStatement || e instanceof PsiDoWhileStatement; + return e instanceof PsiWhileStatementImpl // Don't use "e instanceof PsiWhileStatement" because JspWhileStatement intanceof PsiWhileStatement, + // but we doesn't support unwrap JspWhileStatement. + || e instanceof PsiDoWhileStatement; } @Override diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java index 10a0aa98a4ff..860af752e6c3 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java @@ -218,6 +218,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext )); final List processors = myDerivedClassesRequests.get(sortedID); + LOG.assertTrue(processors != null, psiClass.getClass().getName()); ClassInheritorsSearch.search(psiClass, searchScope, false) .forEach(createMembersProcessor(processors, scope)); } @@ -229,12 +230,14 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext final List sortedIDs = getSortedIDs(myDerivedMethodsRequests); for (SmartPsiElementPointer sortedID : sortedIDs) { final PsiMethod psiMethod = (PsiMethod)sortedID.getElement(); + if (psiMethod == null) continue; final RefMethod refMethod = (RefMethod)refManager.getReference(psiMethod); context .incrementJobDoneAmount(GlobalInspectionContextImpl.FIND_EXTERNAL_USAGES, refManager.getQualifiedName(refMethod)); final List processors = myDerivedMethodsRequests.get(sortedID); + LOG.assertTrue(processors != null, psiMethod.getClass().getName()); OverridingMethodsSearch.search(psiMethod, searchScope, true) .forEach(createMembersProcessor(processors, scope)); } @@ -249,6 +252,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext if (psiField == null) continue; final List processors = myFieldUsagesRequests.get(sortedID); + LOG.assertTrue(processors != null, psiField.getClass().getName()); context .incrementJobDoneAmount(GlobalInspectionContextImpl.FIND_EXTERNAL_USAGES, refManager.getQualifiedName(refManager.getReference(psiField))); @@ -267,6 +271,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext if (psiClass == null) continue; final List processors = myClassUsagesRequests.get(sortedID); + LOG.assertTrue(processors != null, psiClass.getClass().getName()); context.incrementJobDoneAmount(GlobalInspectionContextImpl.FIND_EXTERNAL_USAGES, ApplicationManager.getApplication().runReadAction( new Computable() { public String compute() { @@ -289,6 +294,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext if (psiMethod == null) continue; final List processors = myMethodUsagesRequests.get(sortedID); + LOG.assertTrue(processors != null, psiMethod.getClass().getName()); context .incrementJobDoneAmount(GlobalInspectionContextImpl.FIND_EXTERNAL_USAGES, refManager.getQualifiedName(refManager.getReference(psiMethod))); diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java index e32806c81a66..2af30d5bffb6 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.psi.impl; import com.intellij.ProjectTopics; @@ -55,7 +51,6 @@ import com.intellij.psi.javadoc.JavadocManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.psi.util.PsiModificationTracker; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlFile; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Processor; @@ -65,10 +60,14 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentMap; +/** + * @author max + */ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.JavaPsiFacadeImpl"); @@ -90,9 +89,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { PsiManagerImpl psiManager, final ProjectRootManagerEx projectRootManagerEx, StartupManager startupManager, - MessageBus bus - - ) { + MessageBus bus) { myProject = project; myResolveHelper = new PsiResolveHelperImpl(PsiManager.getInstance(project)); myJavadocManager = new JavadocManagerImpl(project); @@ -270,7 +267,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { @NotNull public PsiJavaParserFacade getParserFacade() { - return getElementFactory(); // TODO: ligter implementation which doesn't mark all the elements as generated. + return getElementFactory(); // TODO: lighter implementation which doesn't mark all the elements as generated. } @NotNull @@ -370,6 +367,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { return false; } + @Nullable private PsiPackage findPackageDefault(String qualifiedName) { final PsiPackage aPackage = myFileManager.findPackage(qualifiedName); if (aPackage == null && myCurrentMigration != null) { @@ -416,9 +414,9 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { final Map packagesMap = new HashMap(); final String qualifiedName = psiPackage.getQualifiedName(); for (PsiDirectory dir : psiPackage.getDirectories(scope)) { - PsiDirectory[] subdirs = dir.getSubdirectories(); - for (PsiDirectory subdir : subdirs) { - final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(subdir); + PsiDirectory[] subDirs = dir.getSubdirectories(); + for (PsiDirectory subDir : subDirs) { + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir); if (aPackage != null) { final String subQualifiedName = aPackage.getQualifiedName(); if (subQualifiedName.startsWith(qualifiedName) && !packagesMap.containsKey(subQualifiedName)) { @@ -578,16 +576,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { case BEFORE_CHILD_MOVEMENT: case BEFORE_CHILD_REPLACEMENT: case BEFORE_CHILD_ADDITION: - break; case BEFORE_CHILD_REMOVAL: - checkAnnotation(event.getChild()); - checkModifierListOwner(event.getChild()); - if (event.getChild() instanceof PsiClassOwner) { - PsiClass[] classes = ((PsiClassOwner)event.getChild()).getClasses(); - for (PsiClass psiClass : classes) { - checkModifierListOwner(psiClass); - } - } break; case CHILD_ADDED: @@ -611,15 +600,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { } } - private void checkModifierListOwner(PsiElement child) { - if (child instanceof PsiClass || child instanceof PsiMethod) { - PsiModifierList modifierList = ((PsiModifierListOwner)child).getModifierList(); - if (modifierList != null && modifierList.getAnnotations().length > 0) { - myModificationTracker.incAnnotationModificationCounter(); - } - } - } - private void processChange(final PsiElement parent, final PsiElement child1, final PsiElement child2) { try { if (!isInsideCodeBlock(parent)) { @@ -629,8 +609,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { else { myModificationTracker.incOutOfCodeBlockModificationCounter(); } - checkAnnotation(parent); - checkModifierListOwner(parent); return; } @@ -643,12 +621,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { } } - private void checkAnnotation(PsiElement parent) { - if (PsiTreeUtil.getParentOfType(parent, PsiAnnotation.class, false) != null) { - myModificationTracker.incAnnotationModificationCounter(); - } - } - private static boolean isClassOwner(final PsiElement element) { return element instanceof PsiClassOwner && !(element instanceof XmlFile) || element instanceof JspDirective; } diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java index 15a2009b3d3a..d14200cece98 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java @@ -25,6 +25,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.impl.source.DummyHolder; @@ -34,6 +35,7 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -41,8 +43,6 @@ import org.jetbrains.annotations.NotNull; import java.util.Map; import java.util.Properties; -import static com.intellij.openapi.util.text.StringUtil.join; - /** * @author max */ @@ -79,6 +79,13 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ }; public static final JavaParserUtil.ParserWrapper REFERENCE = new JavaParserUtil.ParserWrapper() { + @Override + public void parse(final PsiBuilder builder) { + ReferenceParser.parseJavaCodeReference(builder, false, true, false, false, false); + } + }; + + public static final JavaParserUtil.ParserWrapper DIAMOND_REF = new JavaParserUtil.ParserWrapper() { @Override public void parse(final PsiBuilder builder) { ReferenceParser.parseJavaCodeReference(builder, false, true, false, false, true); @@ -174,7 +181,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override public PsiDocTag createDocTagFromText(@NotNull final String text) throws IncorrectOperationException { - return createDocCommentFromText(join("/**\n", text, "\n */")).getTags()[0]; + return createDocCommentFromText(StringUtil.join("/**\n", text, "\n */")).getTags()[0]; } @NotNull @@ -186,7 +193,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override public PsiDocComment createDocCommentFromText(@NotNull final String text) throws IncorrectOperationException { - final PsiMethod method = createMethodFromText(join(text, "void m();"), null); + final PsiMethod method = createMethodFromText(StringUtil.join(text, "void m();"), null); final PsiDocComment comment = method.getDocComment(); assert comment != null : text; return comment; @@ -201,7 +208,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @NotNull @Override public PsiClass createClassFromText(@NotNull final String body, final PsiElement context) throws IncorrectOperationException { - final PsiJavaFile aFile = createDummyJavaFile(join("class _Dummy_ { ", body, " }")); + final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ { ", body, " }")); final PsiClass[] classes = aFile.getClasses(); if (classes.length != 1) { throw new IncorrectOperationException("Incorrect class \"" + body + "\"."); @@ -293,7 +300,9 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException { final boolean isStaticImport = context instanceof PsiImportStaticStatement && !((PsiImportStaticStatement)context).isOnDemand(); - final JavaParserUtil.ParserWrapper wrapper = isStaticImport ? STATIC_IMPORT_REF : REFERENCE; + final boolean mayHaveDiamonds = context instanceof PsiNewExpression && + PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7); + final JavaParserUtil.ParserWrapper wrapper = isStaticImport ? STATIC_IMPORT_REF : mayHaveDiamonds ? DIAMOND_REF : REFERENCE; final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, false), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiJavaCodeReferenceElement)) { @@ -385,11 +394,12 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ @Override public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType, @NotNull final String exceptionName, final PsiElement context) throws IncorrectOperationException { - final String text = join("catch (", exceptionType.getCanonicalText(), " ", exceptionName, ") {}"); + final String text = StringUtil + .join("catch (", exceptionType.getCanonicalText(), " ", exceptionName, ") {}"); final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CATCH_SECTION, false), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiCatchSection)) { - throw new IncorrectOperationException("Incorrect catch section \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect catch section '" + text + "'. Parsed element: "+element); } setupCatchBlock(exceptionName, context, (PsiCatchSection)element); return (PsiCatchSection)myManager.getCodeStyleManager().reformat(element); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index 465ba6e29c9f..d9f9633b048e 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -524,7 +524,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme throw new IncorrectOperationException(aClass.toString()); } final PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(getProject()).getParserFacade(); - final PsiJavaCodeReferenceElement ref = parserFacade.createReferenceFromText(name, null); + final PsiJavaCodeReferenceElement ref = parserFacade.createReferenceFromText(name, getParent()); getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode()); return ref; } @@ -562,7 +562,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme final PsiManager manager = aClass.getManager(); final PsiReferenceParameterList parameterList = getParameterList(); String text = (parameterList != null ? qName + parameterList.getText() : qName); - PsiJavaCodeReferenceElement ref = facade.getParserFacade().createReferenceFromText(text, null); + PsiJavaCodeReferenceElement ref = facade.getParserFacade().createReferenceFromText(text, getParent()); getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode()); if (!preserveQualification /*&& (TreeUtil.findParent(ref, ElementType.DOC_COMMENT) == null)*/) { final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(aClass.getProject()); @@ -605,7 +605,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme throw new IncorrectOperationException("Cannot bind to default package: "+aPackage); } final PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(getProject()).getParserFacade(); - final PsiJavaCodeReferenceElement ref = parserFacade.createReferenceFromText(qName, null); + final PsiJavaCodeReferenceElement ref = parserFacade.createReferenceFromText(qName, getParent()); getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode()); return ref; } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index b49ea654f6dd..03419e8d18c6 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -259,7 +259,13 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements @NotNull public String getCanonicalText() { PsiElement element = resolve(); - if (element instanceof PsiClass) return ((PsiClass)element).getQualifiedName(); + if (element instanceof PsiClass) { + String fqn = ((PsiClass)element).getQualifiedName(); + if (fqn == null) { + LOG.error("FQN is null. reference:" + getElement().getText()+"; resolves to "+element); + } + return fqn; + } return getCachedTextSkipWhiteSpaceAndComments(); } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 9e8f2a32fabd..6f657eecc649 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -678,9 +678,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr PsiParameter[] parameters = list.getParameters(); final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters(); - PsiParameter[] newParms = new PsiParameter[parameterInfos.length - - (baseMethod != null ? baseMethod.getParameterList().getParametersCount() - - method.getParameterList().getParametersCount() : 0)]; + final int delta = baseMethod != null ? baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount() : 0; + PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)]; final String[] oldParameterNames = changeInfo.getOldParameterNames(); final String[] oldParameterTypes = changeInfo.getOldParameterTypes(); for (int i = 0; i < newParms.length; i++) { @@ -865,6 +864,20 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } } + for (UsageInfo usageInfo : usagesSet) { + if (usageInfo instanceof OverriderUsageInfo) { + final PsiMethod method = (PsiMethod)usageInfo.getElement(); + final PsiMethod baseMethod = ((OverriderUsageInfo)usageInfo).getBaseMethod(); + final int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount(); + if (delta > 0) { + final boolean[] toRemove = myChangeInfo.toRemoveParm(); + if (toRemove[toRemove.length - 1]) { //todo check if implicit parameter is not the last one + conflictDescriptions.putValue(baseMethod, "Implicit last parameter should not be deleted"); + } + } + } + } + return conflictDescriptions; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index a63f7a2a676f..1254d9567356 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -89,7 +89,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { myMethodToSearchFor = methodToSearchFor; myOccurrences = occurrences; myMustBeFinal = mustBeFinal; - myExprMarker = expr != null ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null; + myExprMarker = expr != null && expr.isPhysical() ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null; myExprText = myExpr != null ? myExpr.getText() : null; myWholePanel = new JPanel(new GridBagLayout()); @@ -187,7 +187,9 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { final JPanel wrapper = new JPanel(new BorderLayout()); wrapper.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - wrapper.add(myCanBeFinal, BorderLayout.NORTH); + if (myCanBeFinal != null) { + wrapper.add(myCanBeFinal, BorderLayout.NORTH); + } panel.add(wrapper, BorderLayout.SOUTH); return panel; @@ -200,7 +202,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { @Override protected PsiExpression getExpr() { - return myExpr; + return myExpr != null && myExpr.isValid() && myExpr.isPhysical() ? myExpr : null; } @Override @@ -299,9 +301,11 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { public void run() { final PsiFile containingFile = myMethod.getContainingFile(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); - myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker, myExprText); - if (myExpr != null) { - myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange()); + if (myExprMarker != null) { + myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker, myExprText); + if (myExpr != null) { + myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange()); + } } final List occurrenceMarkers = getOccurrenceMarkers(); for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index b8d27999117c..89b5b5b85567 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -164,8 +164,9 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R final Introducer introducer = new Introducer(project, expr, localVar, editor); final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); if (validEnclosingMethods.size() == 1 || unitTestMode) { - if (validEnclosingMethods.get(0).findDeepestSuperMethod() == null || unitTestMode) { - introducer.introduceParameter(method, method); + final PsiMethod methodToIntroduceParameterTo = validEnclosingMethods.get(0); + if (methodToIntroduceParameterTo.findDeepestSuperMethod() == null || unitTestMode) { + introducer.introduceParameter(methodToIntroduceParameterTo, methodToIntroduceParameterTo); return true; } } @@ -176,8 +177,8 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R } private void chooseMethodToIntroduceParameter(final Editor editor, - final List validEnclosingMethods, - final Introducer introducer) { + final List validEnclosingMethods, + final Introducer introducer) { final JPanel panel = new JPanel(new BorderLayout()); final JCheckBox superMethod = new JCheckBox("Use super method of", true); superMethod.setMnemonic('U'); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 001e566b46c3..2e95f0d34778 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -478,6 +478,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final VariableInplaceRenamer renamer = new VariableInplaceIntroducer(project, expression, editor, elementToRename, cantChangeFinalModifier, typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers); + PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); renamer.performInplaceRename(false, new LinkedHashSet(Arrays.asList(suggestedName.names))); } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java index 2a164b4ea3c6..5da76bbd8561 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java @@ -235,7 +235,9 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { titlePanel.setText(IntroduceVariableBase.REFACTORING_NAME); panel.add(titlePanel, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - panel.add(myCanBeFinal, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + if (myCanBeFinal != null) { + panel.add(myCanBeFinal, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + } panel.add(Box.createVerticalBox(), new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0,0)); diff --git a/java/java-impl/src/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java index 62ec0ecd036d..f2aa46ad6bd7 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/LocalHidesRenamedLocalUsageInfo.java @@ -40,9 +40,11 @@ public class LocalHidesRenamedLocalUsageInfo extends UnresolvableCollisionUsageI public String getDescription() { + PsiElement element = getElement(); + String type = element == null ? "element" : UsageViewUtil.getType(element); final String descr = RefactoringBundle.message("there.is.already.a.0.it.will.conflict.with.the.renamed.1", RefactoringUIUtil.getDescription(myConflictingElement, true), - UsageViewUtil.getType(getElement())); + type); return CommonRefactoringUtil.capitalize(descr); } } diff --git a/java/java-impl/src/com/intellij/refactoring/util/CanonicalTypes.java b/java/java-impl/src/com/intellij/refactoring/util/CanonicalTypes.java index ea47fb2c9e12..b86d99362340 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/CanonicalTypes.java +++ b/java/java-impl/src/com/intellij/refactoring/util/CanonicalTypes.java @@ -24,6 +24,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.List; @@ -38,6 +39,7 @@ public class CanonicalTypes { private CanonicalTypes() { } public abstract static class Type { + @NotNull public abstract PsiType getType(PsiElement context, final PsiManager manager) throws IncorrectOperationException; @NonNls @@ -53,6 +55,7 @@ public class CanonicalTypes { myType = type; } + @NotNull public PsiType getType(PsiElement context, final PsiManager manager) { return myType; } @@ -71,6 +74,7 @@ public class CanonicalTypes { myComponentType = componentType; } + @NotNull public PsiType getType(PsiElement context, final PsiManager manager) throws IncorrectOperationException { return myComponentType.getType(context, manager).createArrayType(); } @@ -91,6 +95,7 @@ public class CanonicalTypes { myComponentType = componentType; } + @NotNull public PsiType getType(PsiElement context, final PsiManager manager) throws IncorrectOperationException { return new PsiEllipsisType(myComponentType.getType(context, manager)); } @@ -113,6 +118,7 @@ public class CanonicalTypes { myBound = bound; } + @NotNull public PsiType getType(PsiElement context, final PsiManager manager) throws IncorrectOperationException { if(myBound == null) return PsiWildcardType.createUnbounded(context.getManager()); if (myIsExtending) { @@ -140,6 +146,7 @@ public class CanonicalTypes { myText = text; } + @NotNull public PsiType getType(PsiElement context, final PsiManager manager) throws IncorrectOperationException { return JavaPsiFacade.getInstance(context.getProject()).getElementFactory().createTypeFromText(myText, context); } @@ -162,6 +169,7 @@ public class CanonicalTypes { mySubstitutor = substitutor; } + @NotNull public PsiType getType(PsiElement context, final PsiManager manager) throws IncorrectOperationException { final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); final PsiElementFactory factory = facade.getElementFactory(); @@ -205,6 +213,7 @@ public class CanonicalTypes { myTypes = types; } + @NotNull @Override public PsiType getType(final PsiElement context, final PsiManager manager) throws IncorrectOperationException { final List types = ContainerUtil.map(myTypes, new Function() { diff --git a/java/java-tests/testData/codeInsight/completion/smartType/UnboundTypeArgs-out.java b/java/java-tests/testData/codeInsight/completion/smartType/UnboundTypeArgs-out.java new file mode 100644 index 000000000000..e0f7ba5fcded --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/UnboundTypeArgs-out.java @@ -0,0 +1,10 @@ +interface Foo {} +interface FooEx extends Foo { + T foo(); +} + +class Bar { + { + Foo f = new FooEx<>() {}; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/UnboundTypeArgs.java b/java/java-tests/testData/codeInsight/completion/smartType/UnboundTypeArgs.java new file mode 100644 index 000000000000..aa2333d3906c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/UnboundTypeArgs.java @@ -0,0 +1,10 @@ +interface Foo {} +interface FooEx extends Foo { + T foo(); +} + +class Bar { + { + Foo f = new FE + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addImport/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addImport/after1.java new file mode 100644 index 000000000000..1eaaa5649726 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addImport/after1.java @@ -0,0 +1,8 @@ +import java.util.Map; + +// "Import Class" "true" +public class Foo { + void foo() { + Map<> l; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addImport/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addImport/before1.java new file mode 100644 index 000000000000..a307e2447fc9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addImport/before1.java @@ -0,0 +1,6 @@ +// "Import Class" "true" +public class Foo { + void foo() { + Map<> l; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index b32fd98fe38c..8f90525530a4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -861,6 +861,8 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { doTest(); } + public void testUnboundTypeArgs() throws Exception { doTest(); } + public void testIDEADEV2668() throws Exception { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddImportActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddImportActionTest.java new file mode 100644 index 000000000000..bf3df435a68b --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddImportActionTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2011 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.intention; + +import com.intellij.codeInsight.daemon.LightIntentionActionTestCase; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.pom.java.LanguageLevel; + +public class AddImportActionTest extends LightIntentionActionTestCase { + + public void test() throws Exception { + final LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(getProject()); + + extension.setLanguageLevel(LanguageLevel.JDK_1_5); + doAllTests(); + + extension.setLanguageLevel(LanguageLevel.HIGHEST); + doAllTests(); + } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/addImport"; + } +} diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java index c8d9ce3ae398..d82b19dd8c87 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java @@ -29,9 +29,10 @@ public class CompletionParameters { private final CompletionType myCompletionType; private final int myOffset; private final int myInvocationCount; + private final boolean myRelaxedMatching; protected CompletionParameters(@NotNull final PsiElement position, @NotNull final PsiFile originalFile, - final CompletionType completionType, int offset, final int invocationCount) { + final CompletionType completionType, int offset, final int invocationCount, final boolean relaxedMatching) { assert offset >= position.getTextRange().getStartOffset(); myPosition = position; assert position.isValid(); @@ -39,14 +40,19 @@ public class CompletionParameters { myCompletionType = completionType; myOffset = offset; myInvocationCount = invocationCount; + myRelaxedMatching = relaxedMatching; } public CompletionParameters withType(CompletionType type) { - return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount); + return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myRelaxedMatching); } public CompletionParameters withInvocationCount(int newCount) { - return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount); + return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount, myRelaxedMatching); + } + + public CompletionParameters withRelaxedMatching() { + return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, myInvocationCount, true); } @NotNull @@ -82,4 +88,8 @@ public class CompletionParameters { public int getInvocationCount() { return myInvocationCount; } + + public boolean relaxMatching() { + return myRelaxedMatching; + } } diff --git a/platform/lang-api/src/com/intellij/find/FindModel.java b/platform/lang-api/src/com/intellij/find/FindModel.java index 33e4a8f99b12..5f4cbc12dd68 100644 --- a/platform/lang-api/src/com/intellij/find/FindModel.java +++ b/platform/lang-api/src/com/intellij/find/FindModel.java @@ -38,7 +38,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable { void findModelChanged(FindModel findModel); } - private CopyOnWriteArrayList myObservers = new CopyOnWriteArrayList(); + private final CopyOnWriteArrayList myObservers = new CopyOnWriteArrayList(); public void addObserver(FindModelObserver observer) { myObservers.add(observer); @@ -712,7 +712,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable { } public void setCustomScope(final SearchScope customScope) { - boolean changed = this.customScope != null ? this.customScope.equals(customScope) : (customScope != null); + boolean changed = this.customScope != null ? this.customScope.equals(customScope) : customScope != null; this.customScope = customScope; if (changed) { notifyObservers(); @@ -766,7 +766,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable { myPattern = pattern = Pattern.compile(toFind, isCaseSensitive() ? Pattern.MULTILINE : Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); } catch(PatternSyntaxException e){ - LOG.error(e); + LOG.error("Regexp:'"+toFind+"'", e); myPattern = null; return null; } diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiModificationTracker.java b/platform/lang-api/src/com/intellij/psi/util/PsiModificationTracker.java index 6bd00d4c7b67..2463c6c899b3 100644 --- a/platform/lang-api/src/com/intellij/psi/util/PsiModificationTracker.java +++ b/platform/lang-api/src/com/intellij/psi/util/PsiModificationTracker.java @@ -19,7 +19,6 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.ModificationTracker; public interface PsiModificationTracker extends ModificationTracker { - /** * This key can be passed as a dependency in a {@link com.intellij.psi.util.CachedValueProvider}. * @see #getModificationCount() @@ -48,12 +47,6 @@ public interface PsiModificationTracker extends ModificationTracker { long getJavaStructureModificationCount(); - /** - * Tracks modifications in Java annotations and annotated classes and methods. - * @return current counter value. - */ - long getAnnotationModificationCount(); - interface Listener { void modificationCountChanged(); } diff --git a/platform/lang-api/src/com/intellij/refactoring/RefactoringActionHandler.java b/platform/lang-api/src/com/intellij/refactoring/RefactoringActionHandler.java index d75c4e1afe28..43e4ebda2289 100644 --- a/platform/lang-api/src/com/intellij/refactoring/RefactoringActionHandler.java +++ b/platform/lang-api/src/com/intellij/refactoring/RefactoringActionHandler.java @@ -25,10 +25,11 @@ import org.jetbrains.annotations.NotNull; /** * RefactoringActionHandler is an implementation of IDEA refactoring, * with dialogs, UI and all. - * It is what gets invoked when user choses an item from 'Refactoring' menu.
+ * It is what gets invoked when user chooses an item from 'Refactoring' menu.
* * RefactoringActionHandler is a "one-shot" object: you should not * invoke it twice. + * * @see RefactoringActionHandlerFactory */ public interface RefactoringActionHandler { @@ -36,8 +37,9 @@ public interface RefactoringActionHandler { * Invokes refactoring action from editor. The refactoring obtains * all data from editor selection. * - * @param editor editor that refactoring is invoked in - * @param file file should correspond to editor + * @param project the project in which the refactoring is invoked. + * @param editor editor that refactoring is invoked in + * @param file file should correspond to editor * @param dataContext can be null for some but not all of refactoring action handlers * (it is recommended to pass DataManager.getDataContext() instead of null) */ @@ -47,8 +49,8 @@ public interface RefactoringActionHandler { * Invokes refactoring action from elsewhere (not from editor). Some refactorings * do not implement this method. * - * @param project the project in which the refactoring is invoked. - * @param elements list of elements that refactoring should work on. Refactoring-dependent. + * @param project the project in which the refactoring is invoked. + * @param elements list of elements that refactoring should work on. Refactoring-dependent. * @param dataContext can be null for some but not all of refactoring action handlers * (it is recommended to pass DataManager.getDataContext() instead of null) */ diff --git a/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java index be7b6eed7e0e..b4ea9663673e 100644 --- a/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java +++ b/platform/lang-impl/src/com/intellij/codeHighlighting/TextEditorHighlightingPass.java @@ -88,7 +88,8 @@ public abstract class TextEditorHighlightingPass implements HighlightingPass { public final void applyInformationToEditor() { if (!isValid()) return; // Document has changed. if (DumbService.getInstance(myProject).isDumb() && !(this instanceof DumbAware)) { - PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(getDocument()); + Document document = getDocument(); + PsiFile file = document == null ? null : PsiDocumentManager.getInstance(myProject).getPsiFile(document); if (file != null) { ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(myProject)).getFileStatusMap().markFileUpToDate(getDocument(), file, getId()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 421341b5e3cf..7d003ebd1a4e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -53,6 +53,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.impl.PsiFileEx; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -291,11 +292,20 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { indicator.duringCompletion(initContext); ProgressManager.checkCanceled(); - data.set(CompletionService.getCompletionService().performCompletion(parameters, new Consumer() { + Consumer consumer = new Consumer() { public void consume(final LookupElement lookupElement) { indicator.addItem(lookupElement); } - })); + }; + LookupElement[] result = CompletionService.getCompletionService().performCompletion(parameters, consumer); + if (NameUtil.isUseMinusculeHumpMatcher() && parameters.getInvocationCount() == 0) { + if (result.length == 0) { + result = CompletionService.getCompletionService().performCompletion(parameters.withRelaxedMatching(), consumer); + } else { + indicator.restartOnEmpty = true; + } + } + data.set(result); } }); } @@ -347,7 +357,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { LOG.error("wrong text: copy='" + fileCopy.getText() + "'; element='" + insertedElement.getText() + "'; range=" + range); } - return new CompletionParameters(insertedElement, fileCopy.getOriginalFile(), myCompletionType, offset, invocationCount); + return new CompletionParameters(insertedElement, fileCopy.getOriginalFile(), myCompletionType, offset, invocationCount, invocationCount >= 2); } private AutoCompletionDecision shouldAutoComplete( diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 5c51cacbda78..e77fad64b7cb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; +import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; import com.intellij.codeInsight.hint.EditorHintListener; import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.lookup.*; @@ -399,7 +400,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement Disposer.dispose(myQueue); CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); - assert currentCompletion == this : currentCompletion + "!=" + this; + LOG.assertTrue(currentCompletion == this, currentCompletion + "!=" + this); CompletionServiceImpl.getCompletionService().setCurrentCompletion(null); CompletionServiceImpl.assertPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.Synchronous.class, CompletionPhase.Restarted.class); @@ -573,6 +574,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } + public boolean restartOnEmpty = false; + public void prefixUpdated() { final CharSequence text = myEditor.getDocument().getCharsSequence(); final int caretOffset = myEditor.getCaretModel().getOffset(); @@ -585,7 +588,9 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } - hideAutopopupIfMeaningless(); + if (hideAutopopupIfMeaningless() && restartOnEmpty) { + CompletionAutoPopupHandler.scheduleAutoPopup(getProject(), myEditor, getParameters().getOriginalFile()); + } updateFocus(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java index 2e7378f5117d..70a83f4454e5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java @@ -28,13 +28,15 @@ public class CamelHumpMatcher extends PrefixMatcher { private NameUtil.Matcher myMatcher; private final boolean myCaseSensitive; private final int currentSetting; + private final boolean myRelaxedMatching; public CamelHumpMatcher(@NotNull final String prefix) { - this(prefix, true); + this(prefix, true, false); } - public CamelHumpMatcher(String prefix, boolean caseSensitive) { + public CamelHumpMatcher(String prefix, boolean caseSensitive, boolean relaxedMatching) { super(prefix); + myRelaxedMatching = relaxedMatching; currentSetting = CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE; myCaseSensitive = caseSensitive; } @@ -47,10 +49,11 @@ public class CamelHumpMatcher extends PrefixMatcher { ourLastCompletionCaseSetting = currentSetting; } - NameUtil.Matcher pattern = ourPatternCache.get(myPrefix); + String key = myRelaxedMatching + myPrefix; + NameUtil.Matcher pattern = ourPatternCache.get(key); if (pattern == null) { pattern = createCamelHumpsMatcher(); - ourPatternCache.put(myPrefix, pattern); + ourPatternCache.put(key, pattern); } myMatcher = pattern; } @@ -81,7 +84,7 @@ public class CamelHumpMatcher extends PrefixMatcher { @NotNull public PrefixMatcher cloneWithPrefix(@NotNull final String prefix) { - return new CamelHumpMatcher(prefix); + return new CamelHumpMatcher(prefix, myCaseSensitive, myRelaxedMatching); } private NameUtil.Matcher createCamelHumpsMatcher() { @@ -89,6 +92,10 @@ public class CamelHumpMatcher extends PrefixMatcher { return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true); } + if (myRelaxedMatching) { + return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true); + } + switch (CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE) { case CodeInsightSettings.NONE: return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true); @@ -106,4 +113,8 @@ public class CamelHumpMatcher extends PrefixMatcher { public String toString() { return myPrefix; } + + public boolean isRelaxedMatching() { + return myRelaxedMatching; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 99b2bf31a3c5..7b78d815d82d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -82,7 +82,7 @@ public class CompletionServiceImpl extends CompletionService{ final PsiElement position = parameters.getPosition(); final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset()); final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset()); - return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix), contributor, defaultSorter(parameters), null); + return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix, true, parameters.relaxMatching()), contributor, defaultSorter(parameters), null); } @Override @@ -148,7 +148,8 @@ public class CompletionServiceImpl extends CompletionService{ @NotNull public CompletionResultSet withPrefixMatcher(@NotNull final String prefix) { - return withPrefixMatcher(new CamelHumpMatcher(prefix)); + boolean relaxed = getPrefixMatcher() instanceof CamelHumpMatcher && ((CamelHumpMatcher)getPrefixMatcher()).isRelaxedMatching(); + return withPrefixMatcher(new CamelHumpMatcher(prefix, true, relaxed)); } @NotNull @@ -160,7 +161,8 @@ public class CompletionServiceImpl extends CompletionService{ @NotNull @Override public CompletionResultSet caseInsensitive() { - return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false)); + boolean relaxed = getPrefixMatcher() instanceof CamelHumpMatcher && ((CamelHumpMatcher)getPrefixMatcher()).isRelaxedMatching(); + return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false, relaxed)); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index f8d7ffac5e18..31ed3138b919 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -423,10 +423,12 @@ public class HighlightInfo implements Segment { } public int getActualStartOffset() { - return highlighter == null || !highlighter.isValid() ? startOffset : highlighter.getStartOffset(); + RangeHighlighterEx h = highlighter; + return h == null || !h.isValid() ? startOffset : h.getStartOffset(); } public int getActualEndOffset() { - return highlighter == null || !highlighter.isValid() ? endOffset : highlighter.getEndOffset(); + RangeHighlighterEx h = highlighter; + return h == null || !h.isValid() ? endOffset : h.getEndOffset(); } //public void setCustomColorScheme(@Nullable final EditorColorsScheme customColorScheme) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index caf48987b262..207642e11676 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -76,6 +76,11 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { return Result.CONTINUE; } + scheduleAutoPopup(project, editor, file); + return Result.STOP; + } + + public static void scheduleAutoPopup(final Project project, final Editor editor, final PsiFile file) { final boolean isMainEditor = FileEditorManager.getInstance(project).getSelectedTextEditor() == editor; final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(); @@ -95,7 +100,6 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { } }; AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, CodeInsightSettings.getInstance().AUTO_LOOKUP_DELAY); - return Result.STOP; } public static void invokeAutoPopupCompletion(Project project, final Editor editor) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java index d147913fbba2..938b42fe5d8d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectWordUtil.java @@ -20,6 +20,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.TextRange; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -102,9 +103,12 @@ public class SelectWordUtil { return null; } - public static TextRange getWordSelectionRange(CharSequence editorText, int cursorOffset) { - if (editorText.length() == 0) return null; - if (cursorOffset > 0 && !Character.isJavaIdentifierPart(editorText.charAt(cursorOffset)) && + @Nullable + public static TextRange getWordSelectionRange(@NotNull CharSequence editorText, int cursorOffset) { + int length = editorText.length(); + if (length == 0) return null; + if (cursorOffset == length || + cursorOffset > 0 && !Character.isJavaIdentifierPart(editorText.charAt(cursorOffset)) && Character.isJavaIdentifierPart(editorText.charAt(cursorOffset - 1))) { cursorOffset--; } @@ -117,7 +121,7 @@ public class SelectWordUtil { start--; } - while (end < editorText.length() && Character.isJavaIdentifierPart(editorText.charAt(end))) { + while (end < length && Character.isJavaIdentifierPart(editorText.charAt(end))) { end++; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 96cc9fd1da61..50b649715a8a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -87,12 +87,12 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { private final Project myProject; private final Editor myEditor; - private int myMinPrefixLength; private int myPreferredItemsCount; private String myInitialPrefix; private LookupArranger myCustomArranger; - private RangeMarker myLookupStartMarker; + private boolean myStableStart; + @NotNull private RangeMarker myLookupStartMarker; private final JList myList = new JBList(new DefaultListModel()); private final LookupCellRenderer myCellRenderer; private Boolean myPositionedAbove = null; @@ -154,6 +154,8 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { myIconPanel.setBackground(Color.LIGHT_GRAY); myIconPanel.add(myProcessIcon); + updateLookupStart(0); + final ListModel model = myList.getModel(); addEmptyItem((DefaultListModel)model); updateListHeight(model); @@ -270,10 +272,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { return myModel.getActionsFor(element); } - public int getMinPrefixLength() { - return myMinPrefixLength; - } - public JList getList() { return myList; } @@ -421,15 +419,17 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } private void checkMinPrefixLengthChanges(Collection items) { + if (myStableStart) return; + if (!myCalculating && !items.isEmpty()) { + myStableStart = true; + } + int minPrefixLength = items.isEmpty() ? 0 : Integer.MAX_VALUE; for (final LookupElement item : items) { minPrefixLength = Math.min(item.getPrefixMatcher().getPrefix().length(), minPrefixLength); } - if (myMinPrefixLength != minPrefixLength) { - myLookupStartMarker = null; - } - myMinPrefixLength = minPrefixLength; + updateLookupStart(minPrefixLength); } private void restoreSelection(@Nullable LookupElement oldSelected, boolean choosePreselectedItem, @Nullable String oldInvariant) { @@ -568,7 +568,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { Dimension dim = component.getPreferredSize(); int lookupStart = getLookupStart(); if (lookupStart < 0) { - LOG.error(lookupStart + "; minprefix=" + myMinPrefixLength + "; offset=" + myEditor.getCaretModel().getOffset() + "; element=" + + LOG.error(lookupStart + "; offset=" + myEditor.getCaretModel().getOffset() + "; element=" + getPsiElement()); } @@ -656,12 +656,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } public int getLookupStart() { - if (myLookupStartMarker == null) { - final int start = calcLookupStart(); - myLookupStartMarker = myEditor.getDocument().createRangeMarker(start, start); - myLookupStartMarker.setGreedyToLeft(true); - } - return myLookupStartMarker.getStartOffset(); } @@ -675,6 +669,9 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { finally { myChangeGuard = false; } + if (isVisible()) { + updateLookupBounds(); + } LOG.assertTrue(!myDisposed, disposeTrace); } @@ -816,11 +813,14 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } - private int calcLookupStart() { + private int updateLookupStart(int myMinPrefixLength) { int offset = myEditor.getSelectionModel().hasSelection() ? myEditor.getSelectionModel().getSelectionStart() : myEditor.getCaretModel().getOffset(); - return Math.max(offset - myMinPrefixLength - myAdditionalPrefix.length(), 0); + int start = Math.max(offset - myMinPrefixLength - myAdditionalPrefix.length(), 0); + myLookupStartMarker = myEditor.getDocument().createRangeMarker(start, start); + myLookupStartMarker.setGreedyToLeft(true); + return start; } @Nullable @@ -1138,8 +1138,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } updateScrollbarVisibility(); - HintManagerImpl.adjustEditorHintPosition(this, myEditor, calculatePosition(getComponent())); - layoutStatusIcons(); + updateLookupBounds(); if (reused) { ensureSelectionVisible(); @@ -1147,6 +1146,11 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } + private void updateLookupBounds() { + HintManagerImpl.adjustEditorHintPosition(this, myEditor, calculatePosition(getComponent())); + layoutStatusIcons(); + } + private void layoutStatusIcons() { final JLayeredPane layeredPane = getComponent().getRootPane().getLayeredPane(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java index 0c32cfa102bd..16a9ae0f7ead 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java @@ -126,8 +126,11 @@ public class TypedHandler implements TypedActionHandler { @Nullable private static CharFilter.Result getFiltersDecision(char charTyped, LookupImpl lookup) { + LookupElement item = lookup.getCurrentItem(); + int prefixLength = (item == null ? 0 : item.getPrefixMatcher().getPrefix().length()) + lookup.getAdditionalPrefix().length(); + for (final CharFilter extension : getFilters()) { - final CharFilter.Result result = extension.acceptChar(charTyped, lookup.getMinPrefixLength() + lookup.getAdditionalPrefix().length(), lookup); + final CharFilter.Result result = extension.acceptChar(charTyped, prefixLength, lookup); if (result != null) { return result; } diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 25c2e8dd3756..8d830f886b2b 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -47,6 +47,7 @@ import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; @@ -699,7 +700,7 @@ public class FindUtil { }; editor.getCaretModel().addCaretListener(listener); } - JComponent component = HintUtil.createInformationLabel(message); + JComponent component = HintUtil.createInformationLabel(JDOMUtil.escapeText(message, false, false)); final LightweightHint hint = new LightweightHint(component); HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, HintManager.UNDER, HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java index abe5c374252b..31845dd7dcc9 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java @@ -133,10 +133,11 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil myUserActivityDelay = userActivityDelay; } - public void updateInBackground(final FindModel findModel, final boolean allowedToChangedEditorSelection) { + public void updateInBackground(FindModel findModel, final boolean allowedToChangedEditorSelection) { myLivePreviewAlarm.cancelAllRequests(); if (findModel == null) return; final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); + final FindModel copy = (FindModel)findModel.clone(); Runnable request = new Runnable() { @Override public void run() { @@ -151,7 +152,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil } else { ApplicationManager.getApplication().invokeAndWait(denyReplace, ModalityState.NON_MODAL); } - mySearchResults.updateThreadSafe(findModel, allowedToChangedEditorSelection, null); + mySearchResults.updateThreadSafe(copy, allowedToChangedEditorSelection, null); } }; if (unitTestMode) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java index fcf036795d8d..e1b9ca5bdc0a 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java @@ -13,30 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * Created by IntelliJ IDEA. - * User: mike - * Date: Jul 18, 2002 - * Time: 5:57:57 PM - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ package com.intellij.psi.impl; import com.intellij.ProjectTopics; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.PsiDirectory; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.messages.MessageBus; +import java.util.concurrent.atomic.AtomicLong; + +/** + * @author mike + * Date: Jul 18, 2002 + */ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTreeChangePreprocessor { - private volatile long myModificationCount = 0; - private volatile long myOutOfCodeBlockModificationCount = 0; - private volatile long myJavaStructureModificationCount = 0; - private volatile long myAnnotationModificationCount = 0; + private final AtomicLong myModificationCount = new AtomicLong(0); + private final AtomicLong myOutOfCodeBlockModificationCount = new AtomicLong(0); + private final AtomicLong myJavaStructureModificationCount = new AtomicLong(0); private final Listener myPublisher; public PsiModificationTrackerImpl(Project project) { @@ -58,23 +54,19 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr }); } - public void incCounter(){ - myModificationCount++; - myJavaStructureModificationCount++; + public void incCounter() { + myModificationCount.getAndIncrement(); + myJavaStructureModificationCount.getAndIncrement(); incOutOfCodeBlockModificationCounter(); } public void incOutOfCodeBlockModificationCounter() { - myOutOfCodeBlockModificationCount++; + myOutOfCodeBlockModificationCount.getAndIncrement(); myPublisher.modificationCountChanged(); } - public void incAnnotationModificationCounter() { - myAnnotationModificationCount++; - } - public void treeChanged(PsiTreeChangeEventImpl event) { - myModificationCount++; + myModificationCount.getAndIncrement(); if (event.getParent() instanceof PsiDirectory) { incOutOfCodeBlockModificationCounter(); } @@ -83,18 +75,14 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr } public long getModificationCount() { - return myModificationCount; + return myModificationCount.get(); } public long getOutOfCodeBlockModificationCount() { - return myOutOfCodeBlockModificationCount; + return myOutOfCodeBlockModificationCount.get(); } public long getJavaStructureModificationCount() { - return myJavaStructureModificationCount; - } - - public long getAnnotationModificationCount() { - return myAnnotationModificationCount; + return myJavaStructureModificationCount.get(); } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java index 58c8201cdb57..07a62799ea0e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java @@ -81,8 +81,8 @@ public class IndexCacheManagerImpl implements CacheManager{ return processor.getResults().isEmpty() ? PsiFile.EMPTY_ARRAY : processor.toArray(PsiFile.EMPTY_ARRAY); } - public static boolean shouldBeFound(VirtualFile virtualFile, ProjectFileIndex index) { - return (index.isInContent(virtualFile) || index.isInLibrarySource(virtualFile)) && !virtualFile.getFileType().isBinary(); + public static boolean shouldBeFound(GlobalSearchScope scope, VirtualFile virtualFile, ProjectFileIndex index) { + return (scope.isSearchOutsideRootModel() || index.isInContent(virtualFile) || index.isInLibrarySource(virtualFile)) && !virtualFile.getFileType().isBinary(); } public boolean processFilesWithWord(@NotNull final Processor psiFileProcessor, @NotNull final String word, final short occurrenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) { @@ -111,13 +111,12 @@ public class IndexCacheManagerImpl implements CacheManager{ if (vFiles.isEmpty()) return true; final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); - final boolean globalScope = scope.isSearchOutsideRootModel(); final Processor virtualFileProcessor = new ReadActionProcessor() { @Override public boolean processInReadAction(VirtualFile virtualFile) { LOG.assertTrue(virtualFile.isValid()); - if (virtualFile.isValid() && scope.contains(virtualFile) && (globalScope || shouldBeFound(virtualFile, index))) { + if (virtualFile.isValid() && scope.contains(virtualFile) && shouldBeFound(scope, virtualFile, index)) { final PsiFile psiFile = myPsiManager.findFile(virtualFile); return psiFile == null || psiFileProcessor.process(psiFile); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index b6d1302fb081..22caca427ebf 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -674,21 +674,20 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final GlobalSearchScope commonScope, final ProgressIndicator progress) { final MultiMap local = createMultiMap(); - final boolean inRootsOnly = !commonScope.isSearchOutsideRootModel(); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { if (progress != null) progress.checkCanceled(); FileBasedIndex.getInstance().processValues(IdIndex.NAME, entry, null, new FileBasedIndex.ValueProcessor() { public boolean process(VirtualFile file, Integer value) { if (progress != null) progress.checkCanceled(); - if (inRootsOnly && !IndexCacheManagerImpl.shouldBeFound(file, index)) { - return true; - } - int mask = value.intValue(); - for (RequestWithProcessor single : data) { - final PsiSearchRequest request = single.request; - if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) { - local.putValue(file, single); + + if (IndexCacheManagerImpl.shouldBeFound(commonScope, file, index)) { + int mask = value.intValue(); + for (RequestWithProcessor single : data) { + final PsiSearchRequest request = single.request; + if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) { + local.putValue(file, single); + } } } return true; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java index 886eb2f81ffe..79d46cefb692 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java @@ -166,4 +166,9 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider { } } } + + @Override + public String toString() { + return "Injected file '"+getVirtualFile().getName()+"' " + (isValid() ? "" : " invalid") + (physical ? "" : " nonphysical"); + } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java index 47a892abfbe6..927486970b09 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java @@ -102,10 +102,16 @@ public abstract class ParameterTableModelBase

extends L if (!table.isCellEditable(row, table.convertColumnIndexToModel(column))) { Color bg = table.getBackground().darker(); component.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 230)); - if (component instanceof EditorTextField) { - ((EditorTextField)component).setCenterByHeight(false); - } } + + if (component instanceof EditorTextField) { + ((EditorTextField)component).setCenterByHeight(false); + } + + if (component instanceof SimpleColoredComponent) { + ((SimpleColoredComponent)component).setIpad(new Insets(0, 0, 0, 0)); + } + return component; } }; diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java index f76582636804..388efed04a1e 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java @@ -63,6 +63,12 @@ public class CodeFragmentTableCellRenderer implements TableCellRenderer { } }; } + + if (!table.isShowing()) { + editorTextField.ensureWillComputePreferredSize(); + } + + editorTextField.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); editorTextField.setBorder(hasFocus ? BorderFactory.createLineBorder(table.getForeground()): new EmptyBorder(1, 1, 1, 1)); return editorTextField; } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index 9b159b26218c..18e210767567 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -3338,11 +3338,6 @@ public class AbstractTreeUi { notified = true; } } - - if (!notified) { - myTreeModel.nodeChanged(node); - } - } public DefaultTreeModel getTreeModel() { diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java index e8f09344f49a..e6bf2e36b339 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java @@ -43,15 +43,17 @@ public class DataKey { } public static DataKey create(@NotNull @NonNls String name) { - if (ourDataKeyIndex.containsKey(name)) { - //noinspection unchecked - return ourDataKeyIndex.get(name); + //noinspection unchecked + DataKey key = ourDataKeyIndex.get(name); + if (key != null) { + return key; } - DataKey key = new DataKey(name); + key = new DataKey(name); ourDataKeyIndex.put(name, key); return key; } + @NotNull public String getName() { return myName; } @@ -74,7 +76,7 @@ public class DataKey { } @Nullable - public T getData(DataProvider dataProvider) { + public T getData(@NotNull DataProvider dataProvider) { //noinspection unchecked return (T) dataProvider.getData(myName); } diff --git a/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java b/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java index 59c0d210a457..5a96c0ed05be 100644 --- a/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java @@ -29,7 +29,9 @@ public class BooleanTableCellRenderer extends JCheckBox implements TableCellRend public BooleanTableCellRenderer() { super(); - setHorizontalAlignment(JLabel.CENTER); + setHorizontalAlignment(CENTER); + setVerticalAlignment(CENTER); + setBorder(null); } public Component getTableCellRendererComponent(JTable table, Object value, diff --git a/platform/platform-api/src/com/intellij/ui/components/JBViewport.java b/platform/platform-api/src/com/intellij/ui/components/JBViewport.java index ed1180d4f867..c1f65c4561f9 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBViewport.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBViewport.java @@ -49,6 +49,11 @@ public class JBViewport extends JViewport { }); } + @Override + public Dimension getPreferredSize() { + return super.getPreferredSize(); //To change body of overridden methods use File | Settings | File Templates. + } + @Override public void paint(Graphics g) { super.paint(g); diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java index e2b5c222f367..72b106b4934d 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java @@ -48,7 +48,7 @@ public class HintUtil { HintHint hintHint = new HintHint().setTextBg(INFORMATION_COLOR).setTextFg(Color.black).setFont(getBoldFont()).setAwtTooltip(true); HintLabel label = new HintLabel(); - label.setText(JDOMUtil.escapeText(text, false, false), hintHint); + label.setText(text, hintHint); label.setIcon(INFORMATION_ICON); if (!hintHint.isAwtTooltip()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java index 6d90ee6f7eb6..b9d53adc76c1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java @@ -379,7 +379,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return myDisposed || temporarilyDisposed; } - private volatile boolean temporarilyDisposed = false; + protected volatile boolean temporarilyDisposed = false; @TestOnly public void setTemporarilyDisposed(boolean disposed) { temporarilyDisposed = disposed; @@ -725,6 +725,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return super.hashCode(); } + @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"}) public final boolean equals(Object obj) { return super.equals(obj); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java index 8197d311427f..07e1e7df6b1c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java @@ -81,11 +81,13 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx } public int getStartOffset() { - return intervalStart() + (myNode == null ? 0 : myNode.computeDeltaUpToRoot()); + RangeMarkerTree.RMNode node = myNode; + return intervalStart() + (node == null ? 0 : node.computeDeltaUpToRoot()); } public int getEndOffset() { - return intervalEnd() + (myNode == null ? 0 : myNode.computeDeltaUpToRoot()); + RangeMarkerTree.RMNode node = myNode; + return intervalEnd() + (node == null ? 0 : node.computeDeltaUpToRoot()); } public void invalidate() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java index a0ced136790a..2e337d355a48 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java @@ -144,7 +144,7 @@ public abstract class RedBlackTree { Node e = n; while (e.getParent() != null) e = e.getParent(); - assert e == root; // assert the node belongs to our tree + assert e == root : e; // assert the node belongs to our tree if (n.getLeft() != null && n.getRight() != null) { // Copy key/value from predecessor and then delete it instead diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index 7240dd7f3e19..0e514acfdd43 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -1568,14 +1568,14 @@ private final class MyVirtualFileListener extends VirtualFileAdapter { // already open if (eachWindow.findFileIndex(newFile) != -1) continue; - closeFile(eachFile, eachWindow); try { newFile.putUserData(EditorWindow.INITIAL_INDEX_KEY, i); - openFile(newFile, eachFile == selected); + openFileImpl2(eachWindow, newFile, eachFile == selected); } finally { newFile.putUserData(EditorWindow.INITIAL_INDEX_KEY, null); } + closeFile(eachFile, eachWindow); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java index 3a310408c839..2bcc26bbf359 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java @@ -454,7 +454,8 @@ public class ProjectImpl extends ComponentManagerImpl implements ProjectEx { @Override public String toString() { return "Project" - + (isDisposed() ? " (Disposed)" : isDefault() ? "" : " '" + getLocation()+"'") + + (isDisposed() ? " (Disposed" + (temporarilyDisposed ? " temporarily" : "") + ")" + :isDefault() ? "" : " '" + getLocation()+"'") + (isDefault() ? " (Default)" : "") + " " + myName ; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index e2082d36e450..804f5fa9c787 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -170,7 +170,9 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { Disposer.register(Disposer.get("ui"), this); } - addWidget(new ToolWindowsWidget(), Position.LEFT); + if (master == null) { + addWidget(new ToolWindowsWidget(), Position.LEFT); + } } @@ -762,7 +764,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { return myFrame; } - private static class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusBarWidget.Multiframe, Disposable, + private static class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusBarWidget, Disposable, UISettingsListener, PropertyChangeListener { private static final Icon HIDDEN = IconLoader.getIcon("/general/tbShown.png"); @@ -841,11 +843,6 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { return myStatusBar != null && myStatusBar.getFrame() != null && myStatusBar.getFrame().getProject() != null && Registry.is("ide.windowSystem.showTooWindowButtonsSwitcher"); } - @Override - public StatusBarWidget copy() { - return new ToolWindowsWidget(); - } - @Override public JComponent getComponent() { return this; diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java index 6e217d4d1beb..410b47c0cf23 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java @@ -74,6 +74,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, private Color myEnforcedBgColor = null; private boolean myOneLineMode; // use getter to access this field! It is allowed to override getter and change initial behaviour private boolean myCenterByHeight = true; + private boolean myEnsureWillComputePreferredSize; + private Dimension myPassivePreferredSize; public EditorTextField() { this(""); @@ -307,9 +309,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, boolean isFocused = isFocusOwner(); - myEditor = createEditor(); - final JComponent component = myEditor.getComponent(); - add(component); + initEditor(); super.addNotify(); @@ -323,6 +323,12 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, } } + private void initEditor() { + myEditor = createEditor(); + final JComponent component = myEditor.getComponent(); + add(component); + } + public void removeNotify() { super.removeNotify(); releaseEditor(); @@ -555,7 +561,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, int prefHeight = c.getPreferredSize().height; if (myOneLineMode && getSize().height > prefHeight && myCenterByHeight) { int y = insets.top + getSize().height / 2 - prefHeight / 2; - c.setBounds(insets.left, y - 1, getSize().width - insets.left - insets.right, prefHeight); + c.setBounds(insets.left, y, getSize().width - insets.left - insets.right, prefHeight + 1); } else { c.setBounds(insets.left, insets.top, getSize().width - insets.left - insets.right, getSize().height - insets.top - insets.bottom); } @@ -565,6 +571,16 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, if (super.isPreferredSizeSet()) { return super.getPreferredSize(); } + + boolean toReleaseEditor = false; + if (myEditor == null && myEnsureWillComputePreferredSize) { + myEnsureWillComputePreferredSize = false; + initEditor(); + toReleaseEditor = true; + } + + + Dimension size = new Dimension(100, 20); if (myEditor != null) { final Dimension preferredSize = new Dimension(myEditor.getComponent().getPreferredSize()); final Insets insets = getInsets(); @@ -574,10 +590,17 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, preferredSize.height += insets.top; preferredSize.height += insets.bottom; } - - return preferredSize; + size = preferredSize; + } else if (myPassivePreferredSize != null) { + size = myPassivePreferredSize; } - return new Dimension(100, 20); + + if (toReleaseEditor) { + releaseEditor(); + myPassivePreferredSize = size; + } + + return size; } public Component getNextFocusableComponent() { @@ -653,6 +676,10 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, myCenterByHeight = centerByHeight; } + public void ensureWillComputePreferredSize() { + myEnsureWillComputePreferredSize = true; + } + private static class DelegatingToRootTraversalPolicy extends FocusTraversalPolicy { @Override public Component getComponentAfter(final Container aContainer, final Component aComponent) { diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMCustomMessagesParsing.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMCustomMessagesParsing.java index 0420bfbbd2d4..aca2118f3404 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMCustomMessagesParsing.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMCustomMessagesParsing.java @@ -15,13 +15,16 @@ */ package com.intellij.execution.testframework.sm; +import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.sm.runner.OutputToGeneralTestEventsConverter; +import org.jetbrains.annotations.NotNull; /** * @author gregsh */ public interface SMCustomMessagesParsing { - OutputToGeneralTestEventsConverter createTestEventsConverter(final String testFrameworkName); + OutputToGeneralTestEventsConverter createTestEventsConverter(@NotNull final String testFrameworkName, + @NotNull final TestConsoleProperties consoleProperties); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java index 926310c5741c..04a0391b79d0 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java @@ -179,8 +179,8 @@ public class SMTestRunnerConnectionUtil { @NotNull final String testFrameworkName) { //build messages consumer final OutputToGeneralTestEventsConverter outputConsumer = consoleProperties instanceof SMCustomMessagesParsing - ? ((SMCustomMessagesParsing)consoleProperties).createTestEventsConverter(testFrameworkName) - : new OutputToGeneralTestEventsConverter(testFrameworkName); + ? ((SMCustomMessagesParsing)consoleProperties).createTestEventsConverter(testFrameworkName, consoleProperties) + : new OutputToGeneralTestEventsConverter(testFrameworkName, consoleProperties); //events processor final GeneralToSMTRunnerEventsConvertor eventsProcessor = new GeneralToSMTRunnerEventsConvertor(resultsViewer.getTestsRootNode(), diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java index 72d25d4ae4ae..2f5a921a296d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java @@ -16,6 +16,7 @@ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; @@ -41,10 +42,13 @@ import static com.intellij.execution.testframework.sm.runner.GeneralToSMTRunnerE */ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer { private static final Logger LOG = Logger.getInstance(OutputToGeneralTestEventsConverter.class.getName()); - + + private static final String TEAMCITY_SERVICE_MESSAGE_PREFIX = "##teamcity["; + private GeneralTestEventsProcessor myProcessor; private final MyServiceMessageVisitor myServiceMessageVisitor; private final String myTestFrameworkName; + private boolean myStdinSupportEnabled; private static class OutputChunk { private final Key myKey; @@ -70,10 +74,12 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer private final List myOutputChunks; - public OutputToGeneralTestEventsConverter(@NotNull final String testFrameworkName) { + public OutputToGeneralTestEventsConverter(@NotNull final String testFrameworkName, + @NotNull final TestConsoleProperties consoleProperties) { myTestFrameworkName = testFrameworkName; myServiceMessageVisitor = new MyServiceMessageVisitor(); myOutputChunks = new ArrayList(); + myStdinSupportEnabled = consoleProperties.isEditable(); } public void setProcessor(final GeneralTestEventsProcessor processor) { @@ -145,9 +151,28 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer if (lastChar == '\n' || lastChar == '\r') { // buffer contains consistent string flushStdOutputBuffer(); + } else { + // test framework may show some promt and ask user for smth. Question may not + // finish with \n or \r thus buffer wont be flushed and user will have to input smth + // before question. And question will became visible with next portion of text. + // Such behaviour is confusing. So + // 1. Let's assume that sevice messages starts with \n if console is editable + // 2. Then we can suggest that each service message will start from new line and buffer should + // be flushed before every service message. Thus if chunks list is empty and output doesn't end + // with \n or \r but starts with ##teamcity then it is a service message and should be buffered otherwise + // we can safely flush buffer. + + // TODO if editable: + if (myStdinSupportEnabled && !isMostLikelyServiceMessagePart(text)) { + flushStdOutputBuffer(); + } } } + protected boolean isMostLikelyServiceMessagePart(@NotNull final String text) { + return text.startsWith(TEAMCITY_SERVICE_MESSAGE_PREFIX); + } + private void processConsistentText(final String text, final Key outputType, boolean tcLikeFakeOutput) { try { final ServiceMessage serviceMessage = parseServiceMessage(text, outputType); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java index cab20db48634..bcbd4ba5260f 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java @@ -20,6 +20,7 @@ import com.intellij.execution.configurations.RuntimeConfiguration; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.ide.util.PropertiesComponent; import com.intellij.util.config.Storage; +import org.jetbrains.annotations.NotNull; /** * @author: Roman Chernyatchik @@ -32,11 +33,12 @@ public class SMTRunnerConsoleProperties extends TestConsoleProperties { * @param testFrameworkName Prefix for storage which keeps runner settings. E.g. "RubyTestUnit" * @param executor */ - public SMTRunnerConsoleProperties(final RuntimeConfiguration config, - final String testFrameworkName, - Executor executor) + public SMTRunnerConsoleProperties(@NotNull final RuntimeConfiguration config, + @NotNull final String testFrameworkName, + @NotNull final Executor executor) { - super(new Storage.PropertiesComponentStorage(testFrameworkName + "Support.", PropertiesComponent.getInstance()), config.getProject(), + super(new Storage.PropertiesComponentStorage(testFrameworkName + "Support.", PropertiesComponent.getInstance()), + config.getProject(), executor); myConfiguration = config; } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java index 52e6351a2ad9..57332b78d476 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java @@ -136,10 +136,14 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp * Allows to make console editable and disable/enable input sending in process stdin stream. * Normally tests shouldn't ask anything in stdin so console is view only by default. * - * NB: Process input support feature isn't fully implemented. Input text will be lost after + * NB1: Process input support feature isn't fully implemented. Input text will be lost after * switching to any other test/suite in tests results view. It's highly not recommended to change * default behaviour. Please do it only in critical cases and only if you are sure that you need this feature. * + * + * NB2: If you are using Service Messages based test runner please ensure that before each service message + * (e.g. #teamcity[...]) you always send "\n" to the output stream. + * * @return False for view-only mode and true for stdin support. */ public boolean isEditable() { diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index ca9ec6d39b1c..6aa2f991828f 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -93,7 +93,7 @@ public class ChunkExtractor { } }; - public static TextChunk[] extractChunks(PsiFile file, UsageInfo2UsageAdapter usageAdapter) { + public static TextChunk[] extractChunks(@NotNull PsiFile file, UsageInfo2UsageAdapter usageAdapter) { return ourExtractors.get().getValue().get(file).extractChunks(usageAdapter); } diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 299e66e4d6d2..1849cd9c696f 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -120,7 +120,8 @@ public class UsageInfo2UsageAdapter implements UsageInModule, } private TextChunk[] initChunks() { - TextChunk[] chunks = ChunkExtractor.extractChunks(getPsiFile(), this); + PsiFile file = getPsiFile(); + TextChunk[] chunks = file == null ? TextChunk.EMPTY_ARRAY : ChunkExtractor.extractChunks(file, this); myTextChunks = new SoftReference(chunks); return chunks; } @@ -328,7 +329,10 @@ public class UsageInfo2UsageAdapter implements UsageInModule, if (containingFile == null && oContainingFile == null || !Comparing.equal(containingFile, oContainingFile)) { return 0; } - return getFirstSegment().getStartOffset() - o.getFirstSegment().getStartOffset(); + Segment s1 = getFirstSegment(); + Segment s2 = o.getFirstSegment(); + if (s1 == null || s2 == null) return 0; + return s1.getStartOffset() - s2.getStartOffset(); } public void rename(String newName) throws IncorrectOperationException { diff --git a/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java b/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java index 6e143b75c8d9..b9be931810a9 100644 --- a/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java +++ b/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java @@ -50,8 +50,9 @@ public class FileGroupingRule implements UsageGroupingRule { } public UsageGroup groupUsage(Usage usage) { - if (usage instanceof UsageInFile) { - return new FileUsageGroup(myProject, ((UsageInFile)usage).getFile()); + VirtualFile virtualFile; + if (usage instanceof UsageInFile && (virtualFile = ((UsageInFile)usage).getFile()) != null) { + return new FileUsageGroup(myProject, virtualFile); } return null; } @@ -62,7 +63,7 @@ public class FileGroupingRule implements UsageGroupingRule { private String myPresentableName; private ComputableIcon myIcon; - public FileUsageGroup(Project project, VirtualFile file) { + public FileUsageGroup(@NotNull Project project, @NotNull VirtualFile file) { myProject = project; myFile = file instanceof VirtualFileWindow ? ((VirtualFileWindow)file).getDelegate() : file; myPresentableName = myFile.getName(); @@ -91,13 +92,11 @@ public class FileGroupingRule implements UsageGroupingRule { final FileUsageGroup fileUsageGroup = (FileUsageGroup)o; - if (myFile != null ? !myFile.equals(fileUsageGroup.myFile) : fileUsageGroup.myFile != null) return false; - - return true; + return myFile.equals(fileUsageGroup.myFile); } public int hashCode() { - return myFile != null ? myFile.hashCode() : 0; + return myFile.hashCode(); } public Icon getIcon(boolean isOpen) { @@ -145,7 +144,7 @@ public class FileGroupingRule implements UsageGroupingRule { @Nullable public PsiFile getPsiFile() { - return myFile != null && myFile.isValid() ? PsiManager.getInstance(myProject).findFile(myFile) : null; + return myFile.isValid() ? PsiManager.getInstance(myProject).findFile(myFile) : null; } @NotNull diff --git a/platform/util/src/com/intellij/util/containers/IntArrayList.java b/platform/util/src/com/intellij/util/containers/IntArrayList.java index 4e3b07ef52f2..d595a53cc008 100644 --- a/platform/util/src/com/intellij/util/containers/IntArrayList.java +++ b/platform/util/src/com/intellij/util/containers/IntArrayList.java @@ -15,6 +15,8 @@ */ package com.intellij.util.containers; +import java.util.Arrays; + public class IntArrayList implements Cloneable { private int[] myData; private int mySize; @@ -163,4 +165,9 @@ public class IntArrayList implements Cloneable { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + mySize); } } + + @Override + public String toString() { + return Arrays.toString(toArray()); + } } diff --git a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java index f0a16c3f4270..34c5cf6c3323 100644 --- a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java @@ -279,7 +279,8 @@ class BeanBinding implements Binding { return new AccessorBindingWrapper(accessor, binding); } - return new OptionTagBinding(accessor, xmlSerializer); + OptionTag optionTag = XmlSerializerImpl.findAnnotation(accessor.getAnnotations(), OptionTag.class); + return new OptionTagBinding(accessor, xmlSerializer, optionTag); } } diff --git a/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java b/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java index dd3216ab4a72..06f1f369bbea 100644 --- a/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java @@ -19,42 +19,57 @@ package com.intellij.util.xmlb; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.xmlb.annotations.OptionTag; import org.jdom.Attribute; import org.jdom.Content; import org.jdom.Element; import org.jdom.Text; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -//todo: use TagBinding class OptionTagBinding implements Binding { - private final static Logger LOG = Logger.getInstance("#" + OptionTagBinding.class.getName()); private final Accessor accessor; private final String myName; private final Binding myBinding; + private final String myTagName; + private final String myNameAttribute; + private final String myValueAttribute; - public OptionTagBinding(Accessor accessor, XmlSerializerImpl xmlSerializer) { + public OptionTagBinding(Accessor accessor, XmlSerializerImpl xmlSerializer, @Nullable OptionTag optionTag) { this.accessor = accessor; - myName = accessor.getName(); myBinding = xmlSerializer.getBinding(accessor); + if (optionTag != null) { + String name = optionTag.value(); + myName = name.isEmpty() ? accessor.getName() : name; + myTagName = optionTag.tag(); + myNameAttribute = optionTag.nameAttribute(); + myValueAttribute = optionTag.valueAttribute(); + } + else { + myName = accessor.getName(); + myTagName = Constants.OPTION; + myNameAttribute = Constants.NAME; + myValueAttribute = Constants.VALUE; + } } public Object serialize(Object o, Object context) { - Element targetElement = new Element(Constants.OPTION); + Element targetElement = new Element(myTagName); Object value = accessor.read(o); - targetElement.setAttribute(Constants.NAME, myName); + targetElement.setAttribute(myNameAttribute, myName); if (value == null) return targetElement; Object node = myBinding.serialize(value, targetElement); if (node instanceof Text) { Text text = (Text)node; - targetElement.setAttribute(Constants.VALUE, text.getText()); + targetElement.setAttribute(myValueAttribute, text.getText()); } else { if (targetElement != node) { @@ -72,7 +87,7 @@ class OptionTagBinding implements Binding { assert nodes.length != 0 : "Empty nodes passed to: " + this; Element element = ((Element)nodes[0]); - Attribute valueAttr = element.getAttribute(Constants.VALUE); + Attribute valueAttr = element.getAttribute(myValueAttribute); if (valueAttr != null) { Object value = myBinding.deserialize(o, valueAttr); @@ -102,8 +117,8 @@ class OptionTagBinding implements Binding { public boolean isBoundTo(Object node) { if (!(node instanceof Element)) return false; Element e = (Element)node; - if (!e.getName().equals(Constants.OPTION)) return false; - String name = e.getAttributeValue(Constants.NAME); + if (!e.getName().equals(myTagName)) return false; + String name = e.getAttributeValue(myNameAttribute); return name != null && name.equals(myName); } diff --git a/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java b/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java new file mode 100644 index 000000000000..3f921b3ed206 --- /dev/null +++ b/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2011 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.util.xmlb.annotations; + +import com.intellij.util.xmlb.Constants; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Store value in tag like <option name="optionName" value="optionValue"/> + * + * @author nik + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.METHOD}) +public @interface OptionTag { + String value() default ""; + String tag() default Constants.OPTION; + String nameAttribute() default Constants.NAME; + String valueAttribute() default Constants.VALUE; +} diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java index ec4b0dd6aceb..5879e223de30 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java @@ -21,9 +21,6 @@ import com.intellij.util.xmlb.annotations.*; import junit.framework.TestCase; import org.jdom.Element; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import java.io.IOException; import java.util.*; import java.util.Collection; @@ -36,7 +33,7 @@ public class XmlSerializerTest extends TestCase { public static class EmptyBean { } - public void testEmptyBeanSerialization() throws Exception { + public void testEmptyBeanSerialization() { doSerializerTest("", new EmptyBean()); } @@ -44,7 +41,7 @@ public class XmlSerializerTest extends TestCase { public static class EmptyBeanWithCustomName { } - public void testEmptyBeanSerializationWithCustomName() throws Exception { + public void testEmptyBeanSerializationWithCustomName() { doSerializerTest("", new EmptyBeanWithCustomName()); } @@ -67,7 +64,7 @@ public class XmlSerializerTest extends TestCase { } } - public void testPublicFieldSerialization() throws Exception { + public void testPublicFieldSerialization() { BeanWithPublicFields bean = new BeanWithPublicFields(); doSerializerTest( @@ -91,7 +88,7 @@ public class XmlSerializerTest extends TestCase { public String NEW_S = "foo"; } - public void testPublicFieldSerializationWithInheritance() throws Exception { + public void testPublicFieldSerializationWithInheritance() { BeanWithPublicFieldsDescendant bean = new BeanWithPublicFieldsDescendant(); doSerializerTest( @@ -120,7 +117,7 @@ public class XmlSerializerTest extends TestCase { public BeanWithPublicFields BEAN2 = new BeanWithPublicFields(); } - public void testSubBeanSerialization() throws Exception { + public void testSubBeanSerialization() { BeanWithSubBean bean = new BeanWithSubBean(); doSerializerTest( "\n" + @@ -153,7 +150,7 @@ public class XmlSerializerTest extends TestCase { bean); } - public void testNullFieldValue() throws Exception { + public void testNullFieldValue() { BeanWithPublicFields bean1 = new BeanWithPublicFields(); doSerializerTest( @@ -187,7 +184,7 @@ public class XmlSerializerTest extends TestCase { public List VALUES = new ArrayList(Arrays.asList("a", "b", "c")); } - public void testListSerialization() throws Exception { + public void testListSerialization() { BeanWithList bean = new BeanWithList(); doSerializerTest( @@ -221,7 +218,7 @@ public class XmlSerializerTest extends TestCase { public Set VALUES = new LinkedHashSet(Arrays.asList("a", "b", "w")); } - public void testSetSerialization() throws Exception { + public void testSetSerialization() { BeanWithSet bean = new BeanWithSet(); doSerializerTest( "\n" + @@ -259,7 +256,7 @@ public class XmlSerializerTest extends TestCase { } } - public void testMapSerialization() throws Exception { + public void testMapSerialization() { BeanWithMap bean = new BeanWithMap(); doSerializerTest( "\n" + @@ -307,7 +304,7 @@ public class XmlSerializerTest extends TestCase { } } - public void testMapSerializationWithAnnotations() throws Exception { + public void testMapSerializationWithAnnotations() { BeanWithMapWithAnnotations bean = new BeanWithMapWithAnnotations(); doSerializerTest( "\n" + @@ -335,7 +332,7 @@ public class XmlSerializerTest extends TestCase { public Map VALUES = new HashMap(); } - public void testMapWithBeanValue() throws Exception { + public void testMapWithBeanValue() { BeanWithMapWithBeanValue bean = new BeanWithMapWithBeanValue(); bean.VALUES.put("a", new BeanWithProperty("James")); @@ -372,6 +369,33 @@ public class XmlSerializerTest extends TestCase { "", bean); } + + public static class BeanWithOption { + @OptionTag("path") + public String PATH; + } + + public void testOptionTag() { + BeanWithOption bean = new BeanWithOption(); + bean.PATH = "123"; + doSerializerTest("\n" + + " ", bean); + } + + public static class BeanWithCustomizedOption { + @OptionTag(tag = "setting", nameAttribute = "key", valueAttribute = "saved") + public String PATH; + } + + public void testCustomizedOptionTag() { + BeanWithCustomizedOption bean = new BeanWithCustomizedOption(); + bean.PATH = "123"; + doSerializerTest("\n" + + " \n" + + "", bean); + } + public static class BeanWithProperty { private String name = "James"; @@ -392,7 +416,7 @@ public class XmlSerializerTest extends TestCase { } } - public void testPropertySerialization() throws Exception { + public void testPropertySerialization() { BeanWithProperty bean = new BeanWithProperty(); doSerializerTest( @@ -414,7 +438,7 @@ public class XmlSerializerTest extends TestCase { public String STRING_V = "hello"; } - public void testFieldWithTagAnnotation() throws Exception { + public void testFieldWithTagAnnotation() { BeanWithFieldWithTagAnnotation bean = new BeanWithFieldWithTagAnnotation(); doSerializerTest( @@ -431,7 +455,7 @@ public class XmlSerializerTest extends TestCase { "", bean); } - public void testShuffledDeserialize() throws Exception { + public void testShuffledDeserialize() { BeanWithPublicFields bean = new BeanWithPublicFields(); bean.INT_V = 987; bean.STRING_V = "1234"; @@ -448,7 +472,7 @@ public class XmlSerializerTest extends TestCase { assertEquals("1234", bean.STRING_V); } - public void testFilterSerializer() throws Exception { + public void testFilterSerializer() { BeanWithPublicFields bean = new BeanWithPublicFields(); assertSerializer(bean, "\n" + @@ -465,7 +489,7 @@ public class XmlSerializerTest extends TestCase { public static class BeanWithArray { public String[] ARRAY_V = new String[] {"a", "b"}; } - public void testArray() throws Exception { + public void testArray() { final BeanWithArray bean = new BeanWithArray(); doSerializerTest( "\n" + @@ -498,7 +522,7 @@ public class XmlSerializerTest extends TestCase { return "foo"; } } - public void testTransient() throws Exception { + public void testTransient() { final BeanWithTransient bean = new BeanWithTransient(); doSerializerTest("", bean); } @@ -507,7 +531,7 @@ public class XmlSerializerTest extends TestCase { @com.intellij.util.xmlb.annotations.AbstractCollection(surroundWithTag = false) public String[] V = new String[]{"a"}; } - public void testArrayAnnotationWithoutTagNAmeGivesError() throws Exception { + public void testArrayAnnotationWithoutTagNAmeGivesError() { final BeanWithArrayWithoutTagName bean = new BeanWithArrayWithoutTagName(); try { @@ -524,7 +548,7 @@ public class XmlSerializerTest extends TestCase { @com.intellij.util.xmlb.annotations.AbstractCollection(elementTag = "vvalue", elementValueAttribute = "v") public String[] V = new String[]{"a", "b"}; } - public void testArrayAnnotationWithElementTag() throws Exception { + public void testArrayAnnotationWithElementTag() { final BeanWithArrayWithElementTagName bean = new BeanWithArrayWithElementTagName(); doSerializerTest( @@ -557,7 +581,7 @@ public class XmlSerializerTest extends TestCase { public String[] V = new String[]{"a", "b"}; public int INT_V = 1; } - public void testArrayWithoutTag() throws Exception { + public void testArrayWithoutTag() { final BeanWithArrayWithoutTag bean = new BeanWithArrayWithoutTag(); doSerializerTest( @@ -587,7 +611,7 @@ public class XmlSerializerTest extends TestCase { @Property(surroundWithTag = false) public int INT_V = 1; } - public void testPropertyWithoutTagWithPrimitiveType() throws Exception { + public void testPropertyWithoutTagWithPrimitiveType() { final BeanWithPropertyWithoutTagOnPrimitiveValue bean = new BeanWithPropertyWithoutTagOnPrimitiveValue(); try { @@ -605,7 +629,7 @@ public class XmlSerializerTest extends TestCase { public BeanWithPublicFields BEAN1 = new BeanWithPublicFields(); public int INT_V = 1; } - public void testPropertyWithoutTag() throws Exception { + public void testPropertyWithoutTag() { final BeanWithPropertyWithoutTag bean = new BeanWithPropertyWithoutTag(); doSerializerTest( @@ -638,7 +662,7 @@ public class XmlSerializerTest extends TestCase { public String[] V = new String[]{"a", "b"}; public int INT_V = 1; } - public void testArrayWithoutAllTags() throws Exception { + public void testArrayWithoutAllTags() { final BeanWithArrayWithoutAllsTag bean = new BeanWithArrayWithoutAllsTag(); doSerializerTest( @@ -666,7 +690,7 @@ public class XmlSerializerTest extends TestCase { public String[] V = new String[]{"a", "b"}; public int INT_V = 1; } - public void testArrayWithoutAllTags2() throws Exception { + public void testArrayWithoutAllTags2() { final BeanWithArrayWithoutAllsTag2 bean = new BeanWithArrayWithoutAllsTag2(); doSerializerTest( @@ -706,7 +730,7 @@ public class XmlSerializerTest extends TestCase { public BeanWithPublicFields[] V = new BeanWithPublicFields[] {}; } - public void testPolymorphicArray() throws Exception { + public void testPolymorphicArray() { final BeanWithPolymorphicArray bean = new BeanWithPolymorphicArray(); doSerializerTest( @@ -747,7 +771,7 @@ public class XmlSerializerTest extends TestCase { @Attribute("name") public String name = "James"; } - public void testBeanWithPrimitivePropertyBoundToAttribute() throws Exception { + public void testBeanWithPrimitivePropertyBoundToAttribute() { final BeanWithPropertiesBoundToAttribute bean = new BeanWithPropertiesBoundToAttribute(); doSerializerTest("", bean); @@ -771,7 +795,7 @@ public class XmlSerializerTest extends TestCase { return !accessor.read(bean).equals("skip"); } } - public void testPropertyFilter() throws Exception { + public void testPropertyFilter() { BeanWithPropertyFilter bean = new BeanWithPropertyFilter(); doSerializerTest( @@ -797,7 +821,7 @@ public class XmlSerializerTest extends TestCase { public org.jdom.Element actions; } - public void testSerializeJDOMElementField() throws Exception { + public void testSerializeJDOMElementField() { BeanWithJDOMElement element = new BeanWithJDOMElement(); element.STRING_V = "a"; element.actions = new Element("x").addContent(new Element("a")).addContent(new Element("b")); @@ -881,7 +905,7 @@ public class XmlSerializerTest extends TestCase { } } - public void testTextAnnotation() throws Exception { + public void testTextAnnotation() { BeanWithTextAnnotation bean = new BeanWithTextAnnotation(); doSerializerTest( @@ -911,7 +935,7 @@ public class XmlSerializerTest extends TestCase { public TestEnum FLD = TestEnum.VALUE_1; } - public void testEnums() throws Exception { + public void testEnums() { BeanWithEnum bean = new BeanWithEnum(); doSerializerTest( @@ -927,7 +951,7 @@ public class XmlSerializerTest extends TestCase { public Map, String> myMap = new HashMap, String>(); } - public void testSetKeysInMap() throws Exception { + public void testSetKeysInMap() { final BeanWithSetKeysInMap bean = new BeanWithSetKeysInMap(); bean.myMap.put(new HashSet(Arrays.asList("1", "2", "3")), "numbers"); bean.myMap.put(new HashSet(Arrays.asList("a", "b", "c")), "letters"); @@ -982,7 +1006,7 @@ public class XmlSerializerTest extends TestCase { public Map MAP = new HashMap(); } - public void testMapWithNotSurroundingKeyAndValue() throws Exception { + public void testMapWithNotSurroundingKeyAndValue() { BeanWithMapWithoutSurround bean = new BeanWithMapWithoutSurround(); bean.MAP.put(new BeanWithPublicFields(1, "a"), new BeanWithTextAnnotation(2, "b")); @@ -1028,24 +1052,29 @@ public class XmlSerializerTest extends TestCase { //--------------------------------------------------------------------------------------------------- - private void assertSerializer(Object bean, String expected, SerializationFilter filter) - throws TransformerException, ParserConfigurationException, IOException { + private static void assertSerializer(Object bean, String expected, SerializationFilter filter) { assertSerializer(bean, expected, "Serialization failure", filter); } - private Object doSerializerTest(String expectedText, Object bean) - throws ParserConfigurationException, TransformerException, XmlSerializationException, IOException { - Element element = assertSerializer(bean, expectedText, "Serialization failure", null); + private static Object doSerializerTest(String expectedText, Object bean) { + try { + Element element = assertSerializer(bean, expectedText, "Serialization failure", null); - //test deserializer + //test deserializer - Object o = XmlSerializer.deserialize(element, bean.getClass()); - assertSerializer(o, expectedText, "Deserialization failure", null); - return o; + Object o = XmlSerializer.deserialize(element, bean.getClass()); + assertSerializer(o, expectedText, "Deserialization failure", null); + return o; + } + catch (XmlSerializationException e) { + throw e; + } + catch (Exception e) { + throw new RuntimeException(e); + } } - private Element assertSerializer(Object bean, String expectedText, String message, SerializationFilter filter) - throws ParserConfigurationException, XmlSerializationException, TransformerException, IOException { + private static Element assertSerializer(Object bean, String expectedText, String message, SerializationFilter filter) throws XmlSerializationException { Element element = serialize(bean, filter); @@ -1060,7 +1089,7 @@ public class XmlSerializerTest extends TestCase { return element; } - private Element serialize(Object bean, SerializationFilter filter) throws ParserConfigurationException { + private static Element serialize(Object bean, SerializationFilter filter) { return XmlSerializer.serialize(bean, filter); } } diff --git a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java index 814e01a7f5b5..053c0b639c6d 100644 --- a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java +++ b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java @@ -56,14 +56,8 @@ public class VcsUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.vcsUtil.VcsUtil"); - /** - * Call "fileDirty" in the read action. - */ public static void markFileAsDirty(final Project project, final VirtualFile file) { - final VcsDirtyScopeManager mgr = VcsDirtyScopeManager.getInstance(project); - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { mgr.fileDirty(file); } - }); + VcsDirtyScopeManager.getInstance(project).fileDirty(file); } public static void markFileAsDirty(final Project project, final FilePath path) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java index 9c827f731a93..1415c6defd4f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java @@ -45,7 +45,7 @@ public class ScheduleForAdditionAction extends AnAction implements DumbAware { } public void update(AnActionEvent e) { - final boolean enabled = e.getData(PlatformDataKeys.PROJECT) != null && (getUnversionedFiles(e) != null); + final boolean enabled = e.getData(PlatformDataKeys.PROJECT) != null && (thereAreUnversionedFiles(e)); e.getPresentation().setEnabled(enabled); final String place = e.getPlace(); if (ActionPlaces.ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION.equals(place) || ActionPlaces.CHANGES_VIEW_POPUP.equals(place) ) { @@ -62,8 +62,13 @@ public class ScheduleForAdditionAction extends AnAction implements DumbAware { changeListManager.addUnversionedFiles(changeListManager.getDefaultChangeList(), unversionedFiles); } + protected boolean thereAreUnversionedFiles(final AnActionEvent e) { + final List unversionedFiles = getUnversionedFiles(e); + return unversionedFiles != null && !(unversionedFiles.isEmpty()); + } + @Nullable - private static List getUnversionedFiles(final AnActionEvent e) { + protected List getUnversionedFiles(final AnActionEvent e) { // first get from the ChangeListView List unversionedFiles = e.getData(ChangesListView.UNVERSIONED_FILES_DATA_KEY); if (unversionedFiles != null && !unversionedFiles.isEmpty()) { @@ -88,4 +93,4 @@ public class ScheduleForAdditionAction extends AnAction implements DumbAware { return unversionedFiles.isEmpty() ? null : unversionedFiles; } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java index 258e9c9f572b..586e201b58b0 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java @@ -86,8 +86,12 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { return; } final PsiElement[] tryBlockChildren = tryBlock.getChildren(); - final Set variables = - collectVariables(tryStatement); + final Set variables = new HashSet(); + for (PsiLocalVariable variable : collectVariables(tryStatement)) { + if (!isVariableUsedOutsideContext(variable, tryStatement)) { + variables.add(variable); + } + } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); @NonNls final StringBuilder newTryStatementText = @@ -315,7 +319,7 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { if (resourceList != null) { return; } - final Set variables = + final List variables = collectVariables(tryStatement); if (variables.isEmpty()) { return; @@ -338,17 +342,7 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { final int index = findInitialization(tryBlockStatements, variable, hasInitializer); if (index >= 0 ^ hasInitializer) { - final VariableUsedOutsideContextVisitor visitor = - new VariableUsedOutsideContextVisitor(variable, - tryStatement); - final PsiElement context = - PsiTreeUtil.getParentOfType(variable, - PsiCodeBlock.class); - if (context == null) { - continue; - } - context.accept(visitor); - if (visitor.variableIsUsed()) { + if (isVariableUsedOutsideContext(variable, tryStatement)) { continue; } found = true; @@ -362,17 +356,32 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { } } - static Set collectVariables( + static boolean isVariableUsedOutsideContext( + PsiVariable variable, PsiElement context) { + final VariableUsedOutsideContextVisitor visitor = + new VariableUsedOutsideContextVisitor(variable, + context); + final PsiElement declarationScope = + PsiTreeUtil.getParentOfType(variable, + PsiCodeBlock.class); + if (declarationScope == null) { + return true; + } + declarationScope.accept(visitor); + return visitor.variableIsUsed(); + } + + static List collectVariables( PsiTryStatement tryStatement) { final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); if (finallyBlock == null) { - return Collections.EMPTY_SET; + return Collections.EMPTY_LIST; } final PsiStatement[] statements = finallyBlock.getStatements(); if (statements.length == 0) { - return Collections.EMPTY_SET; + return Collections.EMPTY_LIST; } - final Set variables = new LinkedHashSet(); + final List variables = new ArrayList(); for (PsiStatement statement : statements) { final PsiLocalVariable variable = findAutoCloseableVariable(statement); diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/options/ExternalOptionHelper.java b/plugins/copyright/src/com/maddyhome/idea/copyright/options/ExternalOptionHelper.java index e0783eb7fefa..f5f971a37abe 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/options/ExternalOptionHelper.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/options/ExternalOptionHelper.java @@ -17,6 +17,7 @@ package com.maddyhome.idea.copyright.options; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.JDOMUtil; import com.maddyhome.idea.copyright.CopyrightProfile; import org.jdom.Document; @@ -54,10 +55,11 @@ public class ExternalOptionHelper { } } } - return profiles.isEmpty() ? null : profiles; + return profiles; } catch (Exception e) { - logger.error(e); + logger.info(e); + Messages.showErrorDialog(e.getMessage(), "Import Failure"); return null; } } diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java index 1eebcd37f55a..21d3c270e204 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java @@ -201,7 +201,8 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se if (files.length != 1) return; final List copyrightProfiles = ExternalOptionHelper.loadOptions(VfsUtil.virtualToIoFile(files[0])); - if (copyrightProfiles != null) { + if (copyrightProfiles == null) return; + if (!copyrightProfiles.isEmpty()) { if (copyrightProfiles.size() == 1) { importProfile(copyrightProfiles.get(0)); } else { @@ -224,7 +225,7 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se } } else { - Messages.showWarningDialog(myProject, "The selected file did not contain any copyright settings.", "Import Failure"); + Messages.showWarningDialog(myProject, "The selected file does not contain any copyright settings.", "Import Failure"); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java index db926545b20b..d1d7e4a877fc 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java @@ -68,14 +68,20 @@ public class GithubCheckoutProvider implements CheckoutProvider { // All the preliminary work is already done, go and clone the selected repository! final RepositoryInfo selectedRepository = checkoutDialog.getSelectedRepository(); + final boolean writeAccessAllowed = GithubUtil.isWriteAccessAllowed(project, selectedRepository); + if (!writeAccessAllowed){ + Messages.showErrorDialog(project, "It seems that you have only read access to the selected repository.\n" + + "GitHub supports only https protocol for readonly access, which is not supported yet.\n" + + "More details are available here: http://youtrack.jetbrains.net/issue/IDEA-55298", "Cannot clone this repository"); + return; + } + final String host = writeAccessAllowed ? "git@" + settings.getHost() + ":" : "https://github.com" + settings.getHost() + "/"; final String selectedPath = checkoutDialog.getSelectedPath(); final VirtualFile selectedPathFile = LocalFileSystem.getInstance().findFileByPath(selectedPath); final String projectName = checkoutDialog.getProjectName(); final String repositoryName = selectedRepository.getName(); final String repositoryOwner = selectedRepository.getOwner(); - final String checkoutUrl = settings.getLogin().equals(repositoryOwner) - ? "git@github.com:" + repositoryOwner + "/" + repositoryName + ".git" - : "https://github.com/" + repositoryOwner + "/" + repositoryName + ".git"; + final String checkoutUrl = host + repositoryOwner + "/" + repositoryName + ".git"; GitCheckoutProvider.checkout(project, listener, selectedPathFile, checkoutUrl, projectName, "origin", selectedPath); } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 9cac56ee2348..ce4b8a94e456 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -139,6 +139,29 @@ public class GithubUtil { return Collections.emptyList(); } + public static boolean isPushableRepo(final String url, final String login, final String password, final RepositoryInfo repositoryInfo) { + try { + final HttpMethod method = doREST(url, login, password, "/repos/pushable", false); + final InputStream stream = method.getResponseBodyAsStream(); + final Element element = new SAXBuilder(false).build(stream).getRootElement(); + if ("error".equals(element.getName())){ + LOG.warn("Got error element by request: " + "/repos/pushable"); + return false; + } + final List repositories = element.getChildren(); + for (int i = 0; i < repositories.size(); i++) { + final Element repo = (Element)repositories.get(i); + if (repositoryInfo.equals(new RepositoryInfo(repo))){ + return true; + } + } + } + catch (Exception e) { + // ignore + } + return false; + } + @Nullable public static RepositoryInfo getDetailedRepoInfo(final String url, final String login, final String password, final String name) { try { @@ -325,4 +348,15 @@ public class GithubUtil { } return null; } + + public static boolean isWriteAccessAllowed(final Project project, final RepositoryInfo repo) { + final GithubSettings settings = GithubSettings.getInstance(); + return accessToGithubWithModalProgress(project, new Computable() { + @Override + public Boolean compute() { + ProgressManager.getInstance().getProgressIndicator().setText("Extracting info about pushable repositories"); + return isPushableRepo(settings.getHost(), settings.getLogin(), settings.getPassword(), repo); + } + }); + } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java b/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java index 592b452b37e1..7d33bf5975e0 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java +++ b/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java @@ -1,5 +1,6 @@ package org.jetbrains.plugins.github; +import com.intellij.openapi.util.Comparing; import org.jdom.Element; /** @@ -28,4 +29,14 @@ public class RepositoryInfo { public String getParent() { return myRepository.getChildText("parent"); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof RepositoryInfo)){ + return false; + } + final RepositoryInfo repositoryInfo = (RepositoryInfo)obj; + return Comparing.equal(getName(), repositoryInfo.getName()) && + Comparing.equal(getOwner(), repositoryInfo.getOwner()); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 0721d3e3b227..a09bf84e1765 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -453,7 +453,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } }); - if (StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix())) { + if (StringUtil.isCapitalized(result.getPrefixMatcher().getPrefix()) || parameters.relaxMatching()) { addAllClasses(parameters, result, inheritors); } } diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index e642a1f88b26..b4f4ccb8f8b7 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -243,6 +243,7 @@ readonly refactor refactored refactoring +refactorings reifiable reification reifications diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java index 21abda3041a3..a695f74754f8 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java @@ -691,7 +691,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe notification.expire(); } } - })); + }), myProject); } } return issues; diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPass.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPass.java index cd3986aea36a..26ff294aa781 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPass.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPass.java @@ -24,6 +24,7 @@ import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.lang.xml.XMLLanguage; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.ColorKey; import com.intellij.openapi.editor.colors.EditorColorsManager; @@ -72,6 +73,10 @@ public class HtmlTagTreeHighlightingPass extends TextEditorHighlightingPass { @Override public void doCollectInformation(ProgressIndicator progress) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + return; + } + if (!WebEditorOptions.getInstance().isTagTreeHighlightingEnabled()) { return; } diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPassFactory.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPassFactory.java index dd1bc7d94c4b..b1d46c614fb2 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPassFactory.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/HtmlTagTreeHighlightingPassFactory.java @@ -20,6 +20,7 @@ import com.intellij.codeHighlighting.Pass; import com.intellij.codeHighlighting.TextEditorHighlightingPass; import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory; import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -39,6 +40,10 @@ public class HtmlTagTreeHighlightingPassFactory extends AbstractProjectComponent } public TextEditorHighlightingPass createHighlightingPass(@NotNull final PsiFile file, @NotNull final Editor editor) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + return null; + } + if (editor.isOneLineMode()) return null; if (!(file instanceof XmlFile) || !HtmlUtil.hasHtml(file)) { diff --git a/xml/impl/src/com/intellij/lang/xml/XmlUnwrapDescriptor.java b/xml/impl/src/com/intellij/lang/xml/XmlUnwrapDescriptor.java index fae085b71b74..ca2d4ed07fae 100644 --- a/xml/impl/src/com/intellij/lang/xml/XmlUnwrapDescriptor.java +++ b/xml/impl/src/com/intellij/lang/xml/XmlUnwrapDescriptor.java @@ -22,37 +22,59 @@ import com.intellij.lang.Language; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlChildRole; import com.intellij.psi.xml.XmlTag; -import com.intellij.util.SmartList; +import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; public class XmlUnwrapDescriptor implements UnwrapDescriptor { public List> collectUnwrappers(Project project, Editor editor, PsiFile file) { - List> result = new SmartList>(); - int offset = editor.getCaretModel().getOffset(); + PsiElement e1 = file.findElementAt(offset); if (e1 != null) { Language language = e1.getParent().getLanguage(); if (language != file.getLanguage()) { UnwrapDescriptor unwrapDescriptor = LanguageUnwrappers.INSTANCE.forLanguage(language); if (unwrapDescriptor != null && !(unwrapDescriptor instanceof XmlUnwrapDescriptor)) { - result.addAll(unwrapDescriptor.collectUnwrappers(project, editor, file)); + return unwrapDescriptor.collectUnwrappers(project, editor, file); } } } - PsiElement tag = PsiTreeUtil.getParentOfType(e1, XmlTag.class); - while (tag != null) { - result.add(new Pair(tag, new XmlEnclosingTagUnwrapper())); - tag = PsiTreeUtil.getParentOfType(tag, XmlTag.class); + List> result = new ArrayList>(); + + FileViewProvider viewProvider = file.getViewProvider(); + + for (Language language : viewProvider.getLanguages()) { + UnwrapDescriptor unwrapDescriptor = LanguageUnwrappers.INSTANCE.forLanguage(language); + if (unwrapDescriptor instanceof XmlUnwrapDescriptor) { + PsiElement e = viewProvider.findElementAt(offset, language); + + PsiElement tag = PsiTreeUtil.getParentOfType(e, XmlTag.class); + while (tag != null) { + if (XmlChildRole.START_TAG_END_FINDER.findChild(tag.getNode()) != null) { // Exclude implicit tags suck as 'jsp:root' + result.add(new Pair(tag, new XmlEnclosingTagUnwrapper())); + } + tag = PsiTreeUtil.getParentOfType(tag, XmlTag.class); + } + } } + Collections.sort(result, new Comparator>() { + @Override + public int compare(Pair o1, Pair o2) { + return o2.first.getTextOffset() - o1.first.getTextOffset(); + } + }); + return result; }