diff --git a/.idea/libraries/winp.xml b/.idea/libraries/winp.xml index 07689aee601a..8566148396e4 100644 --- a/.idea/libraries/winp.xml +++ b/.idea/libraries/winp.xml @@ -9,4 +9,4 @@ - \ No newline at end of file + diff --git a/build/conf/mac/Contents/Info.plist b/build/conf/mac/Contents/Info.plist index 9fcd21c14315..8daa490e8ecc 100644 --- a/build/conf/mac/Contents/Info.plist +++ b/build/conf/mac/Contents/Info.plist @@ -31,11 +31,11 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - @@bundle_name@@ @@product_version@@ + @@bundle_name@@@@product_state@@ CFBundlePackageType APPL CFBundleIdentifier - @@bundle_identifier@@ + @@bundle_identifier@@@@product_state@@ CFBundleSignature ???? CFBundleGetInfoString diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index f93dd53fa8a2..7421c91f9cc5 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -367,8 +367,7 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args -> String minor = p("component.version.minor") String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}" - String productVersion = "${p("component.version.major")}.${minor}" - if (isEap() && !minor.contains("RC") && !minor.contains("Beta")) productVersion += " EAP" + String EAP = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "-EAP" : "" Map properties = readIdeaProperties(args) @@ -429,7 +428,7 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args -> replacefilter(token: "@@executable@@", value: executable) replacefilter(token: "@@icns@@", value: icns) replacefilter(token: "@@bundle_name@@", value: fullName) - replacefilter(token: "@@product_version@@", value: productVersion) + replacefilter(token: "@@product_state@@", value: EAP) replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier) replacefilter(token: "@@year@@", value: "$todayYear") replacefilter(token: "@@version@@", value: version) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index e04539b3e469..9ceffac57eb4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -931,7 +931,7 @@ public class BuildManager implements ApplicationComponent{ // validate tools.jar presence final JavaSdkType projectJdkType = (JavaSdkType)projectJdk.getSdkType(); - if (projectJdk.equals(internalJdk)) { + if (FileUtil.pathsEqual(projectJdk.getHomePath(), internalJdk.getHomePath())) { // important: because internal JDK can be either JDK or JRE, // this is the most universal way to obtain tools.jar path in this particular case final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java index ed829100c502..25d95ed86292 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -21,61 +21,49 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; -import com.intellij.debugger.ui.ExportDialog; -import com.intellij.idea.ActionsBundle; +import com.intellij.ide.actions.ExportToTextFileAction; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.SystemProperties; +import com.intellij.unscramble.ThreadDumpPanel; +import com.intellij.unscramble.ThreadState; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.util.List; public class ExportThreadsAction extends AnAction implements AnAction.TransparentUpdate { public void actionPerformed(AnActionEvent e) { - Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) { return; } DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); - if(context.getDebuggerSession() != null) { - String destinationDirectory = ""; - final VirtualFile baseDir = project.getBaseDir(); - if (baseDir != null) destinationDirectory = baseDir.getPresentableUrl(); - - ExportDialog dialog = new ExportDialog(context.getDebugProcess(), destinationDirectory); - if (dialog.showAndGet()) { - try { - File file = new File(dialog.getFilePath()); - BufferedWriter writer = new BufferedWriter(new FileWriter(file)); - try { - String text = StringUtil.convertLineSeparators(dialog.getTextToSave(), SystemProperties.getLineSeparator()); - writer.write(text); + final DebuggerSession session = context.getDebuggerSession(); + if(session != null && session.isAttached()) { + final DebugProcessImpl process = context.getDebugProcess(); + if (process != null) { + process.getManagerThread().invoke(new DebuggerCommandImpl() { + protected void action() throws Exception { + final List threads = ThreadDumpAction.buildThreadStates(process.getVirtualMachineProxy()); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ExportToTextFileAction.export(project, ThreadDumpPanel.createToFileExporter(project, threads)); + } + }, ModalityState.NON_MODAL); } - finally { - writer.close(); - } - } - catch (IOException ex) { - Messages - .showMessageDialog(project, ex.getMessage(), ActionsBundle.actionText(DebuggerActions.EXPORT_THREADS), Messages.getErrorIcon()); - } + }); } } } - - public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java index e8eb1a902504..96e6d015f026 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -83,7 +83,7 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp } } - private static List buildThreadStates(VirtualMachineProxyImpl vmProxy) { + static List buildThreadStates(VirtualMachineProxyImpl vmProxy) { final List threads = vmProxy.getVirtualMachine().allThreads(); final List result = new ArrayList(); final Map nameToThreadMap = new HashMap(); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java index 09898a068e3a..0b1cd18bb05b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -322,7 +322,7 @@ public class JavaDebugProcess extends XDebugProcess { public void registerAdditionalActions(@NotNull DefaultActionGroup leftToolbar, @NotNull DefaultActionGroup topToolbar, @NotNull DefaultActionGroup settings) { Constraints beforeRunner = new Constraints(Anchor.BEFORE, "Runner.Layout"); leftToolbar.add(Separator.getInstance(), beforeRunner); - leftToolbar.add(ActionManager.getInstance().getAction(DebuggerActions.EXPORT_THREADS), beforeRunner); + //leftToolbar.add(ActionManager.getInstance().getAction(DebuggerActions.EXPORT_THREADS), beforeRunner); leftToolbar.add(ActionManager.getInstance().getAction(DebuggerActions.DUMP_THREADS), beforeRunner); leftToolbar.add(Separator.getInstance(), beforeRunner); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java index 8e5cfb72ce3f..a088e953557f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -287,7 +287,7 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos } leftToolbar.addSeparator(); - addAction(leftToolbar, DebuggerActions.EXPORT_THREADS); + //addAction(leftToolbar, DebuggerActions.EXPORT_THREADS); addAction(leftToolbar, DebuggerActions.DUMP_THREADS); leftToolbar.addSeparator(); diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java index ca7c26dbc811..65c6777bcbbb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java @@ -106,7 +106,9 @@ public class CodeInsightUtil { if (parent == null) return PsiElement.EMPTY_ARRAY; while (true) { if (parent instanceof PsiStatement) { - parent = parent.getParent(); + if (!(element1 instanceof PsiComment || element2 instanceof PsiComment)) { + parent = parent.getParent(); + } break; } if (parent instanceof PsiCodeBlock) break; diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java index 5ef5abbc9b0d..a5b22a82ec83 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java @@ -45,6 +45,7 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.SdkModificator; @@ -161,7 +162,12 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM application.invokeLater(new Runnable() { @Override public void run() { - setupRootAndAnnotateExternally(entry, project, listOwner, annotationFQName, fromFile, packageName, value); + DumbService.getInstance(project).withAlternativeResolveEnabled(new Runnable() { + @Override + public void run() { + setupRootAndAnnotateExternally(entry, project, listOwner, annotationFQName, fromFile, packageName, value); + } + }); } }, project.getDisposed()); } diff --git a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java index fc5fe63e7a98..6352d8105a0a 100644 --- a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java +++ b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java @@ -27,10 +27,10 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Comparing; @@ -146,6 +146,10 @@ public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider { @Override public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) { + if (DumbService.isDumb(project)) { + return null; + } + GlobalSearchScope scope = null; if (moduleName != null) { final Module module = ModuleManager.getInstance(project).findModuleByName(moduleName); diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java new file mode 100644 index 000000000000..99cf1e82073b --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2015 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.psi.impl.smartPointers; + +import com.intellij.lang.java.JavaLanguage; +import com.intellij.psi.*; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dennis.Ushakov + */ +public class JavaAnchorProvider implements SmartPointerAnchorProvider { + @Override + public PsiElement getAnchor(PsiElement element) { + if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { + return null; + } + + if (element instanceof PsiClass) { + if (element instanceof PsiAnonymousClass) { + return ((PsiAnonymousClass)element).getBaseClassReference().getReferenceNameElement(); + } else { + return ((PsiClass)element).getNameIdentifier(); + } + } else if (element instanceof PsiMethod) { + return ((PsiMethod)element).getNameIdentifier(); + } else if (element instanceof PsiVariable) { + return ((PsiVariable)element).getNameIdentifier(); + } + return null; + } + + @Nullable + @Override + public PsiElement getElement(PsiElement anchor) { + if (anchor instanceof PsiIdentifier) { + PsiElement parent = anchor.getParent(); + if (parent instanceof PsiJavaCodeReferenceElement) { // anonymous class, type + parent = parent.getParent(); + } + + if (!anchor.equals(AnchorElementInfoFactory.getAnchor(parent))) return null; + + return parent; + } + return null; + } +} diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java index 1c37445ba749..f477247181c0 100644 --- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java +++ b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -19,6 +19,7 @@ import com.intellij.codeInsight.highlighting.HighlightManager; import com.intellij.execution.ui.ConsoleView; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; +import com.intellij.ide.ExporterToTextFile; import com.intellij.notification.NotificationGroup; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; @@ -32,22 +33,25 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.util.PlatformIcons; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.datatransfer.StringSelection; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; +import java.io.File; +import java.util.*; import java.util.List; import static com.intellij.icons.AllIcons.Debugger.ThreadStates.*; @@ -56,7 +60,7 @@ import static com.intellij.icons.AllIcons.Debugger.ThreadStates.*; * @author Jeka * @author Konstantin Bulenkov */ -public class ThreadDumpPanel extends JPanel { +public class ThreadDumpPanel extends JPanel implements DataProvider { private static final Icon PAUSE_ICON_DAEMON = new LayeredIcon(Paused, Daemon_sign); private static final Icon LOCKED_ICON_DAEMON = new LayeredIcon(Locked, Daemon_sign); private static final Icon RUNNING_ICON_DAEMON = new LayeredIcon(Running, Daemon_sign); @@ -68,6 +72,7 @@ public class ThreadDumpPanel extends JPanel { private final List myThreadDump; private final JPanel myFilterPanel; private final SearchTextField myFilterField; + private final ExporterToTextFile myExporterToTextFile; public ThreadDumpPanel(final Project project, final ConsoleView consoleView, final DefaultActionGroup toolbarActions, final List threadDump) { super(new BorderLayout()); @@ -103,11 +108,14 @@ public class ThreadDumpPanel extends JPanel { } }); + myExporterToTextFile = createToFileExporter(project, myThreadDump); + FilterAction filterAction = new FilterAction(); filterAction.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_FIND).getShortcutSet(), myThreadList); toolbarActions.add(filterAction); toolbarActions.add(new CopyToClipboardAction(threadDump, project)); toolbarActions.add(new SortThreadsAction()); + toolbarActions.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EXPORT_TO_TEXT_FILE)); add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false).getComponent(), BorderLayout.WEST); JPanel leftPanel = new JPanel(new BorderLayout()); @@ -137,6 +145,15 @@ public class ThreadDumpPanel extends JPanel { } } + @Nullable + @Override + public Object getData(@NonNls String dataId) { + if (PlatformDataKeys.EXPORTER_TO_TEXT_FILE.is(dataId)) { + return myExporterToTextFile; + } + return null; + } + private void updateThreadList() { String text = myFilterPanel.isVisible() ? myFilterField.getText() : ""; DefaultListModel model = (DefaultListModel)myThreadList.getModel(); @@ -354,4 +371,59 @@ public class ThreadDumpPanel extends JPanel { updateThreadList(); } } + + public static ExporterToTextFile createToFileExporter(Project project, List threadStates) { + return new MyToFileExporter(project, threadStates); + } + + private static class MyToFileExporter implements ExporterToTextFile { + private final Project myProject; + private final List myThreadStates; + + public MyToFileExporter(Project project, List threadStates) { + myProject = project; + myThreadStates = threadStates; + } + + @Override + public JComponent getSettingsEditor() { + return null; + } + + @Override + public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException {} + + @Override + public void removeSettingsChangedListener(ChangeListener listener) {} + + @Override + public String getReportText() { + StringBuilder sb = new StringBuilder(); + for (ThreadState state : myThreadStates) { + sb.append(state.getStackTrace()).append("\n\n"); + } + return sb.toString(); + } + + private static final @NonNls String DEFAULT_REPORT_FILE_NAME = "threads_report.txt"; + + @Override + public String getDefaultFilePath() { + final VirtualFile baseDir = myProject.getBaseDir(); + if (baseDir != null) { + return baseDir.getPresentableUrl() + File.separator + DEFAULT_REPORT_FILE_NAME; + } + return null; + } + + @Override + public void exportedTo(String filePath) { + + } + + @Override + public boolean canExport() { + return !myThreadStates.isEmpty(); + } + } } diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java index 1b925e02eabe..87cc8e38cb2f 100644 --- a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java +++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java @@ -18,6 +18,7 @@ package com.intellij.psi.search.searches; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.project.Project; @@ -170,6 +171,9 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory() { @Override public SearchScope compute() { + if (!aClass.isValid()) { + throw new ProcessCanceledException(); + } return aClass.getUseScope(); } }), checkDeep); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java index ca19d9766eb8..aa389214205a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java @@ -196,7 +196,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx { DumbService dumbService = DumbService.getInstance(getProject()); PsiElementFinder[] finders = finders(); if (dumbService.isDumb()) { - List list = dumbService.filterByDumbAwareness(Arrays.asList(finders)); + List list = dumbService.filterByDumbAwareness(finders); finders = list.toArray(new PsiElementFinder[list.size()]); } return finders; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java index b5933ed64e68..8a1f32ce83f4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java @@ -24,7 +24,6 @@ import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.ElementClassHint; import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.PsiScopeProcessor; -import com.intellij.util.ObjectUtils; import com.intellij.util.containers.MostlySingularMultiMap; import org.jetbrains.annotations.NotNull; @@ -83,7 +82,16 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele @NotNull public PsiNamedElement getElement() { - return (PsiNamedElement)ObjectUtils.assertNotNull(myElement.retrieve()); + PsiElement element = myElement.retrieve(); + if (element == null) { + String message = "Anchor hasn't survived: " + myElement; + if (myElement instanceof PsiAnchor.StubIndexReference) { + message += "; diagnostics=" + ((PsiAnchor.StubIndexReference)myElement).diagnoseNull(); + } + throw new AssertionError(message); + } + + return (PsiNamedElement)element; } public PsiElement getFileContext() { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java index 9c8b8b4772b3..8ee31c32f6ef 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java @@ -288,10 +288,8 @@ public class InferenceIncorporationPhase { public boolean process(Pair pair) { final PsiType sType = pair.first; final PsiType tType = pair.second; - if (!mySession.isProperType(sType) && !mySession.isProperType(tType)) { - if (!(sType instanceof PsiWildcardType) && !(tType instanceof PsiWildcardType) && sType != null && tType != null) { - addConstraint(new TypeEqualityConstraint(sType, tType)); - } + if (!(sType instanceof PsiWildcardType) && !(tType instanceof PsiWildcardType) && sType != null && tType != null) { + addConstraint(new TypeEqualityConstraint(sType, tType)); } return true; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 90fe82d20b46..9ec7ab51b059 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -1127,13 +1127,18 @@ public class InferenceSession { if (parameters.length == functionalMethodParameters.length && !varargs || isStatic && varargs) {//static methods - if (method.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, qualifierResolveResult.getSubstitutor())) { + PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor(); + if (method.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor)) { + //15.13.1 If ClassType is a raw type, but is not a non-static member type of a raw type, + //the candidate notional member methods are those specified in ยง15.9.3 for a + //class instance creation expression that uses <> to elide the type arguments to a class initBounds(containingClass.getTypeParameters()); + psiSubstitutor = PsiSubstitutor.EMPTY; } for (int i = 0; i < functionalMethodParameters.length; i++) { final PsiType pType = signature.getParameterTypes()[i]; - addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, qualifierResolveResult.getSubstitutor(), varargs)), + addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, psiSubstitutor, varargs)), PsiImplUtil.normalizeWildcardTypeByPosition(pType, reference))); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java index 1b66ab4dada0..56674fa3952b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java @@ -111,10 +111,10 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR @NotNull @Override public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) { - return inferTypeArguments(); + return inferTypeArguments(includeReturnConstraint); } - private PsiSubstitutor inferTypeArguments() { + private PsiSubstitutor inferTypeArguments(boolean includeReturnConstraint) { if (interfaceMethod == null) return substitutor; final InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference); session.initThrowsConstraints(method); @@ -127,7 +127,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR return substitutor; } - if (interfaceMethodReturnType != PsiType.VOID && interfaceMethodReturnType != null) { + if (includeReturnConstraint && interfaceMethodReturnType != PsiType.VOID && interfaceMethodReturnType != null) { if (method.isConstructor()) { //todo session.initBounds(reference, method.getContainingClass().getTypeParameters()); @@ -230,7 +230,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR if (!(conflict instanceof MethodCandidateInfo)) continue; final PsiMethod psiMethod = ((MethodCandidateInfo)conflict).getElement(); - final PsiSubstitutor substitutor = conflict.getSubstitutor(); + final PsiSubstitutor substitutor = ((MethodCandidateInfo)conflict).getSubstitutor(false); final PsiType[] parameterTypes = psiMethod.getSignature(substitutor).getParameterTypes(); final boolean varargs = ((MethodCandidateInfo)conflict).isVarargs(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RawQualifier.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RawQualifier.java index 67bbac28af1e..69fd19863ad2 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RawQualifier.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RawQualifier.java @@ -39,6 +39,6 @@ class MyTest1 { static void foo(I3 i) {} static { - foo(Foo::new); + foo(Foo::new); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java index 6b4de4e565a8..0696aadf6179 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java @@ -67,7 +67,7 @@ class MyTest1 { } public static void main(String[] args) { - m(Foo::new); + m(Foo::new); } } class MyTest2 { @@ -104,6 +104,6 @@ class MyTest2 { } public static void main(String[] args) { - m(Foo::new); + m(Foo::new); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/HighlightReferenceWhenContradictBoundsAreInferred.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/HighlightReferenceWhenContradictBoundsAreInferred.java index c05073e7870f..0d1e79863b9d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/HighlightReferenceWhenContradictBoundsAreInferred.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/HighlightReferenceWhenContradictBoundsAreInferred.java @@ -29,10 +29,10 @@ class Test { static void meth4(I3 s) { } static { - meth1(Foo::new); + meth1(Foo::new); meth2(Foo::new); - meth3(Foo::new); - meth4(Foo::new); + meth3(Foo::new); + meth4(Foo::new); meth1(Test::foo); meth2(Test::foo); diff --git a/java/java-tests/testData/codeInsight/generation/surroundWith/java/SurroundIfBranchWithNoBracesAndComment.java b/java/java-tests/testData/codeInsight/generation/surroundWith/java/SurroundIfBranchWithNoBracesAndComment.java new file mode 100644 index 000000000000..563c1795a3f6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generation/surroundWith/java/SurroundIfBranchWithNoBracesAndComment.java @@ -0,0 +1,7 @@ +class Test { + void m() { + if (true) + // comment + System.out.println(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generation/surroundWith/java/SurroundIfBranchWithNoBracesAndComment_after.java b/java/java-tests/testData/codeInsight/generation/surroundWith/java/SurroundIfBranchWithNoBracesAndComment_after.java new file mode 100644 index 000000000000..801e09e42baa --- /dev/null +++ b/java/java-tests/testData/codeInsight/generation/surroundWith/java/SurroundIfBranchWithNoBracesAndComment_after.java @@ -0,0 +1,8 @@ +class Test { + void m() { + if (true) { + // comment + System.out.println(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/generation/surroundWith/JavaSurroundWithTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/generation/surroundWith/JavaSurroundWithTest.java index c4dce5fd134b..dd8b42ffd98f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/generation/surroundWith/JavaSurroundWithTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/generation/surroundWith/JavaSurroundWithTest.java @@ -94,11 +94,11 @@ public class JavaSurroundWithTest extends LightCodeInsightTestCase { } public void testSurroundNonExpressionWithParenthesis() throws Exception { - doTest(getTestName(false), new JavaWithParenthesesSurrounder()); + doTest(new JavaWithParenthesesSurrounder()); } public void testSurroundNonExpressionWithCast() throws Exception { - doTest(getTestName(false), new JavaWithCastSurrounder()); + doTest(new JavaWithCastSurrounder()); } public void testSurroundExpressionWithCastEmptyLineAfter() throws Exception { @@ -110,52 +110,52 @@ public class JavaSurroundWithTest extends LightCodeInsightTestCase { } public void testSurroundNonExpressionWithNot() throws Exception { - doTest(getTestName(false), new JavaWithNotSurrounder()); + doTest(new JavaWithNotSurrounder()); } public void testSurroundBinaryWithCast() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithCastSurrounder()); + doTest(new JavaWithCastSurrounder()); } public void testSurroundConditionalWithCast() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithCastSurrounder()); + doTest(new JavaWithCastSurrounder()); } public void testSurroundAssignmentWithCast() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithCastSurrounder()); + doTest(new JavaWithCastSurrounder()); } public void testSurroundWithNotNullCheck() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithNullCheckSurrounder()); + doTest(new JavaWithNullCheckSurrounder()); } public void testSurroundExpressionWithIf() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithIfExpressionSurrounder()); + doTest(new JavaWithIfExpressionSurrounder()); } public void testSurroundExpressionWithIfForBoxedBooleans() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithIfExpressionSurrounder()); + doTest(new JavaWithIfExpressionSurrounder()); } public void testSurroundExpressionWithNotForBoxedBooleans() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithNotSurrounder()); + doTest(new JavaWithNotSurrounder()); } public void testSurroundExpressionWithElseIf() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithIfExpressionSurrounder()); + doTest(new JavaWithIfExpressionSurrounder()); } public void testSurroundExpressionWithElseIfElse() { TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); - doTest(getTestName(false), new JavaWithIfElseExpressionSurrounder()); + doTest(new JavaWithIfElseExpressionSurrounder()); } public void testSurroundWithTryFinallyUsingIndents() { @@ -163,7 +163,7 @@ public class JavaSurroundWithTest extends LightCodeInsightTestCase { boolean oldUseTabs = indentOptions.USE_TAB_CHARACTER; try { indentOptions.USE_TAB_CHARACTER = true; - doTest(getTestName(false), new JavaWithTryFinallySurrounder()); + doTest(new JavaWithTryFinallySurrounder()); } finally { indentOptions.USE_TAB_CHARACTER = oldUseTabs; @@ -171,9 +171,17 @@ public class JavaSurroundWithTest extends LightCodeInsightTestCase { } public void testSurroundWithTryCatchFunctionalExpression() { - doTest(getTestName(false), new JavaWithTryCatchSurrounder()); + doTest(new JavaWithTryCatchSurrounder()); } + public void testSurroundIfBranchWithNoBracesAndComment() { + doTest(new JavaWithBlockSurrounder()); + } + + private void doTest(Surrounder surrounder) { + doTest(getTestName(false), surrounder); + } + private void doTest(@NotNull String fileName, final Surrounder surrounder) { configureByFile(BASE_PATH + fileName + ".java"); diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java index 24c55c48f618..3e389146db80 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,6 +17,7 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightTestCase; +import com.intellij.ide.highlighter.HtmlFileType; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Document; @@ -37,6 +38,7 @@ import com.intellij.psi.stubs.StubTree; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.xml.XmlTag; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PlatformTestUtil; @@ -469,4 +471,64 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase { assertEquals(range1.shiftRight(1), pointer1.getRange()); assertEquals(range2.shiftRight(1), pointer2.getRange()); } + + public void testInXml() { + final PsiFile file = configureByText(HtmlFileType.INSTANCE, + "\n" + + "\n" + + "
\n" + + " \n" + + "\n" + + " \n" + + "" + ); + + final XmlTag fieldSet = PsiTreeUtil.getParentOfType(file.findElementAt(file.getText().indexOf("fieldset")), XmlTag.class); + assertNotNull(fieldSet); + assertEquals("fieldset", fieldSet.getName()); + + final XmlTag select = PsiTreeUtil.getParentOfType(file.findElementAt(file.getText().indexOf("select")), XmlTag.class); + assertNotNull(select); + assertEquals("select", select.getName()); + + final SmartPsiElementPointer fieldSetPointer = SmartPointerManager.getInstance(getProject()).createSmartPsiElementPointer( + fieldSet); + final SmartPsiElementPointer selectPointer = SmartPointerManager.getInstance(getProject()).createSmartPsiElementPointer(select); + + WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() { + @Override + public void run() { + getEditor().getDocument().insertString(getEditor().getCaretModel().getOffset(), ""); + } + }); + + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + + final XmlTag newFieldSet = fieldSetPointer.getElement(); + assertNotNull(newFieldSet); + assertEquals("fieldset", newFieldSet.getName()); + + final XmlTag newSelect = selectPointer.getElement(); + assertNotNull(newSelect); + assertEquals("select", newSelect.getName()); + } + public void testInsertImport() { + final PsiFile file = configureByText(JavaFileType.INSTANCE, + "class S {\n" + + "}"); + + PsiClass aClass = ((PsiJavaFile)file).getClasses()[0]; + + WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() { + @Override + public void run() { + getEditor().getDocument().insertString(0, "import java.util.Map;\n"); + } + }); + + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + + PsiClass aClass2 = ((PsiJavaFile)file).getClasses()[0]; + assertSame(aClass, aClass2); + } } diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java index aac45eac8e03..6f8cd3c20fc9 100644 --- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java +++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java @@ -2,14 +2,12 @@ package com.intellij.compiler; import com.intellij.compiler.server.BuildManager; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.application.impl.ApplicationImpl; -import com.intellij.openapi.components.*; -import com.intellij.openapi.components.impl.stores.StateStorageManager; -import com.intellij.openapi.components.impl.stores.StoreUtil; +import com.intellij.openapi.components.impl.stores.ComponentStoreImpl; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; @@ -19,24 +17,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ModuleRootModificationUtil; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.NamedJDOMExternalizable; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; -import com.intellij.util.SystemProperties; -import junit.framework.AssertionFailedError; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.JDomSerializationUtil; -import org.junit.Assert; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -60,74 +41,27 @@ public class CompilerTestUtil { } public static void saveApplicationSettings() { - saveApplicationComponent(ProjectJdkTable.getInstance()); - saveApplicationComponent(FileTypeManager.getInstance()); + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + @Override + public void run() { + doSaveComponent(ProjectJdkTable.getInstance()); + doSaveComponent(FileTypeManager.getInstance()); + } + }, ModalityState.any()); } - public static void saveApplicationComponent(Object appComponent) { - try { - final File file; - String componentName; - State state = StoreUtil.getStateSpec(appComponent.getClass()); - if (state != null) { - componentName = state.name(); - Storage storageToWrite = findNonDeprecated(state.storages()); - StateStorageManager storageManager = ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager(); - file = new File(storageManager.expandMacros(storageToWrite.file())); + public static void saveApplicationComponent(final Object appComponent) { + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + @Override + public void run() { + doSaveComponent(appComponent); } - else if (appComponent instanceof ExportableApplicationComponent && appComponent instanceof NamedJDOMExternalizable) { - componentName = ((ExportableApplicationComponent)appComponent).getComponentName(); - file = PathManager.getOptionsFile((NamedJDOMExternalizable)appComponent); - } - else { - throw new AssertionError( appComponent.getClass() + " doesn't have @State annotation and doesn't implement ExportableApplicationComponent"); - } - - final Element root = new Element("application"); - Element element = JDomSerializationUtil.createComponentElement(componentName); - if (appComponent instanceof JDOMExternalizable) { - ((JDOMExternalizable)appComponent).writeExternal(element); - } - else { - //noinspection unchecked - element.addContent(((PersistentStateComponent)appComponent).getState().cloneContent()); - } - root.addContent(element); - Assert.assertTrue("Cannot create " + file, FileUtil.createIfDoesntExist(file)); - new WriteAction() { - @Override - protected void run(@NotNull final Result result) throws IOException { - VfsRootAccess.allowRootAccess(file.getAbsolutePath()); - try { - VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); - Assert.assertNotNull(file.getAbsolutePath(), virtualFile); - //emulate save via 'saveSettings' so file won't be treated as changed externally - OutputStream stream = virtualFile.getOutputStream(new SaveSessionRequestor()); - try { - JDOMUtil.writeParent(root, stream, SystemProperties.getLineSeparator()); - } - finally { - stream.close(); - } - } - finally { - VfsRootAccess.disallowRootAccess(file.getAbsolutePath()); - } - } - }.execute().throwException(); - } - catch (WriteExternalException e) { - throw new RuntimeException(e); - } + }, ModalityState.any()); } - private static Storage findNonDeprecated(Storage[] storages) { - for (Storage storage : storages) { - if (!storage.deprecated()) { - return storage; - } - } - throw new AssertionFailedError("All storages are deprecated"); + private static void doSaveComponent(Object appComponent) { + //noinspection TestOnlyProblems + ((ComponentStoreImpl)((ApplicationImpl)ApplicationManager.getApplication()).getStateStore()).saveApplicationComponent(appComponent); } public static void enableExternalCompiler() { @@ -164,10 +98,4 @@ public class CompilerTestUtil { } }.execute(); } - - private static class SaveSessionRequestor implements StateStorage.SaveSession { - @Override - public void save() { - } - } } diff --git a/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeAssocTable.java b/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeAssocTable.java index 8646ba0c72aa..ad29218f28c4 100644 --- a/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeAssocTable.java +++ b/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeAssocTable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.openapi.fileTypes.impl; import com.intellij.openapi.fileTypes.ExactFileNameMatcher; @@ -226,7 +225,7 @@ public class FileTypeAssocTable { } @NotNull - public List getAssociations(final T type) { + public List getAssociations(@NotNull T type) { List result = new ArrayList(); for (Pair mapping : myMatchingMappings) { if (mapping.getSecond() == type) { @@ -255,28 +254,33 @@ public class FileTypeAssocTable { return result; } - public boolean hasAssociationsFor(final T fileType) { - if (myExtensionMappings.values().contains(fileType)) return true; - if (myExactFileNameMappings.values().contains(fileType)) return true; - if (myExactFileNameAnyCaseMappings.values().contains(fileType)) return true; + public boolean hasAssociationsFor(@NotNull T fileType) { + if (myExtensionMappings.values().contains(fileType) || + myExactFileNameMappings.values().contains(fileType) || + myExactFileNameAnyCaseMappings.values().contains(fileType)) { + return true; + } for (Pair mapping : myMatchingMappings) { - if (mapping.getSecond() == fileType) return true; + if (mapping.getSecond() == fileType) { + return true; + } } return false; } - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } - final FileTypeAssocTable that = (FileTypeAssocTable)o; - - if (!myExtensionMappings.equals(that.myExtensionMappings)) return false; - if (!myMatchingMappings.equals(that.myMatchingMappings)) return false; - if (!myExactFileNameMappings.equals(that.myExactFileNameMappings)) return false; - if (!myExactFileNameAnyCaseMappings.equals(that.myExactFileNameAnyCaseMappings)) return false; - - return true; + FileTypeAssocTable that = (FileTypeAssocTable)o; + return myExtensionMappings.equals(that.myExtensionMappings) && + myMatchingMappings.equals(that.myMatchingMappings) && + myExactFileNameMappings.equals(that.myExactFileNameMappings) && + myExactFileNameAnyCaseMappings.equals(that.myExactFileNameAnyCaseMappings); } public int hashCode() { diff --git a/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java b/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java index e64ed100419e..747c0528753a 100644 --- a/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java +++ b/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java @@ -45,7 +45,6 @@ public class IgnoredPatternSet { addIgnoreMask(ignoredFile); } } - } void addIgnoreMask(@NotNull String ignoredFile) { diff --git a/lib/src/winp-1.23-sources.jar b/lib/src/winp-1.23-sources.jar new file mode 100644 index 000000000000..255784887d3a Binary files /dev/null and b/lib/src/winp-1.23-sources.jar differ diff --git a/lib/winp-1.23.jar b/lib/winp-1.23.jar new file mode 100644 index 000000000000..3d88c38c0a95 Binary files /dev/null and b/lib/winp-1.23.jar differ diff --git a/platform/analysis-api/src/com/intellij/codeInsight/highlighting/HighlightErrorFilter.java b/platform/analysis-api/src/com/intellij/codeInsight/highlighting/HighlightErrorFilter.java index 5c89d98ecfa2..ad0679329bd5 100644 --- a/platform/analysis-api/src/com/intellij/codeInsight/highlighting/HighlightErrorFilter.java +++ b/platform/analysis-api/src/com/intellij/codeInsight/highlighting/HighlightErrorFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -16,6 +16,7 @@ package com.intellij.codeInsight.highlighting; +import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.PsiErrorElement; import org.jetbrains.annotations.NotNull; @@ -23,6 +24,7 @@ import org.jetbrains.annotations.NotNull; * @author spleaner */ public abstract class HighlightErrorFilter { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.highlightErrorFilter"); public abstract boolean shouldHighlightErrorElement(@NotNull final PsiErrorElement element); diff --git a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java index 9119fd6eadab..8c2a8c5c51e2 100644 --- a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java +++ b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionAction.java @@ -34,6 +34,8 @@ import org.jetbrains.annotations.NotNull; *

