diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 6e6bd9102279..a83e0cf79c4b 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -2378,7 +2378,9 @@ public class CompileDriver { final boolean justCreated = file.mkdirs(); vFile = lfs.refreshAndFindFileByIoFile(file); - assert vFile != null: "Virtual file not found for " + file.getPath() + "; mkdirs() exit code is " + justCreated; + if (vFile == null) { + assert false: "Virtual file not found for " + file.getPath() + "; mkdirs() exit code is " + justCreated + "; file exists()? " + file.exists(); + } return vFile; } 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 1750e8e5ae58..7950cc21013c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -47,6 +47,7 @@ import com.intellij.psi.filters.getters.ExpectedTypesGetter; import com.intellij.psi.filters.types.AssignableFromFilter; import com.intellij.psi.impl.source.tree.ElementType; import com.intellij.psi.scope.ElementClassFilter; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; @@ -183,7 +184,8 @@ public class JavaCompletionContributor extends CompletionContributor { final ASTNode node = lastElement.getNode(); assert node != null; - if (node.getElementType() == JavaTokenType.DOUBLE_LITERAL) { + final IElementType elementType = node.getElementType(); + if (elementType == JavaTokenType.DOUBLE_LITERAL || elementType == JavaTokenType.LONG_LITERAL || elementType == JavaTokenType.INTEGER_LITERAL || elementType == JavaTokenType.FLOAT_LITERAL) { return; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java index 02870ac48ecc..081d6a4d70e2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java @@ -31,12 +31,14 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ex.RangeMarkerEx; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.util.FieldConflictsResolver; +import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; @@ -202,7 +204,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix { List> arguments, PsiSubstitutor substitutor, ExpectedTypeInfo[] expectedTypes, - @Nullable PsiElement context) { + @Nullable final PsiElement context) { method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method); @@ -239,7 +241,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix { PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument()); final int offset = newEditor.getCaretModel().getOffset(); PsiMethod method = PsiTreeUtil.findElementOfClassAtOffset(targetFile, offset - 1, PsiMethod.class, false); - + if (context instanceof PsiMethod) { + final PsiTypeParameter[] typeParameters = ((PsiMethod)context).getTypeParameters(); + if (typeParameters.length > 0) { + for (PsiTypeParameter typeParameter : typeParameters) { + if (checkTypeParam( method, typeParameter)) { + method.getTypeParameterList().add(typeParameter); + } + } + } + } if (method != null) { try { CreateFromUsageUtils.setupMethodBody(method); @@ -260,6 +271,29 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix { } } + private static boolean checkTypeParam(final PsiElement typeElement, + final PsiTypeParameter typeParameter) { + final String typeParameterName = typeParameter.getName(); + final boolean[] found = new boolean[] {false}; + typeElement.accept(new JavaRecursiveElementWalkingVisitor(){ + + @Override + public void visitElement(PsiElement element) { + if (found[0]) return; + super.visitElement(element); + } + + @Override + public void visitTypeElement(PsiTypeElement type) { + super.visitTypeElement(type); + if (Comparing.strEqual(typeParameterName, type.getText())) { + found[0] = true; + } + } + }); + return found[0]; + } + protected boolean shouldBeAbstract(PsiClass targetClass) { return shouldBeAbstractImpl(targetClass); } 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 ede4be1340d3..fdb2e6363fca 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -799,14 +799,12 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final OccurrencesChooser.ReplaceChoice replaceChoice) { final SuggestedNameInfo suggestedName = getSuggestedName(typeSelectorManager.getDefaultType(), expr); final String variableName = suggestedName.names[0]; - final Boolean generateFinals = JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_FINALS; final boolean replaceAll = replaceChoice == OccurrencesChooser.ReplaceChoice.ALL || replaceChoice == OccurrencesChooser.ReplaceChoice.NO_WRITE; final boolean declareFinal = !anyAssignmentLHS && (replaceAll && - declareFinalIfAll || generateFinals == null ? - CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS : - generateFinals.booleanValue()); + declareFinalIfAll || + CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS); final boolean replaceWrite = anyAssignmentLHS && replaceChoice == OccurrencesChooser.ReplaceChoice.ALL; return new IntroduceVariableSettings() { @Override diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index 4417ef29a1fd..a812ec211c41 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -176,14 +176,20 @@ public class ReassignVariableUtil { @Nullable static String getAdvertisementText(Editor editor, PsiDeclarationStatement declaration, PsiType type, PsiType[] typesForAll) { final VariablesProcessor processor = findVariablesOfType(editor, declaration, type); + final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); if (processor.size() > 0) { - final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); final Shortcut[] shortcuts = keymap.getShortcuts("IntroduceVariable"); if (shortcuts.length > 0) { return "Press " + shortcuts[0] + " to reassign existing variable"; } } - return typesForAll.length > 1 ? "Press Shift Tab to change type" : null; + if (typesForAll.length > 1) { + final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable"); + if (shortcuts.length > 0) { + return "Press " + shortcuts[0] + " to change type"; + } + } + return null; } public static Expression createExpression(final TypeExpression expression, final String defaultType) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterMethodTypeParamUsed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterMethodTypeParamUsed.java new file mode 100644 index 000000000000..f2437aef38fe --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterMethodTypeParamUsed.java @@ -0,0 +1,12 @@ +// "Create Method 'f'" "true" +class A { + T foo(){ + B x = f(); + } + + private B f() { + return null; //To change body of created methods use File | Settings | File Templates. + } +} + +class B{} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeMethodTypeParamUsed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeMethodTypeParamUsed.java new file mode 100644 index 000000000000..364f4fa683ba --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeMethodTypeParamUsed.java @@ -0,0 +1,8 @@ +// "Create Method 'f'" "true" +class A { + T foo(){ + B x = f(); + } +} + +class B{} 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 e842a0efbe29..8e2fff95297d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -84,6 +84,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private final Update myUpdate = new Update("update") { public void run() { updateLookup(); + myQueue.setMergingTimeSpan(100); } }; private LightweightHint myHint; @@ -136,7 +137,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myLookup.addLookupListener(myLookupListener); myLookup.setCalculating(true); - myQueue = new MergingUpdateQueue("completion lookup progress", 100, true, myEditor.getContentComponent()); + myQueue = new MergingUpdateQueue("completion lookup progress", 200, true, myEditor.getContentComponent()); ApplicationManager.getApplication().assertIsDispatchThread(); registerItself(); 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 fab60030a8e6..d8f37935fcfa 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 @@ -91,6 +91,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { private boolean myDisposed = false; private boolean myHidden = false; private LookupElement myPreselectedItem = EMPTY_LOOKUP_ITEM; + private final List myFrozenItems = new ArrayList(); private String mySelectionInvariant = null; private boolean mySelectionTouched; private boolean myFocused = true; @@ -186,6 +187,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { @TestOnly public void resort() { mySelectionTouched = false; + myFrozenItems.clear(); myPreselectedItem = EMPTY_LOOKUP_ITEM; final List items = myModel.getItems(); myModel.clearItems(); @@ -261,6 +263,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { public void setAdditionalPrefix(final String additionalPrefix) { myAdditionalPrefix = additionalPrefix; myInitialPrefix = null; + myFrozenItems.clear(); refreshUi(); } @@ -270,6 +273,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } if (myReused) { + myFrozenItems.clear(); myModel.collectGarbage(); myReused = false; } @@ -397,6 +401,12 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } private void addMostRelevantItems(DefaultListModel model, Set firstItems, final Collection> sortedItems) { + for (LookupElement item : myFrozenItems) { + if (prefixMatches(item) && firstItems.add(item)) { + model.addElement(item); + } + } + for (final List elements : sortedItems) { final List suitable = new SmartList(); for (final LookupElement item : elements) { @@ -409,6 +419,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { for (final LookupElement item : suitable) { firstItems.add(item); model.addElement(item); + myFrozenItems.add(item); } } } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index ac53b2cafa8d..8df435eff698 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -1084,7 +1084,7 @@ public class SingleInspectionProfilePanel extends JPanel { private class MyFilterComponent extends FilterComponent { public MyFilterComponent() { super(INSPECTION_FILTER_HISTORY, 10); - setHistory(Arrays.asList("\"New in 9\"")); + setHistory(Arrays.asList("\"New in 10\"")); } public void filter() { 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 28fef28a9ba1..2c3c9fc6c6f1 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 @@ -646,10 +646,9 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { first = false; } else { - for (VirtualFile file : local.keySet()) { - if (intersection.containsKey(file)) { - intersection.putValues(file, local.get(file)); - } + intersection.keySet().retainAll(local.keySet()); + for (VirtualFile file : intersection.keySet()) { + intersection.get(file).retainAll(local.get(file)); } } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java index ee72101f67c8..531dce74dd47 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java @@ -21,6 +21,10 @@ import com.intellij.concurrency.JobScheduler; import com.intellij.history.LocalHistory; import com.intellij.ide.caches.CacheUpdater; import com.intellij.lang.ASTNode; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationDisplayType; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationAdapter; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; @@ -262,10 +266,21 @@ public class FileBasedIndex implements ApplicationComponent { final File corruptionMarker = new File(PathManager.getIndexRoot(), CORRUPTION_MARKER_NAME); final boolean currentVersionCorrupted = corruptionMarker.exists(); + boolean versionChanged = false; for (FileBasedIndexExtension extension : extensions) { - registerIndexer(extension, currentVersionCorrupted); + versionChanged |= registerIndexer(extension, currentVersionCorrupted); } FileUtil.delete(corruptionMarker); + String rebuildNotification = null; + if (currentVersionCorrupted) { + rebuildNotification = "Index files on disk are corrupted, global index rebuild scheduled."; + } + else if (versionChanged) { + rebuildNotification = "Index file format has changed for some indices. These indices will be rebuilt."; + } + if (rebuildNotification != null) { + Notifications.Bus.notify(new Notification("Indexing", "Index Rebuild", rebuildNotification, NotificationType.INFORMATION), NotificationDisplayType.BALLOON_ONLY, null); + } dropUnregisteredIndices(); // check if rebuild was requested for any index during registration @@ -332,7 +347,8 @@ public class FileBasedIndex implements ApplicationComponent { * @return true if registered index requires full rebuild for some reason, e.g. is just created or corrupted @param extension * @param isCurrentVersionCorrupted */ - private void registerIndexer(final FileBasedIndexExtension extension, final boolean isCurrentVersionCorrupted) throws IOException { + private boolean registerIndexer(final FileBasedIndexExtension extension, final boolean isCurrentVersionCorrupted) throws IOException { + boolean versionChanged = false; final ID name = extension.getName(); final int version = extension.getVersion(); if (!extension.dependsOnFileContent()) { @@ -342,6 +358,7 @@ public class FileBasedIndex implements ApplicationComponent { final File versionFile = IndexInfrastructure.getVersionFile(name); if (isCurrentVersionCorrupted || IndexInfrastructure.versionDiffers(versionFile, version)) { if (!isCurrentVersionCorrupted) { + versionChanged = true; LOG.info("Version has changed for index " + extension.getName() + ". The index will be rebuilt."); } FileUtil.delete(IndexInfrastructure.getIndexRootDir(name)); @@ -364,6 +381,7 @@ public class FileBasedIndex implements ApplicationComponent { IndexInfrastructure.rewriteVersion(versionFile, version); } } + return versionChanged; } private static void saveRegisteredIndices(Collection> ids) { diff --git a/platform/platform-api/src/com/intellij/notification/Notifications.java b/platform/platform-api/src/com/intellij/notification/Notifications.java index 6f6215f6d4e1..817257d5fb43 100644 --- a/platform/platform-api/src/com/intellij/notification/Notifications.java +++ b/platform/platform-api/src/com/intellij/notification/Notifications.java @@ -15,6 +15,7 @@ */ package com.intellij.notification; +import com.intellij.ide.FrameStateManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; @@ -57,16 +58,21 @@ public interface Notifications { return; } - final MessageBus bus = project == null ? ApplicationManager.getApplication().getMessageBus() : project.getMessageBus(); - if (EventQueue.isDispatchThread()) bus.syncPublisher(TOPIC).notify(notification, defaultDisplayType); - else { - //noinspection SSBasedInspection - SwingUtilities.invokeLater(new Runnable() { - public void run() { - bus.syncPublisher(TOPIC).notify(notification, defaultDisplayType); + FrameStateManager.getInstance().getApplicationActive().doWhenDone(new Runnable() { + @Override + public void run() { + final MessageBus bus = project == null ? ApplicationManager.getApplication().getMessageBus() : project.getMessageBus(); + if (EventQueue.isDispatchThread()) bus.syncPublisher(TOPIC).notify(notification, defaultDisplayType); + else { + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + public void run() { + bus.syncPublisher(TOPIC).notify(notification, defaultDisplayType); + } + }); } - }); - } + } + }); } } } diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index b58fed44fff8..b140c9ba17de 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -370,7 +370,9 @@ public class FileUtil { while(true){ try{ //noinspection SSBasedInspection - return File.createTempFile(prefix, suffix, dir).getCanonicalFile(); + final File temp = File.createTempFile(prefix, suffix, dir); + final File canonical = temp.getCanonicalFile(); + return SystemInfo.isWindows && canonical.getAbsolutePath().contains(" ") ? temp.getAbsoluteFile() : canonical; } catch(IOException e){ // Win32 createFileExclusively access denied if (++exceptionsCount >= 100) {