From 7675771cce44149b83014c7129f9e64bc9ceb1da Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 28 Aug 2017 17:50:06 +0200 Subject: [PATCH 01/31] add NotNull, default impl --- ...BuildArtifactsBeforeRunTaskProviderBase.java | 4 ++-- .../compiler/options/CompileStepBeforeRun.java | 13 ------------- .../CompileStepBeforeRunNoErrorCheck.java | 9 ++------- .../options/MakeProjectStepBeforeRun.java | 12 ++---------- .../ExternalSystemBeforeRunTaskProvider.java | 6 +++--- .../execution/BeforeRunTaskProvider.java | 17 ++++++++++++----- .../impl/RunConfigurationBeforeRunProvider.java | 6 +++--- .../impl/UnknownBeforeRunTaskProvider.java | 9 ++------- .../AbstractToolBeforeRunTaskProvider.java | 7 ++++--- .../config/impl/AntBeforeRunTaskProvider.java | 4 ++-- .../tasks/MavenBeforeRunTasksProvider.java | 4 ++-- 11 files changed, 34 insertions(+), 57 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java index b0a020996609..8625479451a4 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java @@ -80,7 +80,7 @@ public abstract class BuildArtifactsBeforeRunTaskProviderBase pointers = new THashSet<>(); for (Artifact artifact : artifacts) { @@ -111,7 +111,7 @@ public abstract class BuildArtifactsBeforeRunTaskProviderBase)task.getArtifactPointers()) { if (pointer.getArtifact() != null) { return true; diff --git a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java index a6f9ca169927..e69bb5641048 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java +++ b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java @@ -106,15 +106,6 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider tasks = ContainerUtilRt.newArrayList(); diff --git a/platform/lang-api/src/com/intellij/execution/BeforeRunTaskProvider.java b/platform/lang-api/src/com/intellij/execution/BeforeRunTaskProvider.java index 96fce915bd9b..d41b4db7eb2e 100644 --- a/platform/lang-api/src/com/intellij/execution/BeforeRunTaskProvider.java +++ b/platform/lang-api/src/com/intellij/execution/BeforeRunTaskProvider.java @@ -41,15 +41,18 @@ public abstract class BeforeRunTaskProvider { return null; } - public abstract String getDescription(T task); - + public String getDescription(T task) { + return getName(); + } @Nullable public Icon getTaskIcon(T task) { return null; } - public abstract boolean isConfigurable(); + public boolean isConfigurable() { + return false; + } /** * @return 'before run' task for the configuration or null, if the task from this provider is not applicable to the specified configuration @@ -60,9 +63,13 @@ public abstract class BeforeRunTaskProvider { /** * @return {@code true} if task configuration is changed */ - public abstract boolean configureTask(final RunConfiguration runConfiguration, T task); + public boolean configureTask(@NotNull RunConfiguration runConfiguration, @NotNull T task) { + return false; + } - public abstract boolean canExecuteTask(RunConfiguration configuration, T task); + public boolean canExecuteTask(@NotNull RunConfiguration configuration, @NotNull T task) { + return true; + } public abstract boolean executeTask(DataContext context, RunConfiguration configuration, ExecutionEnvironment env, T task); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java index cf96838fdd13..4b4e1b13848d 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java @@ -125,7 +125,7 @@ extends BeforeRunTaskProvider Date: Mon, 28 Aug 2017 17:53:28 +0200 Subject: [PATCH 02/31] add NotNull, default impl --- .../options/CompileStepBeforeRunNoErrorCheck.java | 10 ---------- .../compiler/options/MakeProjectStepBeforeRun.java | 9 --------- .../execution/impl/UnknownBeforeRunTaskProvider.java | 4 ++-- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRunNoErrorCheck.java b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRunNoErrorCheck.java index 8f050d9cd3db..76e66170fba7 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRunNoErrorCheck.java +++ b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRunNoErrorCheck.java @@ -61,21 +61,11 @@ public class CompileStepBeforeRunNoErrorCheck return CompileStepBeforeRun.shouldCreateTask(runConfiguration) ? new MakeBeforeRunTaskNoErrorCheck() : null; } - @Override - public boolean configureTask(@NotNull RunConfiguration runConfiguration, @NotNull MakeBeforeRunTaskNoErrorCheck task) { - return false; - } - @Override public String getName() { return ExecutionBundle.message("before.launch.compile.step.no.error.check"); } - @Override - public boolean canExecuteTask(@NotNull RunConfiguration configuration, @NotNull MakeBeforeRunTaskNoErrorCheck task) { - return true; - } - @Override public boolean executeTask(DataContext context, RunConfiguration configuration, diff --git a/java/execution/impl/src/com/intellij/compiler/options/MakeProjectStepBeforeRun.java b/java/execution/impl/src/com/intellij/compiler/options/MakeProjectStepBeforeRun.java index bb5faca1311c..ecb21407f272 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/MakeProjectStepBeforeRun.java +++ b/java/execution/impl/src/com/intellij/compiler/options/MakeProjectStepBeforeRun.java @@ -63,15 +63,6 @@ public class MakeProjectStepBeforeRun extends BeforeRunTaskProvider Date: Thu, 31 Aug 2017 14:01:45 +0200 Subject: [PATCH 03/31] initial LaunchBrowserBeforeRunTaskProvider --- .../intellij/ui/layout/MigLayoutBuilder.kt | 5 +- .../src/com/intellij/ui/layout/Row.kt | 4 +- .../src/META-INF/XmlPlugin.xml | 2 + .../LaunchBrowserBeforeRunTaskProvider.kt | 99 +++++++++++++++++++ 4 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt diff --git a/platform/platform-impl/src/com/intellij/ui/layout/MigLayoutBuilder.kt b/platform/platform-impl/src/com/intellij/ui/layout/MigLayoutBuilder.kt index cfbb452dcaeb..c0ab98a9adf3 100644 --- a/platform/platform-impl/src/com/intellij/ui/layout/MigLayoutBuilder.kt +++ b/platform/platform-impl/src/com/intellij/ui/layout/MigLayoutBuilder.kt @@ -317,9 +317,12 @@ private fun createComponentConstraints(constraints: Array? = null, } if (growPolicy == GrowPolicy.SHORT_TEXT) { -// cc().minWidth("210") cc().maxWidth("210") } + else if (growPolicy == GrowPolicy.MEDIUM_TEXT) { + cc().minWidth("210") + cc().maxWidth("350") + } return _cc } diff --git a/platform/platform-impl/src/com/intellij/ui/layout/Row.kt b/platform/platform-impl/src/com/intellij/ui/layout/Row.kt index 75bf50abfad7..ff0e1998aa04 100644 --- a/platform/platform-impl/src/com/intellij/ui/layout/Row.kt +++ b/platform/platform-impl/src/com/intellij/ui/layout/Row.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -148,5 +148,5 @@ abstract class Row() { } enum class GrowPolicy { - SHORT_TEXT + SHORT_TEXT, MEDIUM_TEXT } \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index dca03e9be781..9647a5d61a6b 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -585,6 +585,8 @@ key="browsers.settings" bundle="messages.IdeBundle"/> + + diff --git a/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt b/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt new file mode 100644 index 000000000000..99c169ee681a --- /dev/null +++ b/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2000-2017 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.ide.browsers + +import com.intellij.execution.BeforeRunTask +import com.intellij.execution.BeforeRunTaskProvider +import com.intellij.execution.configurations.RunConfiguration +import com.intellij.execution.runners.ExecutionEnvironment +import com.intellij.icons.AllIcons +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.components.BaseState +import com.intellij.openapi.ui.TextFieldWithBrowseButton +import com.intellij.openapi.util.Key +import com.intellij.ui.components.CheckBox +import com.intellij.ui.components.dialog +import com.intellij.ui.layout.* +import com.intellij.util.ui.UIUtil +import com.intellij.util.xmlb.annotations.Attribute +import com.intellij.xml.XmlBundle +import javax.swing.Icon +import javax.swing.border.EmptyBorder + +internal class LaunchBrowserBeforeRunTaskProvider : BeforeRunTaskProvider() { + companion object { + val ID = Key.create("LaunchBrowser.Before.Run") + } + + override fun getName() = "Launch Web Browser" + + override fun getId() = ID + + override fun getIcon(): Icon = AllIcons.Nodes.PpWeb + + override fun isConfigurable() = true + + override fun createTask(runConfiguration: RunConfiguration) = LaunchBrowserBeforeRunTask() + + override fun configureTask(runConfiguration: RunConfiguration, task: LaunchBrowserBeforeRunTask): Boolean { + val browserSelector = BrowserSelector() + val browserComboBox = browserSelector.mainComponent + if (UIUtil.isUnderAquaLookAndFeel()) { + browserComboBox.border = EmptyBorder(3, 0, 0, 0) + } + + val url = TextFieldWithBrowseButton() + StartBrowserPanel.setupUrlField(url, runConfiguration.project) + + val startJavaScriptDebuggerCheckBox = if (JavaScriptDebuggerStarter.Util.hasStarters()) CheckBox(XmlBundle.message("start.browser.with.js.debugger")) else null + + val modificationCount = task.state.modificationCount + val panel = panel { + row("Browser:") { + browserComboBox() + startJavaScriptDebuggerCheckBox?.invoke() + } + row("Url:") { + url(growPolicy = GrowPolicy.MEDIUM_TEXT) + } + } + dialog("Launch Web Browser", panel = panel, resizable = true) + .show() + + task.state.browser = browserSelector.selected + if (startJavaScriptDebuggerCheckBox != null) { + task.state.withDebugger = startJavaScriptDebuggerCheckBox.isSelected + } + return modificationCount != task.state.modificationCount + } + + override fun executeTask(context: DataContext?, + configuration: RunConfiguration?, + env: ExecutionEnvironment?, + task: LaunchBrowserBeforeRunTask?): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} + +internal class LaunchBrowserBeforeRunTaskState : BaseState() { + @get:Attribute(value = "browser", converter = WebBrowserReferenceConverter::class) + var browser by storedProperty() + var withDebugger by storedProperty(false) +} + +internal class LaunchBrowserBeforeRunTask : BeforeRunTask(LaunchBrowserBeforeRunTaskProvider.ID) { + val state = LaunchBrowserBeforeRunTaskState() +} \ No newline at end of file From e304fa5c18eaaf2acd2ea80a7d305c11fd24ac05 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 31 Aug 2017 14:27:39 +0200 Subject: [PATCH 04/31] add NotNull --- .../impl/run/BuildArtifactsBeforeRunTaskBase.java | 6 +++--- .../service/execution/ExternalSystemBeforeRunTask.java | 6 +++--- .../src/com/intellij/execution/BeforeRunTask.java | 10 ++++------ .../impl/RunConfigurationBeforeRunProvider.java | 4 ++-- .../execution/impl/UnknownBeforeRunTaskProvider.java | 4 ++-- .../com/intellij/tools/AbstractToolBeforeRunTask.java | 6 +++--- .../lang/ant/config/impl/AntBeforeRunTask.java | 7 ++++--- .../jetbrains/idea/maven/tasks/MavenBeforeRunTask.java | 7 ++++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskBase.java index ad73ef77b92d..8d86241f2ec3 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskBase.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -45,7 +45,7 @@ public abstract class BuildArtifactsBeforeRunTaskBase children = element.getChildren(myElementName); final ArtifactPointerManager pointerManager = ArtifactPointerManager.getInstance(myProject); @@ -62,7 +62,7 @@ public abstract class BuildArtifactsBeforeRunTaskBase implements Cloneabl myIsEnabled = isEnabled; } - public void writeExternal(Element element) { + public void writeExternal(@NotNull Element element) { element.setAttribute("enabled", String.valueOf(myIsEnabled)); } - public void readExternal(Element element) { + public void readExternal(@NotNull Element element) { String attribValue = element.getAttributeValue("enabled"); if (attribValue == null) { attribValue = element.getAttributeValue("value"); // maintain compatibility with old format } - if (attribValue == null) - attribValue = "true"; - myIsEnabled = Boolean.valueOf(attribValue).booleanValue(); + myIsEnabled = attribValue == null || Boolean.parseBoolean(attribValue); } //Task may aggregate several items or targets to do (e.g. BuildArtifactsBeforeRunTask) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java index 4b4e1b13848d..35e93ca20651 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java @@ -291,7 +291,7 @@ extends BeforeRunTaskProvider{ myTargetName = targetName; } - public void writeExternal(Element element) { + public void writeExternal(@NotNull Element element) { super.writeExternal(element); if (myAntFileUrl != null && myTargetName != null) { element.setAttribute("antfile", myAntFileUrl); @@ -58,7 +59,7 @@ public class AntBeforeRunTask extends BeforeRunTask{ } } - public void readExternal(Element element) { + public void readExternal(@NotNull Element element) { super.readExternal(element); final String url = element.getAttributeValue("antfile"); final String targetName = element.getAttributeValue("target"); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTask.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTask.java index 8a77eb8ac382..0fe12ae70385 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTask.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -18,6 +18,7 @@ package org.jetbrains.idea.maven.tasks; import com.intellij.execution.BeforeRunTask; import com.intellij.openapi.util.io.FileUtil; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.project.MavenProject; public class MavenBeforeRunTask extends BeforeRunTask { @@ -50,14 +51,14 @@ public class MavenBeforeRunTask extends BeforeRunTask { } @Override - public void writeExternal(Element element) { + public void writeExternal(@NotNull Element element) { super.writeExternal(element); if (myProjectPath != null) element.setAttribute("file", myProjectPath); if (myGoal != null) element.setAttribute("goal", myGoal); } @Override - public void readExternal(Element element) { + public void readExternal(@NotNull Element element) { super.readExternal(element); myProjectPath = element.getAttributeValue("file"); myGoal = element.getAttributeValue("goal"); From 270691cbc553a6ad7381839a5f1bfe19a8598ab2 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 31 Aug 2017 18:00:23 +0200 Subject: [PATCH 05/31] =?UTF-8?q?BeforeRunTask=20=E2=80=94=20ability=20to?= =?UTF-8?q?=20use=20PersistentStateComponent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/intellij/execution/BeforeRunTask.java | 11 +++++- .../intellij/execution/impl/RunManagerImpl.kt | 29 +++++++++++---- .../RunnerAndConfigurationSettingsImpl.kt | 4 +- .../configurationStore/xmlSerializer.kt | 19 +++++++--- .../openapi/roots/impl/RootModelImpl.java | 2 +- .../idea/copyright/CopyrightProfile.kt | 6 +-- .../conversion/IdeaSpecificSettings.java | 2 +- .../LaunchBrowserBeforeRunTaskProvider.kt | 37 +++++++++++++++---- 8 files changed, 81 insertions(+), 29 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java b/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java index fcff2ca565df..634f29e00c6b 100644 --- a/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java +++ b/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java @@ -16,6 +16,7 @@ package com.intellij.execution; +import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.util.Key; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -27,6 +28,9 @@ import org.jetbrains.annotations.NotNull; public abstract class BeforeRunTask implements Cloneable { @NotNull protected final Key myProviderId; + + // cannot be set to true by default, because RunManager.getHardcodedBeforeRunTasks creates before run task for each provider + // and some providers set enabled to true in the constructor to indicate, that before run task should be added to RC by default (on create) private boolean myIsEnabled; protected BeforeRunTask(@NotNull Key providerId) { @@ -47,7 +51,12 @@ public abstract class BeforeRunTask implements Cloneabl } public void writeExternal(@NotNull Element element) { - element.setAttribute("enabled", String.valueOf(myIsEnabled)); + if (this instanceof PersistentStateComponent) { + ((PersistentStateComponent)this).getState(); + } + else { + element.setAttribute("enabled", String.valueOf(myIsEnabled)); + } } public void readExternal(@NotNull Element element) { diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt index e3a6ebb949d6..277a8538d133 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt @@ -16,9 +16,7 @@ package com.intellij.execution.impl import com.intellij.ProjectTopics -import com.intellij.configurationStore.OLD_NAME_CONVERTER -import com.intellij.configurationStore.SchemeManagerIprProvider -import com.intellij.configurationStore.save +import com.intellij.configurationStore.* import com.intellij.execution.* import com.intellij.execution.compound.CompoundRunConfiguration import com.intellij.execution.configurations.* @@ -58,6 +56,7 @@ import kotlin.concurrent.write private val SELECTED_ATTR = "selected" internal val METHOD = "method" private val OPTION = "option" +private val RECENT = "recent_temporary" // open for Upsource (UpsourceRunManager overrides to disable loadState (empty impl)) @State(name = "RunManager", defaultStateAsResource = true, storages = arrayOf(Storage(StoragePathMacros.WORKSPACE_FILE))) @@ -65,7 +64,6 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi companion object { @JvmField val CONFIGURATION = "configuration" - private val RECENT = "recent_temporary" @JvmField val NAME_ATTR = "name" @@ -607,7 +605,15 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi for (task in tasks) { val child = Element(OPTION) child.setAttribute(NAME_ATTR, task.providerId.toString()) - task.writeExternal(child) + if (task is PersistentStateComponent<*>) { + if (!task.isEnabled) { + child.setAttribute("enabled", "false") + } + task.serializeStateInto(child) + } + else { + task.writeExternal(child) + } methodElement.addContent(child) } return methodElement @@ -800,7 +806,14 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi val key = methodElement.getAttributeValue(NAME_ATTR) val provider = stringIdToBeforeRunProvider.getOrPut(key) { UnknownBeforeRunTaskProvider(key) } val beforeRunTask = (if (provider is RunConfigurationBeforeRunProvider) provider.createTask(settings.configuration, this) else provider.createTask(settings.configuration)) ?: continue - beforeRunTask.readExternal(methodElement) + if (beforeRunTask is PersistentStateComponent<*>) { + // for PersistentStateComponent we don't write default value for enabled, so, set it to true explicitly + beforeRunTask.isEnabled = true + beforeRunTask.deserializeAndLoadState(methodElement) + } + else { + beforeRunTask.readExternal(methodElement) + } if (result == null) { result = SmartList() } @@ -996,8 +1009,8 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi private fun getHardcodedBeforeRunTasks(configuration: RunConfiguration): List> { var result: MutableList>? = null for (provider in Extensions.getExtensions(BeforeRunTaskProvider.EXTENSION_POINT_NAME, project)) { - val task = provider.createTask(configuration) - if (task != null && task.isEnabled) { + val task = provider.createTask(configuration) ?: continue + if (task.isEnabled) { configuration.factory.configureBeforeRunTaskDefaults(provider.id, task) if (task.isEnabled) { if (result == null) { diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt index 353718bb4828..1e7ed9860a92 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt @@ -17,7 +17,7 @@ package com.intellij.execution.impl import com.intellij.configurationStore.SerializableScheme import com.intellij.configurationStore.deserializeAndLoadState -import com.intellij.configurationStore.serializeInto +import com.intellij.configurationStore.serializeStateInto import com.intellij.execution.* import com.intellij.execution.configurations.* import com.intellij.execution.runners.ProgramRunner @@ -282,7 +282,7 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m private fun serializeConfigurationInto(configuration: RunConfiguration, element: Element) { if (configuration is PersistentStateComponent<*>) { - configuration.state!!.serializeInto(element) + configuration.serializeStateInto(element) } else { configuration.writeExternal(element) diff --git a/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt b/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt index 6651be07dec2..2cfc6b6e074e 100644 --- a/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt +++ b/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt @@ -119,15 +119,24 @@ fun PersistentStateComponent<*>.deserializeAndLoadState(element: Element) { (this as PersistentStateComponent).loadState(state) } +fun PersistentStateComponent<*>.serializeStateInto(element: Element) { + state?.let { serializeObjectInto(it, element) } +} + +@Deprecated("") fun T.serializeInto(target: Element) { - if (this is Element) { - val iterator = children.iterator() + serializeObjectInto(this, target) +} + +fun serializeObjectInto(o: Any, target: Element) { + if (o is Element) { + val iterator = o.children.iterator() for (child in iterator) { iterator.remove() target.addContent(child) } - val attributeIterator = attributes.iterator() + val attributeIterator = o.attributes.iterator() for (attribute in attributeIterator) { attributeIterator.remove() target.setAttribute(attribute) @@ -135,8 +144,8 @@ fun T.serializeInto(target: Element) { return } - val binding = serializer.getClassBinding(javaClass) - (binding as BeanBinding).serializeInto(this, target, null) + val binding = serializer.getClassBinding(o.javaClass) + (binding as BeanBinding).serializeInto(o, target, getDefaultSerializationFilter()) } private val serializer = object : XmlSerializerImpl.XmlSerializerBase() { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java index 0710feaa8309..65c9bf372724 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -455,7 +455,7 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel for (ModuleExtension extension : myExtensions) { if (extension instanceof PersistentStateComponent) { //noinspection ConstantConditions - XmlSerializer.serializeInto(((PersistentStateComponent)extension).getState(), element); + XmlSerializer.serializeStateInto(((PersistentStateComponent)extension), element); } else { //noinspection deprecation diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightProfile.kt b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightProfile.kt index 078e274f1605..df992a08cd3e 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightProfile.kt +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightProfile.kt @@ -16,7 +16,7 @@ package com.maddyhome.idea.copyright import com.intellij.configurationStore.SerializableScheme -import com.intellij.configurationStore.serializeInto +import com.intellij.configurationStore.serializeObjectInto import com.intellij.openapi.components.BaseState import com.intellij.openapi.options.ExternalizableScheme import com.intellij.util.xmlb.annotations.OptionTag @@ -36,7 +36,7 @@ class CopyrightProfile @JvmOverloads constructor(profileName: String? = null) : // ugly name to preserve compatibility // must be not private because otherwise binding is not created for private accessor @get:OptionTag("myName") - internal var profileName by string() + private var profileName by string() var notice by string(DEFAULT_COPYRIGHT_NOTICE) var keyword by string(EntityUtil.encode("Copyright")) @@ -61,7 +61,7 @@ class CopyrightProfile @JvmOverloads constructor(profileName: String? = null) : override fun writeScheme(): Element { val element = Element("copyright") - serializeInto(element) + serializeObjectInto(this, element) return element } } diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java index 88f47fbfb8b2..bb6843b1e741 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java @@ -261,7 +261,7 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings() + @get:Attribute() + var url by string() + @get:Attribute() var withDebugger by storedProperty(false) } -internal class LaunchBrowserBeforeRunTask : BeforeRunTask(LaunchBrowserBeforeRunTaskProvider.ID) { - val state = LaunchBrowserBeforeRunTaskState() +internal class LaunchBrowserBeforeRunTask : BeforeRunTask(LaunchBrowserBeforeRunTaskProvider.ID), PersistentStateComponent { + private var state = LaunchBrowserBeforeRunTaskState() + + override fun loadState(state: LaunchBrowserBeforeRunTaskState) { + state.resetModificationCount() + this.state = state + } + + override fun getState() = state } \ No newline at end of file From 584cde07fb4a3ac9e2812def6bc62066ba9670be Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 31 Aug 2017 18:27:47 +0200 Subject: [PATCH 06/31] LaunchBrowserBeforeRunTaskProvider --- ...ildArtifactsBeforeRunTaskProviderBase.java | 6 ++-- .../options/CompileStepBeforeRun.java | 2 +- .../CompileStepBeforeRunNoErrorCheck.java | 6 ++-- .../options/MakeProjectStepBeforeRun.java | 2 +- .../ExternalSystemBeforeRunTaskProvider.java | 6 ++-- .../execution/BeforeRunTaskProvider.java | 2 +- .../RunConfigurationBeforeRunProvider.java | 6 ++-- .../impl/UnknownBeforeRunTaskProvider.java | 2 +- .../AbstractToolBeforeRunTaskProvider.java | 2 +- .../config/impl/AntBeforeRunTaskProvider.java | 2 +- .../tasks/MavenBeforeRunTasksProvider.java | 6 ++-- .../intellij/ide/browsers/BrowserStarter.java | 21 ++++++++++-- .../LaunchBrowserBeforeRunTaskProvider.kt | 34 ++++++++++++++++--- 13 files changed, 68 insertions(+), 29 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java index 8625479451a4..96babf1a05a5 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProviderBase.java @@ -121,9 +121,9 @@ public abstract class BuildArtifactsBeforeRunTaskProviderBase result = Ref.create(false); final Semaphore finished = new Semaphore(); diff --git a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java index e69bb5641048..5820e32b81ed 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java +++ b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java @@ -106,7 +106,7 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider { return true; } - public abstract boolean executeTask(DataContext context, RunConfiguration configuration, ExecutionEnvironment env, T task); + public abstract boolean executeTask(DataContext context, @NotNull RunConfiguration configuration, @NotNull ExecutionEnvironment env, @NotNull T task); /** * diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java index 35e93ca20651..bb0ebe034bbe 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java @@ -172,9 +172,9 @@ extends BeforeRunTaskProvider openPageNow(), millis, TimeUnit.MILLISECONDS); + private void openPageLater() { + JobScheduler.getScheduler().schedule(() -> openPageNow(), 1000, TimeUnit.MILLISECONDS); } private void openPageNow() { diff --git a/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt b/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt index 6a66b4cda4cc..301cc0658d7c 100644 --- a/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt +++ b/xml/impl/src/com/intellij/ide/browsers/LaunchBrowserBeforeRunTaskProvider.kt @@ -17,13 +17,17 @@ package com.intellij.ide.browsers import com.intellij.execution.BeforeRunTask import com.intellij.execution.BeforeRunTaskProvider +import com.intellij.execution.ExecutionListener +import com.intellij.execution.ExecutionManager import com.intellij.execution.configurations.RunConfiguration +import com.intellij.execution.process.ProcessHandler import com.intellij.execution.runners.ExecutionEnvironment import com.intellij.icons.AllIcons import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.components.BaseState import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.ui.TextFieldWithBrowseButton +import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Key import com.intellij.ui.components.CheckBox import com.intellij.ui.components.dialog @@ -91,11 +95,31 @@ internal class LaunchBrowserBeforeRunTaskProvider : BeforeRunTaskProvider Date: Fri, 1 Sep 2017 15:52:37 +0300 Subject: [PATCH 07/31] Better logging for failed AnAction.update() --- .../src/com/intellij/openapi/actionSystem/impl/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java index 8c74f71d35d4..65d7cef0b877 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java @@ -68,7 +68,7 @@ public class Utils{ private static void handleUpdateException(AnAction action, Presentation presentation, Throwable exc) { String id = ActionManager.getInstance().getId(action); if (id != null) { - LOG.error("update failed for AnAction with ID=" + id, exc); + LOG.error("update failed for AnAction(" + action.getClass().getName() + ") with ID=" + id, exc); } else { LOG.error("update failed for ActionGroup: " + action + "[" + presentation.getText() + "]", exc); From 915e999d4074ab42797d09adb6c18c0047929f2d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 31 Aug 2017 20:12:19 +0300 Subject: [PATCH 08/31] "suppress with non-nls comment" crashes on injections with suffix --- .../codeInspection/i18n/SuppressByCommentOutAction.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/SuppressByCommentOutAction.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/SuppressByCommentOutAction.java index 32cad3a9c4bc..d5d194b71445 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/SuppressByCommentOutAction.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/SuppressByCommentOutAction.java @@ -18,6 +18,7 @@ package com.intellij.codeInspection.i18n; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.SuppressIntentionAction; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -76,8 +77,9 @@ class SuppressByCommentOutAction extends SuppressIntentionAction { } private static PsiElement findJavaCodeUpThere(PsiElement element) { + InjectedLanguageManager injectedManager = InjectedLanguageManager.getInstance(element.getProject()); while (element != null) { - if (element.getLanguage() == JavaLanguage.INSTANCE) return element; + if (element.getLanguage() == JavaLanguage.INSTANCE && !injectedManager.isInjectedFragment(element.getContainingFile())) return element; element = element.getContext(); } return null; From d7b672597e7a787e3013eeb5f38ae4ca30532a06 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 1 Sep 2017 16:51:26 +0300 Subject: [PATCH 09/31] Add name ID for usage tree component --- .../usageView/src/com/intellij/usages/impl/UsageViewImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index b481623485bd..ad83b2b58a15 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -231,6 +231,7 @@ public class UsageViewImpl implements UsageView { return expandingAll ? EmptyEnumeration.getInstance() : super.getExpandedDescendants(parent); } }; + myTree.setName("UsageViewTree"); myRootPanel = new MyPanel(myTree); Disposer.register(this, myRootPanel); From 1f15146106afa472a9b118fb6d590195bdc25268 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 1 Sep 2017 16:52:05 +0300 Subject: [PATCH 10/31] cleanup --- .../java/codeInsight/daemon/LightAdvHighlightingTest.java | 5 +++-- .../testSrc/com/intellij/roots/RootsChangedTest.java | 8 ++++---- .../intellij/codeInspection/SuppressIntentionAction.java | 1 - .../codeInspection/SuppressIntentionActionFromFix.java | 4 +++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingTest.java index 1356f057c926..fd100352fc09 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingTest.java @@ -60,6 +60,7 @@ import com.intellij.psi.xml.XmlToken; import com.intellij.psi.xml.XmlTokenType; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.VfsTestUtil; +import com.intellij.util.ObjectUtils; import com.intellij.util.ui.UIUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -196,10 +197,10 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase { } finally { PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); - VirtualFile file = FileDocumentManager.getInstance().getFile(e.getDocument()); + VirtualFile file = ObjectUtils.notNull(FileDocumentManager.getInstance().getFile(e.getDocument())); FileEditorManager.getInstance(getProject()).closeFile(file); VfsTestUtil.deleteFile(file); - VirtualFile file2 = FileDocumentManager.getInstance().getFile(e2.getDocument()); + VirtualFile file2 = ObjectUtils.notNull(FileDocumentManager.getInstance().getFile(e2.getDocument())); FileEditorManager.getInstance(getProject()).closeFile(file2); VfsTestUtil.deleteFile(file2); } diff --git a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java index 9d35e9de69b3..b17bdadd9f74 100644 --- a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java @@ -248,7 +248,7 @@ public class RootsChangedTest extends ModuleTestCase { rootModelB.addLibraryEntry(libraryA); rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel()); rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel()); - ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB}; + ModifiableRootModel[] rootModels = {rootModelA, rootModelB}; if (rootModels.length > 0) { ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel()); } @@ -317,7 +317,7 @@ public class RootsChangedTest extends ModuleTestCase { final Library libraryQ = libraryTable.createLibrary("Q"); assertEventsCount(0); - ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB}; + ModifiableRootModel[] rootModels = {rootModelA, rootModelB}; if (rootModels.length > 0) { ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel()); } @@ -337,8 +337,8 @@ public class RootsChangedTest extends ModuleTestCase { } private static class MyModuleRootListener implements ModuleRootListener { - private int beforeCount = 0; - private int afterCount = 0; + private int beforeCount; + private int afterCount; @Override public void beforeRootsChange(ModuleRootEvent event) { diff --git a/platform/analysis-api/src/com/intellij/codeInspection/SuppressIntentionAction.java b/platform/analysis-api/src/com/intellij/codeInspection/SuppressIntentionAction.java index 369dd223eab9..6835134ca375 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/SuppressIntentionAction.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/SuppressIntentionAction.java @@ -73,7 +73,6 @@ public abstract class SuppressIntentionAction implements Iconable, IntentionActi * @param project the project in which the file is opened. * @param editor the editor for the file. * @param element the element under cursor. - * @throws IncorrectOperationException * */ public abstract void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException; diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java index b727fe954f32..9bc6190b2bda 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java @@ -50,7 +50,8 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction { @NotNull public static SuppressIntentionAction[] convertBatchToSuppressIntentionActions(@NotNull SuppressQuickFix[] actions) { - return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, fix -> convertBatchToSuppressIntentionAction(fix)); + return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, + SuppressIntentionActionFromFix::convertBatchToSuppressIntentionAction); } @Override @@ -93,6 +94,7 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction { return myFix.getFamilyName(); } + @Override public boolean isSuppressAll() { return myFix.isSuppressAll(); } From da6a41d41da11efb63012025476695f66f334bf3 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 1 Sep 2017 17:02:28 +0300 Subject: [PATCH 11/31] replace whole attribute only for html --- .../intellij/psi/impl/source/xml/XmlAttributeImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java index 99d0c633d8ee..6320751eee49 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl.source.xml; import com.intellij.lang.ASTNode; +import com.intellij.lang.html.HTMLLanguage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; import com.intellij.pom.PomManager; @@ -324,11 +325,12 @@ public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute, Hi xmlAspectChangeSet.add(new XmlAttributeSetImpl(getParent(), oldName, null)); xmlAspectChangeSet.add(new XmlAttributeSetImpl(getParent(), nameText, oldValue)); event.registerChangeSet(model.getModelAspect(XmlAspect.class), xmlAspectChangeSet); - if (oldValue.isEmpty()) { - CodeEditUtil.replaceChild(XmlAttributeImpl.this, name, newName); - } else { + if (!oldValue.isEmpty() && getLanguage().isKindOf(HTMLLanguage.INSTANCE)) { CodeEditUtil.replaceChild(getTreeParent(), XmlAttributeImpl.this, attribute.getNode()); } + else { + CodeEditUtil.replaceChild(XmlAttributeImpl.this, name, newName); + } return event; } }); From e2af228d30b814d81065d3796e75158538dfcca9 Mon Sep 17 00:00:00 2001 From: Alexander Kass Date: Tue, 22 Aug 2017 09:37:22 +0300 Subject: [PATCH 12/31] DocComp: ignore see https://stackoverflow.com/questions/178667/does-jeditorpane-have-charset-problems-when-showing-html --- .../codeInsight/documentation/DocumentationComponent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java index df91737f02f5..f98e1bb2a830 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java @@ -250,6 +250,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr @Override public void setDocument(Document doc) { super.setDocument(doc); + doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE); if (doc instanceof StyledDocument) { doc.putProperty("imageCache", myImageProvider); } From 027f4b331ea74058c478c08583c1cdf6a02d5f38 Mon Sep 17 00:00:00 2001 From: Alexander Kass Date: Thu, 31 Aug 2017 13:08:14 +0300 Subject: [PATCH 13/31] JBZipFile: support interchanging r/w operations --- .../com/intellij/util/io/zip/JBZipEntry.java | 10 +++- .../com/intellij/util/io/zip/JBZipFile.java | 6 +- .../util/io/zip/JBZipOutputStream.java | 22 ++++--- .../util/io/zip/UpdateableZipTest.java | 59 +++++++++++++++++++ 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/platform/util/src/com/intellij/util/io/zip/JBZipEntry.java b/platform/util/src/com/intellij/util/io/zip/JBZipEntry.java index 2c5945f60452..e7522da5c305 100644 --- a/platform/util/src/com/intellij/util/io/zip/JBZipEntry.java +++ b/platform/util/src/com/intellij/util/io/zip/JBZipEntry.java @@ -23,6 +23,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; @@ -370,9 +371,14 @@ public class JBZipEntry implements Cloneable { } private InputStream getInputStream() throws IOException { + myFile.ensureFlushed(getHeaderOffset() + JBZipFile.LFH_OFFSET_FOR_FILENAME_LENGTH + JBZipFile.WORD); long start = calcDataOffset(); - - BoundedInputStream bis = new BoundedInputStream(start, getCompressedSize()); + long size = getCompressedSize(); + myFile.ensureFlushed(start + size); + if (myFile.archive.length() < start + size) { + throw new EOFException(); + } + BoundedInputStream bis = new BoundedInputStream(start, size); switch (getMethod()) { case ZipEntry.STORED: return bis; diff --git a/platform/util/src/com/intellij/util/io/zip/JBZipFile.java b/platform/util/src/com/intellij/util/io/zip/JBZipFile.java index a8b5ce8969cd..08afcbd6ec3f 100644 --- a/platform/util/src/com/intellij/util/io/zip/JBZipFile.java +++ b/platform/util/src/com/intellij/util/io/zip/JBZipFile.java @@ -187,7 +187,7 @@ public class JBZipFile { } myOutputStream.finish(); - archive.setLength(myOutputStream.written); + archive.setLength(myOutputStream.getWritten()); } archive.close(); } @@ -454,4 +454,8 @@ public class JBZipFile { } return myOutputStream; } + + void ensureFlushed(long end) throws IOException { + if (myOutputStream != null) myOutputStream.ensureFlushed(end); + } } diff --git a/platform/util/src/com/intellij/util/io/zip/JBZipOutputStream.java b/platform/util/src/com/intellij/util/io/zip/JBZipOutputStream.java index df5276ab40de..1ad6920469cd 100644 --- a/platform/util/src/com/intellij/util/io/zip/JBZipOutputStream.java +++ b/platform/util/src/com/intellij/util/io/zip/JBZipOutputStream.java @@ -48,7 +48,7 @@ class JBZipOutputStream { private final CRC32 crc = new CRC32(); - long written = 0; + private long writtenOnDisk = 0; /** * The encoding to use for filenames and the file comment. @@ -93,8 +93,7 @@ class JBZipOutputStream { public JBZipOutputStream(JBZipFile file, long currentCDOffset) throws IOException { myFile = file; raf = myFile.archive; - written = currentCDOffset; - raf.seek(currentCDOffset); + writtenOnDisk = currentCDOffset; } /** @@ -129,12 +128,12 @@ class JBZipOutputStream { * @since 1.1 */ public void finish() throws IOException { - long cdOffset = written; + long cdOffset = getWritten(); final List entries = myFile.getEntries(); for (int i = 0, entriesSize = entries.size(); i < entriesSize; i++) { writeCentralFileHeader(entries.get(i)); } - long cdLength = written - cdOffset; + long cdLength = getWritten() - cdOffset; writeCentralDirectoryEnd(cdLength, cdOffset); flushBuffer(); def.end(); @@ -209,7 +208,7 @@ class JBZipOutputStream { * @since 1.1 */ protected void writeLocalFileHeader(JBZipEntry ze) throws IOException { - ze.setHeaderOffset(written); + ze.setHeaderOffset(getWritten()); writeOut(LFH_SIG); @@ -376,11 +375,16 @@ class JBZipOutputStream { if (myBuffer.size() > 8192) { flushBuffer(); } - written += length; + } + + void ensureFlushed(long end) throws IOException { + if (end > writtenOnDisk) flushBuffer(); } private void flushBuffer() throws IOException { + raf.seek(writtenOnDisk); raf.write(myBuffer.getInternalBuffer(), 0, myBuffer.size()); + writtenOnDisk += myBuffer.size(); myBuffer.reset(); } @@ -423,4 +427,8 @@ class JBZipOutputStream { writeLocalFileHeader(entry); writeOut(outputBytes, 0, outputBytesLength); } + + long getWritten() { + return writtenOnDisk + myBuffer.size(); + } } diff --git a/platform/util/testSrc/com/intellij/util/io/zip/UpdateableZipTest.java b/platform/util/testSrc/com/intellij/util/io/zip/UpdateableZipTest.java index b2dfb56e36f0..5cac1f2292af 100644 --- a/platform/util/testSrc/com/intellij/util/io/zip/UpdateableZipTest.java +++ b/platform/util/testSrc/com/intellij/util/io/zip/UpdateableZipTest.java @@ -20,6 +20,7 @@ package com.intellij.util.io.zip; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import junit.framework.TestCase; import java.io.*; @@ -108,6 +109,64 @@ public class UpdateableZipTest extends TestCase { utilZip.close(); } + public void testReadWrite1() throws Exception { + JBZipFile jbZip = new JBZipFile(zipFile); + try { + assertEntryWithContentExists(jbZip, "/first", "first"); + assertEntryWithContentExists(jbZip, "/second", "second"); + + createOrReplaceEntryData(jbZip, "/third", "third"); + + assertEntryWithContentExists(jbZip, "/third", "third"); + } + finally { + jbZip.close(); + } + } + + public void testReadWrite2() throws Exception { + JBZipFile jbZip = new JBZipFile(zipFile); + try { + assertEntryWithContentExists(jbZip, "/first", "first"); + assertEntryWithContentExists(jbZip, "/second", "second"); + + createOrReplaceEntryData(jbZip, "/first", "first_new"); + + assertEntryWithContentExists(jbZip, "/first", "first_new"); + } + finally { + jbZip.close(); + } + } + + public void testMissingSeeks() throws Exception { + JBZipFile jbZip = new JBZipFile(zipFile); + try { + assertEntryWithContentExists(jbZip, "/first", "first"); + assertEntryWithContentExists(jbZip, "/second", "second"); + + //seek end + createOrReplaceEntryData(jbZip, "/third", "third"); + //seek somewhere + assertEntryWithContentExists(jbZip, "/first", "first"); + //write somewhere :) + createOrReplaceEntryData(jbZip, "/forth", "forth"); + + assertEntryWithContentExists(jbZip, "/first", "first"); + assertEntryWithContentExists(jbZip, "/second", "second"); + assertEntryWithContentExists(jbZip, "/third", "third"); + assertEntryWithContentExists(jbZip, "/forth", "forth"); + } + finally { + jbZip.close(); + } + } + + private void createOrReplaceEntryData(JBZipFile jbZip, String name, String data) throws IOException { + JBZipEntry newEntry = jbZip.getOrCreateEntry(name); + newEntry.setData(data.getBytes(CharsetToolkit.UTF8_CHARSET)); + } + /* public void testAppendToIdeaJar() throws Exception { //ProfilingUtil.startCPUProfiling(); From 9d48ac9ac83455e2f6feafde6c38c99066e94f3e Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 1 Sep 2017 17:05:55 +0300 Subject: [PATCH 14/31] provide means to retrieve current state as is --- .../src/com/intellij/ide/RecentProjectsManagerBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java index fbaa85e004c8..4e73d9626836 100644 --- a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java +++ b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java @@ -191,6 +191,11 @@ public abstract class RecentProjectsManagerBase extends RecentProjectsManager im } } + @NotNull + protected State getStateInner() { + return myState; + } + @Override public void loadState(final State state) { state.makePathsSystemIndependent(); From e1126dc44e98d9e37017b5913ed9ab8010095711 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Fri, 1 Sep 2017 17:41:35 +0300 Subject: [PATCH 15/31] Add PersistableCodeStyleSchemes --- .../psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java index 978049dc9548..f6463e40fc72 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java @@ -38,7 +38,7 @@ import org.jetbrains.annotations.Nullable; }, additionalExportFile = CodeStyleSchemesImpl.CODE_STYLES_DIR_PATH ) -class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements PersistentStateComponent { +public class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements PersistentStateComponent { public String CURRENT_SCHEME_NAME = CodeStyleSchemeImpl.DEFAULT_SCHEME_NAME; public PersistableCodeStyleSchemes(@NotNull SchemeManagerFactory schemeManagerFactory) { @@ -65,6 +65,7 @@ class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements Persis @Override public void loadState(Element state) { + CURRENT_SCHEME_NAME = CodeStyleSchemeImpl.DEFAULT_SCHEME_NAME; XmlSerializer.deserializeInto(this, state); CodeStyleScheme current = CURRENT_SCHEME_NAME == null ? null : mySchemeManager.findSchemeByName(CURRENT_SCHEME_NAME); setCurrentScheme(current == null ? getDefaultScheme() : current); From 9a41b7da399ab9310d408e34b6429904c1bdb73b Mon Sep 17 00:00:00 2001 From: Aleksey Rostovskiy Date: Mon, 28 Aug 2017 18:20:16 +0300 Subject: [PATCH 16/31] [gui-test] Refactorings to use common project creation tests --- .../framework/GuiTestLocalRunner.kt | 12 ++++--- .../framework/GuiTestSuite.kt | 5 +-- .../testGuiFramework/impl/GuiTestCase.kt | 32 ++++++++++++++++++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestLocalRunner.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestLocalRunner.kt index 1256de53acaa..34b3c118e79e 100755 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestLocalRunner.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestLocalRunner.kt @@ -38,7 +38,9 @@ import kotlin.reflect.KClass class GuiTestLocalRunner @Throws(InitializationError::class) -constructor(testClass: Class<*>) : BlockJUnit4ClassRunner(testClass) { + constructor(testClass: Class<*>, val ide: Ide?) : BlockJUnit4ClassRunner(testClass) { + + constructor(testClass: Class<*>): this(testClass, null) val SERVER_LOG = org.apache.log4j.Logger.getLogger("#com.intellij.testGuiFramework.framework.GuiTestLocalRunner")!! val criticalError = Ref(false) @@ -67,8 +69,10 @@ constructor(testClass: Class<*>) : BlockJUnit4ClassRunner(testClass) { val server = JUnitServerHolder.getServer() try { - if (!server.isConnected()) - runIdeLocally(port = server.getPort(), ide = getIdeFromAnnotation(this@GuiTestLocalRunner.testClass.javaClass)) + if (!server.isConnected()) { + val localIde = ide ?: getIdeFromAnnotation(this@GuiTestLocalRunner.testClass.javaClass) + runIdeLocally(port = server.getPort(), ide = localIde) + } val jUnitTestContainer = JUnitTestContainer(method.declaringClass, method.name) server.send(TransportMessage(MessageType.RUN_TEST, jUnitTestContainer)) } @@ -147,7 +151,5 @@ constructor(testClass: Class<*>) : BlockJUnit4ClassRunner(testClass) { return Ide(ideType, 0, 0) } } - - } diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestSuite.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestSuite.kt index 614507555e8b..ec90f2ee64d9 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestSuite.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestSuite.kt @@ -40,9 +40,7 @@ class GuiTestSuite(suiteClass: Class<*>, val builder: RunnerBuilder) : Suite(sui //let's start IDE to complete installation, import configs and etc before running tests if (myFirstStart) firstStart() val testClass = runner.description.testClass - //check that ide types are equal - check(GuiTestLocalRunner.getIdeFromAnnotation(testClass).ideType.javaClass == myIde.ideType.javaClass) - val guiTestLocalRunner = GuiTestLocalRunner(testClass) + val guiTestLocalRunner = GuiTestLocalRunner(testClass, myIde) super.runChild(guiTestLocalRunner, notifier) } catch (e: Exception) { @@ -59,5 +57,4 @@ class GuiTestSuite(suiteClass: Class<*>, val builder: RunnerBuilder) : Suite(sui } - } diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index 2466dd354630..f8e1f5d50734 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -16,6 +16,7 @@ package com.intellij.testGuiFramework.impl import com.intellij.ide.GeneralSettings +import com.intellij.openapi.editor.impl.EditorComponentImpl import com.intellij.openapi.ui.ComponentWithBrowseButton import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil @@ -122,7 +123,6 @@ open class GuiTestCase : GuiTestBase() { val screenshotTaker = ScreenshotTaker() var pathToSaveScreenshots = getTestScreenshotDirPath() - val settingsTitle: String = if (isMac()) "Preferences" else "Settings" val defaultSettingsTitle: String = if (isMac()) "Default Preferences" else "Default Settings" val slash: String = File.separator @@ -745,5 +745,35 @@ open class GuiTestCase : GuiTestBase() { return flagCheckFunction() } } + /** + *@timeout in seconds to wait for the text in run window + */ + fun waitForTextInRunWindow(text: String, windowId: String = "Run") { + ideFrame { + toolwindow(id = windowId) { + content { + pause("Wait for $text in run window") { isRunWindowContainsText(text) } + } + waitForBackgroundTasksToFinish() + } + } + } + + /** + * Is run window contains @text + */ + private fun CustomToolWindowFixture.ContentFixture.isRunWindowContainsText(text: String): Boolean { + val outputText = getRunWindowText() + if (outputText!!.contains(text)) { + return true + } + return false + } + + private fun CustomToolWindowFixture.ContentFixture.getRunWindowText(): String? { + val consoleEditor = waitUntilFound(getContent().component as Container, EditorComponentImpl::class.java, + 10) { it is EditorComponentImpl } + return GuiTestUtilKt.computeOnEdt { consoleEditor.editor.document.text } + } } From df3abe88cda948ef9eb061be82f008e313e6bb45 Mon Sep 17 00:00:00 2001 From: Aleksey Rostovskiy Date: Wed, 30 Aug 2017 11:35:58 +0300 Subject: [PATCH 17/31] [gui-test] Fix closeProject method; other improvements --- .../com/intellij/testGuiFramework/framework/GuiTestBase.java | 2 +- .../src/com/intellij/testGuiFramework/impl/GuiTestCase.kt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestBase.java b/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestBase.java index 7d334c5075f1..e140ed7c0b78 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestBase.java +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestBase.java @@ -77,7 +77,7 @@ import static org.junit.Assert.*; @RunWith(GuiTestLocalRunner.class) public abstract class GuiTestBase { - protected Robot myRobot; + public Robot myRobot; private final Logger LOG = Logger.getInstance(GuiTestBase.class); diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index f8e1f5d50734..0422a773f606 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -137,6 +137,7 @@ open class GuiTestCase : GuiTestBase() { @Throws(InvocationTargetException::class, InterruptedException::class) override fun tearDown() { + closeAllProjects() super.tearDown() } From 3f980ddf5d1a823738d436b89a8ec721232e94ae Mon Sep 17 00:00:00 2001 From: Aleksey Rostovskiy Date: Wed, 30 Aug 2017 11:58:30 +0300 Subject: [PATCH 18/31] [gui-test] Remove unnecessary code from GuiTestCase to ToolWindowUtils; other fixes --- .../src/com/intellij/testGuiFramework/impl/GuiTestCase.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index 0422a773f606..2c2e22d474b2 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -16,7 +16,6 @@ package com.intellij.testGuiFramework.impl import com.intellij.ide.GeneralSettings -import com.intellij.openapi.editor.impl.EditorComponentImpl import com.intellij.openapi.ui.ComponentWithBrowseButton import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil From bf87f414ec2b698459ca4b7fb915252427092c9c Mon Sep 17 00:00:00 2001 From: Aleksey Rostovskiy Date: Wed, 30 Aug 2017 14:55:23 +0300 Subject: [PATCH 19/31] [gui-test] Merge previous commits & fix related problems --- .../intellij/testGuiFramework/impl/GuiTestCase.kt | 9 +++++---- .../intellij/testGuiFramework/impl/GuiTestUtilKt.kt | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index 2c2e22d474b2..cb9d8dfbee85 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -16,6 +16,7 @@ package com.intellij.testGuiFramework.impl import com.intellij.ide.GeneralSettings +import com.intellij.openapi.editor.impl.EditorComponentImpl import com.intellij.openapi.ui.ComponentWithBrowseButton import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil @@ -713,10 +714,10 @@ open class GuiTestCase : GuiTestBase() { return "@${uiScaleVal}x" } - protected fun waitUntilFound(container: Container?, - componentClass: Class, - timeout: Long, - matcher: (ComponentType) -> Boolean): ComponentType { + fun waitUntilFound(container: Container?, + componentClass: Class, + timeout: Long, + matcher: (ComponentType) -> Boolean): ComponentType { return GuiTestUtil.waitUntilFound(myRobot, container, typeMatcher(componentClass) { matcher(it) }, timeout.toFestTimeout()) } diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestUtilKt.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestUtilKt.kt index e2a86dad5d28..818e741867cd 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestUtilKt.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestUtilKt.kt @@ -266,6 +266,19 @@ object GuiTestUtilKt { return result?.first } + fun ensureCreateHasDone(guiTestCase: GuiTestCase) { + try { + com.intellij.testGuiFramework.impl.GuiTestUtilKt.waitUntilGone(robot = guiTestCase.myRobot, + matcher = com.intellij.testGuiFramework.impl.GuiTestUtilKt.typeMatcher( + com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame::class.java) { it.isShowing }) + } + catch (timeoutError: WaitTimedOutError) { + with(guiTestCase) { + welcomeFrame { button("Create").clickWhenEnabled() } + } + } + } + } fun main(args: Array) { From 0f6f0c4d95a091364ca4b48035eca3eff2b56988 Mon Sep 17 00:00:00 2001 From: Aleksey Rostovskiy Date: Thu, 31 Aug 2017 12:57:28 +0300 Subject: [PATCH 20/31] [gui-test] fixes after review IDEA-CR-24181 --- .../testGuiFramework/impl/GuiTestCase.kt | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index cb9d8dfbee85..985be993d9ac 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -16,7 +16,6 @@ package com.intellij.testGuiFramework.impl import com.intellij.ide.GeneralSettings -import com.intellij.openapi.editor.impl.EditorComponentImpl import com.intellij.openapi.ui.ComponentWithBrowseButton import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil @@ -746,35 +745,4 @@ open class GuiTestCase : GuiTestBase() { return flagCheckFunction() } } - /** - *@timeout in seconds to wait for the text in run window - */ - fun waitForTextInRunWindow(text: String, windowId: String = "Run") { - ideFrame { - toolwindow(id = windowId) { - content { - pause("Wait for $text in run window") { isRunWindowContainsText(text) } - } - waitForBackgroundTasksToFinish() - } - } - } - - /** - * Is run window contains @text - */ - private fun CustomToolWindowFixture.ContentFixture.isRunWindowContainsText(text: String): Boolean { - val outputText = getRunWindowText() - if (outputText!!.contains(text)) { - return true - } - return false - } - - private fun CustomToolWindowFixture.ContentFixture.getRunWindowText(): String? { - val consoleEditor = waitUntilFound(getContent().component as Container, EditorComponentImpl::class.java, - 10) { it is EditorComponentImpl } - return GuiTestUtilKt.computeOnEdt { consoleEditor.editor.document.text } - } - } From c1fbd3e970377ea5bec0329ea49b7a9281bb8d59 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Fri, 1 Sep 2017 17:30:33 +0300 Subject: [PATCH 21/31] [jvm-lang] refactor CreateFieldFromUsage - use class w/ fields and methods instead of static methods with bunch of parameters and weird return types; - extract common functions to separate file for reusing; - add few new methods for working with PSI tree from Kotlin code. --- .../lang/java/request/createFieldFromUsage.kt | 213 +++++++----------- .../lang/java/request/createFromUsageUtils.kt | 95 ++++++++ .../src/com/intellij/psi/util/psiTreeUtil.kt | 18 +- 3 files changed, 188 insertions(+), 138 deletions(-) create mode 100644 java/java-impl/src/com/intellij/lang/java/request/createFromUsageUtils.kt diff --git a/java/java-impl/src/com/intellij/lang/java/request/createFieldFromUsage.kt b/java/java-impl/src/com/intellij/lang/java/request/createFieldFromUsage.kt index c4350b4d3338..334c75f341e7 100644 --- a/java/java-impl/src/com/intellij/lang/java/request/createFieldFromUsage.kt +++ b/java/java-impl/src/com/intellij/lang/java/request/createFieldFromUsage.kt @@ -25,121 +25,108 @@ import com.intellij.lang.jvm.JvmClassKind import com.intellij.lang.jvm.JvmModifier import com.intellij.lang.jvm.actions.CreateFieldRequest import com.intellij.lang.jvm.actions.EP_NAME -import com.intellij.openapi.project.Project import com.intellij.psi.* -import com.intellij.psi.codeStyle.CodeStyleSettingsManager -import com.intellij.psi.codeStyle.JavaCodeStyleSettings -import com.intellij.psi.util.PsiTreeUtil -import com.intellij.psi.util.PsiTreeUtil.getParentOfType import com.intellij.psi.util.PsiUtil.resolveClassInClassTypeOnly import com.intellij.psi.util.parentOfType -import com.intellij.psi.util.parentsOfType -import com.intellij.util.VisibilityUtil -import java.util.* -import kotlin.collections.LinkedHashSet fun generateActions(ref: PsiReferenceExpression): List { - ref.referenceName ?: return emptyList() + if (ref.referenceName == null) return emptyList() + val fieldRequests = CreateFieldRequests(ref).collectRequests() val extensions = EP_NAME.extensions - return generateRequests(ref).flatMap { (clazz, request) -> + return fieldRequests.flatMap { (clazz, request) -> extensions.flatMap { ext -> ext.createAddFieldActions(clazz, request) } } } -private fun generateRequests(ref: PsiReferenceExpression): List> { - val (instanceContext, staticContext) = collectTargets(ref) ?: return emptyList() +private class CreateFieldRequests(val myRef: PsiReferenceExpression) { - val instanceFieldRequests = instanceContext.filter { - it.classKind !in STATIC_ONLY - }.map { - it to generateRequest(ref, it, false) - } - val staticFieldRequests = staticContext.map { - it to generateRequest(ref, it, true) + private val requests = LinkedHashMap() + + fun collectRequests(): Map { + doCollectRequests() + return requests } - return instanceFieldRequests + staticFieldRequests + private fun doCollectRequests() { + val qualifier = myRef.qualifierExpression + + if (qualifier != null) { + val instanceClass = resolveClassInClassTypeOnly(qualifier.type) + if (instanceClass != null) { + processHierarchy(instanceClass) + } + else { + val staticClass = (qualifier as? PsiJavaCodeReferenceElement)?.resolve() as? PsiClass + if (staticClass != null) { + processClass(staticClass, true) + } + } + } + else { + val baseClass = extractBaseClassFromSwitchStatement() + if (baseClass != null) { + processHierarchy(baseClass) + } + else { + processOuterAndImported() + } + } + } + + private fun extractBaseClassFromSwitchStatement(): PsiClass? { + val parent = myRef.parent as? PsiSwitchLabelStatement ?: return null + val switchStatement = parent.parentOfType() ?: return null + return resolveClassInClassTypeOnly(switchStatement.expression?.type) + } + + private fun processHierarchy(baseClass: PsiClass) { + for (clazz in hierarchy(baseClass)) { + processClass(clazz, false) + } + } + + private fun processOuterAndImported() { + val inStaticContext = myRef.isInStaticContext() + for (outerClass in collectOuterClasses(myRef)) { + processClass(outerClass, inStaticContext) + } + for (imported in collectOnDemandImported(myRef)) { + processClass(imported, true) + } + } + + private fun processClass(target: JvmClass, staticContext: Boolean) { + if (!staticContext && target.classKind in STATIC_ONLY) return + val modifiers = mutableSetOf() + + if (staticContext) { + modifiers += JvmModifier.STATIC + } + + if (shouldCreateFinalField(myRef, target)) { + modifiers += JvmModifier.FINAL + } + + val ownerClass = myRef.parentOfType() + val visibility = computeVisibility(myRef.project, ownerClass, target) + if (visibility != null) { + modifiers += visibility + } + + val request = CreateFieldFromJavaUsageRequest( + modifiers = modifiers, + reference = myRef, + useAnchor = target.toJavaClassOrNull() == ownerClass, + constant = false + ) + requests[target] = request + } } private val STATIC_ONLY = arrayOf(JvmClassKind.INTERFACE, JvmClassKind.ANNOTATION) -private fun generateRequest(ref: PsiReferenceExpression, target: JvmClass, static: Boolean): CreateFieldRequest { - val modifiers = mutableSetOf() - - if (static) { - modifiers += JvmModifier.STATIC - } - - if (shouldCreateFinalField(ref, target)) { - modifiers += JvmModifier.FINAL - } - - val ownerClass = getParentOfType(ref, PsiClass::class.java) - val visibility = computeVisibility(ref.project, ownerClass, target) - if (visibility != null) { - modifiers += visibility - } - - return CreateFieldFromJavaUsageRequest( - modifiers = modifiers, - reference = ref, - useAnchor = target.toJavaClassOrNull() == ownerClass, - constant = false - ) -} - -private typealias Couple = Pair - -private fun collectTargets(ref: PsiReferenceExpression): Couple>? { - var baseClass: PsiClass? = null - var inStaticContext = false - val qualifier: PsiExpression? = ref.qualifierExpression - - if (qualifier == null) { - val parent = ref.parent - if (parent is PsiSwitchLabelStatement) { - val switchStatement = getParentOfType(parent, PsiSwitchStatement::class.java) - if (switchStatement != null) { - baseClass = resolveClassInClassTypeOnly(switchStatement.expression?.type) - } - } - if (baseClass == null) { - return collectOuterAndImported(ref) - } - } - else { - baseClass = resolveClassInClassTypeOnly(qualifier.type) - if (baseClass == null) { - inStaticContext = true - baseClass = (qualifier as? PsiJavaCodeReferenceElement)?.resolve() as? PsiClass - } - } - baseClass ?: return null - if (inStaticContext) { - return Pair(emptyList(), listOf(baseClass)) - } - val hierarchy = hierarchy(baseClass).filter { it !is PsiTypeParameter } - return Pair(hierarchy, emptyList()) -} - -private fun collectOuterAndImported(place: PsiElement): Couple> { - val inStaticContext = place.parentOfType()?.hasModifierProperty(PsiModifier.STATIC) ?: false - val outerClasses = collectOuterClasses(place) - val importedClasses = collectOnDemandImported(place) - return if (inStaticContext) Pair(emptyList(), outerClasses + importedClasses) else Pair(outerClasses, importedClasses) -} - -private fun collectOuterClasses(place: PsiElement): List { - val result = mutableListOf() - for (clazz in place.parentsOfType()) { - result.add(clazz) - if (clazz.hasModifierProperty(PsiModifier.STATIC)) break - } - return result -} - /** * Given unresolved unqualified reference, * this reference could be resolved into static member if some class which has it's members imported. @@ -155,41 +142,7 @@ private fun collectOnDemandImported(place: PsiElement): List { return onDemandImports.mapNotNull { it.resolveTargetClass() } } -private fun hierarchy(clazz: PsiClass): Collection { - val result = LinkedHashSet() - val queue = LinkedList() - queue.add(clazz) - while (queue.isNotEmpty()) { - val current = queue.removeFirst() - if (result.add(current)) { - queue.addAll(current.supers) - } - } - return result -} - private fun shouldCreateFinalField(ref: PsiReferenceExpression, targetClass: JvmClass): Boolean { val javaClass = targetClass.toJavaClassOrNull() ?: return false return CreateFieldFromUsageFix.shouldCreateFinalMember(ref, javaClass) } - -private fun computeVisibility(project: Project, ownerClass: PsiClass?, targetClass: JvmClass): JvmModifier? { - if (targetClass.classKind == JvmClassKind.INTERFACE || targetClass.classKind == JvmClassKind.ANNOTATION) return JvmModifier.PUBLIC - if (ownerClass != null) { - targetClass.toJavaClassOrNull()?.let { javaClass -> - if (javaClass == ownerClass || PsiTreeUtil.isAncestor(javaClass, ownerClass, false)) { - return JvmModifier.PRIVATE - } - } - } - val setting = CodeStyleSettingsManager.getSettings(project).getCustomSettings(JavaCodeStyleSettings::class.java).VISIBILITY - if (setting == VisibilityUtil.ESCALATE_VISIBILITY) { - return null // TODO - } - else if (setting == PsiModifier.PACKAGE_LOCAL) { - return JvmModifier.PACKAGE_LOCAL - } - else { - return JvmModifier.valueOf(setting.toUpperCase()) - } -} diff --git a/java/java-impl/src/com/intellij/lang/java/request/createFromUsageUtils.kt b/java/java-impl/src/com/intellij/lang/java/request/createFromUsageUtils.kt new file mode 100644 index 000000000000..7c5ffaea2c7d --- /dev/null +++ b/java/java-impl/src/com/intellij/lang/java/request/createFromUsageUtils.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2017 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.lang.java.request + +import com.intellij.lang.java.actions.toJavaClassOrNull +import com.intellij.lang.jvm.JvmClass +import com.intellij.lang.jvm.JvmClassKind +import com.intellij.lang.jvm.JvmModifier +import com.intellij.openapi.project.Project +import com.intellij.psi.* +import com.intellij.psi.codeStyle.CodeStyleSettingsManager +import com.intellij.psi.codeStyle.JavaCodeStyleSettings +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.util.parentOfType +import com.intellij.psi.util.parents +import com.intellij.psi.util.parentsOfType +import com.intellij.util.VisibilityUtil +import java.util.* +import kotlin.collections.ArrayList + +internal fun PsiExpression.isInStaticContext(): Boolean { + return isWithinStaticMember() || isWithinConstructorCall() +} + +internal fun PsiExpression.isWithinStaticMember(): Boolean { + return parentOfType()?.hasModifierProperty(PsiModifier.STATIC) ?: false +} + +//usages inside delegating constructor call +internal fun PsiExpression.isWithinConstructorCall(): Boolean { + val owner = parentOfType() as? PsiMethod ?: return false + if (!owner.isConstructor) return false + + val parent = parents().firstOrNull { it !is PsiExpression } as? PsiExpressionList ?: return false + val grandParent = parent.parent as? PsiMethodCallExpression ?: return false + + val calleText = grandParent.methodExpression.text + return calleText == PsiKeyword.SUPER || calleText == PsiKeyword.THIS +} + +internal fun computeVisibility(project: Project, ownerClass: PsiClass?, targetClass: JvmClass): JvmModifier? { + if (targetClass.classKind == JvmClassKind.INTERFACE || targetClass.classKind == JvmClassKind.ANNOTATION) return JvmModifier.PUBLIC + if (ownerClass != null) { + targetClass.toJavaClassOrNull()?.let { javaClass -> + if (javaClass == ownerClass || PsiTreeUtil.isAncestor(javaClass, ownerClass, false)) { + return JvmModifier.PRIVATE + } + } + } + val setting = CodeStyleSettingsManager.getSettings(project).getCustomSettings(JavaCodeStyleSettings::class.java).VISIBILITY + if (setting == VisibilityUtil.ESCALATE_VISIBILITY) { + return null // TODO + } + else if (setting == PsiModifier.PACKAGE_LOCAL) { + return JvmModifier.PACKAGE_LOCAL + } + else { + return JvmModifier.valueOf(setting.toUpperCase()) + } +} + +internal fun collectOuterClasses(place: PsiElement): List { + val result = ArrayList() + for (clazz in place.parentsOfType()) { + result.add(clazz) + if (clazz.hasModifierProperty(PsiModifier.STATIC)) break + } + return result +} + +internal fun hierarchy(clazz: PsiClass): List { // TODO implementation based on JvmClasses + val result = LinkedHashSet() + val queue = LinkedList() + queue.add(clazz) + while (queue.isNotEmpty()) { + val current = queue.removeFirst() + if (result.add(current)) { + queue.addAll(current.supers) + } + } + return result.filter { it !is PsiTypeParameter } +} diff --git a/java/java-impl/src/com/intellij/psi/util/psiTreeUtil.kt b/java/java-impl/src/com/intellij/psi/util/psiTreeUtil.kt index a9221c950e37..e7021d3a5f0f 100644 --- a/java/java-impl/src/com/intellij/psi/util/psiTreeUtil.kt +++ b/java/java-impl/src/com/intellij/psi/util/psiTreeUtil.kt @@ -16,15 +16,17 @@ package com.intellij.psi.util import com.intellij.psi.PsiElement +import kotlin.reflect.KClass -inline fun PsiElement.parentOfType(): T? { - return PsiTreeUtil.getParentOfType(this, T::class.java) +inline fun PsiElement.parentOfType(): T? = parentOfType(T::class) + +fun PsiElement.parentOfType(vararg classes: KClass): T? { + return PsiTreeUtil.getParentOfType(this, *classes.map { it.java }.toTypedArray()) } -inline fun PsiElement?.parentsOfType(): Sequence { - return parentsOfType(T::class.java) -} -fun PsiElement?.parentsOfType(clazz: Class): Sequence { - return generateSequence(this) { it.parent }.filterIsInstance(clazz) -} +inline fun PsiElement.parentsOfType(): Sequence = parentsOfType(T::class.java) + +fun PsiElement.parentsOfType(clazz: Class): Sequence = parents().filterIsInstance(clazz) + +fun PsiElement.parents(): Sequence = generateSequence(this) { it.parent } From 0f1e83ae135f2d075a25279a8c02d96f37f175d2 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Fri, 1 Sep 2017 18:32:21 +0300 Subject: [PATCH 22/31] add logging for deleted files --- .../jetbrains/intellij/build/impl/CompilationContextImpl.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy index c02dfb7031e6..9a445ad2401a 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy @@ -211,6 +211,7 @@ class CompilationContextImpl implements CompilationContext { messages.info("Skipped cleaning for $file.absolutePath") } else { + messages.info("Deleting $file.absolutePath") FileUtil.delete(file) } } From 1be9c4122650a7dcc7d1cd609533da2c8096372d Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Fri, 1 Sep 2017 14:20:34 +0200 Subject: [PATCH 23/31] IDEA-172716: Docker - Add "Build" action into ">>" for Dockerfiles - step 1: allow "build only" run configurations --- .../remoteServer/impl/runtime/ServerTaskExecutorImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java index 986ed1c2fa10..6a6e8f3a5cbb 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java @@ -53,7 +53,8 @@ public class ServerTaskExecutorImpl implements ServerTaskExecutor { } catch (Throwable e) { LOG.info(e); - callback.errorOccurred(e.getMessage()); + String message = e.getMessage(); + callback.errorOccurred(message != null ? message : e.getClass().getName()); } }); } From d2928aaac74e9147f06555478476f8eb029aaeea Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 1 Sep 2017 18:34:11 +0300 Subject: [PATCH 24/31] fix npe --- .../src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java index 6320751eee49..08713d4e5c15 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java @@ -35,6 +35,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.xml.*; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; import com.intellij.xml.XmlAttributeDescriptor; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.util.XmlUtil; @@ -311,7 +312,7 @@ public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute, Hi public PsiElement setName(@NotNull final String nameText) throws IncorrectOperationException { final ASTNode name = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(this); final String oldName = name.getText(); - final String oldValue = getValue(); + final String oldValue = ObjectUtils.notNull(getValue(), ""); final PomModel model = PomManager.getModel(getProject()); final XmlAttribute attribute = XmlElementFactory.getInstance(getProject()).createAttribute(nameText, oldValue, this); final ASTNode newName = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild((ASTNode)attribute); From 6cf15cb3501840fb334f8c1373e742d1fbabc438 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 1 Sep 2017 15:52:18 +0200 Subject: [PATCH 25/31] add assertPointersAreDisposed --- .../testFramework/src/com/intellij/testFramework/FixtureRule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt b/platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt index d5412608c8d9..e2f4581ec6e9 100644 --- a/platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt +++ b/platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt @@ -30,7 +30,6 @@ import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.project.ex.ProjectEx import com.intellij.openapi.project.ex.ProjectManagerEx import com.intellij.openapi.project.impl.ProjectManagerImpl -import com.intellij.openapi.util.Disposer import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS @@ -101,6 +100,7 @@ class ProjectRule(val projectDescriptor: LightProjectDescriptor = LightProjectDe sharedProject = null sharedModule = null (ProjectManager.getInstance() as ProjectManagerImpl).forceCloseProject(project, true) + (VirtualFilePointerManager.getInstance() as VirtualFilePointerManagerImpl).assertPointersAreDisposed() } } From abe0e4facc2ff8b0693eca7e6a27f9040216fdd8 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 1 Sep 2017 17:53:04 +0200 Subject: [PATCH 26/31] deprecate BeforeRunTask.write/readExternal --- .../lang-api/src/com/intellij/execution/BeforeRunTask.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java b/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java index 634f29e00c6b..517741ed5483 100644 --- a/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java +++ b/platform/lang-api/src/com/intellij/execution/BeforeRunTask.java @@ -50,6 +50,9 @@ public abstract class BeforeRunTask implements Cloneabl myIsEnabled = isEnabled; } + /** + * @deprecated Use PersistentStateComponent (see LaunchBrowserBeforeRunTask for example). + */ public void writeExternal(@NotNull Element element) { if (this instanceof PersistentStateComponent) { ((PersistentStateComponent)this).getState(); @@ -59,6 +62,9 @@ public abstract class BeforeRunTask implements Cloneabl } } + /** + * @deprecated Use PersistentStateComponent (see LaunchBrowserBeforeRunTask for example). + */ public void readExternal(@NotNull Element element) { String attribValue = element.getAttributeValue("enabled"); if (attribValue == null) { From 3a2a54275f7068241f67ba405aaf3756e9a2a030 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Fri, 1 Sep 2017 18:55:23 +0300 Subject: [PATCH 27/31] properties: cache default base name (IDEA-178385) --- .../lang/properties/PropertiesUtil.java | 57 ++++++++++++------- .../properties/ResourceBundleManager.java | 14 ++--- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java index a6c67972057b..ef71c12dccc4 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -23,6 +23,9 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; import com.intellij.reference.SoftLazyValue; import com.intellij.util.Function; import com.intellij.util.SmartList; @@ -98,32 +101,42 @@ public class PropertiesUtil { } @NotNull - static String getDefaultBaseName(@NotNull final VirtualFile file) { - final String name = file.getName(); + static String getDefaultBaseName(@NotNull final PsiFile file) { + return CachedValuesManager.getCachedValue(file, new CachedValueProvider() { + @NotNull + @Override + public Result compute() { + return Result.create(computeBaseName(), file); + } - if (!StringUtil.containsChar(name, '_')) { - return FileUtil.getNameWithoutExtension(name); - } + private String computeBaseName() { + final String name = file.getName(); - final Matcher matcher = LOCALE_PATTERN.matcher(name); - final String baseNameWithExtension; - - int matchIndex = 0; - while (matcher.find(matchIndex)) { - final MatchResult matchResult = matcher.toMatchResult(); - final String[] splitted = matchResult.group(1).split("_"); - if (splitted.length > 1) { - final String langCode = splitted[1]; - if (!LOCALES_LANGUAGE_CODES.getValue().contains(langCode)) { - matchIndex = matchResult.start(1) + 1; - continue; + if (!StringUtil.containsChar(name, '_')) { + return FileUtil.getNameWithoutExtension(name); } - baseNameWithExtension = name.substring(0, matchResult.start(1)) + name.substring(matchResult.end(1)); + + final Matcher matcher = LOCALE_PATTERN.matcher(name); + final String baseNameWithExtension; + + int matchIndex = 0; + while (matcher.find(matchIndex)) { + final MatchResult matchResult = matcher.toMatchResult(); + final String[] splitted = matchResult.group(1).split("_"); + if (splitted.length > 1) { + final String langCode = splitted[1]; + if (!LOCALES_LANGUAGE_CODES.getValue().contains(langCode)) { + matchIndex = matchResult.start(1) + 1; + continue; + } + baseNameWithExtension = name.substring(0, matchResult.start(1)) + name.substring(matchResult.end(1)); + return FileUtil.getNameWithoutExtension(baseNameWithExtension); + } + } + baseNameWithExtension = name; return FileUtil.getNameWithoutExtension(baseNameWithExtension); } - } - baseNameWithExtension = name; - return FileUtil.getNameWithoutExtension(baseNameWithExtension); + }); } @NotNull diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java index 40b5fc240e40..50397814c48d 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -197,17 +197,13 @@ public class ResourceBundleManager implements PersistentStateComponent Date: Fri, 1 Sep 2017 18:10:13 +0200 Subject: [PATCH 28/31] IDEA-176040 IDE throws exception: Error while loading external changes:null. Project will be reloaded --- .../DefaultStateSerializer.kt | 2 +- .../xdebugger/impl/XDebuggerManagerImpl.java | 18 ++++++++++++------ .../breakpoints/XBreakpointManagerImpl.java | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/platform/projectModel-impl/src/com/intellij/configurationStore/DefaultStateSerializer.kt b/platform/projectModel-impl/src/com/intellij/configurationStore/DefaultStateSerializer.kt index e079a67292d1..a3f6dde6e3a1 100644 --- a/platform/projectModel-impl/src/com/intellij/configurationStore/DefaultStateSerializer.kt +++ b/platform/projectModel-impl/src/com/intellij/configurationStore/DefaultStateSerializer.kt @@ -30,7 +30,7 @@ fun deserializeState(stateElement: Element?, stateClass: Class, mergeInto stateClass == Element::class.java -> stateElement as T? JDOMExternalizable::class.java.isAssignableFrom(stateClass) -> { if (mergeInto != null) { - LOG.error("State is ${stateClass.name}, merge into is ${mergeInto.toString()}, state element text is ${JDOMUtil.writeElement(stateElement)}") + LOG.error("State is ${stateClass.name}, merge into is $mergeInto, state element text is ${JDOMUtil.writeElement(stateElement)}") } val t = ReflectionUtil.newInstance(stateClass) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java index f7f8f527be6e..18dc8626aa73 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java @@ -335,9 +335,11 @@ public class XDebuggerManagerImpl extends XDebuggerManager } @Override - public void loadState(final XDebuggerState state) { - myBreakpointManager.loadState(state.myBreakpointManagerState); - myWatchesManager.loadState(state.myWatchesManagerState); + public void loadState(@NotNull XDebuggerState state) { + XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState = state.myBreakpointManagerState; + myBreakpointManager.loadState(breakpointManagerState == null ? new XBreakpointManagerImpl.BreakpointManagerState() : breakpointManagerState); + XDebuggerWatchesManager.WatchesManagerState managerState = state.myWatchesManagerState; + myWatchesManager.loadState(managerState == null ? new XDebuggerWatchesManager.WatchesManagerState() : managerState); } public void showExecutionPosition() { @@ -346,32 +348,36 @@ public class XDebuggerManagerImpl extends XDebuggerManager @SuppressWarnings("UnusedDeclaration") public static class XDebuggerState { + @Nullable private XBreakpointManagerImpl.BreakpointManagerState myBreakpointManagerState; + @Nullable private XDebuggerWatchesManager.WatchesManagerState myWatchesManagerState; public XDebuggerState() { } - public XDebuggerState(final XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState, XDebuggerWatchesManager.WatchesManagerState watchesManagerState) { + public XDebuggerState(@Nullable XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState, @Nullable XDebuggerWatchesManager.WatchesManagerState watchesManagerState) { myBreakpointManagerState = breakpointManagerState; myWatchesManagerState = watchesManagerState; } + @Nullable @Property(surroundWithTag = false) public XBreakpointManagerImpl.BreakpointManagerState getBreakpointManagerState() { return myBreakpointManagerState; } - public void setBreakpointManagerState(final XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState) { + public void setBreakpointManagerState(@Nullable final XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState) { myBreakpointManagerState = breakpointManagerState; } + @Nullable @Property(surroundWithTag = false) public XDebuggerWatchesManager.WatchesManagerState getWatchesManagerState() { return myWatchesManagerState; } - public void setWatchesManagerState(XDebuggerWatchesManager.WatchesManagerState watchesManagerState) { + public void setWatchesManagerState(@Nullable XDebuggerWatchesManager.WatchesManagerState watchesManagerState) { myWatchesManagerState = watchesManagerState; } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java index 2b0e172c3872..699f5b284f83 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java @@ -387,7 +387,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta } @Override - public void loadState(final BreakpointManagerState state) { + public void loadState(@NotNull BreakpointManagerState state) { myBreakpointsDialogSettings = state.getBreakpointsDialogProperties(); myAllBreakpoints.clear(); From d8178958246c5e4ff201066875fc23d72c88336d Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 1 Sep 2017 19:11:50 +0300 Subject: [PATCH 29/31] use replaced attribute --- .../codeInsight/template/emmet/nodes/GenerationNode.java | 2 +- .../com/intellij/psi/impl/source/xml/XmlAttributeImpl.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java index 5252a5226062..a1278ac8fae4 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java @@ -449,7 +449,7 @@ public class GenerationNode extends UserDataHolderBase { String attributeName = defaultAttribute.getName(); if (attributeName.length() > 1) { if (isImpliedAttribute(attributeName)) { - defaultAttribute.setName(attributeName.substring(1)); + defaultAttribute = (XmlAttribute)defaultAttribute.setName(attributeName.substring(1)); } final String oldValue = defaultAttribute.getValue(); if (oldValue != null && StringUtil.containsChar(oldValue, '|')) { diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java index 08713d4e5c15..8250d28b288d 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlAttributeImpl.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.xml; import com.intellij.lang.ASTNode; import com.intellij.lang.html.HTMLLanguage; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.pom.PomManager; import com.intellij.pom.PomModel; @@ -317,6 +318,7 @@ public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute, Hi final XmlAttribute attribute = XmlElementFactory.getInstance(getProject()).createAttribute(nameText, oldValue, this); final ASTNode newName = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild((ASTNode)attribute); final XmlAspect aspect = model.getModelAspect(XmlAspect.class); + final Ref replaced = Ref.create(this); model.runTransaction(new PomTransactionBase(getParent(), aspect) { @Override public PomModelEvent runInner() { @@ -328,6 +330,7 @@ public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute, Hi event.registerChangeSet(model.getModelAspect(XmlAspect.class), xmlAspectChangeSet); if (!oldValue.isEmpty() && getLanguage().isKindOf(HTMLLanguage.INSTANCE)) { CodeEditUtil.replaceChild(getTreeParent(), XmlAttributeImpl.this, attribute.getNode()); + replaced.set(attribute); } else { CodeEditUtil.replaceChild(XmlAttributeImpl.this, name, newName); @@ -335,7 +338,7 @@ public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute, Hi return event; } }); - return this; + return replaced.get(); } @Override From fc65d05fd19a25166d9c4710a7f50732eec47ec9 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Fri, 1 Sep 2017 19:14:32 +0300 Subject: [PATCH 30/31] add info about incremental compilation --- .../jetbrains/intellij/build/impl/CompilationContextImpl.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy index 9a445ad2401a..a201cc319c51 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy @@ -165,6 +165,7 @@ class CompilationContextImpl implements CompilationContext { unpackCompiledClasses(messages, ant, classesOutput, options) outputDirectoriesToKeep.add(classesDirName) } + messages.info("Incremental compilation: " + options.incrementalCompilation) if (options.incrementalCompilation) { outputDirectoriesToKeep.add(dataDirName) outputDirectoriesToKeep.add(classesDirName) From d91635bdc86d1c551697c2265215d5b2d5136fd7 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Fri, 1 Sep 2017 19:35:02 +0300 Subject: [PATCH 31/31] inspections: introduce empty tool wrapper array --- .../com/intellij/codeInspection/ex/InspectionToolWrapper.java | 2 ++ .../intellij/codeInspection/actions/GotoInspectionModel.java | 3 +-- .../src/com/intellij/mock/MockInspectionProfile.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/analysis-api/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java b/platform/analysis-api/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java index 46bd56e55668..fc65b991cdc1 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java @@ -37,6 +37,8 @@ import java.net.URL; * Date: 9/28/11 */ public abstract class InspectionToolWrapper { + public static final InspectionToolWrapper[] EMPTY_ARRAY = new InspectionToolWrapper[0]; + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionToolWrapper"); protected T myTool; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java index e02c51a9a7a4..8c6f7de850ab 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/GotoInspectionModel.java @@ -35,7 +35,6 @@ import java.util.Map; * @author Konstantin Bulenkov */ public class GotoInspectionModel extends SimpleChooseByNameModel { - private static final InspectionToolWrapper[] EMPTY_WRAPPERS_ARRAY = new InspectionToolWrapper[0]; private final Map myToolNames = new HashMap<>(); private final String[] myNames; private final InspectionListCellRenderer myListCellRenderer = new InspectionListCellRenderer(); @@ -69,7 +68,7 @@ public class GotoInspectionModel extends SimpleChooseByNameModel { public Object[] getElementsByName(final String name, final String pattern) { final InspectionToolWrapper tool = myToolNames.get(name); if (tool == null) { - return EMPTY_WRAPPERS_ARRAY; + return InspectionToolWrapper.EMPTY_ARRAY; } return new InspectionToolWrapper[] {tool}; } diff --git a/platform/testFramework/src/com/intellij/mock/MockInspectionProfile.java b/platform/testFramework/src/com/intellij/mock/MockInspectionProfile.java index 1b5753f3acf0..fbbe38ef0fb1 100644 --- a/platform/testFramework/src/com/intellij/mock/MockInspectionProfile.java +++ b/platform/testFramework/src/com/intellij/mock/MockInspectionProfile.java @@ -29,7 +29,7 @@ import java.util.Set; * @author peter */ public class MockInspectionProfile extends InspectionProfileImpl { - private InspectionToolWrapper[] myInspectionTools = new InspectionToolWrapper[0]; + private InspectionToolWrapper[] myInspectionTools = InspectionToolWrapper.EMPTY_ARRAY; private final Set myDisabledTools = new THashSet<>(); public MockInspectionProfile() {