diff --git a/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java b/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java new file mode 100644 index 000000000000..5f51296b37d9 --- /dev/null +++ b/json/src/com/intellij/json/psi/impl/JsonTreeChangePreprocessor.java @@ -0,0 +1,82 @@ +package com.intellij.json.psi.impl; + +import com.intellij.json.JsonLanguage; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; +import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.PsiModificationTrackerImpl; +import com.intellij.psi.impl.PsiTreeChangeEventImpl; +import com.intellij.psi.impl.PsiTreeChangePreprocessor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Mikhail Golubev + */ +public class JsonTreeChangePreprocessor implements PsiTreeChangePreprocessor { + /** + * @see com.intellij.psi.impl.PsiTreeChangePreprocessorBase#treeChanged(com.intellij.psi.impl.PsiTreeChangeEventImpl) + */ + @Override + public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { + final PsiElement element = event.getParent(); + if (element == null || !(element.getManager() instanceof PsiManagerImpl)) { + return; + } + final PsiModificationTrackerImpl modificationTracker = (PsiModificationTrackerImpl)element.getManager().getModificationTracker(); + boolean changedInsideCodeBlock = false; + + switch (event.getCode()) { + case BEFORE_CHILDREN_CHANGE: + if (event.getParent() instanceof PsiFile) { + changedInsideCodeBlock = true; + break; + } + + case CHILDREN_CHANGED: + if (event.isGenericChange()) { + return; + } + changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); + break; + + case BEFORE_CHILD_ADDITION: + case BEFORE_CHILD_REMOVAL: + case CHILD_ADDED: + case CHILD_REMOVED: + changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); + break; + + case BEFORE_PROPERTY_CHANGE: + case PROPERTY_CHANGED: + changedInsideCodeBlock = false; + break; + + case BEFORE_CHILD_REPLACEMENT: + case CHILD_REPLACED: + changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); + break; + + case BEFORE_CHILD_MOVEMENT: + case CHILD_MOVED: + changedInsideCodeBlock = isInsideCodeBlock(event.getOldParent()) && isInsideCodeBlock(event.getNewParent()); + break; + } + + if (!changedInsideCodeBlock) { + modificationTracker.incOutOfCodeBlockModificationCounter(); + } + } + + private boolean isInsideCodeBlock(@Nullable PsiElement element) { + if (element instanceof PsiFileSystemItem) { + return false; + } + if (element == null || element.getParent() == null) { + return true; + } + // Consider all elements of JSON PSI as externally visible, i.e. they are out of code block + return !(element.getLanguage() instanceof JsonLanguage); + } +} diff --git a/json/src/com/intellij/json/structureView/JsonStructureViewModel.java b/json/src/com/intellij/json/structureView/JsonStructureViewModel.java index 19aca25684c1..ecc577767c8f 100644 --- a/json/src/com/intellij/json/structureView/JsonStructureViewModel.java +++ b/json/src/com/intellij/json/structureView/JsonStructureViewModel.java @@ -34,8 +34,7 @@ public class JsonStructureViewModel extends StructureViewModelBase implements St @Override public boolean isAutoExpand(@NotNull StructureViewTreeElement element) { - final Object value = element.getValue(); - return value instanceof PsiFile || value instanceof JsonProperty || value instanceof JsonObject; + return true; } @Override diff --git a/platform/core-api/src/com/intellij/psi/ResolvingHint.java b/platform/core-api/src/com/intellij/psi/ResolvingHint.java index 4eb98d3c6bc3..49b2fe3aca94 100644 --- a/platform/core-api/src/com/intellij/psi/ResolvingHint.java +++ b/platform/core-api/src/com/intellij/psi/ResolvingHint.java @@ -17,6 +17,9 @@ package com.intellij.psi; /** + * CAUTION: this is a workaround to fix java method searcher performance. + * This can be removed in future if the searcher is fixed to obey {@link com.intellij.psi.PsiReference#isReferenceTo(PsiElement)} contract. + * * Can be implemented by {@link com.intellij.psi.PsiReference} * @author Dmitry Avdeev */ diff --git a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java index cf10656a24ed..73743f86d796 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java +++ b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 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,21 +25,18 @@ import java.util.SortedMap; import java.util.TreeMap; @State( - name = "Registry", - storages = { - @Storage( - file = StoragePathMacros.APP_CONFIG + "/other.xml")} + name = "Registry", + storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml") ) public class RegistryState implements BaseComponent, PersistentStateComponent { private static final Logger LOG = Logger.getInstance(RegistryState.class); - public RegistryState() { - } - + @Override public Element getState() { return Registry.getInstance().getState(); } + @Override public void loadState(Element state) { Registry.getInstance().loadState(state); SortedMap userProperties = new TreeMap(Registry.getInstance().getUserProperties()); @@ -52,14 +49,17 @@ public class RegistryState implements BaseComponent, PersistentStateComponent componentToContainingListElement = new LinkedHashMap(); - for (ExportableComponent component : fileToComponents.values()) { if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) { ComponentElementProperties componentElementProperties = new ComponentElementProperties(); @@ -72,10 +72,9 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { componentToContainingListElement.put(component, componentElementProperties); } } - final Set componentElementProperties = new LinkedHashSet(componentToContainingListElement.values()); myChooser = new ElementsChooser(true); myChooser.setColorUnmarkedElements(false); - for (final ComponentElementProperties componentElementProperty : componentElementProperties) { + for (ComponentElementProperties componentElementProperty : new LinkedHashSet(componentToContainingListElement.values())) { myChooser.addElement(componentElementProperty, true, componentElementProperty); } myChooser.sort(new Comparator() { @@ -149,7 +148,7 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { } private static boolean addToExistingListElement(@NotNull ExportableComponent component, - Map componentToContainingListElement, + @NotNull Map componentToContainingListElement, @NotNull MultiMap fileToComponents) { File file = null; for (File exportFile : component.getExportFiles()) { @@ -236,9 +235,8 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { } Set getExportableComponents() { - final List markedElements = myChooser.getMarkedElements(); - final Set components = new HashSet(); - for (ComponentElementProperties elementProperties : markedElements) { + Set components = new THashSet(); + for (ComponentElementProperties elementProperties : myChooser.getMarkedElements()) { components.addAll(elementProperties.myComponents); } return components; @@ -265,11 +263,9 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { public String toString() { Set names = new LinkedHashSet(); - - for (final ExportableComponent component : myComponents) { + for (ExportableComponent component : myComponents) { names.add(component.getPresentableName()); } - return StringUtil.join(names.toArray(new String[names.size()]), ", "); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java index a0d35ea70d2b..e5267bfc74c0 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java @@ -63,7 +63,7 @@ public class ExportSettingsAction extends AnAction implements DumbAware { public void actionPerformed(@Nullable AnActionEvent e) { ApplicationManager.getApplication().saveSettings(); - ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(getExportableComponentsMap(true), true, + ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true, IdeBundle.message("title.select.components.to.export"), IdeBundle.message( "prompt.please.check.all.components.to.export")); @@ -77,7 +77,7 @@ public class ExportSettingsAction extends AnAction implements DumbAware { } Set exportFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - for (final ExportableComponent markedComponent : markedComponents) { + for (ExportableComponent markedComponent : markedComponents) { ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles()); } @@ -136,7 +136,7 @@ public class ExportSettingsAction extends AnAction implements DumbAware { } @NotNull - public static MultiMap getExportableComponentsMap(final boolean onlyExisting) { + public static MultiMap getExportableComponentsMap(final boolean onlyExisting, final boolean computePresentableNames) { ExportableApplicationComponent[] components1 = ApplicationManager.getApplication().getComponents(ExportableApplicationComponent.class); List components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class); final MultiMap result = MultiMap.createLinkedSet(); @@ -204,7 +204,15 @@ public class ExportSettingsAction extends AnAction implements DumbAware { else { files = fileExists ? new File[]{file, additionalExportFile} : new File[]{additionalExportFile}; } - result.putValue(file, new MyExportableComponent(files, getExportableComponentPresentableName(stateAnnotation, aClass, pluginDescriptor))); + ExportableComponentItem item = new ExportableComponentItem(files, + computePresentableNames + ? getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) + : "", + storage.roamingType()); + result.putValue(file, item); + if (additionalExportFile != null) { + result.putValue(additionalExportFile, item); + } } } } @@ -215,7 +223,7 @@ public class ExportSettingsAction extends AnAction implements DumbAware { } @NotNull - private static String getExportableComponentPresentableName(@NotNull State state, @NotNull Class aClass, @Nullable PluginDescriptor pluginDescriptor) { + private static String getComponentPresentableName(@NotNull State state, @NotNull Class aClass, @Nullable PluginDescriptor pluginDescriptor) { if (state.presentableName() != State.NameGetter.class) { try { return ReflectionUtil.newInstance(state.presentableName()).get(); @@ -249,13 +257,15 @@ public class ExportSettingsAction extends AnAction implements DumbAware { return defaultName; } - private static final class MyExportableComponent implements ExportableComponent { + public static final class ExportableComponentItem implements ExportableComponent { private final File[] files; private final String name; + private final RoamingType roamingType; - public MyExportableComponent(@NotNull File[] files, @NotNull String name) { + public ExportableComponentItem(@NotNull File[] files, @NotNull String name, @NotNull RoamingType roamingType) { this.files = files; this.name = name; + this.roamingType = roamingType; } @NotNull @@ -269,6 +279,11 @@ public class ExportSettingsAction extends AnAction implements DumbAware { public String getPresentableName() { return name; } + + @NotNull + public RoamingType getRoamingType() { + return roamingType; + } } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java index fa57b995cd9c..3945fe2b522e 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java @@ -35,6 +35,7 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.updateSettings.impl.UpdateSettings; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.util.Consumer; import com.intellij.util.containers.MultiMap; import com.intellij.util.io.ZipUtil; @@ -80,10 +81,10 @@ public class ImportSettingsAction extends AnAction implements DumbAware { return; } - MultiMap filesToComponents = ExportSettingsAction.getExportableComponentsMap(false); - List components = getComponentsStored(saveFile, filesToComponents.values()); - filesToComponents.values().retainAll(components); - final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(filesToComponents, false, + MultiMap fileToComponents = ExportSettingsAction.getExportableComponentsMap(false, true); + List components = getComponentsStored(saveFile, fileToComponents.values()); + fileToComponents.values().retainAll(components); + final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(fileToComponents, false, IdeBundle.message("title.select.components.to.import"), IdeBundle.message("prompt.check.components.to.import")); if (!dialog.showAndGet()) { @@ -150,13 +151,13 @@ public class ImportSettingsAction extends AnAction implements DumbAware { @NotNull private static List getComponentsStored(@NotNull File zipFile, @NotNull Collection registeredComponents) throws IOException { - final File configPath = new File(PathManager.getConfigPath()); - final ArrayList components = new ArrayList(); + File configPath = new File(PathManager.getConfigPath()); + List components = new ArrayList(); for (ExportableComponent component : registeredComponents) { for (File exportFile : component.getExportFiles()) { - final String rPath = FileUtil.getRelativePath(configPath, exportFile); + String rPath = FileUtilRt.getRelativePath(configPath, exportFile); assert rPath != null; - String relativePath = FileUtil.toSystemIndependentName(rPath); + String relativePath = FileUtilRt.toSystemIndependentName(rPath); if (exportFile.isDirectory()) { relativePath += '/'; } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java index 09132fb032ac..64bb3e8c88e4 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java @@ -164,7 +164,7 @@ public class RepositoryHelper { } private synchronized static List readPluginsStream(@NotNull URLConnection connection, - ProgressIndicator indicator, + @Nullable ProgressIndicator indicator, @NotNull String file) throws Exception { File localFile; InputStream input = getConnectionInputStream(connection); diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java index 2d1069e26eb1..f5f9429b8cf5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java @@ -98,7 +98,7 @@ public class PluginDownloader { return prepareToInstall(pi, myBuildNumber); } - public boolean prepareToInstall(@Nullable ProgressIndicator pi, @Nullable BuildNumber forBuildNumber) throws IOException { + public boolean prepareToInstall(@Nullable ProgressIndicator progressIndicator, @Nullable BuildNumber forBuildNumber) throws IOException { if (myFile != null) { return true; } @@ -118,7 +118,7 @@ public class PluginDownloader { // download plugin String errorMessage = IdeBundle.message("unknown.error"); try { - myFile = downloadPlugin(pi); + myFile = downloadPlugin(progressIndicator); } catch (IOException ex) { myFile = null; @@ -236,15 +236,15 @@ public class PluginDownloader { } } - private File downloadPlugin(@Nullable final ProgressIndicator pi) throws IOException { + private File downloadPlugin(@Nullable final ProgressIndicator progressIndicator) throws IOException { final File pluginsTemp = new File(PathManager.getPluginTempPath()); if (!pluginsTemp.exists() && !pluginsTemp.mkdirs()) { throw new IOException(IdeBundle.message("error.cannot.create.temp.dir", pluginsTemp)); } final File file = FileUtil.createTempFile(pluginsTemp, "plugin_", "_download", true, false); - if (pi != null) { - pi.setText(IdeBundle.message("progress.connecting")); + if (progressIndicator != null) { + progressIndicator.setText(IdeBundle.message("progress.connecting")); } URLConnection connection = null; @@ -252,19 +252,19 @@ public class PluginDownloader { connection = openConnection(myPluginUrl); final InputStream is = (ApplicationManager.getApplication() != null) - ? UrlConnectionUtil.getConnectionInputStream(connection, pi) + ? UrlConnectionUtil.getConnectionInputStream(connection, progressIndicator) : connection.getInputStream(); if (is == null) { throw new IOException("Failed to open connection"); } - if (ApplicationManager.getApplication() != null && pi != null) { - pi.setText(IdeBundle.message("progress.downloading.plugin", getPluginName())); + if (progressIndicator != null && ApplicationManager.getApplication() != null) { + progressIndicator.setText(IdeBundle.message("progress.downloading.plugin", getPluginName())); } try { final OutputStream fos = new BufferedOutputStream(new FileOutputStream(file, false)); try { - NetUtils.copyStreamContent(pi, is, fos, connection.getContentLength()); + NetUtils.copyStreamContent(progressIndicator, is, fos, connection.getContentLength()); } finally { fos.close(); diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index f72fed2b53fc..6e879427859a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -273,7 +273,7 @@ public final class UpdateChecker { Map downloaded, Collection incompatiblePlugins, boolean collectToUpdate, - ProgressIndicator indicator) throws IOException { + @Nullable ProgressIndicator indicator) throws IOException { final String pluginId = downloader.getPluginId(); final String pluginVersion = downloader.getPluginVersion(); if (collectToUpdate && PluginManagerCore.getDisabledPlugins().contains(pluginId)) return; diff --git a/platform/platform-impl/src/com/intellij/util/io/UrlConnectionUtil.java b/platform/platform-impl/src/com/intellij/util/io/UrlConnectionUtil.java index 198ead74eeec..3b1e7049942d 100644 --- a/platform/platform-impl/src/com/intellij/util/io/UrlConnectionUtil.java +++ b/platform/platform-impl/src/com/intellij/util/io/UrlConnectionUtil.java @@ -38,7 +38,7 @@ public class UrlConnectionUtil { public static @Nullable - InputStream getConnectionInputStream(URLConnection connection, ProgressIndicator pi) { + InputStream getConnectionInputStream(URLConnection connection, @Nullable ProgressIndicator pi) { try { return getConnectionInputStreamWithException(connection, pi); } diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index 62ade0b9a446..deeec3ad3fa2 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -18,6 +18,7 @@ + diff --git a/xml/impl/src/com/intellij/ide/browsers/actions/OpenFileInDefaultBrowserAction.java b/xml/impl/src/com/intellij/ide/browsers/actions/OpenFileInDefaultBrowserAction.java index 1ead1b6faeb4..482e22aa896f 100644 --- a/xml/impl/src/com/intellij/ide/browsers/actions/OpenFileInDefaultBrowserAction.java +++ b/xml/impl/src/com/intellij/ide/browsers/actions/OpenFileInDefaultBrowserAction.java @@ -24,11 +24,12 @@ import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.xml.util.HtmlUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class OpenFileInDefaultBrowserAction extends DumbAwareAction { @Override - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { Presentation presentation = e.getPresentation(); Pair result = BaseOpenInBrowserAction.doUpdate(e); @@ -63,7 +64,7 @@ public class OpenFileInDefaultBrowserAction extends DumbAwareAction { } @Nullable - private static WebBrowser findUsingBrowser() { + public static WebBrowser findUsingBrowser() { WebBrowserManager browserManager = WebBrowserManager.getInstance(); DefaultBrowserPolicy defaultBrowserPolicy = browserManager.getDefaultBrowserPolicy(); if (defaultBrowserPolicy == DefaultBrowserPolicy.FIRST || (defaultBrowserPolicy == DefaultBrowserPolicy.SYSTEM && !BrowserLauncherAppless.canUseSystemDefaultBrowserPolicy())) { @@ -86,7 +87,7 @@ public class OpenFileInDefaultBrowserAction extends DumbAwareAction { } @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { BaseOpenInBrowserAction.open(e, findUsingBrowser()); } }