* Implement {@link HighPriorityAction HighPriorityAction} or * {@link LowPriorityAction LowPriorityAction} to change ordering. + *

+ * Can be {@link com.intellij.openapi.project.DumbAware}. * * @see IntentionManager#registerIntentionAndMetaData(IntentionAction, String...) */ diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java index 84625d642c58..3936e59161b2 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -25,7 +25,6 @@ import com.intellij.lang.LanguageUtil; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.Annotator; import com.intellij.openapi.extensions.ExtensionPointListener; -import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.progress.ProgressManager; @@ -50,7 +49,6 @@ import java.util.List; public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware { private AnnotationHolderImpl myAnnotationHolder; - public static final ExtensionPointName FILTER_EP_NAME = ExtensionPointName.create("com.intellij.highlightErrorFilter"); private final HighlightErrorFilter[] myErrorFilters; private final Project myProject; private final boolean myHighlightErrorElements; @@ -67,7 +65,7 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware { myProject = project; myHighlightErrorElements = highlightErrorElements; myRunAnnotators = runAnnotators; - myErrorFilters = Extensions.getExtensions(FILTER_EP_NAME, project); + myErrorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, project); myDumbService = DumbService.getInstance(project); myBatchMode = batchMode; } diff --git a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java index 6f4818b29207..29a8905a45b9 100644 --- a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java +++ b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -100,35 +100,36 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore { } private static void addParentClasspath(List classpathElements) throws MalformedURLException { - ClassLoader loader = BootstrapClassLoaderUtil.class.getClassLoader(); - if (loader instanceof URLClassLoader) { - ContainerUtil.addAll(classpathElements, ((URLClassLoader)loader).getURLs()); - } - else { - String loaderName = loader.getClass().getName(); - try { - Class antClassLoaderClass = Class.forName("org.apache.tools.ant.AntClassLoader"); - if (antClassLoaderClass.isInstance(loader) || - "org.apache.tools.ant.AntClassLoader".equals(loaderName) || - "org.apache.tools.ant.loader.AntClassLoader2".equals(loaderName)) { - String classpath = (String)antClassLoaderClass - .getDeclaredMethod("getClasspath", ArrayUtil.EMPTY_CLASS_ARRAY) - .invoke(loader, ArrayUtil.EMPTY_OBJECT_ARRAY); - StringTokenizer tokenizer = new StringTokenizer(classpath, File.separator, false); - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - classpathElements.add(new File(token).toURI().toURL()); + for (ClassLoader loader = BootstrapClassLoaderUtil.class.getClassLoader(); loader != null; loader = loader.getParent()) { + if (loader instanceof URLClassLoader) { + ContainerUtil.addAll(classpathElements, ((URLClassLoader)loader).getURLs()); + } + else { + String loaderName = loader.getClass().getName(); + try { + Class antClassLoaderClass = Class.forName("org.apache.tools.ant.AntClassLoader"); + if (antClassLoaderClass.isInstance(loader) || + "org.apache.tools.ant.AntClassLoader".equals(loaderName) || + "org.apache.tools.ant.loader.AntClassLoader2".equals(loaderName)) { + String classpath = (String)antClassLoaderClass + .getDeclaredMethod("getClasspath", ArrayUtil.EMPTY_CLASS_ARRAY) + .invoke(loader, ArrayUtil.EMPTY_OBJECT_ARRAY); + StringTokenizer tokenizer = new StringTokenizer(classpath, File.separator, false); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + classpathElements.add(new File(token).toURI().toURL()); + } + } + else { + getLogger().warn("Unknown class loader: " + loaderName); } } - else { - getLogger().warn("Unknown class loader: " + loaderName); - } + catch (ClassCastException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } + catch (ClassNotFoundException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } + catch (NoSuchMethodException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } + catch (IllegalAccessException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } + catch (InvocationTargetException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } } - catch (ClassCastException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } - catch (ClassNotFoundException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } - catch (NoSuchMethodException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } - catch (IllegalAccessException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } - catch (InvocationTargetException e) { getLogger().warn("Unknown class loader '" + loaderName + "'", e); } } } diff --git a/platform/core-api/src/com/intellij/openapi/options/BaseSchemeProcessor.java b/platform/core-api/src/com/intellij/openapi/options/BaseSchemeProcessor.java index 350c403cadd1..845e50fbe804 100644 --- a/platform/core-api/src/com/intellij/openapi/options/BaseSchemeProcessor.java +++ b/platform/core-api/src/com/intellij/openapi/options/BaseSchemeProcessor.java @@ -33,15 +33,15 @@ public abstract class BaseSchemeProcessor implem } @Override - public void onSchemeAdded(@NotNull final T scheme) { + public void onSchemeAdded(@NotNull T scheme) { } @Override - public void onSchemeDeleted(@NotNull final T scheme) { + public void onSchemeDeleted(@NotNull T scheme) { } @Override - public void onCurrentSchemeChanged(final Scheme newCurrentScheme) { + public void onCurrentSchemeChanged(Scheme newCurrentScheme) { } @Nullable @@ -49,6 +49,14 @@ public abstract class BaseSchemeProcessor implem return readScheme(new Document((Element)element.detach())); } + @Nullable + /** + * @param duringLoad If occurred during {@link SchemesManager#loadSchemes()} call + */ + public T readScheme(@NotNull Element element, boolean duringLoad) throws InvalidDataException, IOException, JDOMException { + return readScheme(element); + } + @Override public T readScheme(@NotNull Document schemeContent) throws InvalidDataException, IOException, JDOMException { throw new AbstractMethodError(); diff --git a/platform/core-api/src/com/intellij/openapi/project/DumbService.java b/platform/core-api/src/com/intellij/openapi/project/DumbService.java index bbc3e824e933..68ca99133e46 100644 --- a/platform/core-api/src/com/intellij/openapi/project/DumbService.java +++ b/platform/core-api/src/com/intellij/openapi/project/DumbService.java @@ -29,6 +29,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -159,6 +160,19 @@ public abstract class DumbService { return INSTANCE_KEY.getValue(project); } + /** + * @return all the elements of the given array if there's no dumb mode currently, or the dumb-aware ones if {@link #isDumb()} is true. + * @see #isDumbAware(Object) + */ + @NotNull + public List filterByDumbAwareness(@NotNull T[] array) { + return filterByDumbAwareness(Arrays.asList(array)); + } + + /** + * @return all the elements of the given collection if there's no dumb mode currently, or the dumb-aware ones if {@link #isDumb()} is true. + * @see #isDumbAware(Object) + */ @NotNull public List filterByDumbAwareness(@NotNull Collection collection) { if (isDumb()) { @@ -227,6 +241,20 @@ public abstract class DumbService { */ public abstract void setAlternativeResolveEnabled(boolean enabled); + /** + * Invokes the given runnable with alternative resolve set to true. + * @see #setAlternativeResolveEnabled(boolean) + */ + public void withAlternativeResolveEnabled(@NotNull Runnable runnable) { + setAlternativeResolveEnabled(true); + try { + runnable.run(); + } + finally { + setAlternativeResolveEnabled(false); + } + } + /** * @return whether alternative resolution is enabled for the current thread. * diff --git a/platform/core-impl/src/com/intellij/mock/MockComponentManager.java b/platform/core-impl/src/com/intellij/mock/MockComponentManager.java index 33dce7f09ce3..7a7348fdbee0 100644 --- a/platform/core-impl/src/com/intellij/mock/MockComponentManager.java +++ b/platform/core-impl/src/com/intellij/mock/MockComponentManager.java @@ -43,26 +43,30 @@ public class MockComponentManager extends UserDataHolderBase implements Componen private final MutablePicoContainer myPicoContainer; private final Map myComponents = new HashMap(); + private final Set myDisposableComponents = ContainerUtil.newConcurrentSet(); public MockComponentManager(@Nullable PicoContainer parent, @NotNull Disposable parentDisposable) { myPicoContainer = new DefaultPicoContainer(parent) { - private final Set myDisposableComponents = ContainerUtil.newConcurrentSet(); - @Override @Nullable public Object getComponentInstance(final Object componentKey) { final Object o = super.getComponentInstance(componentKey); - if (o instanceof Disposable && o != MockComponentManager.this) { - if (myDisposableComponents.add(o)) - Disposer.register(MockComponentManager.this, (Disposable)o); - } + registerComponentInDisposer(o); return o; } }; + myPicoContainer.registerComponentInstance(this); Disposer.register(parentDisposable, this); } + private void registerComponentInDisposer(@Nullable Object o) { + if (o instanceof Disposable && o != MockComponentManager.this) { + if (myDisposableComponents.add(o)) + Disposer.register(MockComponentManager.this, (Disposable)o); + } + } + @Override public BaseComponent getComponent(@NotNull String name) { return null; @@ -79,10 +83,12 @@ public class MockComponentManager extends UserDataHolderBase implements Componen public void registerService(@NotNull Class serviceInterface, @NotNull T serviceImplementation) { myPicoContainer.registerComponentInstance(serviceInterface.getName(), serviceImplementation); + registerComponentInDisposer(serviceImplementation); } public void addComponent(@NotNull Class interfaceClass, @NotNull T instance) { myComponents.put(interfaceClass, instance); + registerComponentInDisposer(instance); } @Override diff --git a/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java b/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java index ba12a9d04ea6..d4f3f707d4e6 100644 --- a/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java +++ b/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java @@ -121,8 +121,8 @@ public abstract class AbstractSchemesManager EP_NAME = ExtensionPointName.create("com.intellij.smartPointer.anchorProvider"); + + @Nullable + PsiElement getAnchor(PsiElement element); + + @Nullable + PsiElement getElement(PsiElement anchor); +} diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java index 32edb4d4e0e7..67add6d2a0a2 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java @@ -33,6 +33,7 @@ import com.intellij.util.diff.DiffTreeChangeBuilder; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -173,6 +174,8 @@ public class DiffLog implements DiffTreeChangeBuilder { private InsertEntry(@NotNull ASTNode oldParent, @NotNull ASTNode newNode, int pos) { assert oldParent instanceof CompositeElement : oldParent; + assert pos>=0 : pos; + assert pos<=oldParent.getChildren(null).length : pos + " "+ Arrays.toString(oldParent.getChildren(null)); myOldParent = oldParent; myNewNode = newNode; myPos = pos; diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java index 94fc6b508990..826e3139b8a3 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/TreeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -120,6 +120,14 @@ public class TreeUtil { return null; } + @Nullable + public static ASTNode findParent(ASTNode element, TokenSet types) { + for (ASTNode parent = element.getTreeParent(); parent != null; parent = parent.getTreeParent()) { + if (types.contains(parent.getElementType())) return parent; + } + return null; + } + @Nullable public static LeafElement findFirstLeaf(ASTNode element) { return (LeafElement)findFirstLeaf(element, true); diff --git a/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java b/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java index bf61094015f0..04b41075e483 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java +++ b/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java @@ -24,14 +24,16 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import java.util.Collections; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; public class Extensions { public static final ExtensionPointName AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName("com.intellij.arealistener"); private static LogProvider ourLogger = new SimpleLogProvider(); - private static Map ourAreaInstance2area = new THashMap(); - private static Map ourAreaClass2Configuration = new THashMap(); + private static final Map ourAreaInstance2area = + Collections.synchronizedMap(new THashMap()); + private static final Map ourAreaClass2Configuration = + Collections.synchronizedMap(new THashMap()); @NotNull private static ExtensionsAreaImpl ourRootArea = createRootArea(); @@ -45,14 +47,6 @@ public class Extensions { return rootArea; } - public static void setSynchronized() { - assert ourAreaInstance2area.isEmpty(); - assert ourAreaClass2Configuration.isEmpty(); - - ourAreaInstance2area = new ConcurrentHashMap(); - ourAreaClass2Configuration = new ConcurrentHashMap(); - } - @NotNull public static ExtensionsArea getRootArea() { return ourRootArea; diff --git a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java index 1bcc43b73309..d3fbf73d06bc 100644 --- a/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java +++ b/platform/indexing-impl/src/com/intellij/ide/highlighter/custom/SyntaxTable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -47,10 +47,6 @@ public class SyntaxTable implements Cloneable { private boolean myHasStringEscapes; private volatile KeywordParser myKeywordParser; - // ------------------------------------------------------------------------- - // Constructor - // ------------------------------------------------------------------------- - public SyntaxTable() { myKeywords1 = new TreeSet(); myKeywords2 = new TreeSet(); @@ -73,7 +69,7 @@ public class SyntaxTable implements Cloneable { @Override protected Object clone() throws CloneNotSupportedException { - SyntaxTable cl = (SyntaxTable) super.clone(); + SyntaxTable cl = (SyntaxTable)super.clone(); cl.myKeywords1 = new TreeSet(myKeywords1); cl.myKeywords2 = new TreeSet(myKeywords2); cl.myKeywords3 = new TreeSet(myKeywords3); @@ -82,10 +78,6 @@ public class SyntaxTable implements Cloneable { return cl; } - // ------------------------------------------------------------------------- - // Public interface - // ------------------------------------------------------------------------- - public void addKeyword1(String keyword) { myKeywords1.add(keyword); myKeywordParser = null; diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java index 2450f3fa009d..f484c9fe7bfb 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java @@ -27,6 +27,7 @@ import com.intellij.ui.components.JBList; import com.intellij.util.Function; import com.intellij.util.NotNullFunction; import com.intellij.util.SmartList; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -120,7 +121,7 @@ public abstract class MergeableLineMarkerInfo extends Line } }); final JBList list = new JBList(infos); - list.setFixedCellHeight(20); + list.setFixedCellHeight(UIUtil.LIST_FIXED_CELL_HEIGHT); PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list); if (!markers.get(0).configurePopupAndRenderer(builder, list, infos)) { list.installCellRenderer(new NotNullFunction() { diff --git a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java index bf8cffe0b36e..095cb37707a3 100644 --- a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java +++ b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java @@ -33,6 +33,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; @@ -116,7 +117,7 @@ public class ConfigurationContext { private void createConfiguration() { LOG.assertTrue(myConfiguration == null); final Location location = getLocation(); - myConfiguration = location != null ? + myConfiguration = location != null && !DumbService.isDumb(location.getProject()) ? PreferredProducerFind.createConfiguration(location, this) : null; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java index bb4ff521ebfd..6781dcfef1bf 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java @@ -195,7 +195,7 @@ public interface CodeStyleSettingsCustomizable { SPECIAL_ELSE_IF_TREATMENT, ENUM_CONSTANTS_WRAP, ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS, - INDENT_BRAKE_FROM_CASE + INDENT_BREAK_FROM_CASE } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index 74f1a5c43608..1e7bc6a1c237 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -43,6 +43,10 @@ import java.util.Set; * @author Rustam Vishnyakov */ public class CommonCodeStyleSettings { + // Dev. notes: + // - Do not add language-specific options here, use CustomCodeStyleSettings instead. + // - A new options should be added to CodeStyleSettingsCustomizable as well. + // - Covered by CodeStyleConfigurationsTest. @NonNls private static final String ARRANGEMENT_ELEMENT_NAME = "arrangement"; diff --git a/platform/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java b/platform/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java index 74782538c2ca..0da9d6148dbc 100644 --- a/platform/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java +++ b/platform/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -16,8 +16,10 @@ package com.intellij.refactoring.classMembers; -import com.intellij.psi.PsiElement; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; import com.intellij.psi.util.PsiUtilCore; /** @@ -25,7 +27,7 @@ import com.intellij.psi.util.PsiUtilCore; */ public abstract class MemberInfoBase { protected static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.MemberInfo"); - protected T myMember; + private SmartPsiElementPointer myMember; protected boolean isStatic; protected String displayName; private boolean isChecked = false; @@ -36,7 +38,7 @@ public abstract class MemberInfoBase { private boolean toAbstract = false; public MemberInfoBase(T member) { - myMember = member; + updateMember(member); } public boolean isStatic() { @@ -67,16 +69,16 @@ public abstract class MemberInfoBase { } public T getMember() { - PsiUtilCore.ensureValid(myMember); - return myMember; + T element = myMember.getElement(); + PsiUtilCore.ensureValid(element); + return element; } /** * Use this method solely to update element from smart pointer and the likes - * @param element */ public void updateMember(T element) { - myMember = element; + myMember = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); } public boolean isToAbstract() { @@ -87,7 +89,7 @@ public abstract class MemberInfoBase { this.toAbstract = toAbstract; } - public static interface Filter { + public interface Filter { boolean includeMember(T member); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java index 852b33c5e99a..ff5c27ad756c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java @@ -65,8 +65,7 @@ public class HighlightingSettingsPerFile extends HighlightingLevelManager implem private static FileHighlightingSetting getDefaultHighlightingSetting(@NotNull Project project, final VirtualFile virtualFile) { if (virtualFile != null) { DefaultHighlightingSettingProvider[] providers = DefaultHighlightingSettingProvider.EP_NAME.getExtensions(); - List filtered = - DumbService.getInstance(project).filterByDumbAwareness(Arrays.asList(providers)); + List filtered = DumbService.getInstance(project).filterByDumbAwareness(providers); for (DefaultHighlightingSettingProvider p : filtered) { FileHighlightingSetting setting = p.getDefaultSetting(project, virtualFile); if (setting != null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java index e0d17d3c164b..c1f298982d4b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java @@ -29,6 +29,7 @@ import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowType; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -216,6 +217,7 @@ public abstract class DockablePopupManager { return; } + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject); final Editor injectedEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index d1bbdf28bf32..bddd5acc5b5b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -705,7 +705,7 @@ public class DocumentationManager extends DockablePopupManager transferableDatas = new ArrayList(); + final List transferableDatas = new ArrayList(); - DumbService.getInstance(project).setAlternativeResolveEnabled(true); - try { - for (CopyPastePostProcessor processor : Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) { - transferableDatas.addAll(processor.collectTransferableData(file, editor, startOffsets, endOffsets)); + DumbService.getInstance(project).withAlternativeResolveEnabled(new Runnable() { + @Override + public void run() { + for (CopyPastePostProcessor processor : Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) { + transferableDatas.addAll(processor.collectTransferableData(file, editor, startOffsets, endOffsets)); + } } - } - finally { - DumbService.getInstance(project).setAlternativeResolveEnabled(false); - } + }); String text = editor.getCaretModel().supportsMultipleCarets() ? EditorCopyPasteHelperImpl.getSelectedTextForClipboard(editor, transferableDatas) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index 881013d463eb..b6f951efb865 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -32,6 +32,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; @@ -595,8 +596,16 @@ public class EnterHandler extends BaseEnterHandler { if (docProvider != null) { if (docProvider.findExistingDocComment(comment) != comment) return comment; - String docStub = docProvider.generateDocumentationContentStub(comment); + String docStub; + DumbService.getInstance(project).setAlternativeResolveEnabled(true); + try { + docStub = docProvider.generateDocumentationContentStub(comment); + } + finally { + DumbService.getInstance(project).setAlternativeResolveEnabled(false); + } + if (docStub != null && docStub.length() != 0) { myOffset = CharArrayUtil.shiftForwardUntil(myDocument.getCharsSequence(), myOffset, LINE_SEPARATOR); myOffset = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), myOffset, LINE_SEPARATOR); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java index 0fcccb7c742e..89d0ab4d5348 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java @@ -116,6 +116,7 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser return; } + DumbService.getInstance(project).setAlternativeResolveEnabled(true); document.startGuardedBlockChecking(); try { for (PasteProvider provider : Extensions.getExtensions(EP_NAME)) { @@ -131,6 +132,7 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser } finally { document.stopGuardedBlockChecking(); + DumbService.getInstance(project).setAlternativeResolveEnabled(false); } } @@ -153,21 +155,15 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser final CodeInsightSettings settings = CodeInsightSettings.getInstance(); final Map> extraData = new HashMap>(); - Collection allValues = new ArrayList(); + final Collection allValues = new ArrayList(); - DumbService.getInstance(project).setAlternativeResolveEnabled(true); - try { - for (CopyPastePostProcessor processor : Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) { - List data = processor.extractTransferableData(content); - if (!data.isEmpty()) { - extraData.put(processor, data); - allValues.addAll(data); - } + for (CopyPastePostProcessor processor : Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) { + List data = processor.extractTransferableData(content); + if (!data.isEmpty()) { + extraData.put(processor, data); + allValues.addAll(data); } } - finally { - DumbService.getInstance(project).setAlternativeResolveEnabled(false); - } text = TextBlockTransferable.convertLineSeparators(editor, text, allValues); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java index 359cf711cc9e..c92fe6c9f16e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.event.*; import com.intellij.openapi.editor.impl.EditorImpl; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; @@ -240,7 +241,14 @@ public class ParameterInfoController implements Disposable { Runnable request = new Runnable(){ @Override public void run(){ - if (!myDisposed && !myProject.isDisposed()) updateComponent(); + if (!myDisposed && !myProject.isDisposed()) { + DumbService.getInstance(myProject).withAlternativeResolveEnabled(new Runnable() { + @Override + public void run() { + updateComponent(); + } + }); + } } }; myAlarm.addRequest(request, DELAY, ModalityState.stateForComponent(myEditor.getComponent())); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoHandler.java index 04db9762fdfe..5c71a3191a57 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowParameterInfoHandler.java @@ -91,12 +91,18 @@ public class ShowParameterInfoHandler implements CodeInsightActionHandler { return; } - for (ParameterInfoHandler handler : handlers) { - Object element = handler.findElementForParameterInfo(context); - if (element != null) { - handler.showParameterInfo(element, context); + DumbService.getInstance(project).setAlternativeResolveEnabled(true); + try { + for (ParameterInfoHandler handler : handlers) { + Object element = handler.findElementForParameterInfo(context); + if (element != null) { + handler.showParameterInfo(element, context); + } } } + finally { + DumbService.getInstance(project).setAlternativeResolveEnabled(false); + } } private static void showLookupEditorHint(Object[] descriptors, final Editor editor, final Project project, ParameterInfoHandler handler) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionActionWithTextCaching.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionActionWithTextCaching.java index 2c5b5b3ad8c6..303d002458df 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionActionWithTextCaching.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionActionWithTextCaching.java @@ -18,6 +18,8 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.PossiblyDumbAware; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.diagnostic.Logger; import org.jetbrains.annotations.NotNull; @@ -29,7 +31,7 @@ import java.util.ArrayList; /** * @author cdr */ -class IntentionActionWithTextCaching implements Comparable { +class IntentionActionWithTextCaching implements Comparable, PossiblyDumbAware { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.IntentionActionWithTextCaching"); private final List myOptionIntentions = new ArrayList(); private final List myOptionErrorFixes = new ArrayList(); @@ -109,4 +111,9 @@ class IntentionActionWithTextCaching implements Comparable @Override public void run() { if (myProject.isDisposed()) return; + if (DumbService.isDumb(myProject) && !DumbService.isDumbAware(cachedAction)) { + DumbService.getInstance(myProject).showDumbModeNotification(cachedAction.getText() + " is not available during indexing"); + return; + } + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); final PsiFile file = PsiUtilBase.getPsiFileInEditor(myEditor, myProject); if (file == null) { @@ -294,6 +300,7 @@ class IntentionListStep implements ListPopupStep result.addAll(myCachedInspectionFixes); result.addAll(myCachedIntentions); result.addAll(myCachedGutters); + result = DumbService.getInstance(myProject).filterByDumbAwareness(result); Collections.sort(result, new Comparator() { @Override public int compare(final IntentionActionWithTextCaching o1, final IntentionActionWithTextCaching o2) { 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 e419c42ca35e..06942d6bd1eb 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 @@ -657,15 +657,13 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable, HintManagerImpl.getInstanceImpl().showEditorHint(this, myEditor, p, HintManager.HIDE_BY_ESCAPE | HintManager.UPDATE_BY_SCROLLING, 0, false, HintManagerImpl.createHintHint(myEditor, p, this, HintManager.UNDER).setAwtTooltip(false)); - if (!isVisible()) { + if (!isVisible() || !myList.isShowing()) { hide(); return false; } DaemonCodeAnalyzer.getInstance(myProject).disableUpdateByTimer(this); - LOG.assertTrue(myList.isShowing(), "!showing, disposed=" + myDisposed); - return true; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java index 0d49a89d9c43..94e1933d5cbb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java @@ -153,8 +153,13 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { } else { Navigatable nav = element instanceof Navigatable ? (Navigatable)element : EditSourceUtil.getDescriptor((PsiElement)element); - if (nav != null && nav.canNavigate()) { - navigateToElement(nav); + try { + if (nav != null && nav.canNavigate()) { + navigateToElement(nav); + } + } + catch (IndexNotReadyException e) { + DumbService.getInstance(project).showDumbModeNotification("Navigation is not available while indexing"); } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java index e80b060d94a8..99a064368e30 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java @@ -42,6 +42,7 @@ import com.intellij.openapi.editor.markup.HighlighterTargetArea; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -663,12 +664,17 @@ public class TemplateState implements Disposable { calcedSegments.clear(); for (int i = myCurrentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) { String variableName = myTemplate.getVariableNameAt(i); - int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); + final int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); if (segmentNumber < 0) continue; - Expression expression = myTemplate.getExpressionAt(i); - Expression defaultValue = myTemplate.getDefaultValueAt(i); + final Expression expression = myTemplate.getExpressionAt(i); + final Expression defaultValue = myTemplate.getDefaultValueAt(i); String oldValue = getVariableValueText(variableName); - recalcSegment(segmentNumber, isQuick, expression, defaultValue); + DumbService.getInstance(myProject).withAlternativeResolveEnabled(new Runnable() { + @Override + public void run() { + recalcSegment(segmentNumber, isQuick, expression, defaultValue); + } + }); final TextResult value = getVariableValue(variableName); assert value != null : "name=" + variableName + "\ntext=" + myTemplate.getTemplateText(); String newValue = value.getText(); @@ -1104,9 +1110,14 @@ public class TemplateState implements Disposable { final PsiFile file = getPsiFile(); if (file != null) { CodeStyleManager style = CodeStyleManager.getInstance(myProject); - for (TemplateOptionalProcessor optionalProcessor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) { - optionalProcessor.processText(myProject, myTemplate, myDocument, myTemplateRange, myEditor); - } + DumbService.getInstance(myProject).withAlternativeResolveEnabled(new Runnable() { + @Override + public void run() { + for (TemplateOptionalProcessor optionalProcessor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) { + optionalProcessor.processText(myProject, myTemplate, myDocument, myTemplateRange, myEditor); + } + } + }); PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myDocument); // for Python, we need to indent the template even if reformatting is enabled, because otherwise indents would be broken // and reformat wouldn't be able to fix them diff --git a/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java index beb8b10954d5..322204b738d3 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java @@ -26,6 +26,8 @@ import com.intellij.execution.configurations.RunConfiguration; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.ui.popup.PopupStep; @@ -108,6 +110,11 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { @Override public boolean canBePerformed(DataContext dataContext) { + Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (project != null && DumbService.isDumb(project)) { + return false; + } + final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); final RunnerAndConfigurationSettings existing = context.findExisting(); if (existing == null) { diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index d541b346b1af..3cf6c741549e 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -42,6 +42,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.progress.util.ReadTask; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.*; import com.intellij.openapi.util.Disposer; @@ -637,7 +638,12 @@ public class FindDialog extends DialogWrapper { } private void doOKAction(boolean findAll) { - FindModel validateModel = (FindModel)myModel.clone(); + if (DumbService.isDumb(myProject)) { + Messages.showMessageDialog(myProject, "Find Usages is not available while indexing is in progress", "Indexing", null); + return; + } + + FindModel validateModel = myModel.clone(); applyTo(validateModel, findAll); ValidationInfo validationInfo = getValidationInfo(validateModel); @@ -761,7 +767,7 @@ public class FindDialog extends DialogWrapper { @Override protected ValidationInfo doValidate() { - FindModel validateModel = (FindModel)myModel.clone(); + FindModel validateModel = myModel.clone(); applyTo(validateModel, false); ValidationInfo result = getValidationInfo(validateModel); diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java index 3d064e69cc9e..17ca7e4436bf 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java @@ -35,6 +35,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.ProgressWrapper; import com.intellij.openapi.progress.util.TooManyUsagesStatus; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.DumbServiceImpl; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -209,7 +210,7 @@ public class FindInProjectUtil { TooManyUsagesStatus tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator); do { tooManyUsagesStatus.pauseProcessingIfTooManyUsages(); // wait for user out of read action - found = ApplicationManager.getApplication().runReadAction(new Computable() { + found = DumbService.getInstance(psiFile.getProject()).runReadActionInSmartMode(new Computable() { @Override @NotNull public Integer compute() { diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java index 2ed96628b1f5..acb8a717b8d3 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java @@ -27,6 +27,7 @@ import com.intellij.ide.projectView.impl.ProjectViewPane; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.vfs.VirtualFile; @@ -40,7 +41,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -151,13 +151,19 @@ public abstract class ProjectViewSelectInTarget extends SelectInTargetPsiWrapper } } if (toSelect == null) return; - PsiElement originalElement = toSelect.getOriginalElement(); + PsiElement originalElement; + try { + originalElement = toSelect.getOriginalElement(); + } + catch (IndexNotReadyException e) { + originalElement = toSelect; + } final VirtualFile virtualFile = PsiUtilBase.getVirtualFile(originalElement); select(originalElement, virtualFile, requestFocus); } private TreeStructureProvider[] getProvidersDumbAware() { - List allProviders = Arrays.asList(Extensions.getExtensions(TreeStructureProvider.EP_NAME, myProject)); + TreeStructureProvider[] allProviders = Extensions.getExtensions(TreeStructureProvider.EP_NAME, myProject); List dumbAware = DumbService.getInstance(myProject).filterByDumbAwareness(allProviders); return dumbAware.toArray(new TreeStructureProvider[dumbAware.size()]); } diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java index 8085e3fa0d04..ae22175871a9 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java @@ -219,7 +219,7 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable } private static boolean canBeModified(FileType fileType) { - return fileType instanceof AbstractFileType && !(fileType instanceof ImportedFileType); //todo: add API for canBeModified + return fileType instanceof AbstractFileType; //todo: add API for canBeModified } private void addFileType() { diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java index 0e08183cd32d..9cc256420448 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java @@ -110,7 +110,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.caret"), EditorColors.CARET_COLOR, ColorDescriptor.Kind.FOREGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.caret.row"), EditorColors.CARET_ROW_COLOR, ColorDescriptor.Kind.BACKGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.right.margin"), EditorColors.RIGHT_MARGIN_COLOR, ColorDescriptor.Kind.FOREGROUND), - new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.whitespaces"), EditorColors.WHITESPACES_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.whitespaces"), EditorColors.WHITESPACES_COLOR, ColorDescriptor.Kind.FOREGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.indent.guide"), EditorColors.INDENT_GUIDE_COLOR, ColorDescriptor.Kind.BACKGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.indent.guide.selected"), EditorColors.SELECTED_INDENT_GUIDE_COLOR, ColorDescriptor.Kind.BACKGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.line.number"), EditorColors.LINE_NUMBERS_COLOR, ColorDescriptor.Kind.FOREGROUND), diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java index 569a63b6e31c..9f4b2be1e2e2 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java @@ -65,7 +65,7 @@ public class JavaTestSourceRootEditHandler extends JavaSourceRootEditHandlerBase @Nullable @Override public Icon getFolderUnderRootIcon() { - return AllIcons.Modules.TestSourceFolder; + return AllIcons.Modules.SourceFolder; } @Override diff --git a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java index 3d5318b6c7e3..f5b1170ed2de 100644 --- a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java +++ b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java @@ -23,10 +23,7 @@ import com.intellij.lexer.Lexer; import com.intellij.lexer.MergingLexerAdapter; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.LanguageFileType; -import com.intellij.psi.FileViewProvider; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.SingleRootFileViewProvider; +import com.intellij.psi.*; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.PsiFileImpl; @@ -216,7 +213,7 @@ public class TemplateDataElementType extends IFileElementType implements ITempla return language; } }; - + SingleRootFileViewProvider.doNotCheckFileSizeLimit(virtualFile); return viewProvider.getPsi(language); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java index 76c07b93ffe9..ecf91926e247 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesDialog.java @@ -27,8 +27,10 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileChooser.FileChooserFactory; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.util.Disposer; import com.intellij.psi.PsiDirectory; @@ -195,6 +197,12 @@ public class MoveFilesOrDirectoriesDialog extends DialogWrapper { //myTargetDirectoryField.getChildComponent().addCurrentTextToHistory(); RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_KEYS, myTargetDirectoryField.getChildComponent().getText()); RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE = myCbSearchForReferences.isSelected(); + + if (DumbService.isDumb(myProject)) { + Messages.showMessageDialog(myProject, "Move refactoring is not available while indexing is in progress", "Indexing", null); + return; + } + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { @Override public void run() { diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java index bda2dcc23764..d60058657751 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -368,14 +368,16 @@ public abstract class InplaceRefactoring { final int offset = myEditor.getCaretModel().getOffset(); + Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor); + TextRange range = myScope.getTextRange(); + assert range != null; + RangeMarker rangeMarker = topLevelEditor.getDocument().createRangeMarker(range); + Template template = builder.buildInlineTemplate(); template.setToShortenLongNames(false); template.setToReformat(false); - TextRange range = myScope.getTextRange(); - assert range != null; myHighlighters = new ArrayList(); - Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor); - topLevelEditor.getCaretModel().moveToOffset(range.getStartOffset()); + topLevelEditor.getCaretModel().moveToOffset(rangeMarker.getStartOffset()); TemplateManager.getInstance(myProject).startTemplate(topLevelEditor, template, templateListener); restoreOldCaretPositionAndSelection(offset); diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java index 1d997a30d0af..98de899c6993 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteDialog.java @@ -20,8 +20,10 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.util.DeleteUtil; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.RefactoringSettings; @@ -39,6 +41,7 @@ import java.awt.event.ActionListener; * @author dsl */ public class SafeDeleteDialog extends DialogWrapper { + private final Project myProject; private final PsiElement[] myElements; private final Callback myCallback; @@ -55,6 +58,7 @@ public class SafeDeleteDialog extends DialogWrapper { public SafeDeleteDialog(Project project, PsiElement[] elements, Callback callback) { super(project, true); + myProject = project; myElements = elements; myCallback = callback; myDelegate = getDelegate(); @@ -190,6 +194,11 @@ public class SafeDeleteDialog extends DialogWrapper { @Override protected void doOKAction() { + if (DumbService.isDumb(myProject)) { + Messages.showMessageDialog(myProject, "Safe delete refactoring is not available while indexing is in progress", "Indexing", null); + return; + } + if (myCallback != null && isSafeDelete()) { myCallback.run(this); } else { diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java index 5ee7a73b73a6..cf0386066bef 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java @@ -173,6 +173,11 @@ public class ComponentWithBrowseButton extends JPanel i myBrowseButton = browseButton; } + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(myBrowseButton.isVisible() && myBrowseButton.isEnabled()); + } + @Override public void actionPerformed(AnActionEvent e){ myBrowseButton.doClick(); diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index 8a457e58bbf7..2d86e10c244e 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -23,6 +23,8 @@ import com.intellij.ui.*; import com.intellij.ui.components.JBViewport; import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.ui.*; +import com.intellij.util.ui.update.Activatable; +import com.intellij.util.ui.update.UiNotifyConnector; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -36,6 +38,7 @@ import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.EventObject; @@ -46,7 +49,6 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component private final StatusText myEmptyText; private final ExpandableItemsHandler myExpandableItemsHandler; - private MyCellEditorRemover myEditorRemover; private boolean myEnableAntialiasing; private int myRowHeight = -1; @@ -116,6 +118,8 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component }); myUiUpdating = false; + + new MyCellEditorRemover(); } @Override @@ -213,7 +217,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component final RowSorter.SortKey sortKey = sortableModel.getDefaultSortKey(); if (sortKey != null && sortKey.getColumn() >= 0 && sortKey.getColumn() < model.getColumnCount()) { if (sortableModel.getColumnInfos()[sortKey.getColumn()].isSortable()) { - rowSorter.setSortKeys(Arrays.asList(sortKey)); + rowSorter.setSortKeys(Collections.singletonList(sortKey)); } } } @@ -295,20 +299,14 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component @Override public void removeNotify() { + super.removeNotify(); if (ScreenUtil.isStandardAddRemoveNotify(this)) { - final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - //noinspection HardCodedStringLiteral - keyboardFocusManager.removePropertyChangeListener("permanentFocusOwner", myEditorRemover); - super.removeNotify(); if (myBusyIcon != null) { remove(myBusyIcon); Disposer.dispose(myBusyIcon); myBusyIcon = null; } } - else { - super.removeNotify(); - } } @Override @@ -417,13 +415,6 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } } - if (myEditorRemover == null) { - final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - myEditorRemover = new MyCellEditorRemover(); - //noinspection HardCodedStringLiteral - keyboardFocusManager.addPropertyChangeListener("permanentFocusOwner", myEditorRemover); - } - final TableCellEditor editor = getCellEditor(row, column); if (editor != null && editor.isCellEditable(e)) { editorComp = prepareEditor(editor, row, column); @@ -511,15 +502,57 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component return result; } - private final class MyCellEditorRemover implements PropertyChangeListener { - private final IdeFocusManager myFocusManager; + private final class MyCellEditorRemover extends Activatable.Adapter implements PropertyChangeListener { + private final IdeFocusManager myFocusManager = IdeFocusManager.findInstanceByComponent(JBTable.this); + private boolean myIsActive = false; public MyCellEditorRemover() { - myFocusManager = IdeFocusManager.findInstanceByComponent(JBTable.this); + addPropertyChangeListener("tableCellEditor", this); + new UiNotifyConnector(JBTable.this, this); + } + + public void activate() { + if (!myIsActive) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("permanentFocusOwner", this); + } + myIsActive = true; + } + + public void deactivate() { + if (myIsActive) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener("permanentFocusOwner", this); + } + myIsActive = false; + } + + @Override + public void hideNotify() { + removeCellEditor(); } @Override public void propertyChange(@NotNull final PropertyChangeEvent e) { + if ("tableCellEditor".equals(e.getPropertyName())) { + tableCellEditorChanged(e.getOldValue(), e.getNewValue()); + } + else if ("permanentFocusOwner".equals(e.getPropertyName())) { + permanentFocusOwnerChanged(); + } + } + + private void tableCellEditorChanged(Object from, Object to) { + boolean editingStarted = from == null && to != null; + boolean editingStopped = from != null && to == null; + + if (editingStarted) { + activate(); + } + else if (editingStopped) { + deactivate(); + } + } + + private void permanentFocusOwnerChanged() { if (!isEditing()) { return; } @@ -547,7 +580,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } else if (c instanceof Window) { if (c == SwingUtilities.getWindowAncestor(JBTable.this)) { - getCellEditor().stopCellEditing(); + removeCellEditor(); } break; } @@ -556,6 +589,13 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } }); } + + private void removeCellEditor() { + TableCellEditor cellEditor = getCellEditor(); + if (cellEditor != null && !cellEditor.stopCellEditing()) { + cellEditor.cancelCellEditing(); + } + } } private final class MyMouseListener extends MouseAdapter { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OccurenceNavigatorActionBase.java b/platform/platform-impl/src/com/intellij/ide/actions/OccurenceNavigatorActionBase.java index c7ae78f0cd59..5b3c7582f7c6 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/OccurenceNavigatorActionBase.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/OccurenceNavigatorActionBase.java @@ -19,6 +19,7 @@ package com.intellij.ide.actions; import com.intellij.ide.IdeBundle; import com.intellij.ide.OccurenceNavigator; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.Condition; @@ -79,8 +80,13 @@ abstract class OccurenceNavigatorActionBase extends AnAction implements DumbAwar return; } presentation.setVisible(true); - presentation.setEnabled(hasOccurenceToGo(navigator)); - presentation.setText(getDescription(navigator)); + try { + presentation.setEnabled(hasOccurenceToGo(navigator)); + presentation.setText(getDescription(navigator)); + } + catch (IndexNotReadyException e) { + presentation.setEnabled(false); + } } protected abstract OccurenceNavigator.OccurenceInfo go(OccurenceNavigator navigator); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java index ee95ebd8f0fe..2762cba2a4bb 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java @@ -42,7 +42,9 @@ import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; +import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Properties; /** @@ -90,12 +92,23 @@ public class DarculaLaf extends BasicLookAndFeel { superMethod.setAccessible(true); final UIDefaults metalDefaults = (UIDefaults)superMethod.invoke(new MetalLookAndFeel()); final UIDefaults defaults = (UIDefaults)superMethod.invoke(base); - if (SystemInfo.isLinux && !Registry.is("darcula.use.native.fonts.on.linux")) { - Font font = findFont("DejaVu Sans"); - if (font != null) { + if (SystemInfo.isLinux) { + if (!Registry.is("darcula.use.native.fonts.on.linux")) { + Font font = findFont("DejaVu Sans"); + if (font != null) { + for (Object key : defaults.keySet()) { + if (key instanceof String && ((String)key).endsWith(".font")) { + defaults.put(key, new FontUIResource(font.deriveFont(13f))); + } + } + } + } else if (Arrays.asList("CN", "JP", "KR", "TW").contains(Locale.getDefault().getCountry())) { for (Object key : defaults.keySet()) { if (key instanceof String && ((String)key).endsWith(".font")) { - defaults.put(key, new FontUIResource(font.deriveFont(13f))); + final Font font = defaults.getFont(key); + if (font != null) { + defaults.put(key, new FontUIResource("Dialog", font.getStyle(), font.getSize())); + } } } } diff --git a/platform/platform-impl/src/com/intellij/ide/util/ExportToFileUtil.java b/platform/platform-impl/src/com/intellij/ide/util/ExportToFileUtil.java index 96e5a1523022..995709cb8bbc 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/ExportToFileUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/util/ExportToFileUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -27,15 +27,16 @@ import com.intellij.openapi.editor.EditorSettings; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.editor.impl.EditorFactoryImpl; -import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.FixedSizeButton; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.wm.WindowManager; import com.intellij.util.SystemProperties; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -45,7 +46,6 @@ import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.File; import java.io.FileReader; import java.io.FileWriter; @@ -84,7 +84,7 @@ public class ExportToFileUtil { reader.close(); } } - catch (IOException e) { + catch (IOException ignored) { } } } @@ -112,8 +112,7 @@ public class ExportToFileUtil { private final Project myProject; private final ExporterToTextFile myExporter; protected Editor myTextArea; - protected JTextField myTfFile; - protected JButton myFileButton; + protected TextFieldWithBrowseButton myTfFile; private ChangeListener myListener; public ExportDialogBase(Project project, ExporterToTextFile exporter) { @@ -121,8 +120,8 @@ public class ExportToFileUtil { myProject = project; myExporter = exporter; - myTfFile = new JTextField(); - myFileButton = new FixedSizeButton(myTfFile); + myTfFile = new TextFieldWithBrowseButton(); + myTfFile.addBrowseFolderListener(null, null, myProject, FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()); setHorizontalStretch(1.5f); setTitle(IdeBundle.message("title.export.preview")); @@ -157,7 +156,7 @@ public class ExportToFileUtil { final Document document = ((EditorFactoryImpl)EditorFactory.getInstance()).createDocument(true); ((DocumentImpl)document).setAcceptSlashR(true); - myTextArea = EditorFactory.getInstance().createEditor(document, myProject, StdFileTypes.PLAIN_TEXT, true); + myTextArea = EditorFactory.getInstance().createEditor(document, myProject, FileTypes.PLAIN_TEXT, true); final EditorSettings settings = myTextArea.getSettings(); settings.setLineNumbersShown(false); settings.setLineMarkerAreaShown(false); @@ -171,7 +170,7 @@ public class ExportToFileUtil { } protected JComponent createNorthPanel() { - JPanel filePanel = createFilePanel(myTfFile, myFileButton); + JPanel filePanel = createFilePanel(myTfFile.getTextField(), myTfFile.getButton()); JComponent settingsPanel = myExporter.getSettingsEditor(); if (settingsPanel == null) { return filePanel; @@ -191,11 +190,7 @@ public class ExportToFileUtil { gbConstraints.weightx = 0; panel.add(promptLabel, gbConstraints); gbConstraints.weightx = 1; - panel.add(textField, gbConstraints); - gbConstraints.fill = 0; - gbConstraints.weightx = 0; - gbConstraints.insets = new Insets(0, 0, 0, 0); - panel.add(button, gbConstraints); + panel.add(myTfFile, gbConstraints); String defaultFilePath = myExporter.getDefaultFilePath(); if (! new File(defaultFilePath).isAbsolute()) { @@ -203,30 +198,13 @@ public class ExportToFileUtil { } else { defaultFilePath = defaultFilePath.replace('/', File.separatorChar); } - textField.setText(defaultFilePath); + myTfFile.setText(defaultFilePath); - button.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - browseFile(); - } - } - ); + panel.setBorder(JBUI.Borders.emptyBottom(5)); return panel; } - protected void browseFile() { - JFileChooser chooser = new JFileChooser(); - if (myTfFile != null) { - chooser.setCurrentDirectory(new File(myTfFile.getText())); - } - chooser.showOpenDialog(WindowManager.getInstance().suggestParentWindow(myProject)); - if (chooser.getSelectedFile() != null) { - myTfFile.setText(chooser.getSelectedFile().getAbsolutePath()); - } - } - public String getText() { return myTextArea.getDocument().getText(); } @@ -251,7 +229,7 @@ public class ExportToFileUtil { protected class CopyToClipboardAction extends AbstractAction { public CopyToClipboardAction() { super(IdeBundle.message("button.copy")); - putValue(AbstractAction.SHORT_DESCRIPTION, IdeBundle.message("description.copy.text.to.clipboard")); + putValue(Action.SHORT_DESCRIPTION, IdeBundle.message("description.copy.text.to.clipboard")); } public void actionPerformed(ActionEvent e) { @@ -259,5 +237,5 @@ public class ExportToFileUtil { CopyPasteManager.getInstance().setContents(new StringSelection(s)); } } - }; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java index 9fa6bcfe45c6..77c6685d29a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java @@ -24,15 +24,14 @@ import com.intellij.openapi.components.impl.stores.StateStorageManager.Externali import com.intellij.openapi.components.store.ReadOnlyModificationException; import com.intellij.openapi.components.store.StateStorageBase; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.util.ArrayUtilRt; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; @@ -45,7 +44,9 @@ import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; +import java.io.File; import java.io.IOException; import java.net.URL; import java.util.*; @@ -98,12 +99,7 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { Arrays.sort(names); for (String name : names) { Object component = myComponents.get(name); - if (component instanceof PersistentStateComponent) { - commitPersistentComponent((PersistentStateComponent)component, externalizationSession); - } - else if (component instanceof JDOMExternalizable) { - externalizationSession.setStateInOldStorage(component, ComponentManagerImpl.getComponentName(component), component); - } + commitComponent(externalizationSession, component); } } @@ -119,6 +115,64 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { doSave(externalizationSession == null ? null : externalizationSession.createSaveSessions(), readonlyFiles); } + @TestOnly + public void saveApplicationComponent(@NotNull Object component) { + StateStorageManager.ExternalizationSession externalizationSession = getStateStorageManager().startExternalization(); + if (externalizationSession == null) { + return; + } + + commitComponent(externalizationSession, component); + List sessions = externalizationSession.createSaveSessions(); + if (sessions.isEmpty()) { + return; + } + + final File file; + State state = StoreUtil.getStateSpec(component.getClass()); + if (state != null) { + file = new File(getStateStorageManager().expandMacros(findNonDeprecated(state.storages()).file())); + } + else if (component instanceof ExportableApplicationComponent && component instanceof NamedJDOMExternalizable) { + file = PathManager.getOptionsFile((NamedJDOMExternalizable)component); + } + else { + throw new AssertionError(component.getClass() + " doesn't have @State annotation and doesn't implement ExportableApplicationComponent"); + } + + AccessToken token = WriteAction.start(); + try { + VfsRootAccess.allowRootAccess(file.getAbsolutePath()); + doSave(sessions, Collections.>emptyList()); + } + finally { + try { + VfsRootAccess.disallowRootAccess(file.getAbsolutePath()); + } + finally { + token.finish(); + } + } + } + + private static Storage findNonDeprecated(Storage[] storages) { + for (Storage storage : storages) { + if (!storage.deprecated()) { + return storage; + } + } + throw new AssertionError("All storages are deprecated"); + } + + private void commitComponent(ExternalizationSession externalizationSession, Object component) { + if (component instanceof PersistentStateComponent) { + commitPersistentComponent((PersistentStateComponent)component, externalizationSession); + } + else if (component instanceof JDOMExternalizable) { + externalizationSession.setStateInOldStorage(component, ComponentManagerImpl.getComponentName(component), component); + } + } + protected void doSave(@Nullable List saveSessions, @NotNull List> readonlyFiles) { if (saveSessions != null) { for (SaveSession session : saveSessions) { @@ -137,12 +191,19 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { } } - private void commitPersistentComponent(@NotNull PersistentStateComponent persistentStateComponent, - @NotNull ExternalizationSession session) { - T state = persistentStateComponent.getState(); + private void commitPersistentComponent(@NotNull PersistentStateComponent component, @NotNull ExternalizationSession session) { + T state = component.getState(); if (state != null) { - Storage[] storageSpecs = getComponentStorageSpecs(persistentStateComponent, StoreUtil.getStateSpec(persistentStateComponent), StateStorageOperation.WRITE); - session.setState(storageSpecs, persistentStateComponent, getComponentName(persistentStateComponent), state); + Storage[] storageSpecs = getComponentStorageSpecs(component, StoreUtil.getStateSpec(component), StateStorageOperation.WRITE); + String componentName = getComponentName(component); + //if (state instanceof Element) { + // Element defaultState = getDefaultState(component, componentName, Element.class); + // if (defaultState != null && JDOMUtil.areElementsEqual(defaultState, (Element)state)) { + // session.setState(storageSpecs, component, componentName, new Element("empty")); + // return; + // } + //} + session.setState(storageSpecs, component, componentName, state); } } @@ -230,7 +291,8 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { } Class stateClass = ComponentSerializationUtil.getStateClass(component.getClass()); - T state = getDefaultState(component, name, stateClass); + T defaultState = getDefaultState(component, name, stateClass); + T state = defaultState; Storage[] storageSpecs = getComponentStorageSpecs(component, stateSpec, StateStorageOperation.READ); for (Storage storageSpec : storageSpecs) { @@ -243,6 +305,10 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { } if (state != null) { + // quick dirty fix IDEA-136382 Bundled custom file types disappear + if (defaultState != state && component instanceof FileTypeManager) { + component.loadState(defaultState); + } component.loadState(state); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java index fa69913ea152..19eb5df4d221 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java @@ -17,6 +17,7 @@ package com.intellij.openapi.editor.actions; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; @@ -46,42 +47,24 @@ public class HungryBackspaceAction extends TextComponentEditorAction { } @Override - public void executeWriteAction(@NotNull Editor editor, DataContext dataContext) { + public void executeWriteAction(@NotNull Editor editor, Caret caret, DataContext dataContext) { final Document document = editor.getDocument(); - final int prevSymbolOffset = editor.getCaretModel().getOffset() - 1; - if (prevSymbolOffset < 0) { + final int caretOffset = editor.getCaretModel().getOffset(); + if (caretOffset < 1) { return; } - + final SelectionModel selectionModel = editor.getSelectionModel(); final CharSequence text = document.getCharsSequence(); - final char c = text.charAt(prevSymbolOffset); - final boolean doHungryCheck = !selectionModel.hasSelection() && StringUtil.isWhiteSpace(c); - final EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); - handler.execute(editor, dataContext); - - if (!doHungryCheck) { - return; - } - - final int endOffset = prevSymbolOffset; - if (endOffset > document.getTextLength()) { - return; - } - int startOffset = CharArrayUtil.shiftBackward(text, endOffset - 1, "\t \n"); - if (startOffset < 0) { - // No non-white space symbol before the current caret offset has been found. - startOffset = 0; + final char c = text.charAt(caretOffset - 1); + if (!selectionModel.hasSelection() && StringUtil.isWhiteSpace(c)) { + int startOffset = CharArrayUtil.shiftBackward(text, caretOffset - 2, "\t \n") + 1; + document.deleteString(startOffset, caretOffset); } else { - // Offset now points to the first non-white space symbol before the caret. - // Increment it to point to the first white space symbol instead. - startOffset++; + final EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); + handler.execute(editor, caret, dataContext); } - if (startOffset >= endOffset) { - return; - } - document.deleteString(startOffset, endOffset); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java index 6ed9145ad53c..ef13e9d3cc07 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java @@ -84,11 +84,11 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark private static final TooltipGroup ERROR_STRIPE_TOOLTIP_GROUP = new TooltipGroup("ERROR_STRIPE_TOOLTIP_GROUP", 0); private static int getErrorIconWidth() { - return JBUI.scale(13); + return JBUI.scale(14); } private static int getErrorIconHeight() { - return JBUI.scale(13); + return JBUI.scale(14); } private static int getThinGap() { @@ -482,9 +482,6 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark return myEditor.isMirrored(); } - private static final Dimension STRIPE_BUTTON_PREFERRED_SIZE = new Dimension(getErrorIconWidth() + getThinGap(), getErrorIconHeight() + - getThinGap()); - private class ErrorStripeButton extends JButton { private ErrorStripeButton() { setFocusable(false); @@ -513,7 +510,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark g2d.setTransform(old); } else { - int x = getThinGap() + myMinMarkHeight - JBUI.scale(1); + int x = getThinGap() + myMinMarkHeight; final Rectangle b = new Rectangle(x, 0, getErrorIconWidth(), getErrorIconHeight()); myErrorStripeRenderer.paint(this, g, b); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java index 790160ba9a5a..8c0dcf4df07e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java @@ -457,6 +457,7 @@ public abstract class EditorComposite implements Disposable { } void addEditor(FileEditor editor) { + ApplicationManager.getApplication().assertIsDispatchThread(); FileEditor[] editors = ArrayUtil.append(myEditors, editor); if (myTabbedPaneWrapper == null) { myTabbedPaneWrapper = createTabbedPaneWrapper(editors); 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 5409d69a30d0..1cf6b6fe5682 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 @@ -152,28 +152,39 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } public void exitDumbMode() { - VirtualFile[] files = getOpenFiles(); - for (VirtualFile file : files) { - Set providers = new HashSet(); - List composites = getEditorComposites(file); - for (EditorWithProviderComposite composite : composites) { - providers.addAll(Arrays.asList(composite.getProviders())); + // can happen under write action, so postpone to avoid deadlock on FileEditorProviderManager.getProviders() + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (!project.isDisposed()) + dumbModeFinished(project); } - FileEditorProvider[] newProviders = FileEditorProviderManager.getInstance().getProviders(project, file); - if (newProviders.length > providers.size()) { - List toOpen = new ArrayList(Arrays.asList(newProviders)); - toOpen.removeAll(providers); - // need to open additional non dumb-aware editors - for (EditorWithProviderComposite composite : composites) { - for (FileEditorProvider provider : toOpen) { - FileEditor editor = provider.createEditor(myProject, file); - composite.addEditor(editor, provider); - } - } + }); + } + }); + } + + private void dumbModeFinished(Project project) { + VirtualFile[] files = getOpenFiles(); + for (VirtualFile file : files) { + Set providers = new HashSet(); + List composites = getEditorComposites(file); + for (EditorWithProviderComposite composite : composites) { + providers.addAll(Arrays.asList(composite.getProviders())); + } + FileEditorProvider[] newProviders = FileEditorProviderManager.getInstance().getProviders(project, file); + if (newProviders.length > providers.size()) { + List toOpen = new ArrayList(Arrays.asList(newProviders)); + toOpen.removeAll(providers); + // need to open additional non dumb-aware editors + for (EditorWithProviderComposite composite : composites) { + for (FileEditorProvider provider : toOpen) { + FileEditor editor = provider.createEditor(myProject, file); + composite.addEditor(editor, provider); } } } - }); + } } public void initDockableContentFactory() { @@ -1837,8 +1848,22 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } private class MyRootsListener extends ModuleRootAdapter { + private boolean myScheduled; + @Override public void rootsChanged(ModuleRootEvent event) { + if (myScheduled) return; + myScheduled = true; + DumbService.getInstance(myProject).runWhenSmart(new Runnable() { + @Override + public void run() { + myScheduled = false; + handleRootChange(); + } + }); + } + + private void handleRootChange() { EditorFileSwapper[] swappers = Extensions.getExtensions(EditorFileSwapper.EP_NAME); for (EditorWindow eachWindow : getWindows()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/ExternalizableFileType.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/ExternalizableFileType.java index 957eea0e0dd3..0d7fad7738bf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/ExternalizableFileType.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/ExternalizableFileType.java @@ -22,5 +22,6 @@ import com.intellij.openapi.util.JDOMExternalizable; */ public interface ExternalizableFileType extends JDOMExternalizable { void markDefaultSettings(); + boolean isModified(); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java index 2e115e50ef91..9c32063b9e23 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -27,19 +27,20 @@ import com.intellij.openapi.options.ExternalizableScheme; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.util.*; import com.intellij.util.ArrayUtil; +import com.intellij.util.SmartList; import com.intellij.util.text.StringTokenizer; import org.jdom.Element; import org.jdom.output.XMLOutputter; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Set; - public class AbstractFileType extends UserFileType implements ExternalizableFileType, ExternalizableScheme, CustomSyntaxTableFileType { private static final String SEMICOLON = ";"; @@ -67,7 +68,7 @@ public class AbstractFileType extends UserFileType implements @NonNls private static final String ELEMENT_KEYWORDS3 = "keywords3"; @NonNls private static final String ELEMENT_KEYWORDS4 = "keywords4"; @NonNls private static final String ATTRIBUTE_NAME = "name"; - @NonNls public static final String ELEMENT_EXTENSIONMAP = "extensionMap"; + @NonNls public static final String ELEMENT_EXTENSION_MAP = "extensionMap"; private final ExternalInfo myExternalInfo = new ExternalInfo(); public AbstractFileType(SyntaxTable syntaxTable) { @@ -113,13 +114,10 @@ public class AbstractFileType extends UserFileType implements } @Override - public void readExternal(final Element typeElement) throws InvalidDataException { + public void readExternal(@NotNull Element typeElement) throws InvalidDataException { Element element = typeElement.getChild(ELEMENT_HIGHLIGHTING); if (element != null) { - SyntaxTable table = readSyntaxTable(element); - if (table != null) { - setSyntaxTable(table); - } + setSyntaxTable(readSyntaxTable(element)); } } @@ -210,7 +208,7 @@ public class AbstractFileType extends UserFileType implements } @Override - public void writeExternal(final Element element) throws WriteExternalException { + public void writeExternal(@NotNull Element element) { writeTable(element, getSyntaxTable()); } @@ -330,40 +328,41 @@ public class AbstractFileType extends UserFileType implements @NonNls private static final String ATTRIBUTE_TYPE = "type"; @NotNull - public static List> readAssociations(@NotNull Element e) { - ArrayList> result = new ArrayList>(); - List mappings = e.getChildren(ELEMENT_MAPPING); + public static List> readAssociations(@NotNull Element element) { + List children = element.getChildren(ELEMENT_MAPPING); + if (children.isEmpty()) { + return Collections.emptyList(); + } - for (Object mapping1 : mappings) { - Element mapping = (Element)mapping1; + List> result = new SmartList>(); + for (Element mapping : children) { String ext = mapping.getAttributeValue(ATTRIBUTE_EXT); String pattern = mapping.getAttributeValue(ATTRIBUTE_PATTERN); FileNameMatcher matcher = ext != null ? new ExtensionFileNameMatcher(ext) : FileTypeManager.parseFromString(pattern); result.add(Pair.create(matcher, mapping.getAttributeValue(ATTRIBUTE_TYPE))); } - return result; } @NotNull - public static List> readRemovedAssociations(@NotNull Element e) { - ArrayList> result = new ArrayList>(); - List removedMappings = e.getChildren(ELEMENT_REMOVED_MAPPING); - for (Object removedMapping : removedMappings) { - Element mapping = (Element)removedMapping; - String ext = mapping.getAttributeValue(ATTRIBUTE_EXT); - String pattern = mapping.getAttributeValue(ATTRIBUTE_PATTERN); - String approved = mapping.getAttributeValue(ATTRIBUTE_APPROVED); - - FileNameMatcher matcher = ext != null ? new ExtensionFileNameMatcher(ext) : FileTypeManager.parseFromString(pattern); - result.add(new Trinity(matcher, mapping.getAttributeValue(ATTRIBUTE_TYPE), Boolean.parseBoolean(approved))); + public static List> readRemovedAssociations(@NotNull Element element) { + List> result = new SmartList>(); + List children = element.getChildren(ELEMENT_REMOVED_MAPPING); + if (children.isEmpty()) { + return Collections.emptyList(); } + for (Element mapping : children) { + String ext = mapping.getAttributeValue(ATTRIBUTE_EXT); + FileNameMatcher matcher = ext == null ? FileTypeManager.parseFromString(mapping.getAttributeValue(ATTRIBUTE_PATTERN)) : new ExtensionFileNameMatcher(ext); + result.add(Trinity.create(matcher, mapping.getAttributeValue(ATTRIBUTE_TYPE), Boolean.parseBoolean(mapping.getAttributeValue(ATTRIBUTE_APPROVED)))); + } return result; } - public static Element writeMapping(String typeName, final FileNameMatcher matcher, boolean specifyTypeName) { + @Nullable + public static Element writeMapping(String typeName, @NotNull FileNameMatcher matcher, boolean specifyTypeName) { Element mapping = new Element(ELEMENT_MAPPING); if (matcher instanceof ExtensionFileNameMatcher) { mapping.setAttribute(ATTRIBUTE_EXT, ((ExtensionFileNameMatcher)matcher).getExtension()); @@ -383,7 +382,6 @@ public class AbstractFileType extends UserFileType implements } return mapping; - } static Element writeRemovedMapping(final FileType type, final FileNameMatcher matcher, final boolean specifyTypeName, boolean approved) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index 7c43e6d6be7a..cbf522b010f2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -17,7 +17,6 @@ package com.intellij.openapi.fileTypes.impl; import com.google.common.annotations.VisibleForTesting; import com.intellij.ide.highlighter.custom.SyntaxTable; -import com.intellij.ide.highlighter.custom.impl.ReadFileType; import com.intellij.ide.plugins.PluginManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -29,7 +28,6 @@ import com.intellij.openapi.fileEditor.impl.LoadTextUtil; import com.intellij.openapi.fileTypes.*; import com.intellij.openapi.fileTypes.ex.*; import com.intellij.openapi.options.BaseSchemeProcessor; -import com.intellij.openapi.options.ExternalInfo; import com.intellij.openapi.options.SchemesManager; import com.intellij.openapi.options.SchemesManagerFactory; import com.intellij.openapi.project.Project; @@ -59,7 +57,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import javax.swing.*; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -77,6 +74,7 @@ import java.util.concurrent.atomic.AtomicLong; public class FileTypeManagerImpl extends FileTypeManagerEx implements PersistentStateComponent, ApplicationComponent, Disposable { private static final Logger LOG = Logger.getInstance(FileTypeManagerImpl.class); + // You must update all existing default configurations accordingly private static final int VERSION = 12; private static final Key FILE_TYPE_KEY = Key.create("FILE_TYPE_KEY"); // cached auto-detected file type. If the file was auto-detected as plain text or binary @@ -98,17 +96,12 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent private final Map> myRemovedMappings = new THashMap>(); @NonNls private static final String ELEMENT_FILETYPE = "filetype"; - @NonNls private static final String ELEMENT_FILE_TYPES = "filetypes"; @NonNls private static final String ELEMENT_IGNORE_FILES = "ignoreFiles"; @NonNls private static final String ATTRIBUTE_LIST = "list"; @NonNls private static final String ATTRIBUTE_VERSION = "version"; @NonNls private static final String ATTRIBUTE_NAME = "name"; @NonNls private static final String ATTRIBUTE_DESCRIPTION = "description"; - @NonNls private static final String ATTRIBUTE_ICON = "icon"; - @NonNls private static final String ATTRIBUTE_EXTENSIONS = "extensions"; - @NonNls private static final String ATTRIBUTE_BINARY = "binary"; - @NonNls private static final String ATTRIBUTE_DEFAULT_EXTENSION = "default_extension"; private static class StandardFileType { @NotNull private final FileType fileType; @@ -138,69 +131,19 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent private final AtomicInteger counterAutoDetect = new AtomicInteger(); private final AtomicLong elapsedAutoDetect = new AtomicLong(); - @VisibleForTesting - void initStandardFileTypes() { - final FileTypeConsumer consumer = new FileTypeConsumer() { - @Override - public void consume(@NotNull FileType fileType) { - register(fileType, parse(fileType.getDefaultExtension())); - } - - @Override - public void consume(@NotNull final FileType fileType, String extensions) { - register(fileType, parse(extensions)); - } - - @Override - public void consume(@NotNull final FileType fileType, @NotNull final FileNameMatcher... matchers) { - register(fileType, new ArrayList(Arrays.asList(matchers))); - } - - @Override - public FileType getStandardFileTypeByName(@NotNull final String name) { - final StandardFileType type = myStandardFileTypes.get(name); - return type != null ? type.fileType : null; - } - - private void register(@NotNull FileType fileType, @NotNull List fileNameMatchers) { - final StandardFileType type = myStandardFileTypes.get(fileType.getName()); - if (type != null) { - for (FileNameMatcher matcher : fileNameMatchers) type.matchers.add(matcher); - } - else { - myStandardFileTypes.put(fileType.getName(), new StandardFileType(fileType, fileNameMatchers)); - } - } - }; - - for (FileTypeFactory factory : Extensions.getExtensions(FileTypeFactory.FILE_TYPE_FACTORY_EP)) { - try { - factory.createFileTypes(consumer); - } - catch (Throwable t) { - PluginManager.handleComponentError(t, factory.getClass().getName(), null); - } - } - for (final StandardFileType pair : myStandardFileTypes.values()) { - registerFileTypeWithoutNotification(pair.fileType, pair.matchers); - } - } - - // ------------------------------------------------------------------------- - // Constructor - // ------------------------------------------------------------------------- - public FileTypeManagerImpl(MessageBus bus, SchemesManagerFactory schemesManagerFactory) { myMessageBus = bus; mySchemesManager = schemesManagerFactory.createSchemesManager(FILE_SPEC, new BaseSchemeProcessor() { @NotNull @Override - public AbstractFileType readScheme(@NotNull Element root) { - ReadFileType type = new ReadFileType(AbstractFileType.readSyntaxTable(root.getChild(AbstractFileType.ELEMENT_HIGHLIGHTING)), root); - String fileTypeName = root.getAttributeValue(ATTRIBUTE_NAME); - String fileTypeDescr = root.getAttributeValue(ATTRIBUTE_DESCRIPTION); - String iconPath = root.getAttributeValue(ATTRIBUTE_ICON); - setFileTypeAttributes(fileTypeName, fileTypeDescr, iconPath, type); + public AbstractFileType readScheme(@NotNull Element element, boolean duringLoad) { + if (!duringLoad) { + fireBeforeFileTypesChanged(); + } + AbstractFileType type = (AbstractFileType)loadFileType(element, false); + if (!duringLoad) { + fireFileTypesChanged(); + } return type; } @@ -217,45 +160,34 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } @Override - public Element writeScheme(@NotNull final AbstractFileType fileType) throws WriteExternalException { + public Element writeScheme(@NotNull AbstractFileType fileType) { Element root = new Element(ELEMENT_FILETYPE); - root.setAttribute(ATTRIBUTE_BINARY, String.valueOf(fileType.isBinary())); - root.setAttribute(ATTRIBUTE_DEFAULT_EXTENSION, fileType.getDefaultExtension()); + root.setAttribute("binary", String.valueOf(fileType.isBinary())); + if (!StringUtil.isEmpty(fileType.getDefaultExtension())) { + root.setAttribute("default_extension", fileType.getDefaultExtension()); + } root.setAttribute(ATTRIBUTE_DESCRIPTION, fileType.getDescription()); root.setAttribute(ATTRIBUTE_NAME, fileType.getName()); fileType.writeExternal(root); - Element map = new Element(AbstractFileType.ELEMENT_EXTENSIONMAP); - root.addContent(map); - - if (fileType instanceof ImportedFileType) { - writeImportedExtensionsMap(map, (ImportedFileType)fileType); - } - else { - writeExtensionsMap(map, fileType, false); + Element map = new Element(AbstractFileType.ELEMENT_EXTENSION_MAP); + writeExtensionsMap(map, fileType, false); + if (!map.getChildren().isEmpty()) { + root.addContent(map); } return root; } @Override - public void onSchemeAdded(@NotNull final AbstractFileType scheme) { - fireBeforeFileTypesChanged(); - if (scheme instanceof ReadFileType) { - loadFileType((ReadFileType)scheme); - } - fireFileTypesChanged(); - } - - @Override - public void onSchemeDeleted(@NotNull final AbstractFileType scheme) { + public void onSchemeDeleted(@NotNull AbstractFileType scheme) { fireBeforeFileTypesChanged(); myPatternsTable.removeAllAssociations(scheme); fireFileTypesChanged(); } }, RoamingType.PER_USER); - bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter(){ + bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@NotNull List events) { Collection files = ContainerUtil.map2Set(events, new Function() { @@ -282,6 +214,54 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent initStandardFileTypes(); } + @VisibleForTesting + void initStandardFileTypes() { + FileTypeConsumer consumer = new FileTypeConsumer() { + @Override + public void consume(@NotNull FileType fileType) { + register(fileType, parse(fileType.getDefaultExtension())); + } + + @Override + public void consume(@NotNull final FileType fileType, String extensions) { + register(fileType, parse(extensions)); + } + + @Override + public void consume(@NotNull final FileType fileType, @NotNull final FileNameMatcher... matchers) { + register(fileType, new ArrayList(Arrays.asList(matchers))); + } + + @Override + public FileType getStandardFileTypeByName(@NotNull final String name) { + final StandardFileType type = myStandardFileTypes.get(name); + return type != null ? type.fileType : null; + } + + private void register(@NotNull FileType fileType, @NotNull List fileNameMatchers) { + final StandardFileType type = myStandardFileTypes.get(fileType.getName()); + if (type != null) { + type.matchers.addAll(fileNameMatchers); + } + else { + myStandardFileTypes.put(fileType.getName(), new StandardFileType(fileType, fileNameMatchers)); + } + } + }; + + for (FileTypeFactory factory : FileTypeFactory.FILE_TYPE_FACTORY_EP.getExtensions()) { + try { + factory.createFileTypes(consumer); + } + catch (Throwable e) { + PluginManager.handleComponentError(e, factory.getClass().getName(), null); + } + } + for (StandardFileType pair : myStandardFileTypes.values()) { + registerFileTypeWithoutNotification(pair.fileType, pair.matchers, true); + } + } + private static boolean toLog() { return RE_DETECT_ASYNC && ApplicationManager.getApplication().isUnitTestMode(); } @@ -359,15 +339,6 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent return false; } - private static void writeImportedExtensionsMap(final Element map, final ImportedFileType type) { - for (FileNameMatcher matcher : type.getOriginalPatterns()) { - Element content = AbstractFileType.writeMapping(type.getName(), matcher, false); - if (content != null) { - map.addContent(content); - } - } - } - @Override @NotNull public FileType getStdFileType(@NotNull @NonNls String name) { @@ -391,10 +362,15 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } } // Resolve unresolved mappings initialized before certain plugin initialized. - for (final StandardFileType pair : myStandardFileTypes.values()) { + for (StandardFileType pair : myStandardFileTypes.values()) { bindUnresolvedMappings(pair.fileType); } - if (loadAllFileTypes()) { + + boolean isAtLeastOneStandardFileTypeHasBeenRead = false; + for (AbstractFileType fileType : mySchemesManager.loadSchemes()) { + isAtLeastOneStandardFileTypeHasBeenRead |= myInitialAssociations.hasAssociationsFor(fileType); + } + if (isAtLeastOneStandardFileTypeHasBeenRead) { restoreStandardFileExtensions(); } } @@ -695,9 +671,8 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent @Override public void run() { fireBeforeFileTypesChanged(); - registerFileTypeWithoutNotification(type, defaultAssociations); + registerFileTypeWithoutNotification(type, defaultAssociations, true); fireFileTypesChanged(); - } }); } @@ -715,7 +690,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } private void unregisterFileTypeWithoutNotification(FileType fileType) { - removeAllAssociations(fileType); + myPatternsTable.removeAllAssociations(fileType); mySchemesManager.removeScheme(fileType); if (fileType instanceof FileTypeIdentifiableByVirtualFile) { final FileTypeIdentifiableByVirtualFile fakeFileType = (FileTypeIdentifiableByVirtualFile)fileType; @@ -741,12 +716,8 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent @Override @NotNull public String getIgnoredFilesList() { - final Set masks = myIgnoredPatterns.getIgnoreMasks(); - if (masks.isEmpty()) { - return ""; - } - - return StringUtil.join(masks, ";") + ";"; + Set masks = myIgnoredPatterns.getIgnoreMasks(); + return masks.isEmpty() ? "" : StringUtil.join(masks, ";") + ";"; } @Override @@ -800,10 +771,6 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent removeAssociation(type, matcher, true); } - private void removeAllAssociations(FileType type) { - myPatternsTable.removeAllAssociations(type); - } - @Override public void fireBeforeFileTypesChanged() { FileTypeEvent event = new FileTypeEvent(this); @@ -851,19 +818,17 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent String previousIgnores = getIgnoredFilesList(); - for (final Object o : parentNode.getChildren()) { - final Element e = (Element)o; - if (ELEMENT_FILE_TYPES.equals(e.getName())) { - List children = e.getChildren(ELEMENT_FILETYPE); - for (final Object aChildren : children) { - Element element = (Element)aChildren; - loadFileType(element, true, null, false, null); + for (Element e : parentNode.getChildren()) { + //noinspection SpellCheckingInspection + if ("filetypes".equals(e.getName())) { + for (Element element : e.getChildren(ELEMENT_FILETYPE)) { + loadFileType(element, true); } } else if (ELEMENT_IGNORE_FILES.equals(e.getName())) { myIgnoredPatterns.setIgnoreMasks(e.getAttributeValue(ATTRIBUTE_LIST)); } - else if (AbstractFileType.ELEMENT_EXTENSIONMAP.equals(e.getName())) { + else if (AbstractFileType.ELEMENT_EXTENSION_MAP.equals(e.getName())) { readGlobalMappings(e); } } @@ -920,9 +885,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } private void readGlobalMappings(@NotNull Element e) { - List> associations = AbstractFileType.readAssociations(e); - - for (Pair association : associations) { + for (Pair association : AbstractFileType.readAssociations(e)) { FileType type = getFileTypeByName(association.getSecond()); FileNameMatcher matcher = association.getFirst(); if (type != null) { @@ -948,26 +911,11 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent removeAssociation(type, matcher, false); } else { - myUnresolvedRemovedMappings.put(matcher, Trinity - .create(trinity.getSecond(), myUnresolvedMappings.get(matcher), trinity.getThird())); + myUnresolvedRemovedMappings.put(matcher, Trinity.create(trinity.getSecond(), myUnresolvedMappings.get(matcher), trinity.getThird())); } } } - private void readMappingsForFileType(@NotNull Element e, FileType type) { - List> associations = AbstractFileType.readAssociations(e); - - for (Pair association : associations) { - associate(type, association.getFirst(), false); - } - - List> removedAssociations = AbstractFileType.readRemovedAssociations(e); - - for (Trinity removedAssociation : removedAssociations) { - removeAssociation(type, removedAssociation.getFirst(), false); - } - } - private void addIgnore(@NonNls @NotNull String ignoreMask) { myIgnoredPatterns.addIgnoreMask(ignoreMask); } @@ -1006,76 +954,79 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent @Nullable @Override public Element getState() { - Element parentNode = new Element("state"); - parentNode.setAttribute(ATTRIBUTE_VERSION, String.valueOf(VERSION)); + Element state = new Element("state"); + state.setAttribute(ATTRIBUTE_VERSION, String.valueOf(VERSION)); - Element element = new Element(ELEMENT_IGNORE_FILES); - parentNode.addContent(element); - element.setAttribute(ATTRIBUTE_LIST, getIgnoredFilesList()); - Element map = new Element(AbstractFileType.ELEMENT_EXTENSIONMAP); - parentNode.addContent(map); - - final List fileTypes = Arrays.asList(getRegisteredFileTypes()); - Collections.sort(fileTypes, new Comparator() { - @Override - public int compare(@NotNull FileType o1, @NotNull FileType o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - for (FileType type : fileTypes) { - writeExtensionsMap(map, type, true); + String ignoredFilesList = getIgnoredFilesList(); + if (!StringUtil.isEmpty(ignoredFilesList)) { + state.addContent(new Element(ELEMENT_IGNORE_FILES).setAttribute(ATTRIBUTE_LIST, ignoredFilesList)); } - for (Map.Entry entry : myUnresolvedMappings.entrySet()) { - Element content = AbstractFileType.writeMapping(entry.getValue(), entry.getKey(), true); - if (content != null) { - map.addContent(content); + Element map = new Element(AbstractFileType.ELEMENT_EXTENSION_MAP); + + FileType[] fileTypes = getRegisteredFileTypes(); + if (fileTypes.length > 0) { + Arrays.sort(fileTypes, new Comparator() { + @Override + public int compare(@NotNull FileType o1, @NotNull FileType o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + for (FileType type : fileTypes) { + writeExtensionsMap(map, type, true); } } + if (!myUnresolvedMappings.isEmpty()) { + FileNameMatcher[] unresolvedMappingKeys = myUnresolvedMappings.keySet().toArray(new FileNameMatcher[myUnresolvedMappings.size()]); + Arrays.sort(unresolvedMappingKeys, new Comparator() { + @Override + public int compare(FileNameMatcher o1, FileNameMatcher o2) { + return o1.getPresentableString().compareTo(o2.getPresentableString()); + } + }); + + for (FileNameMatcher fileNameMatcher : unresolvedMappingKeys) { + Element content = AbstractFileType.writeMapping(myUnresolvedMappings.get(fileNameMatcher), fileNameMatcher, true); + if (content != null) { + map.addContent(content); + } + } + } + + if (!map.getChildren().isEmpty()) { + state.addContent(map); + } + int value = fileTypeChangedCount.get(); if (value != 0) { - JDOMExternalizer.write(parentNode, "fileTypeChangedCounter", value); + JDOMExternalizer.write(state, "fileTypeChangedCounter", value); } - return parentNode; + return state; } - private void writeExtensionsMap(final Element map, final FileType type, boolean specifyTypeName) { - final List assocs = myPatternsTable.getAssociations(type); - final Set defaultAssocs = new HashSet(myInitialAssociations.getAssociations(type)); + private void writeExtensionsMap(@NotNull Element map, @NotNull FileType type, boolean specifyTypeName) { + List associations = myPatternsTable.getAssociations(type); + Set defaultAssociations = new THashSet(myInitialAssociations.getAssociations(type)); - for (FileNameMatcher matcher : assocs) { - if (defaultAssocs.contains(matcher)) { - defaultAssocs.remove(matcher); + for (FileNameMatcher matcher : associations) { + if (defaultAssociations.contains(matcher)) { + defaultAssociations.remove(matcher); } else if (shouldSave(type)) { - if (!(type instanceof ImportedFileType) || !((ImportedFileType)type).getOriginalPatterns().contains(matcher)) { - Element content = AbstractFileType.writeMapping(type.getName(), matcher, specifyTypeName); - if (content != null) { - map.addContent(content); - } + Element content = AbstractFileType.writeMapping(type.getName(), matcher, specifyTypeName); + if (content != null) { + map.addContent(content); } } } - for (FileNameMatcher matcher : defaultAssocs) { + for (FileNameMatcher matcher : defaultAssociations) { Element content = AbstractFileType.writeRemovedMapping(type, matcher, specifyTypeName, isApproved(matcher)); if (content != null) { map.addContent(content); } } - - if (type instanceof ImportedFileType) { - List original = ((ImportedFileType)type).getOriginalPatterns(); - for (FileNameMatcher matcher : original) { - if (!assocs.contains(matcher)) { - Element content = AbstractFileType.writeRemovedMapping(type, matcher, specifyTypeName, isApproved(matcher)); - if (content != null) { - map.addContent(content); - } - } - } - } } private boolean isApproved(FileNameMatcher matcher) { @@ -1093,8 +1044,11 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } @NotNull - private static List parse(@NonNls String semicolonDelimited) { - if (semicolonDelimited == null) return Collections.emptyList(); + private static List parse(@Nullable String semicolonDelimited) { + if (semicolonDelimited == null) { + return Collections.emptyList(); + } + StringTokenizer tokenizer = new StringTokenizer(semicolonDelimited, FileTypeConsumer.EXTENSION_DELIMITER, false); ArrayList list = new ArrayList(); while (tokenizer.hasMoreTokens()) { @@ -1106,8 +1060,10 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent /** * Registers a standard file type. Doesn't notifyListeners any change events. */ - private void registerFileTypeWithoutNotification(@NotNull FileType fileType, @NotNull List matchers) { - mySchemesManager.addNewScheme(fileType, true); + private void registerFileTypeWithoutNotification(@NotNull FileType fileType, @NotNull List matchers, boolean addScheme) { + if (addScheme) { + mySchemesManager.addNewScheme(fileType, true); + } for (FileNameMatcher matcher : matchers) { myPatternsTable.addAssociation(matcher, fileType); myInitialAssociations.addAssociation(matcher, fileType); @@ -1116,7 +1072,6 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent if (fileType instanceof FileTypeIdentifiableByVirtualFile) { mySpecialFileTypes.add((FileTypeIdentifiableByVirtualFile)fileType); } - } private void bindUnresolvedMappings(@NotNull FileType fileType) { @@ -1137,143 +1092,95 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } } - // returns true if at least one standard file type has been read - private boolean loadAllFileTypes() { - Collection collection = mySchemesManager.loadSchemes(); - - boolean res = false; - for (AbstractFileType fileType : collection) { - ReadFileType readFileType = (ReadFileType)fileType; - FileType loadedFileType = loadFileType(readFileType); - res |= myInitialAssociations.hasAssociationsFor(loadedFileType); - } - - return res; - } - - private FileType loadFileType(@NotNull ReadFileType readFileType) { - return loadFileType(readFileType.getElement(), false, readFileType.getExternalInfo(), - true, readFileType.getExternalInfo().getCurrentFileName()); - } - - - private FileType loadFileType(@NotNull Element typeElement, boolean isDefaults, final ExternalInfo info, boolean ignoreExisting, String fileName) { + @NotNull + private FileType loadFileType(@NotNull Element typeElement, boolean isDefault) { String fileTypeName = typeElement.getAttributeValue(ATTRIBUTE_NAME); String fileTypeDescr = typeElement.getAttributeValue(ATTRIBUTE_DESCRIPTION); - String iconPath = typeElement.getAttributeValue(ATTRIBUTE_ICON); - String extensionsStr = typeElement.getAttributeValue(ATTRIBUTE_EXTENSIONS); // TODO: support wildcards + String iconPath = typeElement.getAttributeValue("icon"); - FileType type = getFileTypeByName(fileTypeName); - - if (isDefaults && !ignoreExisting) { + String extensionsStr = StringUtil.nullize(typeElement.getAttributeValue("extensions")); + if (isDefault && extensionsStr != null) { + // todo support wildcards extensionsStr = filterAlreadyRegisteredExtensions(extensionsStr); } - List exts = parse(extensionsStr); - if (type != null && !ignoreExisting) { - if (isDefaults) return type; - if (extensionsStr != null) { - removeAllAssociations(type); - for (FileNameMatcher ext : exts) { - associate(type, ext, false); + FileType type = isDefault ? getFileTypeByName(fileTypeName) : null; + if (type != null) { + return type; + } + + Element element = typeElement.getChild(AbstractFileType.ELEMENT_HIGHLIGHTING); + if (element == null) { + for (CustomFileTypeFactory factory : CustomFileTypeFactory.EP_NAME.getExtensions()) { + type = factory.createFileType(typeElement); + if (type != null) { + break; } } - //noinspection deprecation - if (type instanceof JDOMExternalizable) { - try { - //noinspection deprecation - ((JDOMExternalizable)type).readExternal(typeElement); - } - catch (InvalidDataException e) { - throw new RuntimeException(e); - } + if (type == null) { + type = new UserBinaryFileType(); } } else { - type = loadCustomFile(typeElement, info, fileName); - if (type instanceof UserFileType) { - setFileTypeAttributes(fileTypeName, fileTypeDescr, iconPath, (UserFileType)type); - } - registerFileTypeWithoutNotification(type, exts); + SyntaxTable table = AbstractFileType.readSyntaxTable(element); + type = new AbstractFileType(table); + ((AbstractFileType)type).initSupport(); } - if (type instanceof UserFileType) { - UserFileType ft = (UserFileType)type; - setFileTypeAttributes(fileTypeName, fileTypeDescr, iconPath, ft); - } + setFileTypeAttributes((UserFileType)type, fileTypeName, fileTypeDescr, iconPath); + registerFileTypeWithoutNotification(type, parse(extensionsStr), isDefault); - if (isDefaults) { + if (isDefault) { myDefaultTypes.add(type); if (type instanceof ExternalizableFileType) { ((ExternalizableFileType)type).markDefaultSettings(); } } else { - Element extensions = typeElement.getChild(AbstractFileType.ELEMENT_EXTENSIONMAP); + Element extensions = typeElement.getChild(AbstractFileType.ELEMENT_EXTENSION_MAP); if (extensions != null) { - readMappingsForFileType(extensions, type); + for (Pair association : AbstractFileType.readAssociations(extensions)) { + associate(type, association.getFirst(), false); + } + + for (Trinity removedAssociation : AbstractFileType.readRemovedAssociations(extensions)) { + removeAssociation(type, removedAssociation.getFirst(), false); + } } } - return type; } - private String filterAlreadyRegisteredExtensions(String semicolonDelimited) { + @Nullable + private String filterAlreadyRegisteredExtensions(@NotNull String semicolonDelimited) { StringTokenizer tokenizer = new StringTokenizer(semicolonDelimited, FileTypeConsumer.EXTENSION_DELIMITER, false); - ArrayList list = new ArrayList(); + StringBuilder builder = null; while (tokenizer.hasMoreTokens()) { - final String extension = tokenizer.nextToken().trim(); + String extension = tokenizer.nextToken().trim(); if (getFileTypeByExtension(extension) == UnknownFileType.INSTANCE) { - list.add(extension); + if (builder == null) { + builder = new StringBuilder(); + } + else if (builder.length() > 0) { + builder.append(FileTypeConsumer.EXTENSION_DELIMITER); + } + builder.append(extension); } } - return StringUtil.join(list, FileTypeConsumer.EXTENSION_DELIMITER); + return builder == null ? null : builder.toString(); } - @NotNull - private static FileType loadCustomFile(@NotNull Element typeElement, ExternalInfo info, String fileName) { - FileType type = null; - - Element element = typeElement.getChild(AbstractFileType.ELEMENT_HIGHLIGHTING); - if (element != null) { - final SyntaxTable table = AbstractFileType.readSyntaxTable(element); - if (table != null) { - if (info == null) { - type = new AbstractFileType(table); - ((AbstractFileType)type).getExternalInfo().setCurrentFileName(fileName); - } - else { - type = new ImportedFileType(table, info); - ((ImportedFileType)type).readOriginalMatchers(typeElement); - } - ((AbstractFileType)type).initSupport(); - return type; - } + private static void setFileTypeAttributes(@NotNull UserFileType fileType, @Nullable String name, @Nullable String description, @Nullable String iconPath) { + if (!StringUtil.isEmptyOrSpaces(iconPath)) { + fileType.setIcon(IconLoader.getIcon(iconPath)); } - for (CustomFileTypeFactory factory : Extensions.getExtensions(CustomFileTypeFactory.EP_NAME)) { - type = factory.createFileType(typeElement); - if (type != null) { - break; - } + if (description != null) { + fileType.setDescription(description); } - if (type == null) { - type = new UserBinaryFileType(); + if (name != null) { + fileType.setName(name); } - return type; - } - - private static void setFileTypeAttributes(final String fileTypeName, - final String fileTypeDescr, - final String iconPath, - final UserFileType ft) { - if (iconPath != null && !StringUtil.isEmptyOrSpaces(iconPath)) { - Icon icon = IconLoader.getIcon(iconPath); - ft.setIcon(icon); - } - - if (fileTypeDescr != null) ft.setDescription(fileTypeDescr); - if (fileTypeName != null) ft.setName(fileTypeName); } private static boolean shouldSave(FileType fileType) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/ImportedFileType.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/ImportedFileType.java deleted file mode 100644 index 5ca0efb4bea9..000000000000 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/ImportedFileType.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.fileTypes.impl; - -import com.intellij.ide.highlighter.custom.SyntaxTable; -import com.intellij.openapi.fileTypes.FileNameMatcher; -import com.intellij.openapi.options.ExternalInfo; -import com.intellij.openapi.util.Pair; -import org.jdom.Element; - -import java.util.ArrayList; -import java.util.List; - -public class ImportedFileType extends AbstractFileType { - private final List myPatterns = new ArrayList(); - - public ImportedFileType(final SyntaxTable syntaxTable, ExternalInfo copyFrom) { - super(syntaxTable); - if (copyFrom != null) { - getExternalInfo().copy(copyFrom); - } - } - - public List getOriginalPatterns() { - return myPatterns; - } - - public void addPattern(FileNameMatcher pattern) { - myPatterns.add(pattern); - } - - public void readOriginalMatchers(final Element element) { - Element mappingsElement = element.getChild(ELEMENT_EXTENSIONMAP); - if (mappingsElement != null) { - List> list = AbstractFileType.readAssociations(mappingsElement); - for (Pair pair : list) { - addPattern(pair.getFirst()); - } - } - - } -} diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java index 612faa102f71..a8243ab67d1b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java @@ -60,8 +60,6 @@ import java.util.*; public class SchemesManagerImpl extends AbstractSchemesManager { private static final Logger LOG = Logger.getInstance(SchemesManagerFactoryImpl.class); - private static final String NAME = "name"; - private final String myFileSpec; private final SchemeProcessor myProcessor; private final RoamingType myRoamingType; @@ -109,7 +107,7 @@ public class SchemesManagerImplemptyMap()); + E readScheme = readSchemeFromFile(event.getFile(), true, false); if (readScheme != null) { myProcessor.initScheme(readScheme); myProcessor.onSchemeAdded(readScheme); @@ -129,7 +127,7 @@ public class SchemesManagerImplemptyMap()); + E readScheme = readSchemeFromFile(event.getFile(), true, false); if (readScheme != null) { myProcessor.initScheme(readScheme); myProcessor.onSchemeAdded(readScheme); @@ -182,7 +180,7 @@ public class SchemesManagerImplemptyMap()); + E scheme = readSchemeFromFile(file, false, true); if (scheme != null) { result.put(scheme.getName(), scheme); } @@ -234,7 +232,7 @@ public class SchemesManagerImplemptyMap()); + E scheme = readScheme(element, true); boolean fileRenamed = false; assert scheme != null; T existing = findSchemeByName(scheme.getName()); @@ -305,7 +303,6 @@ public class SchemesManagerImpl filter) { + private E readSchemeFromFile(@NotNull final VirtualFile file, boolean forceAdd, boolean duringLoad) { if (!canRead(file)) { return null; } @@ -343,81 +340,43 @@ public class SchemesManagerImpl filter) throws InvalidDataException, IOException, JDOMException { - if (element.getName().equals("shared-scheme")) { - String schemeName = element.getAttributeValue(NAME); - if (filter.containsKey(schemeName)) { - return null; - } - - String schemePath = element.getAttributeValue("original-scheme-path"); - Element sharedElement = myProvider != null && myProvider.isEnabled() ? loadElementOrNull(myProvider.loadContent(schemePath, myRoamingType)) : null; - if (sharedElement == null) { - Element localCopyElement = element.getChild("scheme-local-copy"); - E scheme = localCopyElement == null ? null : doReadScheme(localCopyElement.getChildren().get(0)); - return scheme == null || filter.containsKey(scheme.getName()) ? null : scheme; - } - else { - E result = readScheme(sharedElement, Collections.emptyMap()); - if (result != null) { - renameScheme(result, schemeName); - } - return result; - } - } - else if (element.getName().equals("shared-scheme-original")) { - E scheme = doReadScheme(element.getChildren().get(0)); - if (scheme == null || filter.containsKey(scheme.getName())) { - return null; - } - renameScheme(scheme, element.getAttributeValue(NAME)); - return scheme; - } - else { - E scheme = doReadScheme(element); - return scheme == null || filter.containsKey(scheme.getName()) ? null : scheme; + return null; } } @Nullable - private E doReadScheme(Element element) throws InvalidDataException, IOException, JDOMException { + private E readScheme(@NotNull Element element, boolean duringLoad) throws InvalidDataException, IOException, JDOMException { E scheme; if (myProcessor instanceof BaseSchemeProcessor) { - scheme = ((BaseSchemeProcessor)myProcessor).readScheme(element); + scheme = ((BaseSchemeProcessor)myProcessor).readScheme(element, duringLoad); } else { //noinspection deprecation @@ -656,11 +615,11 @@ public class SchemesManagerImplChoose Implementation of {0} ({1} found) @@ -279,7 +279,9 @@ goto.test.findUsages.subject.title=Test Subjects for {0} goto.test.notFound=No test subjects found incremental.search.tooltip.prefix=Search for: +goto.super.field.chooser.title=Choose super field goto.super.method.chooser.title=Choose super method +goto.super.method.of.chooser.title=Choose Super Method of {0} goto.super.method.findUsages.title=Super methods of {0} goto.super.class.chooser.title=Choose super class or interface javadoc.action.back=Back diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index a1d2c4185efe..1c793f12e3ab 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -1558,6 +1558,11 @@ +