From bae95d81f4d517e21cc9f5d15fe0aed4924172e5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Jul 2016 10:53:34 +0200 Subject: [PATCH 01/41] [platform] update compatibility info in the dialog (IDEA-CR-12398) --- .../updateSettings/impl/UpdateInfoDialog.java | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java index a33d4277f0f9..d7c886513f00 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java @@ -25,6 +25,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.BrowserHyperlinkListener; import com.intellij.ui.JBColor; @@ -45,6 +46,8 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import static com.intellij.openapi.util.Pair.pair; + /** * @author pti */ @@ -55,9 +58,7 @@ class UpdateInfoDialog extends AbstractUpdateDialog { private final BuildInfo myNewBuild; private final PatchInfo myPatch; private final boolean myWriteProtected; - - private String myLicenseInfo = null; - private Color myLicenseInfoColor = null; + private final Pair myLicenseInfo; UpdateInfoDialog(@NotNull UpdateChannel channel, @NotNull BuildInfo newBuild, @@ -74,7 +75,7 @@ class UpdateInfoDialog extends AbstractUpdateDialog { myPatch = patch; myWriteProtected = myPatch != null && !new File(PathManager.getHomePath()).canWrite(); getCancelAction().putValue(DEFAULT_ACTION, Boolean.TRUE); - initLicensingInfo(myUpdatedChannel, myNewBuild); + myLicenseInfo = initLicensingInfo(myUpdatedChannel, myNewBuild); init(); if (incompatiblePlugins != null && !incompatiblePlugins.isEmpty()) { @@ -83,33 +84,32 @@ class UpdateInfoDialog extends AbstractUpdateDialog { } } - private void initLicensingInfo(@NotNull UpdateChannel channel, @NotNull BuildInfo build) { + private static Pair initLicensingInfo(UpdateChannel channel, BuildInfo build) { LicensingFacade facade = LicensingFacade.getInstance(); - if (facade != null) { - if (channel.getLicensing().equals(UpdateChannel.LICENSING_EAP)) { - myLicenseInfo = IdeBundle.message("updates.channel.bundled.key"); - } - else { - Date buildDate = build.getReleaseDate(); - if (buildDate != null) { - Boolean applicable = facade.isApplicableForProduct(buildDate); - if (applicable != null) { - if (applicable == Boolean.FALSE) { - myLicenseInfo = IdeBundle.message("updates.paid.upgrade", channel.getEvalDays()); - myLicenseInfoColor = JBColor.RED; - } - else if (facade.isPerpetualForProduct(buildDate) == Boolean.TRUE) { - myLicenseInfo = IdeBundle.message("updates.fallback.build"); - } - else { - Date expiration = facade.getLicenseExpirationDate(); - if (expiration != null) { - myLicenseInfo = IdeBundle.message("updates.interim.build", DateFormatUtil.formatAboutDialogDate(expiration)); - } - } - } - } - } + if (facade == null) return null; + + if (channel.getLicensing().equals(UpdateChannel.LICENSING_EAP)) { + return pair(IdeBundle.message("updates.channel.bundled.key"), null); + } + + Date releaseDate = build.getReleaseDate(); + Boolean applicable = releaseDate == null ? null : facade.isApplicableForProduct(releaseDate); + if (applicable == null) { + return null; + } + if (applicable == Boolean.FALSE) { + return pair(IdeBundle.message("updates.paid.upgrade", channel.getEvalDays()), JBColor.RED); + } + if (facade.isPerpetualForProduct(releaseDate) == Boolean.TRUE) { + return pair(IdeBundle.message("updates.fallback.build"), null); + } + + Date expiration = facade.getLicenseExpirationDate(); + if (expiration != null) { + return pair(IdeBundle.message("updates.interim.build", DateFormatUtil.formatAboutDialogDate(expiration)), null); + } + else { + return null; } } @@ -269,7 +269,7 @@ class UpdateInfoDialog extends AbstractUpdateDialog { } if (myLicenseInfo != null) { - configureMessageArea(myLicenseArea, myLicenseInfo, myLicenseInfoColor, null); + configureMessageArea(myLicenseArea, myLicenseInfo.first, myLicenseInfo.second, null); } } } From 4658bd7bcd9034c47d4e2d0554d0831d9243c589 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 21 Jul 2016 12:09:48 +0300 Subject: [PATCH 02/41] IDEA-54188 add a configuration option to preselect/automate disconnection and process termination on termination of a debugging session - better settings name --- .../src/com/intellij/ide/GeneralSettingsPanel.form | 2 +- .../platform-resources-en/src/messages/IdeBundle.properties | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form index 8e590d041972..ff3aeb175b05 100644 --- a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form +++ b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form @@ -224,7 +224,7 @@ - + diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index c8cd453903a9..92e9c6bfc1ae 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -38,6 +38,7 @@ checkbox.save.files.on.frame.deactivation=Save files on frame deactivation checkbox.synchronize.files.on.frame.activation=Synchronize files on frame or editor tab activation checkbox.reopen.last.project.on.startup=Reopen last project on startup checkbox.support.screen.readers=Support screen readers (requires restart) +group.settings.process.tab.close=On Closing Tool Window with Running Process radio.process.close.terminate=Terminate process radio.process.close.disaconnect=Disconnect (if available) radio.process.close.ask=Ask From 6419ec128789af44775adc84e055f9426b2d4f50 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Jul 2016 11:19:49 +0200 Subject: [PATCH 03/41] [platform] more accurate fix for missing scratch extensions issue (IDEA-126952) --- .../refactoring/copy/CopyFilesOrDirectoriesDialog.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java index ba412e965c8e..b59abcec95e0 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java @@ -15,6 +15,7 @@ */ package com.intellij.refactoring.copy; +import com.intellij.ide.scratch.ScratchUtil; import com.intellij.ide.util.DirectoryUtil; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.ActionManager; @@ -23,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.ex.FileTypeChooser; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.keymap.KeymapUtil; @@ -43,6 +45,7 @@ import com.intellij.ui.TextFieldWithHistoryWithBrowseButton; import com.intellij.ui.components.JBLabelDecorator; import com.intellij.ui.components.JBTextField; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; import com.intellij.util.PathUtil; import com.intellij.util.PathUtilRt; import com.intellij.util.ui.FormBuilder; @@ -111,6 +114,10 @@ public class CopyFilesOrDirectoriesDialog extends DialogWrapper { VirtualFile vFile = file.getVirtualFile(); text = RefactoringBundle.message(doClone ? "copy.files.clone.file.0" : "copy.files.copy.file.0", shortenPath(vFile)); String fileName = vFile.isInLocalFileSystem() ? vFile.getName() : PathUtil.suggestFileName(file.getName(), true, true); + if (ScratchUtil.isScratch(vFile) && StringUtil.isEmpty(vFile.getExtension())) { + FileType type = ObjectUtils.notNull(file.getLanguage().getAssociatedFileType(), file.getFileType()); + fileName = PathUtil.makeFileName(fileName, type.getDefaultExtension()); + } myNewNameField.setText(fileName); int dotIdx = fileName.lastIndexOf('.'); if (dotIdx > 0) { From 76d5d28cf14c9385fe6f95bb002e3c0911b9fe3c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Jul 2016 11:20:53 +0200 Subject: [PATCH 04/41] Cleanup (minor optimization) --- .../intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java index b59abcec95e0..4eae11fa4f8b 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java @@ -114,7 +114,7 @@ public class CopyFilesOrDirectoriesDialog extends DialogWrapper { VirtualFile vFile = file.getVirtualFile(); text = RefactoringBundle.message(doClone ? "copy.files.clone.file.0" : "copy.files.copy.file.0", shortenPath(vFile)); String fileName = vFile.isInLocalFileSystem() ? vFile.getName() : PathUtil.suggestFileName(file.getName(), true, true); - if (ScratchUtil.isScratch(vFile) && StringUtil.isEmpty(vFile.getExtension())) { + if (StringUtil.isEmpty(vFile.getExtension()) && ScratchUtil.isScratch(vFile)) { FileType type = ObjectUtils.notNull(file.getLanguage().getAssociatedFileType(), file.getFileType()); fileName = PathUtil.makeFileName(fileName, type.getDefaultExtension()); } From 5349118ee606f96acdfad294a4f6db3cf11387ac Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Jul 2016 15:37:56 +0300 Subject: [PATCH 05/41] project configuration: export library from 'terminal' plugin instead of using it directly from 'remote-run' plugin to ensure that library isn't packaged with 'remote-run' plugin by redesigned build scripts --- plugins/terminal/terminal.iml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/terminal/terminal.iml b/plugins/terminal/terminal.iml index b173ddc26343..875cb81a97bb 100644 --- a/plugins/terminal/terminal.iml +++ b/plugins/terminal/terminal.iml @@ -10,7 +10,7 @@ - + @@ -26,4 +26,4 @@ - \ No newline at end of file + From e86f01155d7abd7ae4f01780a8f3e15f13d5b060 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Jul 2016 12:34:43 +0300 Subject: [PATCH 06/41] build scripts redesign, phase 2: scripts which produce the platform and plugins JAR files are rewritten; more customizations added --- .../build/ApplicationInfoProperties.groovy | 4 + .../intellij/build/BuildContext.groovy | 4 + .../intellij/build/BuildTasks.groovy | 5 + .../build/CommonProductModules.groovy | 179 ++++++++ .../build/IdeaCommunityProperties.groovy | 12 +- .../build/MacDistributionCustomizer.groovy | 9 +- .../build/ProductModulesLayout.groovy | 110 +++++ .../intellij/build/ProductProperties.groovy | 40 +- .../intellij/build/ScrambleTool.groovy | 5 + .../WindowsDistributionCustomizer.groovy | 10 + .../build/impl/BuildContextImpl.groovy | 16 +- .../intellij/build/impl/BuildTasksImpl.groovy | 53 ++- .../build/impl/DistributionJARsBuilder.groovy | 401 ++++++++++++++++++ .../intellij/build/impl/LayoutBuilder.groovy | 221 ++++++++++ .../impl/LinuxDistributionBuilder.groovy | 24 +- .../build/impl/MacDistributionBuilder.groovy | 14 +- .../intellij/build/impl/PluginLayout.groovy | 200 +++++++++ .../build/impl/WinExeInstallerBuilder.groovy | 9 +- .../impl/WindowsDistributionBuilder.groovy | 33 +- 19 files changed, 1306 insertions(+), 43 deletions(-) create mode 100644 build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy create mode 100644 build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy create mode 100644 build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy create mode 100644 build/groovy/org/jetbrains/intellij/build/impl/LayoutBuilder.groovy create mode 100644 build/groovy/org/jetbrains/intellij/build/impl/PluginLayout.groovy diff --git a/build/groovy/org/jetbrains/intellij/build/ApplicationInfoProperties.groovy b/build/groovy/org/jetbrains/intellij/build/ApplicationInfoProperties.groovy index ed1055dc6897..cb305c8a5eb0 100644 --- a/build/groovy/org/jetbrains/intellij/build/ApplicationInfoProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ApplicationInfoProperties.groovy @@ -15,6 +15,8 @@ */ package org.jetbrains.intellij.build +import com.intellij.openapi.util.text.StringUtil + import java.text.MessageFormat /** @@ -30,6 +32,7 @@ class ApplicationInfoProperties { final String minorVersionMainPart final String productName final String companyName + final String shortCompanyName final boolean isEAP @SuppressWarnings(["GrUnresolvedAccess", "GroovyAssignabilityCheck"]) @@ -45,6 +48,7 @@ class ApplicationInfoProperties { companyName = root.company.first().@name minorVersionMainPart = minorVersion.takeWhile { it != '.' } isEAP = Boolean.parseBoolean(root.version.first().@eap) + shortCompanyName = StringUtil.trimEnd(companyName, "s.r.o.").trim() } public String getUpperCaseProductName() { shortProductName.toUpperCase() } diff --git a/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy b/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy index 50fdfa225ddd..5a04b403a0a3 100644 --- a/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy +++ b/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy @@ -64,12 +64,16 @@ abstract class BuildContext { */ List bootClassPathJarNames + abstract boolean includeBreakGenLibraries() + abstract void notifyArtifactBuilt(String artifactPath) abstract File findApplicationInfoInSources() abstract JpsModule findApplicationInfoModule() + abstract JpsModule findRequiredModule(String name) + abstract JpsModule findModule(String name) abstract void signExeFile(String path) diff --git a/build/groovy/org/jetbrains/intellij/build/BuildTasks.groovy b/build/groovy/org/jetbrains/intellij/build/BuildTasks.groovy index 1882bc0a20c2..ca8510415a64 100644 --- a/build/groovy/org/jetbrains/intellij/build/BuildTasks.groovy +++ b/build/groovy/org/jetbrains/intellij/build/BuildTasks.groovy @@ -16,6 +16,7 @@ package org.jetbrains.intellij.build import org.jetbrains.intellij.build.impl.BuildTasksImpl +import org.jetbrains.intellij.build.impl.PluginLayout /** * @author nik @@ -53,10 +54,14 @@ abstract class BuildTasks { */ abstract void buildDistributions() + abstract void compileModulesAndBuildDistributions(List allPlugins) + abstract void cleanOutput() abstract void compileProjectAndTests(List includingTestsInModules) + abstract void compileModules(List moduleNames, List includingTestsInModules = []) + public static BuildTasks create(BuildContext context) { return new BuildTasksImpl(context) } diff --git a/build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy b/build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy new file mode 100644 index 000000000000..da7596d7922d --- /dev/null +++ b/build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy @@ -0,0 +1,179 @@ +/* + * Copyright 2000-2016 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. + */ +/* + * Copyright 2000-2016 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 org.jetbrains.intellij.build + +import org.jetbrains.intellij.build.impl.PluginLayout + +import static org.jetbrains.intellij.build.impl.PluginLayout.plugin + +/** + * @author nik + */ +class CommonProductModules { + static List PLATFORM_API_MODULES = [ + "analysis-api", + "built-in-server-api", + "core-api", + "diff-api", + "dvcs-api", + "editor-ui-api", + "external-system-api", + "indexing-api", + "jps-model-api", + "lang-api", + "lvcs-api", + "platform-api", + "projectModel-api", + "remote-servers-agent-rt", + "remote-servers-api", + "usageView", + "vcs-api-core", + "vcs-api", + "vcs-log-api", + "vcs-log-graph-api", + "xdebugger-api", + "xml-analysis-api", + "xml-openapi", + "xml-psi-api", + "xml-structure-view-api" + ] + + static List PLATFORM_IMPLEMENTATION_MODULES = [ + "analysis-impl", + "built-in-server", + "core-impl", + "diff-impl", + "dvcs-impl", + "editor-ui-ex", + "images", + "indexing-impl", + "jps-model-impl", + "jps-model-serialization", + "json", + "lang-impl", + "lvcs-impl", + "platform-impl", + "projectModel-impl", + "protocol-reader-runtime", + "RegExpSupport", + "relaxng", + "remote-servers-impl", + "script-debugger-backend", + "script-debugger-ui", + "smRunner", + "spellchecker", + "structure-view-impl", + "testRunner", + "vcs-impl", + "vcs-log-graph", + "vcs-log-impl", + "xdebugger-impl", + "xml-analysis-impl", + "xml-psi-impl", + "xml-structure-view-impl", + "xml", + "configuration-store-impl", + ] + + /** + * Specifies layout for all plugins which sources are located in 'community' and 'contrib' repositories + */ + static List COMMUNITY_REPOSITORY_PLUGINS = [ + plugin("copyright"), + plugin("java-i18n"), + plugin("hg4idea"), + plugin("github"), + plugin("ant") { + mainJarName = "antIntegration.jar" + withModule("ant-jps-plugin") + }, + plugin("ui-designer") { + directoryName = "uiDesigner" + mainJarName = "uiDesigner.jar" + withJpsModule("ui-designer-jps-plugin") + }, + plugin("properties") { + withModule("properties-psi-api", "properties.jar") + withModule("properties-psi-impl", "properties.jar") + }, + plugin("git4idea") { + withModule("git4idea-rt", "git4idea-rt.jar", false) + withOptionalModule("remote-servers-git") + withOptionalModule("remote-servers-git-java", "remote-servers-git.jar") + }, + plugin("svn4idea") { + withResource("lib/licenses", "lib/licenses") + withResource("lib/sqljetsrc.zip", "lib") + withResource("lib/svnkit-javahl16.zip", "lib") + withResource("lib/trileadsrc.zip", "lib") + }, + plugin("cvs-plugin") { + directoryName = "cvsIntegration" + mainJarName = "cvsIntegration.jar" + withModule("javacvs-src") + withModule("smartcvs-src") + withModule("cvs-core", "cvs_util.jar") + }, + plugin("xpath") { + withModule("xslt-rt", "rt/xslt-rt.jar") + }, + plugin("tasks-core") { + directoryName = "tasks" + withModule("tasks-api") + withModule("jira") + withOptionalModule("tasks-java") + doNotCreateSeperateJarForLocalizableResources() + }, + plugin("terminal") { + withResource("lib/jediterm.in", "lib") + }, + plugin("editorconfig"), + plugin("coverage"), + plugin("yaml"), + plugin("xslt-debugger") { + withModule("xslt-debugger-engine") + withModule("xslt-debugger-engine-impl", "rt/xslt-debugger-engine-impl.jar") + withModuleLibrary("Saxon-6.5.5", "xslt-debugger-engine-impl", "rt") + withModuleLibrary("Saxon-9HE", "xslt-debugger-engine-impl", "rt") + withModuleLibrary("Xalan-2.7.1", "xslt-debugger-engine-impl", "rt") + //todo[nik] unmark 'lib' directory as source root instead + excludeFromModule("xslt-debugger-engine-impl", "rmi-stubs.jar") + excludeFromModule("xslt-debugger-engine-impl", "saxon.jar") + excludeFromModule("xslt-debugger-engine-impl", "saxon9he.jar") + excludeFromModule("xslt-debugger-engine-impl", "serializer.jar") + excludeFromModule("xslt-debugger-engine-impl", "xalan.jar") + }, + plugin("settings-repository") + ] +} \ No newline at end of file diff --git a/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy b/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy index 080e899b92fc..6e15ed2290c1 100644 --- a/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy @@ -29,11 +29,6 @@ class IdeaCommunityProperties extends ProductProperties { buildCrossPlatformDistribution = true } - @Override - String fullNameIncludingEdition(ApplicationInfoProperties applicationInfo) { - "IntelliJ IDEA Community Edition" - } - @Override void copyAdditionalFiles(BuildContext buildContext, String targetDirectory) { buildContext.ant.copy(todir: targetDirectory) { @@ -57,6 +52,12 @@ class IdeaCommunityProperties extends ProductProperties { @Override String rootDirectoryName(String buildNumber) { "" } + @Override + String fullNameIncludingEdition(ApplicationInfoProperties applicationInfo) { "IntelliJ IDEA Community Edition" } + + @Override + String fullNameIncludingEditionAndVendor(ApplicationInfoProperties applicationInfo) { "IntelliJ IDEA Community Edition" } + @Override String uninstallFeedbackPageUrl(ApplicationInfoProperties applicationInfo) { "https://www.jetbrains.com/idea/uninstall/?edition=IC-${applicationInfo.majorVersion}.${applicationInfo.minorVersion}" @@ -82,6 +83,7 @@ class IdeaCommunityProperties extends ProductProperties { { helpId = "IJ" urlSchemes = ["idea"] + associateIpr = true enableYourkitAgentInEAP = false bundleIdentifier = "com.jetbrains.intellij.ce" dmgImagePath = "$projectHome/build/conf/mac/communitydmg.png" diff --git a/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy index fea25a526f62..72f13f6e7123 100644 --- a/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy @@ -29,10 +29,15 @@ abstract class MacDistributionCustomizer { */ String minOSXVersion = "10.8" String helpId = "" - String docTypes = null + String additionalDocTypes = "" List urlSchemes = [] List architectures = ["x86_64"] + /** + * If {@code true} *.ipr files will be associated with the product in Info.plist + */ + boolean associateIpr = false + /** * If {@code true} YourKit agent will be automatically attached when an EAP build of the product starts under Mac OS. This property is * taken into account only if {@link ProductProperties#enableYourkitAgentInEAP} is {@code true}. @@ -58,6 +63,8 @@ abstract class MacDistributionCustomizer { abstract String rootDirectoryName(ApplicationInfoProperties applicationInfo, String buildNumber) + Map customIdeaProperties(ApplicationInfoProperties applicationInfo) { [:] } + void copyAdditionalFiles(BuildContext context, String targetDirectory) { } } diff --git a/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy b/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy new file mode 100644 index 000000000000..900b21eb4bbf --- /dev/null +++ b/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy @@ -0,0 +1,110 @@ +/* + * Copyright 2000-2016 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. + */ +/* + * Copyright 2000-2016 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 org.jetbrains.intellij.build + +import org.jetbrains.intellij.build.impl.PluginLayout + +/** + * @author nik + */ +class ProductModulesLayout { + /** + * Name of the main product JAR file. Outputs of {@link #platformImplementationModules} will be packed into it. + */ + String mainJarName + + /** + * Names of the modules which need to be packed into openapi.jar in the product's 'lib' directory. + * @see CommonProductModules#PLATFORM_API_MODULES + */ + List platformApiModules = [] + + /** + * Names of the modules which need to be included into {@link #mainJarName} in the product's 'lib' directory + * @see CommonProductModules#PLATFORM_IMPLEMENTATION_MODULES + */ + List platformImplementationModules = [] + + /** + * Names of the main modules (containing META-INF/plugin.xml) of the plugins which need to be bundled with the product + */ + List bundledPluginModules = [] + + /** + * Names of the main modules (containing META-INF/plugin.xml) of the plugins which aren't bundled with the product but may be installed + * into it. Zip archives of these plugins will be built and placed under 'plugins' directory in the build artifacts. + */ + List pluginModulesToPublish = [] + + /** + * Paths to JAR files which contents should be extracted into {@link #mainJarName} JAR. + */ + List additionalJarsToUnpackIntoMainJar = [] + + /** + * Maps names of the modules to names of JARs; these modules will be packed into these JARs and copied to the product's 'lib' directory. + */ + Map additionalPlatformModules = [:] + + + /** + * Name of the module which classpath will be used to build searchable options index + */ + String mainModule + + /** + * Name of the module containing search/searchableOptions.xml file. + * //todo[nik] make this optional + */ + String searchableOptionsModule + + /** + * Paths to license files which are required to start IDE in headless mode to generate searchable options index + */ + List licenseFilesToBuildSearchableOptions = [] + + /** + * @param allPlugins descriptions of layout of all plugins which may be included into the product + * @return list of all modules which output is included into the product platform's JARs or the plugin's JARs + */ + List getIncludedModules(List allPlugins) { + Set enabledPluginModules = getEnabledPluginModules() + def allPluginModules = allPlugins.findAll { enabledPluginModules.contains(it.mainModule) }.collectMany { it.getActualModules(enabledPluginModules).values() } + ((allPluginModules + platformApiModules + platformImplementationModules + additionalPlatformModules.keySet()) as Set) as List + } + + Set getEnabledPluginModules() { + (bundledPluginModules + pluginModulesToPublish) as Set + } +} \ No newline at end of file diff --git a/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy b/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy index 0e282ab00355..d32f749a3be8 100644 --- a/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy @@ -39,6 +39,8 @@ public abstract class ProductProperties { */ String applicationInfoModule + String brandingModule + /** * Name of the sh/bat script (without extension) which will contain the commands to run IDE in 'offline inspections' mode */ @@ -54,17 +56,39 @@ public abstract class ProductProperties { */ String additionalIdeJvmArguments = "" - /** - * @return name of the product which will be shown in Windows Installer - */ - String fullNameIncludingEdition(ApplicationInfoProperties applicationInfo) { applicationInfo.productName } - /** * An identifier which will be used to form names for directories where configuration and caches will be stored, usually a product name * without spaces with added version ('IntelliJIdea2016.1' for IntelliJ IDEA 2016.1) */ abstract String systemSelector(ApplicationInfoProperties applicationInfo) + /** + * If {@code true} Alt+Button1 shortcut will be removed from 'Quick Evaluate Expression' action and assigned to 'Add/Remove Caret' action + * (instead of Alt+Shift+Button1) in the default keymap + */ + boolean reassignAltClickToMultipleCarets = false + + /** + * If {@code true} a txt file containing information (in Atlassian Confluence format) about third-party libraries used in the product + * will be generated. + */ + boolean generateLibrariesLicensesTable = true + + /** + * List of licenses information about all libraries which can be used in the product modules + */ + List allLibraryLicenses = CommunityLibraryLicenses.LICENSES_LIST + + /** + * If {@code true} the main product JAR file will be scrambled using {@link BuildContext#scrambleTool} + */ + boolean scrambleMainJar = false + + /** + * Described which modules should be included into the product's platform and which plugins should be bundled with the product + */ + ProductModulesLayout productLayout = new ProductModulesLayout() + /** * If {@code true} cross-platform ZIP archive containing binaries for all OS will be built */ @@ -115,6 +139,12 @@ public abstract class ProductProperties { List excludedPlugins = [] + /** + * Prefix for names of environment variables used by Windows and Linux distributions to allow users customize location of the product JDK + * (<PRODUCT>_JDK variable), *.vmoptions file (<PRODUCT>_VM_OPTIONS variable), idea.properties file (<PRODUCT>_PROPERTIES variable) + */ + String environmentVariableBaseName(ApplicationInfoProperties applicationInfo) { applicationInfo.upperCaseProductName } + /** * Override this method to copy additional files to distributions of all operating systems. */ diff --git a/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy b/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy index 520ae6cdd276..f4b82a995c8b 100644 --- a/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy @@ -22,6 +22,11 @@ package org.jetbrains.intellij.build * @author nik */ interface ScrambleTool { + /** + * @return list of modules used by the tool which need to be compiled before {@link #scramble} method is invoked + */ + List getAdditionalModulesToCompile() + /** * Scramble {@code mainJarName} in {@code "$buildContext.paths.distAll/lib"} directory */ diff --git a/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy index ef315aaa7dfa..cfd30127d203 100644 --- a/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy @@ -61,6 +61,16 @@ abstract class WindowsDistributionCustomizer { */ void copyAdditionalFiles(BuildContext context, String targetDirectory) {} + /** + * The returned name will be shown in Windows Installer and used in Registry keys + */ + String fullNameIncludingEdition(ApplicationInfoProperties applicationInfo) { applicationInfo.productName } + + /** + * The returned name will be used to create links on Desktop + */ + String fullNameIncludingEditionAndVendor(ApplicationInfoProperties applicationInfo) { applicationInfo.shortCompanyName + " " + applicationInfo.productName } + String uninstallFeedbackPageUrl(ApplicationInfoProperties applicationInfo) { return null } diff --git a/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy b/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy index 0563de6aa82c..9a838a58fa15 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy @@ -163,9 +163,14 @@ class BuildContextImpl extends BuildContext { @Override JpsModule findApplicationInfoModule() { - def module = findModule(productProperties.applicationInfoModule) + return findRequiredModule(productProperties.applicationInfoModule) + } + + @Override + JpsModule findRequiredModule(String name) { + def module = findModule(name) if (module == null) { - messages.error("Cannot find module '$productProperties.applicationInfoModule' containing ApplicationInfo.xml file") + messages.error("Cannot find required module '$name' in the project") } return module } @@ -196,6 +201,13 @@ class BuildContextImpl extends BuildContext { } } + @Override + boolean includeBreakGenLibraries() { + def productLayout = productProperties.productLayout + return productLayout.mainJarName == null || //todo[nik] remove this condition later + productLayout.additionalPlatformModules.containsKey("java-runtime") + } + @Override void notifyArtifactBuilt(String artifactPath) { if (!underTeamCity) return diff --git a/build/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy b/build/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy index 942370056642..ea9bfdf940e0 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy @@ -19,9 +19,6 @@ import com.intellij.openapi.util.io.FileUtil import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.build.BuildTasks -import org.jetbrains.intellij.build.LinuxDistributionCustomizer -import org.jetbrains.intellij.build.MacDistributionCustomizer -import org.jetbrains.intellij.build.WindowsDistributionCustomizer import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.jps.model.module.JpsModule @@ -86,9 +83,13 @@ class BuildTasksImpl extends BuildTasks { } } -//todo[nik] do we need 'cp' and 'jvmArgs' parameters? @Override void buildSearchableOptions(String targetModuleName, List modulesToIndex, List pathsToLicenses) { + buildSearchableOptions(new File(buildContext.projectBuilder.moduleOutput(buildContext.findModule(targetModuleName))), modulesToIndex, pathsToLicenses) + } + +//todo[nik] do we need 'cp' and 'jvmArgs' parameters? + void buildSearchableOptions(File targetDirectory, List modulesToIndex, List pathsToLicenses) { //todo[nik] create searchableOptions.xml in a separate directory instead of modifying it in the module output buildContext.executeStep("Build searchable options index", BuildOptions.SEARCHABLE_OPTIONS_INDEX_STEP, { def javaRuntimeClasses = "${buildContext.projectBuilder.moduleOutput(buildContext.findModule("java-runtime"))}" @@ -98,8 +99,7 @@ class BuildTasksImpl extends BuildTasks { buildContext.messages.progress("Building searchable options for modules $modulesToIndex") - def targetModuleOutput = buildContext.projectBuilder.moduleOutput(buildContext.findModule(targetModuleName)) - String targetFile = "$targetModuleOutput/search/searchableOptions.xml" + String targetFile = "${targetDirectory.absolutePath}/search/searchableOptions.xml" FileUtil.delete(new File(targetFile)) def tempDir = "$buildContext.paths.temp/searchableOptions" @@ -123,6 +123,9 @@ class BuildTasksImpl extends BuildTasks { sysproperty(key: "idea.home.path", value: buildContext.paths.projectHome) sysproperty(key: "idea.system.path", value: systemPath) sysproperty(key: "idea.config.path", value: configPath) + if (buildContext.productProperties.platformPrefix != null) { + sysproperty(key: "idea.platform.prefix", value: buildContext.productProperties.platformPrefix) + } arg(value: "$classpathFile") arg(line: "com.intellij.idea.Main traverseUI") arg(value: targetFile) @@ -244,6 +247,26 @@ idea.fatal.error.notification=disabled } } + @Override + void compileModulesAndBuildDistributions(List allPlugins) { + def productLayout = buildContext.productProperties.productLayout + cleanOutput() + def includedModules = productLayout.getIncludedModules(allPlugins) + compileModules(includedModules) + buildContext.messages.block("Build platform and plugin JARs") { + new DistributionJARsBuilder(buildContext, includedModules, allPlugins).buildJARs() + } + if (buildContext.productProperties.scrambleMainJar) { + if (buildContext.scrambleTool != null) { + buildContext.scrambleTool.scramble(buildContext.productProperties.productLayout.mainJarName, buildContext) + } + else { + buildContext.messages.warning("Scrambling skipped: 'srambleTool' isn't defined") + } + } + buildDistributions() + } + @Override void cleanOutput() { buildContext.messages.block("Clean output") { @@ -262,6 +285,11 @@ idea.fatal.error.notification=disabled @Override void compileProjectAndTests(List includingTestsInModules = []) { + compileModules(null, includingTestsInModules) + } + + @Override + void compileModules(List moduleNames, List includingTestsInModules = []) { if (buildContext.options.useCompiledClassesFromProjectOutput) { buildContext.messages.info("Compilation skipped, the compiled classes from the project output will be used") return @@ -272,7 +300,18 @@ idea.fatal.error.notification=disabled } buildContext.projectBuilder.cleanOutput() - buildContext.projectBuilder.buildProduction() + if (moduleNames == null) { + buildContext.projectBuilder.buildProduction() + } + else { + List modulesToBuild = ((moduleNames as Set) + DistributionJARsBuilder.ADDITIONAL_MODULES_TO_COMPILE + + buildContext.scrambleTool?.additionalModulesToCompile ?: []) as List + List invalidModules = modulesToBuild.findAll {buildContext.findModule(it) == null} + if (!invalidModules.empty) { + buildContext.messages.warning("The following modules won't be compiled: $invalidModules") + } + buildContext.projectBuilder.buildModules(modulesToBuild.collect {buildContext.findModule(it)}.findAll {it != null}) + } for (String moduleName : includingTestsInModules) { buildContext.projectBuilder.makeModuleTests(buildContext.findModule(moduleName)) } diff --git a/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy new file mode 100644 index 000000000000..d55e27903dc3 --- /dev/null +++ b/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy @@ -0,0 +1,401 @@ +/* + * Copyright 2000-2016 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. + */ +/* + * Copyright 2000-2016 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 org.jetbrains.intellij.build.impl + +import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.intellij.build.BuildContext +import org.jetbrains.intellij.build.BuildOptions +import org.jetbrains.jps.model.java.JpsJavaClasspathKind +import org.jetbrains.jps.model.java.JpsJavaExtensionService +import org.jetbrains.jps.model.module.JpsLibraryDependency +import org.jetbrains.jps.model.module.JpsModule +import org.jetbrains.jps.util.JpsPathUtil + +/** + * @author nik + */ +class DistributionJARsBuilder { + public static final List ADDITIONAL_MODULES_TO_COMPILE = [ + "java-runtime",//required to build searchable options index + "colorSchemes", "platform-resources", "platform-resources-en", "boot", "icons", "forms_rt", "bootstrap" + ] + private static final boolean COMPRESS_JARS = false + private static final String RESOURCES_INCLUDED = "resources.included" + private static final String RESOURCES_EXCLUDED = "resources.excluded" + private final BuildContext buildContext + private final List allPlugins + private final Set usedModules = new LinkedHashSet<>() + private final List includedModules + + DistributionJARsBuilder(BuildContext buildContext, List includedModules, List allPlugins) { + this.includedModules = includedModules + this.buildContext = buildContext + this.allPlugins = allPlugins + buildContext.ant.patternset(id: RESOURCES_INCLUDED) { + include(name: "**/*.properties") + include(name: "fileTemplates/**/*") + include(name: "inspectionDescriptions/**/*") + include(name: "intentionDescriptions/**/*") + include(name: "tips/**/*") + include(name: "search/**/*") + } + + buildContext.ant.patternset(id: RESOURCES_EXCLUDED) { + exclude(name: "**/*.properties") + exclude(name: "fileTemplates/**/*") + exclude(name: "fileTemplates") + exclude(name: "inspectionDescriptions/**/*") + exclude(name: "inspectionDescriptions") + exclude(name: "intentionDescriptions/**/*") + exclude(name: "intentionDescriptions") + exclude(name: "tips/**/*") + exclude(name: "tips") + } + } + + void buildJARs() { + buildLib() + buildPlugins() + + def productProperties = buildContext.productProperties + if (productProperties.generateLibrariesLicensesTable) { + buildContext.messages.block("Generate table of licenses for used third-party libraries") { + def generator = new LibraryLicensesListGenerator(buildContext.projectBuilder, buildContext.project, productProperties.allLibraryLicenses) + generator.generateLicensesTable("$buildContext.paths.artifacts/${buildContext.applicationInfo.productName}-third-party-libraries.txt", usedModules) + } + } + + if (productProperties.scrambleMainJar) { + createLayoutBuilder().layout(buildContext.paths.artifacts) { + jar("internalUtilities.jar") { + module("internalUtilities") + } + } + } + } + + private void buildLib() { + def ant = buildContext.ant + def layoutBuilder = createLayoutBuilder() + def productLayout = buildContext.productProperties.productLayout + def searchableOptionsDir = new File(buildContext.paths.temp, "searchableOptions/result") + + //todo[nik] move buildSearchableOptions and patchedApplicationInfo methods to this class + def buildTasks = new BuildTasksImpl(buildContext) + buildTasks.buildSearchableOptions(searchableOptionsDir, [productLayout.mainModule], productLayout.licenseFilesToBuildSearchableOptions) + if (!buildContext.options.buildStepsToSkip.contains(BuildOptions.SEARCHABLE_OPTIONS_INDEX_STEP)) { + layoutBuilder.patchModuleOutput(productLayout.searchableOptionsModule, FileUtil.toSystemIndependentName(searchableOptionsDir.absolutePath)) + } + + def applicationInfoFile = FileUtil.toSystemIndependentName(buildTasks.patchApplicationInfo().absolutePath) + def applicationInfoDir = "$buildContext.paths.temp/applicationInfo" + ant.copy(file: applicationInfoFile, todir: "$applicationInfoDir/idea") + layoutBuilder.patchModuleOutput(buildContext.productProperties.applicationInfoModule, applicationInfoDir) + + if (buildContext.productProperties.reassignAltClickToMultipleCarets) { + def patchedKeyMapDir = createKeyMapWithAltClickReassignedToMultipleCarets() + layoutBuilder.patchModuleOutput("platform-resources", FileUtil.toSystemIndependentName(patchedKeyMapDir.absolutePath)) + } + + Set usedJars = collectUsedJars(includedModules, []) - productLayout.additionalJarsToUnpackIntoMainJar + def communityHome = "$buildContext.paths.communityHome" + def resourcesIncluded = RESOURCES_INCLUDED + def resourcesExcluded = RESOURCES_EXCLUDED + + layoutBuilder.layout("$buildContext.paths.distAll/lib") { + jar("util.jar") { + module("util") + module("util-rt") + } + jar("openapi.jar") { + productLayout.platformApiModules.each { module it } + } + + jar("annotations.jar") { + module("annotations-common") + module("annotations") + } + jar("extensions.jar") { module("extensions") } + jar("bootstrap.jar") { module("bootstrap") } + jar("resources.jar", true) { + modulePatches(["platform-resources"]) + module("colorSchemes") + module("platform-resources") + } + + jar("forms_rt.jar") { module("forms_rt") } + + productLayout.additionalPlatformModules.entrySet().findAll { it.value != "resources_en.jar" }.each { + def moduleName = it.key + jar(it.value) { + module(moduleName) + } + } + + jar("resources_en.jar", true) { + productLayout.additionalPlatformModules.entrySet().findAll { it.value == "resources_en.jar"}.each { + modulePatches([it.key]) + module(it.key) + } + module("platform-resources-en") + module("coverage-common") { + ant.patternset(refid: resourcesIncluded) + } + } + + jar("icons.jar") { module("icons") } + jar("boot.jar") { module("boot") } + projectLibrary("KotlinJavaRuntime") + + jar(productLayout.mainJarName, true, false) { + modulePatches(productLayout.platformImplementationModules) + productLayout.platformImplementationModules.each { module it } + module("coverage-common") { + ant.patternset(refid: resourcesExcluded) + } + productLayout.additionalJarsToUnpackIntoMainJar.each { + ant.zipfileset(src: it) + } + } + + usedJars.each { + ant.fileset(file: it) + } + + dir("libpty") { + ant.fileset(dir: "$communityHome/lib/libpty") { + exclude(name: "*.txt") + } + } + dir("ext") {//why ext? + projectLibrary("CGLIB") + } + + dir("src") { + ant.fileset(dir: "$communityHome/lib/src") { + include(name: "trove4j_changes.txt") + include(name: "trove4j_src.jar") + } + } + } + usedModules.addAll(layoutBuilder.usedModules) + } + + private void buildPlugins() { + def ant = buildContext.ant + def productLayout = buildContext.productProperties.productLayout + def layoutBuilder = createLayoutBuilder() + + if (buildContext.productProperties.setPluginAndIDEVersionInPluginXml) { + def pluginsToBuild = getPluginsByModules(productLayout.pluginModulesToPublish) + pluginsToBuild.each { plugin -> + def moduleOutput = buildContext.projectBuilder.moduleOutput(buildContext.findRequiredModule(plugin.mainModule)) + def pluginXmlPath = "$moduleOutput/META-INF/plugin.xml" + if (!new File(pluginXmlPath)) { + buildContext.messages.error("plugin.xml not found in $plugin.mainModule module: $pluginXmlPath") + } + def patchedPluginXmlDir = "$buildContext.paths.temp/patched-plugin-xml/$plugin.mainModule" + ant.copy(file: pluginXmlPath, todir: "$patchedPluginXmlDir/META-INF") + setPluginVersionAndSince("$patchedPluginXmlDir/META-INF/plugin.xml", buildContext.buildNumber) + layoutBuilder.patchModuleOutput(plugin.mainModule, patchedPluginXmlDir) + } + } + + buildPlugins(layoutBuilder, getPluginsByModules(productLayout.bundledPluginModules), "$buildContext.paths.distAll/plugins") + usedModules.addAll(layoutBuilder.usedModules) + + def pluginsToPublishDir = "$buildContext.paths.temp/plugins-to-publish" + def pluginsToPublish = getPluginsByModules(productLayout.pluginModulesToPublish) + buildPlugins(layoutBuilder, pluginsToPublish, pluginsToPublishDir) + pluginsToPublish.each { plugin -> + def directory = plugin.directoryName + ant.zip(destfile: "$buildContext.paths.artifacts/plugins/$directory-${buildContext.buildNumber}.zip") { + zipfileset(dir: "$pluginsToPublishDir/$directory", prefix: directory) + } + } + } + + private List getPluginsByModules(List modules) { + def modulesToInclude = modules as Set + allPlugins.findAll { modulesToInclude.contains(it.mainModule) } + } + + private buildPlugins(LayoutBuilder layoutBuilder, List pluginsToInclude, String targetDirectory) { + def ant = buildContext.ant + def resourceExcluded = RESOURCES_EXCLUDED + def resourcesIncluded = RESOURCES_INCLUDED + def enabledModulesSet = buildContext.productProperties.productLayout.enabledPluginModules + layoutBuilder.layout(targetDirectory) { + pluginsToInclude.each { plugin -> + dir(plugin.directoryName) { + dir("lib") { + def actualModuleJars = plugin.getActualModules(enabledModulesSet) + actualModuleJars.entrySet().each { + def modules = it.value + def jarPath = it.key + jar(jarPath, true) { + modulePatches(modules) + modules.each { moduleName -> + module(moduleName) { + if (plugin.packLocalizableResourcesInCommonJar(moduleName)) { + ant.patternset(refid: resourceExcluded) + } + plugin.moduleExcludes.get(moduleName)?.each { + ant.exclude(name: "$it/**") + } + } + } + } + } + def modulesWithResources = actualModuleJars.values().findAll { plugin.packLocalizableResourcesInCommonJar(it) } + if (!modulesWithResources.empty) { + jar("resources_en.jar") { + modulesWithResources.each { + module(it) { + ant.patternset(refid: resourcesIncluded) + } + } + } + } + plugin.includedProjectLibraries.each { + projectLibrary(it) + } + + //include all module libraries from the plugin modules added to IDE classpath to layout + actualModuleJars.entrySet().findAll {!it.key.contains("/")}.collectMany {it.value}.each { moduleName -> + findModule(moduleName).dependenciesList.dependencies. + findAll { it instanceof JpsLibraryDependency && it?.libraryReference?.parentReference?.resolve() instanceof JpsModule}. + findAll { JpsJavaExtensionService.instance.getDependencyExtension(it)?.scope?.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_RUNTIME) ?: false}. + each { + jpsLibrary(((JpsLibraryDependency)it).library) + } + } + + plugin.includedModuleLibraries.each { data -> + dir(data.relativeOutputPath) { + moduleLibrary(data.moduleName, data.libraryName) + } + } + } + plugin.resourcePaths.entrySet().each { + def contentRoot = JpsPathUtil.urlToPath(findModule(plugin.mainModule).contentRootsList.urls.first()) + def path = "$contentRoot/$it.key" + dir(it.value) { + if (new File(path).isFile()) { + ant.fileset(file: path) + } + else { + ant.fileset(dir: path) + } + } + } + plugin.resourceArchivePaths.entrySet().each { + def contentRoot = JpsPathUtil.urlToPath(findModule(plugin.mainModule).contentRootsList.urls.first()) + def path = "$contentRoot/$it.key" + zip(it.value) { + ant.fileset(dir: path) + } + } + } + } + } + } + + private LayoutBuilder createLayoutBuilder() { + new LayoutBuilder(buildContext.ant, buildContext.project, COMPRESS_JARS) + } + + private void setPluginVersionAndSince(String pluginXmlPath, String buildNumber) { + buildContext.ant.replaceregexp(file: pluginXmlPath, + match: "[\\d.]*", + replace: "${buildNumber}") + buildContext.ant.replaceregexp(file: pluginXmlPath, + match: "\\s*<\\!\\[CDATA\\[\\s*Plugin version: \\\$\\{version\\}", + replace: "\n")) { + def dotIndex = buildNumber.indexOf('.') + def untilBuild = dotIndex > 0 ? Integer.parseInt(buildNumber.substring(0, dotIndex)) + ".*" : buildNumber + def anchor = text.contains("") ? "" : "" + file.text = text.replace(anchor, + "${anchor}\n ${buildNumber}\n \n") + } + } + + private Set collectUsedJars(List modules, List additionalLibFolders) { + def usedJars = new LinkedHashSet(); + List approvedJars = + (["$buildContext.paths.communityHome/lib", "$buildContext.paths.projectHome/lib", "$buildContext.paths.communityHome/xml/relaxng/lib"] as List) + + additionalLibFolders + + def forbiddenJars = [ +// "/dev/", "/rt/", "/ant/", +// "ls-client-api", "/ideaLicenseDecoder", "jcip-annotations", +// "/eawtstub.jar", "/y.jar", "/ysvg.jar" + ] + + modules.each { + def module = buildContext.findModule(it) + if (module != null) { + buildContext.projectBuilder.moduleRuntimeClasspath(module, false).each { + File file = new File(it) + if (file.exists()) { + String path = FileUtil.toSystemIndependentName(file.canonicalPath) + if (path.endsWith(".jar") && approvedJars.any { FileUtil.startsWith(path, it) } && !forbiddenJars.any { path.contains(it) }) { + if (usedJars.add(path)) { + buildContext.messages.info("\tADDED: $path for $module.name") + } + } + } + } + } + } + + return usedJars + } + + private File createKeyMapWithAltClickReassignedToMultipleCarets() { + def sourceFile = new File("${buildContext.projectBuilder.moduleOutput(buildContext.findModule("platform-resources"))}/idea/Keymap_Default.xml") + String defaultKeymapContent = sourceFile.text + defaultKeymapContent = defaultKeymapContent.replace("", "") + defaultKeymapContent = defaultKeymapContent.replace("", + "") + def patchedKeyMapDir = new File(buildContext.paths.temp, "patched-keymap") + def targetFile = new File(patchedKeyMapDir, "idea/Keymap_Default.xml") + FileUtil.createParentDirs(targetFile) + targetFile.text = defaultKeymapContent + return patchedKeyMapDir + } +} diff --git a/build/groovy/org/jetbrains/intellij/build/impl/LayoutBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/LayoutBuilder.groovy new file mode 100644 index 000000000000..d51b5785472a --- /dev/null +++ b/build/groovy/org/jetbrains/intellij/build/impl/LayoutBuilder.groovy @@ -0,0 +1,221 @@ +/* + * Copyright 2000-2016 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. + */ +/* + * Copyright 2000-2016 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 org.jetbrains.intellij.build.impl + +import com.intellij.openapi.util.MultiValuesMap +import com.intellij.util.PathUtilRt +import org.apache.tools.ant.AntClassLoader +import org.jetbrains.jps.model.JpsProject +import org.jetbrains.jps.model.library.JpsLibrary +import org.jetbrains.jps.model.library.JpsOrderRootType +import org.jetbrains.jps.model.module.JpsModule + +/** + * This is replacement for {@link org.jetbrains.jps.gant.JpsGantTool} which doesn't depend on Gant. It also allows us to patch a module + * output before packing it into JAR. + * + * @author nik + */ +class LayoutBuilder { + private final AntBuilder ant + private final boolean compressJars + final Set usedModules = new LinkedHashSet<>() + private final MultiValuesMap moduleOutputPatches = new MultiValuesMap<>(true) + private final JpsProject project + + LayoutBuilder(AntBuilder ant, JpsProject project, boolean compressJars) { + this.project = project + this.ant = ant + this.compressJars = compressJars + + def contextLoaderRef = "GANT_CONTEXT_CLASS_LOADER"; + if (!ant.project.hasReference(contextLoaderRef)) { + ClassLoader contextLoader = Thread.currentThread().contextClassLoader + if (!(contextLoader instanceof AntClassLoader)) { + contextLoader = new AntClassLoader(contextLoader, ant.project, null) + } + ant.project.addReference(contextLoaderRef, contextLoader) + ant.taskdef(name: "layout", loaderRef: contextLoaderRef, classname: "jetbrains.antlayout.tasks.LayoutTask") + } + } + + /** + * Contents of {@code pathToDirectoryWithPatchedFiles} will be used to patch the module output. Set 'preserveDuplicates' to {@code true} + * when calling {@link LayoutSpec#jar} and call {@link LayoutSpec#modulePatches} from its body to apply the patches to the JAR. + */ + void patchModuleOutput(String moduleName, String pathToDirectoryWithPatchedFiles) { + moduleOutputPatches.put(moduleName, pathToDirectoryWithPatchedFiles) + } + + /** + * Creates the output layout accordingly to {@code data} in {@code targetDirectory}. Please note that {@code data} may refer to local + * variables of its method only. It cannot refer to its fields or methods because data's 'owner' field is changed to support the internal DSL. + */ + void layout(String targetDirectory, @DelegatesTo(LayoutSpec) Closure data) { + def spec = new LayoutSpec() + //we cannot set 'spec' as delegate because 'delegate' will be overwritten by AntBuilder + def body = data.rehydrate(null, spec, data.thisObject) + body.resolveStrategy = Closure.OWNER_FIRST + ant.layout(toDir: targetDirectory, body) + } + + class LayoutSpec { + /** + * Create a JAR file with name {@code relativePath} (it may also include parent directories names for the JAR) into the current place + * in the layout. The content of the JAR is specified by {@code body}. + */ + def jar(String relativePath, boolean preserveDuplicates = false, boolean mergeManifests = true, Closure body) { + def directory = PathUtilRt.getParentPath(relativePath) + if (directory == "") { + ant.jar(name: relativePath, compress: compressJars, duplicate: preserveDuplicates ? "preserve" : "fail", + filesetmanifest: mergeManifests ? "merge" : "skip", body) + } + else { + dir(directory) { + jar(PathUtilRt.getFileName(relativePath), preserveDuplicates, mergeManifests, body) + } + } + } + + /** + * Create a Zip file with name {@code relativePath} (it may also include parent directories names for the JAR) into the current place + * in the layout. The content of the JAR is specified by {@code body}. + */ + def zip(String relativePath, Closure body) { + def directory = PathUtilRt.getParentPath(relativePath) + if (directory == "") { + ant.zip(name: relativePath, body) + } + else { + dir(directory) { + zip(PathUtilRt.getFileName(relativePath), body) + } + } + } + + /** + * Create a directory (or several nested directories) {@code relativePath} in the current place in the layout. The content of the + * directory is specified by {@code body}. + */ + def dir(String relativePath, Closure body) { + def parent = PathUtilRt.getParentPath(relativePath) + if (relativePath.empty) { + body() + } + else if (parent.empty) { + ant.dir(name: relativePath, body) + } + else { + dir(parent) { + dir(PathUtilRt.getFileName(relativePath), body) + } + } + } + + /** + * Include the patched outputs of {@code moduleNames} modules to the current place in the layout. This method is supposed to be called + * in the {@code body} of {@link #jar} with 'preserveDuplicates' set to {@code true} + */ + def modulePatches(Collection moduleNames) { + moduleNames.each { + moduleOutputPatches.get(it)?.each { + ant.fileset(dir: it) + } + } + } + + /** + * Include production output of {@code moduleName} to the current place in the layout + */ + def module(String moduleName, Closure body = {}) { + usedModules << moduleName + ant.module(name: moduleName, body) + } + + /** + * Include test output of {@code moduleName} to the current place in the layout + */ + def moduleTests(String moduleName, Closure body = {}) { + ant.moduleTests(name: moduleName, body) + } + + /** + * Include JARs added as classes roots of project library {@code libraryName} to the current place in the layout + */ + def projectLibrary(String libraryName) { + def library = project.libraryCollection.findLibrary(libraryName) + if (library == null) { + throw new IllegalArgumentException("Cannot find library $libraryName in the project") + } + jpsLibrary(library) + } + + /** + * Include JARs added as classes roots of a module library {@code libraryName} from module {@code moduleName} to the current place in the layout + */ + def moduleLibrary(String moduleName, String libraryName) { + def module = findModule(moduleName) + def library = module.libraryCollection.libraries.find {getLibraryName(it) == libraryName} + if (library == null) { + throw new IllegalArgumentException("Cannot find library $libraryName in '$moduleName' module") + } + jpsLibrary(library) + } + + def jpsLibrary(JpsLibrary library) { + library.getFiles(JpsOrderRootType.COMPILED).each { + ant.fileset(file: it.absolutePath) + } + } + + def JpsModule findModule(String name) { + def module = project.modules.find { it.name == name } + if (module == null) { + throw new IllegalArgumentException("Cannot find module '$name' in the project") + } + module + } + + private String getLibraryName(JpsLibrary lib) { + def name = lib.name + if (name.startsWith("#")) { + if (lib.getRoots(JpsOrderRootType.COMPILED).size() != 1) { + def urls = lib.getRoots(JpsOrderRootType.COMPILED).collect { it.url } + throw new IllegalStateException("Non-single entry module library $name: $urls"); + } + File file = lib.getFiles(JpsOrderRootType.COMPILED)[0] + return file.name + } + return name + } + } +} + diff --git a/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy index 1b6549a61c57..23c8cd235d6d 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy @@ -36,7 +36,11 @@ class LinuxDistributionBuilder { //todo[nik] rename void layoutUnix(File ideaProperties) { buildContext.ant.copy(todir: "$unixDistPath/bin") { - fileset(dir: "$buildContext.paths.communityHome/bin/linux") + fileset(dir: "$buildContext.paths.communityHome/bin/linux") { + if (!buildContext.includeBreakGenLibraries()) { + exclude(name: "libbreakgen*") + } + } if (buildContext.productProperties.yourkitAgentBinariesDirectoryPath != null) { fileset(dir: buildContext.productProperties.yourkitAgentBinariesDirectoryPath) { include(name: "libyjpagent-linux*.so") @@ -47,7 +51,9 @@ class LinuxDistributionBuilder { //todo[nik] converting line separators to unix-style make sense only when building Linux distributions under Windows on a local machine; // for real installers we need to checkout all text files with 'lf' separators anyway buildContext.ant.fixcrlf(file: "$unixDistPath/bin/idea.properties", eol: "unix") - buildContext.ant.copy(file: customizer.iconPngPath, tofile: "$unixDistPath/bin/${buildContext.productProperties.baseFileName}.png") + if (customizer.iconPngPath != null) { + buildContext.ant.copy(file: customizer.iconPngPath, tofile: "$unixDistPath/bin/${buildContext.productProperties.baseFileName}.png") + } unixScripts() unixVMOptions() @@ -70,7 +76,17 @@ class LinuxDistributionBuilder { String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${buildContext.bootClassPathJarNames[0]}\"\n" classPath += buildContext.bootClassPathJarNames[1..-1].collect { "CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\"" }.join("\n") - def jvmArgs = buildContext.productProperties.additionalIdeJvmArguments + String jvmArgs + if (buildContext.productProperties.platformPrefix != null +//todo[nik] remove later. This is added to keep current behavior (platform prefix for CE is set in MainImpl anyway) + && buildContext.productProperties.platformPrefix != "Idea") { + jvmArgs = "-Didea.platform.prefix=${buildContext.productProperties.platformPrefix}" + } + else { + jvmArgs = "" + } + + jvmArgs = "$jvmArgs $buildContext.productProperties.additionalIdeJvmArguments".trim() if (buildContext.productProperties.toolsJarRequired) { classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\"" jvmArgs = "$jvmArgs -Didea.jre.check=true".trim() @@ -81,7 +97,7 @@ class LinuxDistributionBuilder { filterset(begintoken: "@@", endtoken: "@@") { filter(token: "product_full", value: fullName) - filter(token: "product_uc", value: buildContext.applicationInfo.upperCaseProductName) + filter(token: "product_uc", value: buildContext.productProperties.environmentVariableBaseName(buildContext.applicationInfo)) filter(token: "vm_options", value: vmOptionsFileName) filter(token: "isEap", value: buildContext.applicationInfo.isEAP) filter(token: "system_selector", value: buildContext.systemSelector) diff --git a/build/groovy/org/jetbrains/intellij/build/impl/MacDistributionBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/MacDistributionBuilder.groovy index 172479fa1e6f..568c693c819d 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/MacDistributionBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/MacDistributionBuilder.groovy @@ -15,12 +15,14 @@ */ package org.jetbrains.intellij.build.impl +import com.intellij.util.PathUtilRt import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.build.JvmArchitecture import org.jetbrains.intellij.build.MacDistributionCustomizer import java.time.LocalDate + /** * @author nik */ @@ -36,21 +38,25 @@ class MacDistributionBuilder { } public layoutMac(File ideaPropertiesFile) { - def docTypes = customizer.docTypes ?: """ + def docTypes = (customizer.associateIpr ? """ CFBundleTypeExtensions ipr CFBundleTypeIconFile - ${buildContext.productProperties.baseFileName}.icns + ${PathUtilRt.getFileName(customizer.icnsPath ?: "idea.icns")} CFBundleTypeName ${buildContext.applicationInfo.productName} Project File CFBundleTypeRole Editor -""" - Map customIdeaProperties = ["idea.jre.check": "$buildContext.productProperties.toolsJarRequired"]; +""" : "") + customizer.additionalDocTypes + Map customIdeaProperties = [:] + if (buildContext.productProperties.toolsJarRequired) { + customIdeaProperties["idea.jre.check"] = "true" + } + customIdeaProperties.putAll(customizer.customIdeaProperties(buildContext.applicationInfo)) layoutMacApp(ideaPropertiesFile, customIdeaProperties, docTypes) customizer.copyAdditionalFiles(buildContext, macDistPath) def macZipPath = buildMacZip() diff --git a/build/groovy/org/jetbrains/intellij/build/impl/PluginLayout.groovy b/build/groovy/org/jetbrains/intellij/build/impl/PluginLayout.groovy new file mode 100644 index 000000000000..2ae33d4a4d73 --- /dev/null +++ b/build/groovy/org/jetbrains/intellij/build/impl/PluginLayout.groovy @@ -0,0 +1,200 @@ +/* + * Copyright 2000-2016 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. + */ +/* + * Copyright 2000-2016 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 org.jetbrains.intellij.build.impl + +import com.intellij.openapi.util.MultiValuesMap +import groovy.transform.Immutable + +/** + * @author nik + */ +class PluginLayout { + final String mainModule + String directoryName + /** JAR name (or path relative to 'lib' directory) to module name */ + final MultiValuesMap moduleJars = new MultiValuesMap<>(true) + /** source directory -> relative path to a target directory under the plugin directory */ + final Map resourcePaths = [:] + /** source directory -> relative path to a zip file under the plugin directory */ + final Map resourceArchivePaths = [:] + /** module name to entries which should be excluded from its output */ + final MultiValuesMap moduleExcludes = new MultiValuesMap<>(true) + final List includedProjectLibraries = [] + final List includedModuleLibraries = [] + private final Set optionalModules = new LinkedHashSet<>() + private final Set modulesWithLocalizableResourcesInCommonJar = new LinkedHashSet<>() + private boolean doNotCreateSeparateJarForLocalizableResources + + private PluginLayout(String mainModule) { + this.mainModule = mainModule + } + + /** + * Creates the plugin layout description. The default plugin layout is composed of a jar with name {@code mainModuleName}.jar containing output of + * {@code mainModuleName}, resources_en.jar containing translatable resources from {@code mainModuleName}, and the module libraries of + * {@code mainModuleName} with scopes 'Compile' and 'Runtime' placed under 'lib' directory in a directory with name {@code mainModuleName}. + * In you need to include additional resources or modules into the plugin layout specify them in {@code body} parameter. + * + * @param mainModuleName name of the module containing META-INF/plugin.xml file of the plugin + */ + static PluginLayout plugin(String mainModuleName, @DelegatesTo(PluginLayoutSpec) Closure body = {}) { + def layout = new PluginLayout(mainModuleName) + def spec = new PluginLayoutSpec(layout) + body.delegate = spec + body() + layout.directoryName = spec.directoryName + spec.withModule(mainModuleName, spec.mainJarName) + if (layout.doNotCreateSeparateJarForLocalizableResources) { + layout.modulesWithLocalizableResourcesInCommonJar.clear() + } + return layout + } + + MultiValuesMap getActualModules(Set enabledPluginModules) { + def result = new MultiValuesMap(true) + for (Map.Entry> entry : moduleJars.entrySet()) { + for (String moduleName : entry.getValue()) { + if (!optionalModules.contains(moduleName) || enabledPluginModules.contains(moduleName)) { + result.put(entry.key, moduleName) + } + } + } + return result + } + + boolean packLocalizableResourcesInCommonJar(String moduleName) { + return modulesWithLocalizableResourcesInCommonJar.contains(moduleName) + } + + static class PluginLayoutSpec { + private final PluginLayout layout + /** + * Name of the directory (under 'plugins' directory) where the plugin should be placed + */ + String directoryName + /** + * Name of the main plugin JAR file + */ + String mainJarName + + PluginLayoutSpec(PluginLayout layout) { + this.layout = layout + directoryName = layout.mainModule + mainJarName = "${layout.mainModule}.jar" + } + + /** + * Register an optional module which may be excluded from the plugin distribution in some products + */ + void withOptionalModule(String moduleName, String relativeJarPath = "${moduleName}.jar") { + layout.optionalModules << moduleName + withModule(moduleName, relativeJarPath) + } + + /** + * Register an additional module to be included into the plugin distribution. If {@code relativeJarPath} doesn't contain '/' (i.e. the + * JAR will be added to the plugin's classpath) this will also cause modules library from {@code moduleName} with scopes 'Compile' and + * 'Runtime' to be copied to the 'lib' directory of the plugin. + * + * @param relativeJarPath target JAR path relative to 'lib' directory of the plugin; different modules may be packed into the same JAR, + * but don't use this for new plugins; this parameter is temporary added to keep layout of old plugins. + * @param localizableResourcesInCommonJar if {@code true} the translatable resources from the module (messages, inspection descriptions, etc) will be + * placed into a separate 'resources_en.jar'. Do not use this for new plugins, this parameter is temporary added to keep layout of old plugins. + */ + void withModule(String moduleName, String relativeJarPath = "${moduleName}.jar", boolean localizableResourcesInCommonJar = true) { + if (localizableResourcesInCommonJar) { + layout.modulesWithLocalizableResourcesInCommonJar << moduleName + } + layout.moduleJars.put(relativeJarPath, moduleName) + } + + void withJpsModule(String moduleName) { + withModule(moduleName, "jps/${moduleName}.jar") + } + + /** + * @param resourcePath path to resource file or directory relative to the plugin's main module content root + * @param relativeOutputDirectory target path relative to the plugin root directory + */ + void withResource(String resourcePath, String relativeOutputDirectory) { + layout.resourcePaths[resourcePath] = relativeOutputDirectory + } + + /** + * @param resourcePath path to resource file or directory relative to the plugin's main module content root + * @param relativeOutputFile target path relative to the plugin root directory + */ + void withResourceArchive(String resourcePath, String relativeOutputFile) { + layout.resourceArchivePaths[resourcePath] = relativeOutputFile + } + + /** + * Include the project library to 'lib' directory of the plugin distribution + */ + void withProjectLibrary(String libraryName) { + layout.includedProjectLibraries << libraryName + } + + /** + * Include the module library to the plugin distribution. Please note that it makes sense to call this method only + * for additional modules which aren't copied directly to the 'lib' directory of the plugin distribution, because for ordinary modules + * their module libraries are included into the layout automatically. + */ + void withModuleLibrary(String libraryName, String moduleName = layout.mainModule, String relativeOutputPath) { + layout.includedModuleLibraries << new ModuleLibraryData(moduleName: moduleName, libraryName: libraryName, relativeOutputPath: relativeOutputPath) + } + + /** + * Exclude the specified directory when {@code moduleName} is packed into JAR file. + * This is a temporary method added to keep layout of some old plugins. If some directory from a module shouldn't be included into the + * module JAR it's strongly recommended to move that directory outside of the module source roots. + * @param excludedDirectory path to the directory to be exclude relatively to the module output root + */ + void excludeFromModule(String moduleName, String excludedDirectory) { + layout.moduleExcludes.put(moduleName, excludedDirectory) + } + + /** + * Do not create 'resources_en.jar' and pack all resources into corresponding module JARs. + * Do not use this for new plugins, this method is temporary added to keep layout of old plugins. + */ + void doNotCreateSeperateJarForLocalizableResources() { + layout.doNotCreateSeparateJarForLocalizableResources = true + } + } + + @Immutable + static class ModuleLibraryData { + String moduleName + String libraryName + String relativeOutputPath + } +} \ No newline at end of file diff --git a/build/groovy/org/jetbrains/intellij/build/impl/WinExeInstallerBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/WinExeInstallerBuilder.groovy index bf23841eab53..97f17d38ad82 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/WinExeInstallerBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/WinExeInstallerBuilder.groovy @@ -122,13 +122,12 @@ class WinExeInstallerBuilder { !define PRODUCT_VM_OPTIONS_FILE "${toSystemDependentName("$winDistPath/bin/")}\${PRODUCT_VM_OPTIONS_NAME}" """ - String fullProductName = productProperties.fullNameIncludingEdition(buildContext.applicationInfo) def extensionsList = customizer.fileAssociations def fileAssociations = extensionsList.isEmpty() ? "NoAssociation" : extensionsList.join(",") new File(box, "nsiconf/strings.nsi").text = """ -!define MANUFACTURER "JetBrains" -!define MUI_PRODUCT "$fullProductName" -!define PRODUCT_FULL_NAME "$fullProductName" +!define MANUFACTURER "${buildContext.applicationInfo.shortCompanyName}" +!define MUI_PRODUCT "${customizer.fullNameIncludingEdition(buildContext.applicationInfo)}" +!define PRODUCT_FULL_NAME "${customizer.fullNameIncludingEditionAndVendor(buildContext.applicationInfo)}" !define PRODUCT_EXE_FILE "${productProperties.baseFileName}.exe" !define PRODUCT_EXE_FILE_64 "${productProperties.baseFileName}64.exe" !define PRODUCT_ICON_FILE "install.ico" @@ -138,7 +137,7 @@ class WinExeInstallerBuilder { !define ASSOCIATION "$fileAssociations" !define UNINSTALL_WEB_PAGE "${customizer.uninstallFeedbackPageUrl(buildContext.applicationInfo) ?: "feedback_web_page"}" -; if SHOULD_SET_DEFAULT_INSTDIR != 0 then default installation directory will be directory where highest-numbered IDEA build has been installed +; if SHOULD_SET_DEFAULT_INSTDIR != 0 then default installation directory will be directory where highest-numbered IDE build has been installed ; set to 1 for release build !define SHOULD_SET_DEFAULT_INSTDIR "0" diff --git a/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy index 6d0484b21956..937443949483 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy @@ -18,7 +18,9 @@ package org.jetbrains.intellij.build.impl import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.build.JvmArchitecture +import org.jetbrains.intellij.build.ProductModulesLayout import org.jetbrains.intellij.build.WindowsDistributionCustomizer +import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.model.module.JpsModuleSourceRoot /** * @author nik @@ -37,7 +39,11 @@ class WindowsDistributionBuilder { //todo[nik] rename void layoutWin(File ideaProperties) { buildContext.ant.copy(todir: "$winDistPath/bin") { - fileset(dir: "$buildContext.paths.communityHome/bin/win") + fileset(dir: "$buildContext.paths.communityHome/bin/win") { + if (!buildContext.includeBreakGenLibraries()) { + exclude(name: "breakgen*") + } + } if (buildContext.productProperties.yourkitAgentBinariesDirectoryPath != null) { fileset(dir: buildContext.productProperties.yourkitAgentBinariesDirectoryPath) { include(name: "yjpagent*.dll") @@ -47,7 +53,9 @@ class WindowsDistributionBuilder { buildContext.ant.copy(file: ideaProperties.path, todir: "$winDistPath/bin") buildContext.ant.fixcrlf(file: "$winDistPath/bin/idea.properties", eol: "dos") - buildContext.ant.copy(file: customizer.icoPath, tofile: "$winDistPath/bin/${buildContext.productProperties.baseFileName}.ico") + if (customizer.icoPath != null) { + buildContext.ant.copy(file: customizer.icoPath, tofile: "$winDistPath/bin/${buildContext.productProperties.baseFileName}.ico") + } if (customizer.includeBatchLaunchers) { winScripts() } @@ -58,7 +66,7 @@ class WindowsDistributionBuilder { def arch = customizer.bundledJreArchitecture def jreDirectoryPath = arch != null ? buildContext.bundledJreManager.extractWinJre(arch) : null - buildWinZip(jreDirectoryPath, ".win") + buildWinZip(jreDirectoryPath, buildContext.productProperties.buildCrossPlatformDistribution ? ".win" : "") if (arch != null && customizer.buildZipWithBundledOracleJre) { String oracleJrePath = buildContext.bundledJreManager.extractOracleWinJre(arch) if (oracleJrePath != null) { @@ -93,7 +101,7 @@ class WindowsDistributionBuilder { filterset(begintoken: "@@", endtoken: "@@") { filter(token: "product_full", value: fullName) - filter(token: "product_uc", value: buildContext.applicationInfo.upperCaseProductName) + filter(token: "product_uc", value: buildContext.productProperties.environmentVariableBaseName(buildContext.applicationInfo)) filter(token: "vm_options", value: vmOptionsFileName) filter(token: "isEap", value: buildContext.applicationInfo.isEAP) filter(token: "system_selector", value: buildContext.systemSelector) @@ -155,23 +163,28 @@ class WindowsDistributionBuilder { def productName = buildContext.applicationInfo.upperCaseProductName //todo[nik] use '.productName' instead String jdkEnvVarSuffix = arch == JvmArchitecture.x64 ? "_64" : ""; + def envVarBaseName = buildContext.productProperties.environmentVariableBaseName(buildContext.applicationInfo) new File(launcherPropertiesPath).text = """ IDS_JDK_ONLY=$buildContext.productProperties.toolsJarRequired -IDS_JDK_ENV_VAR=${upperCaseProductName}_JDK${jdkEnvVarSuffix} -IDS_APP_TITLE=${productName} Launcher +IDS_JDK_ENV_VAR=${envVarBaseName}_JDK$jdkEnvVarSuffix +IDS_APP_TITLE=$productName Launcher IDS_VM_OPTIONS_PATH=%USERPROFILE%\\\\.$buildContext.systemSelector IDS_VM_OPTION_ERRORFILE=-XX:ErrorFile=%USERPROFILE%\\\\java_error_in_${lowerCaseProductName}_%p.log IDS_VM_OPTION_HEAPDUMPPATH=-XX:HeapDumpPath=%USERPROFILE%\\\\java_error_in_${lowerCaseProductName}.hprof IDC_WINLAUNCHER=${upperCaseProductName}_LAUNCHER -IDS_PROPS_ENV_VAR=${upperCaseProductName}_PROPERTIES -IDS_VM_OPTIONS_ENV_VAR=${upperCaseProductName}${arch.fileSuffix}_VM_OPTIONS -IDS_ERROR_LAUNCHING_APP=Error launching ${productName} +IDS_PROPS_ENV_VAR=${envVarBaseName}_PROPERTIES +IDS_VM_OPTIONS_ENV_VAR=$envVarBaseName${arch.fileSuffix}_VM_OPTIONS +IDS_ERROR_LAUNCHING_APP=Error launching $productName IDS_VM_OPTIONS=$vmOptions """.trim() def communityHome = "$buildContext.paths.communityHome" String inputPath = "$communityHome/bin/WinLauncher/WinLauncher${arch.fileSuffix}.exe" def outputPath = "$winDistPath/bin/$exeFileName" + def resourceModules = [buildContext.findApplicationInfoModule(), buildContext.findModule("icons")] + if (buildContext.productProperties.brandingModule != null) { + resourceModules << buildContext.findRequiredModule(buildContext.productProperties.brandingModule) + } buildContext.ant.java(classname: "com.pme.launcher.LauncherGeneratorMain", fork: "true", failonerror: "true") { sysproperty(key: "java.awt.headless", value: "true") arg(value: inputPath) @@ -186,7 +199,7 @@ IDS_VM_OPTIONS=$vmOptions include(name: "jdom.jar") include(name: "sanselan*.jar") } - [buildContext.findApplicationInfoModule(), buildContext.findModule("icons")].collectMany { it.sourceRoots }.each { JpsModuleSourceRoot root -> + resourceModules.collectMany { it.sourceRoots }.each { JpsModuleSourceRoot root -> pathelement(location: root.file.absolutePath) } } From d18fa1ed5d3e8ae3254f59b8320270fcdd2456cd Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 21 Jul 2016 12:37:34 +0300 Subject: [PATCH 07/41] check enabled flag in prioritizeUiActivity --- .../src/com/intellij/util/io/storage/HeavyProcessLatch.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java index 826ddaf9bff6..83306ca3114a 100644 --- a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java +++ b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java @@ -22,6 +22,7 @@ package com.intellij.util.io.storage; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.registry.Registry; import com.intellij.util.EventDispatcher; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -141,6 +142,10 @@ public class HeavyProcessLatch { public void prioritizeUiActivity() { LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + if (!Registry.is("ide.prioritize.ui.thread", false)) { + return; + } + // don't wait forever in case someone forgot to stop prioritizing before waiting for other threads to complete // wait just for 12 seconds; this will be noticeable (and we'll get 2 thread dumps) but not fatal myPrioritizingDeadLine = System.currentTimeMillis() + 12 * 1000; From 5e9fcb88fbee4b84ae4c70a423776135c1642e61 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Jul 2016 16:57:18 +0300 Subject: [PATCH 08/41] test fixed --- .../com/intellij/codeInsight/daemon/HighlightStressTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/HighlightStressTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/HighlightStressTest.java index 12d72c9ed246..a717ecf9a9f1 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/HighlightStressTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/HighlightStressTest.java @@ -237,7 +237,7 @@ public class HighlightStressTest extends LightDaemonAnalyzerTestCase { } String qualifiedName = aClass.getQualifiedName(); if (qualifiedName.startsWith("java.lang.invoke")) continue; // java.lang.invoke.MethodHandle has weird access attributes in recent rt.jar which causes spurious highlighting errors - if ("Sink".equals(aClass.getName())) continue; + if (qualifiedName.contains(".Sink")) continue; // Sink has weird access in class files imports.append("import " + qualifiedName + ";\n"); usages.append("/**/ "+aClass.getName() + " var" + v + " = null; var" + v + ".toString();\n"); aClasses.add(aClass); @@ -248,7 +248,7 @@ public class HighlightStressTest extends LightDaemonAnalyzerTestCase { WriteCommandAction.runWriteCommandAction(null, () -> getEditor().getDocument().setText(text)); List errors = DaemonAnalyzerTestCase.filter(doHighlighting(), HighlightSeverity.WARNING); - assertEmpty(errors); + assertEmpty(text, errors); Random random = new Random(); int unused = 0; for (int i = 0; i < 100; i++) { From c3ae02d5e069e5e68b4c6be87e32c25187ba1c2c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Jul 2016 18:34:47 +0300 Subject: [PATCH 09/41] removed redundant overrides --- .../daemon/LightAdvHighlightingJdk8Test.java | 6 ------ .../daemon/LightAdvHighlightingJdk9Test.java | 6 ------ .../daemon/lambda/ChangeSignatureTouchLambdaTest.java | 7 ------- .../daemon/lambda/ConstraintsInferenceMiscTest.java | 7 ------- .../daemon/lambda/Diamond8HighlightingTest.java | 7 ------- ...FunctionalExpressionIncompleteHighlightingTest.java | 7 ------- .../FunctionalTypeWildcardParameterizationTest.java | 6 ------ .../daemon/lambda/GenericsHighlighting8Test.java | 5 ----- .../lambda/GenericsHighlightingGenerated8Test.java | 6 ------ .../daemon/lambda/GraphInferenceHighlightingTest.java | 5 ----- .../daemon/lambda/InferencePerformanceTest.java | 6 ------ .../daemon/lambda/Java8ExpressionsCheckTest.java | 7 ------- .../codeInsight/daemon/lambda/Java8RegressionTest.java | 6 ------ .../daemon/lambda/LambdaHighlightingTest.java | 7 ------- .../daemon/lambda/LambdaRedundantCastTest.java | 7 ------- .../daemon/lambda/MethodRefHighlightingTest.java | 6 ------ .../daemon/lambda/MostSpecificResolutionTest.java | 6 ------ ...ewInferenceCollectingAdditionalConstraintsTest.java | 6 ------ .../daemon/lambda/NewLambdaHighlightingTest.java | 7 +------ .../daemon/lambda/NewMethodRefHighlightingTest.java | 6 ------ .../daemon/lambda/OverloadResolutionTest.java | 6 ------ ...ionFromFieldInitializerToConstructorThrowsTest.java | 8 -------- .../daemon/quickFix/AddExceptionToCatchTest.java | 8 -------- .../daemon/quickFix/AddExceptionToThrowsTest.java | 8 -------- .../quickFix/Anonymous2LambdaInspectionTest.java | 7 ------- .../Anonymous2MethodReferenceInspectionTest.java | 7 ------- .../quickFix/ChangeMethodSignatureFromUsage8Test.java | 10 ---------- .../daemon/quickFix/GeneralizeCatchTest.java | 8 -------- .../quickFix/Lambda2MethodReferenceInspectionTest.java | 7 ------- .../RedundantLambdaCodeBlockInspectionTest.java | 7 ------- .../quickFix/RedundantTypeArgsInspectionTest.java | 7 ------- .../quickFix/ReplaceFromOfNullableFixTest.groovy | 7 +------ .../daemon/quickFix/ReplaceWithOfNullableFixTest.java | 7 ------- .../quickFix/Simplify2DiamondInspectionsTest.java | 7 ------- .../quickFix/StreamApiMigrationInspectionTest.java | 7 ------- ...TrivialFunctionalExpressionUsageInspectionTest.java | 7 ------- .../quickFix/TrivialMethodReferenceInspectionTest.java | 7 ------- .../quickFix/WrapLongWithMathToIntExactFixTest.java | 8 -------- .../daemon/quickFix/WrapObjectWithOptionalFixTest.java | 8 -------- .../intention/MergeFilterChainActionTest.java | 7 ------- .../codeInsight/intention/SplitFilterActionTest.java | 7 ------- .../SimplifyStreamApiCallChainsInspectionTest.java | 7 ------- .../StringTokenizerDelimiterInspectionTest.java | 7 ------- .../com/intellij/ide/util/JavaSuperMethodTest.java | 7 ------- .../refactoring/ExtractMethodObject4DebuggerTest.java | 7 ------- .../intellij/refactoring/ExtractMethodObjectTest.java | 8 -------- .../refactoring/IntroduceFunctionalParameterTest.java | 7 ------- .../intellij/refactoring/IntroduceVariableTest.java | 7 ------- .../testSrc/com/intellij/refactoring/PullUpTest.java | 7 ------- .../testSrc/com/intellij/refactoring/PushDownTest.java | 7 ------- .../intellij/refactoring/RenameSuggestionsTest.groovy | 7 +------ .../intellij/refactoring/inline/InlineMethodTest.java | 7 ------- 52 files changed, 3 insertions(+), 356 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk8Test.java index 4c1ab97d7bfd..20fc3af7e55c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk8Test.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon; import com.intellij.codeInspection.compiler.JavacQuirksInspection; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.testFramework.IdeaTestUtil; @@ -33,11 +32,6 @@ public class LightAdvHighlightingJdk8Test extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - private void doTest(boolean warnings, boolean weakWarnings) { doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, weakWarnings, false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk9Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk9Test.java index 14d02606cc86..5a000129aae9 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk9Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk9Test.java @@ -19,7 +19,6 @@ import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.codeInspection.redundantCast.RedundantCastInspection; import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.testFramework.IdeaTestUtil; @@ -34,11 +33,6 @@ public class LightAdvHighlightingJdk9Test extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_9, getModule(), getTestRootDisposable()); } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - private void doTest(boolean checkWarnings, boolean checkInfos) { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ChangeSignatureTouchLambdaTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ChangeSignatureTouchLambdaTest.java index cdfb5a39a4e1..b4f1d7b22dd5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ChangeSignatureTouchLambdaTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ChangeSignatureTouchLambdaTest.java @@ -15,12 +15,10 @@ */ package com.intellij.codeInsight.daemon.lambda; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.PsiType; import com.intellij.refactoring.ChangeSignatureBaseTest; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; import com.intellij.refactoring.changeSignature.ThrownExceptionInfo; -import com.intellij.testFramework.IdeaTestUtil; public class ChangeSignatureTouchLambdaTest extends ChangeSignatureBaseTest { @@ -52,9 +50,4 @@ public class ChangeSignatureTouchLambdaTest extends ChangeSignatureBaseTest { protected String getRelativePath() { return "/codeInsight/daemonCodeAnalyzer/lambda/changeSignature/"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ConstraintsInferenceMiscTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ConstraintsInferenceMiscTest.java index acacc42803d5..ef179f8155b3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ConstraintsInferenceMiscTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ConstraintsInferenceMiscTest.java @@ -16,8 +16,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase { @@ -70,9 +68,4 @@ public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase { private void doTest(final boolean checkWarnings) { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java index a1f1046f56da..7a7898d76757 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Diamond8HighlightingTest.java @@ -16,8 +16,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase { @@ -70,9 +68,4 @@ public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase { private void doTest() throws Exception { doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalExpressionIncompleteHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalExpressionIncompleteHighlightingTest.java index 66234ca38ca0..f0bbbbf0d74a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalExpressionIncompleteHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalExpressionIncompleteHighlightingTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; public class FunctionalExpressionIncompleteHighlightingTest extends LightDaemonAnalyzerTestCase { @@ -45,9 +43,4 @@ public class FunctionalExpressionIncompleteHighlightingTest extends LightDaemonA private void doTest(final boolean checkWarnings) { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java index 507d4d181e50..bf246de5f308 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -48,9 +47,4 @@ public class FunctionalTypeWildcardParameterizationTest extends LightDaemonAnaly IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index 6cf13ad22cb9..980e259b25f1 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -44,11 +44,6 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { return new LocalInspectionTool[]{new UncheckedWarningLocalInspection(), new UnusedImportLocalInspection()}; } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - public void testReferenceTypeParams() { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlightingGenerated8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlightingGenerated8Test.java index 020befac8ee1..19979bc7b905 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlightingGenerated8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlightingGenerated8Test.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; import com.intellij.testFramework.IdeaTestUtil; @@ -26,11 +25,6 @@ import org.jetbrains.annotations.NonNls; public class GenericsHighlightingGenerated8Test extends LightDaemonAnalyzerTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/genericsHighlightingGenerated8"; - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - public void testEmptyTestT() throws Exception {} public void _testUnrelatedClasses() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index 2e8a7bd62059..939c6056f789 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -491,9 +491,4 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferencePerformanceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferencePerformanceTest.java index 5ba7c67c169f..a8ebd709c923 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferencePerformanceTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferencePerformanceTest.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.PlatformTestUtil; import org.jetbrains.annotations.NonNls; @@ -37,9 +36,4 @@ public class InferencePerformanceTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java index 0dc3e2f72109..279f26f2d1e9 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java @@ -18,13 +18,11 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.ExpectedTypesProvider; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import java.util.Collection; @@ -203,9 +201,4 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase { } } } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8RegressionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8RegressionTest.java index 26d9f6d81960..54ae883f2be0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8RegressionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8RegressionTest.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -83,9 +82,4 @@ public class Java8RegressionTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java index 673a5cfaa44a..e6ebf6e2ab0d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { @@ -111,9 +109,4 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { private void doTest(final boolean checkWarnings) { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java index 5a821021f2ec..e7b0bcdba6f3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java @@ -18,8 +18,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.redundantCast.RedundantCastInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -89,9 +87,4 @@ public class LambdaRedundantCastTest extends LightDaemonAnalyzerTestCase { private void doTest() { doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java index 97683fca3d57..96880e40835a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -118,9 +117,4 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java index 7f92628e506d..6e41ee8e6193 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.util.registry.Registry; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -142,9 +141,4 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java index 01a6573ebefb..3cfeaa32fc5e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -40,9 +39,4 @@ public class NewInferenceCollectingAdditionalConstraintsTest extends LightDaemon IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 7bd35c7b68a0..050113fd5ffe 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -337,11 +336,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } -/* + /* public static Test suite() { final TestSuite suite = new TestSuite(); for (int i = 0; i < 1000; i++) { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index 320557441481..fda6beefbc4d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -20,7 +20,6 @@ import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -530,9 +529,4 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java index 56ecc91be0a5..d9da817f04f8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.PlatformTestUtil; import org.jetbrains.annotations.NonNls; @@ -237,9 +236,4 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionFromFieldInitializerToConstructorThrowsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionFromFieldInitializerToConstructorThrowsTest.java index aa50430c9664..75b498bdcac0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionFromFieldInitializerToConstructorThrowsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionFromFieldInitializerToConstructorThrowsTest.java @@ -15,9 +15,6 @@ */ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - /** * @author Dmitry Batkovich */ @@ -30,9 +27,4 @@ public class AddExceptionFromFieldInitializerToConstructorThrowsTest extends Lig protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/addToConstructorThrows"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToCatchTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToCatchTest.java index e55cced09985..4ef4c493e09d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToCatchTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToCatchTest.java @@ -1,8 +1,5 @@ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - public class AddExceptionToCatchTest extends LightQuickFixParameterizedTestCase { public void test() throws Exception { doAllTests(); @@ -12,9 +9,4 @@ public class AddExceptionToCatchTest extends LightQuickFixParameterizedTestCase protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/addCatchBlock"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToThrowsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToThrowsTest.java index 5fa9b96f574d..f25775fb962b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToThrowsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddExceptionToThrowsTest.java @@ -1,8 +1,5 @@ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - public class AddExceptionToThrowsTest extends LightQuickFixParameterizedTestCase { public void test() throws Exception { doAllTests(); @@ -12,9 +9,4 @@ public class AddExceptionToThrowsTest extends LightQuickFixParameterizedTestCase protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/addToThrows"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java index a129c3cbe21d..f496d6a3b3da 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.AnonymousCanBeLambdaInspection; import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class Anonymous2LambdaInspectionTest extends LightQuickFixParameterizedTe protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java index 37e0a4cfd4a8..86ad2edfaaf8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.AnonymousCanBeMethodReferenceInspection; import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class Anonymous2MethodReferenceInspectionTest extends LightQuickFixParame protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java index 0a4f58ca8bbf..fbc121e1a2e2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java @@ -15,12 +15,7 @@ */ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; - -import java.util.ArrayList; -import java.util.LinkedList; public class ChangeMethodSignatureFromUsage8Test extends LightQuickFixParameterizedTestCase { @@ -35,9 +30,4 @@ public class ChangeMethodSignatureFromUsage8Test extends LightQuickFixParameteri protected LanguageLevel getLanguageLevel() { return LanguageLevel.JDK_1_8; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GeneralizeCatchTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GeneralizeCatchTest.java index 90299b35923c..ac0c5b4ae09e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GeneralizeCatchTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GeneralizeCatchTest.java @@ -1,8 +1,5 @@ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - public class GeneralizeCatchTest extends LightQuickFixParameterizedTestCase { public void test() throws Exception { doAllTests(); @@ -12,9 +9,4 @@ public class GeneralizeCatchTest extends LightQuickFixParameterizedTestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/generalizeCatch"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java index 125aaf43ce44..6c6cda6147ae 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection; import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class Lambda2MethodReferenceInspectionTest extends LightQuickFixParameter protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java index 1a34d12eb448..757b720c44c6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.RedundantLambdaCodeBlockInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class RedundantLambdaCodeBlockInspectionTest extends LightQuickFixParamet protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantTypeArgsInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantTypeArgsInspectionTest.java index 67659c1af372..110d2deac42d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantTypeArgsInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantTypeArgsInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.miscGenerics.RedundantTypeArgsInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -35,9 +33,4 @@ public class RedundantTypeArgsInspectionTest extends LightQuickFixParameterizedT protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceFromOfNullableFixTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceFromOfNullableFixTest.groovy index 15ef5ff77f14..213258fa48ef 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceFromOfNullableFixTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceFromOfNullableFixTest.groovy @@ -15,14 +15,13 @@ */ package com.intellij.codeInsight.daemon.quickFix + import com.intellij.codeInspection.LocalInspectionTool import com.intellij.codeInspection.dataFlow.DataFlowInspection import com.intellij.openapi.Disposable import com.intellij.openapi.command.WriteCommandAction -import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile -import com.intellij.testFramework.IdeaTestUtil import org.jetbrains.annotations.NotNull public class ReplaceFromOfNullableFixTest extends LightQuickFixParameterizedTestCase { @@ -82,8 +81,4 @@ public abstract class Optional { super.afterActionCompleted(testName, contents) } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithOfNullableFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithOfNullableFixTest.java index 8df4cf22e5c5..3b486baf08b3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithOfNullableFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithOfNullableFixTest.java @@ -22,8 +22,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.dataFlow.DataFlowInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; public class ReplaceWithOfNullableFixTest extends LightQuickFixParameterizedTestCase { @@ -55,9 +53,4 @@ public class ReplaceWithOfNullableFixTest extends LightQuickFixParameterizedTest ReplaceFromOfNullableFixTest.cleanupGuava(); super.afterActionCompleted(testName, contents); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java index eac9703e7ff0..b9c67141273f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java @@ -18,11 +18,9 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.lang.java.JavaLanguage; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -68,9 +66,4 @@ public class Simplify2DiamondInspectionsTest extends LightQuickFixParameterizedT protected LanguageLevel getLanguageLevel() { return LanguageLevel.JDK_1_8; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/StreamApiMigrationInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/StreamApiMigrationInspectionTest.java index a112ddfa5045..4e6c407ec6f2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/StreamApiMigrationInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/StreamApiMigrationInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.StreamApiMigrationInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class StreamApiMigrationInspectionTest extends LightQuickFixParameterized protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialFunctionalExpressionUsageInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialFunctionalExpressionUsageInspectionTest.java index 5de09e455807..6069a3ff6475 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialFunctionalExpressionUsageInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialFunctionalExpressionUsageInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.TrivialFunctionalExpressionUsageInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class TrivialFunctionalExpressionUsageInspectionTest extends LightQuickFi protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialMethodReferenceInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialMethodReferenceInspectionTest.java index 00263f77aab1..320e749c4475 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialMethodReferenceInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/TrivialMethodReferenceInspectionTest.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.TrivialMethodReferenceInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; @@ -37,9 +35,4 @@ public class TrivialMethodReferenceInspectionTest extends LightQuickFixParameter protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/trivialMethodReference"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapLongWithMathToIntExactFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapLongWithMathToIntExactFixTest.java index a32d1f339ff3..caa712f13340 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapLongWithMathToIntExactFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapLongWithMathToIntExactFixTest.java @@ -15,9 +15,6 @@ */ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - /** * @author Dmitry Batkovich */ @@ -30,9 +27,4 @@ public class WrapLongWithMathToIntExactFixTest extends LightQuickFixParameterize protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/wrapLongWithMathToIntExact"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapObjectWithOptionalFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapObjectWithOptionalFixTest.java index 401fcdc1a61e..993a3347e221 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapObjectWithOptionalFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/WrapObjectWithOptionalFixTest.java @@ -15,9 +15,6 @@ */ package com.intellij.codeInsight.daemon.quickFix; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - /** * @author Dmitry Batkovich */ @@ -30,9 +27,4 @@ public class WrapObjectWithOptionalFixTest extends LightQuickFixParameterizedTes protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/wrapObjectWithOptional"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/MergeFilterChainActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/MergeFilterChainActionTest.java index bcfbeb79b701..b1aa1985cdba 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/MergeFilterChainActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/MergeFilterChainActionTest.java @@ -16,8 +16,6 @@ package com.intellij.codeInsight.intention; import com.intellij.codeInsight.daemon.LightIntentionActionTestCase; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; public class MergeFilterChainActionTest extends LightIntentionActionTestCase { @@ -27,9 +25,4 @@ public class MergeFilterChainActionTest extends LightIntentionActionTestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/mergeFilter"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitFilterActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitFilterActionTest.java index efe14b0a2055..02f1a5967709 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitFilterActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitFilterActionTest.java @@ -16,8 +16,6 @@ package com.intellij.codeInsight.intention; import com.intellij.codeInsight.daemon.LightIntentionActionTestCase; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; public class SplitFilterActionTest extends LightIntentionActionTestCase { @@ -27,9 +25,4 @@ public class SplitFilterActionTest extends LightIntentionActionTestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/splitFilter"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspectionTest.java index c79fb02d6c61..87ab36223390 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspectionTest.java @@ -16,8 +16,6 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; /** @@ -35,11 +33,6 @@ public class SimplifyStreamApiCallChainsInspectionTest extends LightQuickFixPara doAllTests(); } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - @Override protected String getBasePath() { return "/inspection/streamApiCallChains"; diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/StringTokenizerDelimiterInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/StringTokenizerDelimiterInspectionTest.java index ddac3879885c..c51611905489 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/StringTokenizerDelimiterInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/StringTokenizerDelimiterInspectionTest.java @@ -16,8 +16,6 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; /** @@ -39,9 +37,4 @@ public class StringTokenizerDelimiterInspectionTest extends LightQuickFixParamet protected String getBasePath() { return "/inspection/stringTokenizerDelimiter"; } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/ide/util/JavaSuperMethodTest.java b/java/java-tests/testSrc/com/intellij/ide/util/JavaSuperMethodTest.java index 3b241630e76f..cd4e7b3afc32 100644 --- a/java/java-tests/testSrc/com/intellij/ide/util/JavaSuperMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/ide/util/JavaSuperMethodTest.java @@ -17,11 +17,9 @@ package com.intellij.ide.util; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.impl.FindSuperElementsHelper; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -38,11 +36,6 @@ public class JavaSuperMethodTest extends LightDaemonAnalyzerTestCase { return "/codeInsight/gotosuper/"; } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - public void testDoNotGoToSiblingInheritanceIfInLibrary() throws Throwable { configureByFile(getBasePath() + "OverridingLibrary.java"); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java index b5ee7c877183..a6102422f724 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java @@ -21,13 +21,11 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.JavaCodeFragment; import com.intellij.psi.JavaCodeFragmentFactory; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { @@ -314,9 +312,4 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { " }\n" + " }"); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectTest.java index deb8f12c3839..c51c4ae2bbc4 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectTest.java @@ -22,13 +22,10 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.TargetElementUtil; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.refactoring.extractMethodObject.ExtractMethodObjectHandler; import com.intellij.refactoring.extractMethodObject.ExtractMethodObjectProcessor; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; public class ExtractMethodObjectTest extends LightRefactoringTestCase { @@ -145,9 +142,4 @@ public class ExtractMethodObjectTest extends LightRefactoringTestCase { public void testWithPrivateMethodWhichCantBeMoved() throws Exception { doTest(); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java index e6f177806752..dbac0ff8100c 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java @@ -17,12 +17,10 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.openapi.editor.SelectionModel; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import com.intellij.refactoring.extractMethod.ExtractMethodHandler; import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.TestDataPath; import org.jetbrains.annotations.NotNull; @@ -83,11 +81,6 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase return LanguageLevel.JDK_1_8; } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } - private void doTest() { doTest(null); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 56034a69ca86..4ab61941c063 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -18,7 +18,6 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiElement; @@ -29,7 +28,6 @@ import com.intellij.refactoring.introduceVariable.InputValidator; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; import com.intellij.refactoring.introduceVariable.IntroduceVariableSettings; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; @@ -562,9 +560,4 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { testMe.invoke(getProject(), getEditor(), getFile(), null); checkResultByFile(baseName + ".after.java"); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java index c74e41a21383..699d338a410a 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java @@ -16,7 +16,6 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; @@ -26,7 +25,6 @@ import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil; import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -281,9 +279,4 @@ public class PullUpTest extends LightRefactoringTestCase { protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PushDownTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PushDownTest.java index 84648a70edbc..6271f4dc96fe 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PushDownTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PushDownTest.java @@ -16,14 +16,12 @@ package com.intellij.refactoring; import com.intellij.codeInsight.TargetElementUtil; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.memberPushDown.PushDownProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.refactoring.util.classMembers.MemberInfoStorage; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.usageView.UsageInfo; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; @@ -183,9 +181,4 @@ public class PushDownTest extends LightRefactoringTestCase { checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy b/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy index ba23b91162c1..6b979db4f82a 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy +++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy @@ -14,15 +14,14 @@ * limitations under the License. */ package com.intellij.refactoring + import com.intellij.codeInsight.TargetElementUtil import com.intellij.codeInsight.lookup.LookupEx import com.intellij.codeInsight.lookup.LookupManager import com.intellij.codeInsight.template.impl.TemplateManagerImpl import com.intellij.codeInsight.template.impl.TemplateState -import com.intellij.openapi.projectRoots.Sdk import com.intellij.psi.PsiElement import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler -import com.intellij.testFramework.IdeaTestUtil import com.intellij.testFramework.LightCodeInsightTestCase /** * User: anna @@ -71,10 +70,6 @@ class RenameSuggestionsTest extends LightCodeInsightTestCase { doTestSuggestionAvailable(text, "foo") } - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18() - } public void "test by Optional_of initializer"() { def suggestions = getNameSuggestions(""" diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java index 60e48283bda6..30c32410e834 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java @@ -17,7 +17,6 @@ package com.intellij.refactoring.inline; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.TargetElementUtil; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; @@ -27,7 +26,6 @@ import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.LightRefactoringTestCase; import com.intellij.refactoring.MockInlineMethodOptions; import com.intellij.refactoring.util.InlineUtil; -import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -369,9 +367,4 @@ public class InlineMethodTest extends LightRefactoringTestCase { new InlineMethodProcessor(getProject(), method, refExpr, myEditor, options.isInlineThisOnly(), nonCode, nonCode); processor.run(); } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } } From 74e52cde5d729c600a92a3c9d004c13c3afed353 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Jul 2016 18:53:11 +0300 Subject: [PATCH 10/41] javadoc --- .../util/src/com/intellij/util/containers/WeakHashMap.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/util/src/com/intellij/util/containers/WeakHashMap.java b/platform/util/src/com/intellij/util/containers/WeakHashMap.java index 14f44e10e7a0..56f878b1d919 100644 --- a/platform/util/src/com/intellij/util/containers/WeakHashMap.java +++ b/platform/util/src/com/intellij/util/containers/WeakHashMap.java @@ -25,8 +25,13 @@ import java.util.Map; /** * Weak keys hash map. + * Custom TObjectHashingStrategy is supported. * Null keys are NOT allowed * Null values are allowed + * + * Use this class if you need custom TObjectHashingStrategy. + * Do not use this class if you have null keys (shame on you). + * Otherwise it's the same as java.util.WeakHashMap, you are free to use either. */ public final class WeakHashMap extends RefHashMap { public WeakHashMap(int initialCapacity, float loadFactor) { From 1c3bcfc3f58cb29d97612a3d300bc292e2ef79f1 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 21 Jul 2016 12:07:23 +0300 Subject: [PATCH 11/41] cleanup --- .../actions/ShowImplementationsAction.java | 7 ++- .../lang/properties/PropertiesUtil.java | 45 ++++++++++--------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java index 038a85eb921f..37f655cec865 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java @@ -155,8 +155,6 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { String text = ""; PsiElement[] impls = PsiElement.EMPTY_ARRAY; if (element != null) { - //if (element instanceof PsiPackage) return; - impls = getSelfAndImplementations(editor, element, createImplementationsSearcher()); text = SymbolPresentationUtil.getSymbolPresentableText(element); } @@ -176,7 +174,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { } if (!implsList.isEmpty()) { - implsList.toArray( impls = new PsiElement[implsList.size()] ); + impls = implsList.toArray(new PsiElement[implsList.size()]); } } @@ -455,7 +453,8 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { }; if (!myIncludeSelf) { myElements = getSelfAndImplementations(myEditor, myElement, implementationSearcher, false); - } else { + } + else { myElements = getSelfAndImplementations(myEditor, myElement, implementationSearcher); } } 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 315273769180..dd4e9eca0546 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 @@ -40,26 +40,27 @@ import java.util.regex.Pattern; * @author cdr */ public class PropertiesUtil { - public final static Pattern LOCALE_PATTERN = Pattern.compile("(_[a-zA-Z]{2,8}(_[a-zA-Z]{2}|[0-9]{3})?(_[\\w\\-]+)?)\\.[^_]+$"); - public final static Set BASE_NAME_BORDER_CHAR = ContainerUtil.newHashSet('-', '_', '.'); - public final static Locale DEFAULT_LOCALE = new Locale("", "", ""); + private static final Pattern LOCALE_PATTERN = Pattern.compile("(_[a-zA-Z]{2,8}(_[a-zA-Z]{2}|[0-9]{3})?(_[\\w\\-]+)?)\\.[^_]+$"); + public static final Set BASE_NAME_BORDER_CHAR = ContainerUtil.newHashSet('-', '_', '.'); + public static final Locale DEFAULT_LOCALE = new Locale("", "", ""); private static final SoftLazyValue> LOCALES_LANGUAGE_CODES = new SoftLazyValue>() { @NotNull @Override protected Set compute() { final HashSet locales = - new HashSet(ContainerUtil.flatten(ContainerUtil.map(Locale.getAvailableLocales(), - (Function>)locale -> { - final ArrayList languages = ContainerUtil.newArrayList(locale.getLanguage()); - try { - languages.add(locale.getISO3Language()); - } - catch (MissingResourceException ignored) { - // if ISO3 language is not found for existed locale then exception is thrown anyway - } - return languages; - }))); + new HashSet<>(ContainerUtil.flatten(ContainerUtil.map(Locale.getAvailableLocales(), + (Function>)locale -> { + final ArrayList languages = + ContainerUtil.newArrayList(locale.getLanguage()); + try { + languages.add(locale.getISO3Language()); + } + catch (MissingResourceException ignored) { + // if ISO3 language is not found for existed locale then exception is thrown anyway + } + return languages; + }))); locales.addAll(ContainerUtil.newArrayList(Locale.getISOLanguages())); return locales; } @@ -97,7 +98,7 @@ public class PropertiesUtil { } @NotNull - public static String getDefaultBaseName(@NotNull final VirtualFile file) { + static String getDefaultBaseName(@NotNull final VirtualFile file) { final String name = file.getName(); if (!StringUtil.containsChar(name, '_')) { @@ -126,7 +127,7 @@ public class PropertiesUtil { } @NotNull - public static Locale getLocale(final @NotNull PropertiesFile propertiesFile) { + public static Locale getLocale(@NotNull final PropertiesFile propertiesFile) { String name = propertiesFile.getName(); if (!StringUtil.containsChar(name, '_')) return DEFAULT_LOCALE; final String containingResourceBundleBaseName = propertiesFile.getResourceBundle().getBaseName(); @@ -153,7 +154,7 @@ public class PropertiesUtil { * messages_en.properties is a parent of the messages_en_US.properties */ @Nullable - public static PropertiesFile getParent(PropertiesFile file, Collection candidates) { + public static PropertiesFile getParent(@NotNull PropertiesFile file, @NotNull Collection candidates) { VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) return null; String name = virtualFile.getNameWithoutExtension(); @@ -175,7 +176,7 @@ public class PropertiesUtil { @NotNull @Deprecated public static List findAllProperties(Project project, @NotNull ResourceBundle resourceBundle, String key) { - List result = new SmartList(); + List result = new SmartList<>(); List propertiesFiles = resourceBundle.getPropertiesFiles(); for (PropertiesFile propertiesFile : propertiesFiles) { result.addAll(propertiesFile.findPropertiesByKey(key)); @@ -184,7 +185,7 @@ public class PropertiesUtil { } public static List findAllProperties(@NotNull ResourceBundle resourceBundle, String key) { - List result = new SmartList(); + List result = new SmartList<>(); List propertiesFiles = resourceBundle.getPropertiesFiles(); for (PropertiesFile propertiesFile : propertiesFiles) { result.addAll(propertiesFile.findPropertiesByKey(key)); @@ -206,13 +207,13 @@ public class PropertiesUtil { } @Nullable - public static String getPackageQualifiedName(@NotNull PsiDirectory directory) { + static String getPackageQualifiedName(@NotNull PsiDirectory directory) { return ProjectRootManager.getInstance(directory.getProject()).getFileIndex().getPackageNameByDirectory(directory.getVirtualFile()); } @NotNull public static String getPresentableLocale(@NotNull Locale locale) { - List names = new ArrayList(); + List names = new ArrayList<>(); if (!Comparing.strEqual(locale.getDisplayLanguage(), null)) { names.add(locale.getDisplayLanguage()); } @@ -222,7 +223,7 @@ public class PropertiesUtil { if (!Comparing.strEqual(locale.getDisplayVariant(), null)) { names.add(locale.getDisplayVariant()); } - return names.isEmpty() ? "" : (" (" + StringUtil.join(names, "/") + ")"); + return names.isEmpty() ? "" : " (" + StringUtil.join(names, "/") + ")"; } public static boolean hasDefaultLanguage(Locale locale) { From 57fa83a4c08891dee001fcde034d66397005408c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 21 Jul 2016 12:33:25 +0300 Subject: [PATCH 12/41] use mock jdk 8 by default in InspectionTestCase --- .../JavaAPIUsagesInspectionTest.java | 6 ------ .../MagicConstantInspectionTest.java | 4 +++- .../codeInspection/RedundantCast15Test.java | 7 +++++++ .../codeInspection/RedundantCast18Test.java | 11 ----------- .../codeInspection/RedundantThrowTest.java | 11 ----------- .../codeInspection/UnusedReturnValueTest.java | 11 ----------- java/mockJDK-1.8/jre/lib/rt.jar | Bin 5403267 -> 5404399 bytes .../testFramework/InspectionTestCase.java | 4 ++-- .../StandardVariableNames.java | 10 +++++++--- .../standard_variable_names/expected.xml | 7 +++++++ .../AssertWithSideEffectsInspectionTest.java | 7 +++++++ .../FinalPrivateMethodInspectionTest.java | 12 ------------ ...OverridesAbstractMethodInspectionTest.java | 11 ----------- ...terfaceNeverImplementedInspectionTest.java | 8 -------- ...ocalVariableOrParameterInspectionTest.java | 7 +++++++ ...ssaryFullyQualifiedNameInspectionTest.java | 9 ++++++++- ...odOverloadsParentMethodInspectionTest.java | 13 ------------- 17 files changed, 48 insertions(+), 90 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java index 981fb7fe67eb..0e651d1a6199 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java @@ -23,7 +23,6 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.codeInspection.java15api.Java15APIUsageInspection; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.InspectionTestCase; @@ -63,11 +62,6 @@ public class JavaAPIUsagesInspectionTest extends InspectionTestCase { IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_1_6, JavaAPIUsagesInspectionTest.this::doTest); } - @Override - protected Sdk getTestProjectSdk() { - return IdeaTestUtil.getMockJdk18(); - } - //generate apiXXX.txt /* //todo exclude inheritors of ConcurrentMap#putIfAbsent diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/MagicConstantInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/MagicConstantInspectionTest.java index 8588e37d1fbf..3c28371a74c2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/MagicConstantInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/MagicConstantInspectionTest.java @@ -38,6 +38,7 @@ import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.PsiClassImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.FileTreeAccessFilter; +import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.InspectionTestCase; import com.intellij.testFramework.PsiTestUtil; import org.jetbrains.annotations.NotNull; @@ -62,7 +63,8 @@ public class MagicConstantInspectionTest extends InspectionTestCase { @Override protected Sdk getTestProjectSdk() { - return PsiTestUtil.addJdkAnnotations(super.getTestProjectSdk()); + // has to have JFrame and sources + return PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk17()); } private void doTest() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java index a8b27ab21089..d6c194fd1f92 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java @@ -3,6 +3,7 @@ package com.intellij.codeInspection; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.codeInspection.redundantCast.RedundantCastInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.pom.java.LanguageLevel; @@ -17,6 +18,12 @@ public class RedundantCast15Test extends InspectionTestCase { ModuleRootModificationUtil.setModuleSdk(getModule(), getTestProjectSdk()); } + @Override + protected Sdk getTestProjectSdk() { + // in jdk 8 some casts are unnecessary + return IdeaTestUtil.getMockJdk17(); + } + private void doTest() throws Exception { final LocalInspectionToolWrapper toolWrapper = new LocalInspectionToolWrapper(new RedundantCastInspection()); doTest("redundantCast/generics/" + getTestName(false), toolWrapper, "java 1.5"); diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java index fe187a68940d..7e9bcf8e18e4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java @@ -17,10 +17,6 @@ package com.intellij.codeInspection; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.codeInspection.redundantCast.RedundantCastInspection; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.InspectionTestCase; public class RedundantCast18Test extends InspectionTestCase { @@ -35,11 +31,4 @@ public class RedundantCast18Test extends InspectionTestCase { public void testForeachValue() throws Exception { doTest(); } public void testConditional() throws Exception { doTest(); } public void testInferApplicabilityError() throws Exception { doTest(); } - - @Override - protected Sdk getTestProjectSdk() { - Sdk sdk = IdeaTestUtil.getMockJdk17(); - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_8); - return sdk; - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantThrowTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantThrowTest.java index 61dc1d9a5600..4a7d7d1f35ab 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantThrowTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantThrowTest.java @@ -17,10 +17,6 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; import com.intellij.codeInspection.unneededThrows.RedundantThrows; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.InspectionTestCase; public class RedundantThrowTest extends InspectionTestCase { @@ -68,11 +64,4 @@ public class RedundantThrowTest extends InspectionTestCase { public void testThrownClausesInFunctionalExpressions() throws Exception { doTest(); } - - @Override - protected Sdk getTestProjectSdk() { - Sdk sdk = IdeaTestUtil.getMockJdk17(); - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_8); - return sdk; - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueTest.java index 74f27e0b0c11..c72432532ad6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueTest.java @@ -12,10 +12,6 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; import com.intellij.codeInspection.unusedReturnValue.UnusedReturnValue; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.InspectionTestCase; public class UnusedReturnValueTest extends InspectionTestCase { @@ -47,13 +43,6 @@ public class UnusedReturnValueTest extends InspectionTestCase { doTest(); } - @Override - protected Sdk getTestProjectSdk() { - Sdk sdk = IdeaTestUtil.getMockJdk18(); - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_8); - return sdk; - } - public void testSimpleSetter() throws Exception { try { myTool.IGNORE_BUILDER_PATTERN = true; diff --git a/java/mockJDK-1.8/jre/lib/rt.jar b/java/mockJDK-1.8/jre/lib/rt.jar index f3a4f893f3d4e0277f7d7122d88bcad4e34ad3d1..6885606d29649dd7080546543cbc1da1de042ab8 100644 GIT binary patch delta 71425 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 variable names Variable named <code>str</code> doesn't have type 'java.lang.String' #loc + + + StandardVariableNames.java + 32 + Standard variable names + Variable named <code>b</code> doesn't have type 'byte' or 'java.lang.Byte' #loc + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/AssertWithSideEffectsInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/AssertWithSideEffectsInspectionTest.java index b1106554548f..d0b21a7960a7 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/AssertWithSideEffectsInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/AssertWithSideEffectsInspectionTest.java @@ -1,8 +1,15 @@ package com.siyeh.ig.bugs; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class AssertWithSideEffectsInspectionTest extends IGInspectionTestCase { + @Override + protected Sdk getTestProjectSdk() { + // uses SQL + return IdeaTestUtil.getMockJdk17(); + } public void test() throws Exception { doTest("com/siyeh/igtest/bugs/assert_with_side_effects", diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java index cc10fbc46415..7d51d61c834b 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java @@ -15,24 +15,12 @@ */ package com.siyeh.ig.classlayout; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; -import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; /** * @author Bas Leijdekkers */ public class FinalPrivateMethodInspectionTest extends IGInspectionTestCase { - - @Override - protected Sdk getTestProjectSdk() { - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7); - return IdeaTestUtil.getMockJdk17(); - } - public void test() throws Exception { doTest("com/siyeh/igtest/classlayout/final_private_method", new FinalPrivateMethodInspection()); } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspectionTest.java index 753c2f76f53a..5e6ed0b25c88 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspectionTest.java @@ -1,9 +1,5 @@ package com.siyeh.ig.inheritance; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class AbstractMethodOverridesAbstractMethodInspectionTest extends IGInspectionTestCase { @@ -14,11 +10,4 @@ public class AbstractMethodOverridesAbstractMethodInspectionTest extends IGInspe tool.ignoreJavaDoc = true; doTest("com/siyeh/igtest/inheritance/abstract_method_overrides_abstract_method", tool); } - - @Override - protected Sdk getTestProjectSdk() { - Sdk sdk = IdeaTestUtil.getMockJdk17(); - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST); - return sdk; - } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/InterfaceNeverImplementedInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/InterfaceNeverImplementedInspectionTest.java index d0bbbac1b820..1ebeb5519194 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/InterfaceNeverImplementedInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/InterfaceNeverImplementedInspectionTest.java @@ -1,14 +1,11 @@ package com.siyeh.ig.inheritance; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class InterfaceNeverImplementedInspectionTest extends IGInspectionTestCase { - public void test() throws Exception { final LanguageLevelProjectExtension levelProjectExtension = LanguageLevelProjectExtension.getInstance(getProject()); final LanguageLevel level = levelProjectExtension.getLanguageLevel(); @@ -21,9 +18,4 @@ public class InterfaceNeverImplementedInspectionTest extends IGInspectionTestCas levelProjectExtension.setLanguageLevel(level); } } - - @Override - protected Sdk getTestProjectSdk() { - return IdeaTestUtil.getMockJdk18(); - } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFinalOnLocalVariableOrParameterInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFinalOnLocalVariableOrParameterInspectionTest.java index a78fff6c492a..2dcbf3dfe287 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFinalOnLocalVariableOrParameterInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFinalOnLocalVariableOrParameterInspectionTest.java @@ -15,9 +15,16 @@ */ package com.siyeh.ig.style; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class UnnecessaryFinalOnLocalVariableOrParameterInspectionTest extends IGInspectionTestCase { + @Override + protected Sdk getTestProjectSdk() { + // effectively final rules are different in jdk 8 + return IdeaTestUtil.getMockJdk17(); + } public void test() throws Exception { doTest("com/siyeh/igtest/style/unnecessary_final_on_local_variable_or_parameter", diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspectionTest.java index 1856fc662a46..144eac9359b9 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspectionTest.java @@ -1,14 +1,21 @@ package com.siyeh.ig.style; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleSettings; +import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class UnnecessaryFullyQualifiedNameInspectionTest extends IGInspectionTestCase { - private static final String BASE_DIR = "com/siyeh/igtest/style/"; + @Override + protected Sdk getTestProjectSdk() { + // uses awt + return IdeaTestUtil.getMockJdk17(); + } + public void testFqnInJavadoc_Unnecessary_WhenFullyQualifyIfNotImported() throws Exception { doTestWithFqnInJavadocSetting(BASE_DIR + "unnecessary_fqn_javadoc_fully_qualify_if_not_imported", JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED); } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java index 0fe9f5d4c1c1..d187b16cb6ba 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java @@ -1,22 +1,9 @@ package com.siyeh.ig.visibility; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class MethodOverloadsParentMethodInspectionTest extends IGInspectionTestCase { - public void test() throws Exception { doTest("com/siyeh/igtest/visibility/method_overloads_parent_method", new MethodOverloadsParentMethodInspection()); } - - @Override - protected Sdk getTestProjectSdk() { - final Sdk sdk = IdeaTestUtil.getMockJdk17(); - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST); - return sdk; - } - } \ No newline at end of file From 137b925a85aaee2b2c2f8c8345da65f1bc2c78d1 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Jul 2016 12:57:57 +0300 Subject: [PATCH 13/41] build scripts: set custom idea.platform.prefix in bat-file, duplication removed --- .../intellij/build/BuildContext.groovy | 2 ++ .../build/impl/BuildContextImpl.groovy | 18 +++++++++++++ .../impl/LinuxDistributionBuilder.groovy | 14 +--------- .../impl/WindowsDistributionBuilder.groovy | 26 +++---------------- 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy b/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy index 5a04b403a0a3..c4c20b20f765 100644 --- a/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy +++ b/build/groovy/org/jetbrains/intellij/build/BuildContext.groovy @@ -66,6 +66,8 @@ abstract class BuildContext { abstract boolean includeBreakGenLibraries() + abstract String getAdditionalJvmArguments() + abstract void notifyArtifactBuilt(String artifactPath) abstract File findApplicationInfoInSources() diff --git a/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy b/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy index 9a838a58fa15..462928272916 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy @@ -208,6 +208,24 @@ class BuildContextImpl extends BuildContext { productLayout.additionalPlatformModules.containsKey("java-runtime") } + @Override + String getAdditionalJvmArguments() { + String jvmArgs + if (productProperties.platformPrefix != null +//todo[nik] remove later. This is added to keep the current behavior (platform prefix for CE is set in MainImpl anyway) + && productProperties.platformPrefix != "Idea") { + jvmArgs = "-Didea.platform.prefix=${productProperties.platformPrefix}" + } + else { + jvmArgs = "" + } + jvmArgs += " $productProperties.additionalIdeJvmArguments".trim() + if (productProperties.toolsJarRequired) { + jvmArgs += " -Didea.jre.check=true" + } + return jvmArgs.trim() + } + @Override void notifyArtifactBuilt(String artifactPath) { if (!underTeamCity) return diff --git a/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy index 23c8cd235d6d..badd29c54816 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy @@ -76,20 +76,8 @@ class LinuxDistributionBuilder { String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${buildContext.bootClassPathJarNames[0]}\"\n" classPath += buildContext.bootClassPathJarNames[1..-1].collect { "CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\"" }.join("\n") - String jvmArgs - if (buildContext.productProperties.platformPrefix != null -//todo[nik] remove later. This is added to keep current behavior (platform prefix for CE is set in MainImpl anyway) - && buildContext.productProperties.platformPrefix != "Idea") { - jvmArgs = "-Didea.platform.prefix=${buildContext.productProperties.platformPrefix}" - } - else { - jvmArgs = "" - } - - jvmArgs = "$jvmArgs $buildContext.productProperties.additionalIdeJvmArguments".trim() if (buildContext.productProperties.toolsJarRequired) { classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\"" - jvmArgs = "$jvmArgs -Didea.jre.check=true".trim() } buildContext.ant.copy(todir: "${unixDistPath}/bin") { @@ -101,7 +89,7 @@ class LinuxDistributionBuilder { filter(token: "vm_options", value: vmOptionsFileName) filter(token: "isEap", value: buildContext.applicationInfo.isEAP) filter(token: "system_selector", value: buildContext.systemSelector) - filter(token: "ide_jvm_args", value: jvmArgs) + filter(token: "ide_jvm_args", value: buildContext.additionalJvmArguments) filter(token: "class_path", value: classPath) filter(token: "script_name", value: name) } diff --git a/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy index 937443949483..774f54928f64 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy @@ -18,10 +18,9 @@ package org.jetbrains.intellij.build.impl import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.build.JvmArchitecture -import org.jetbrains.intellij.build.ProductModulesLayout import org.jetbrains.intellij.build.WindowsDistributionCustomizer -import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.model.module.JpsModuleSourceRoot + /** * @author nik */ @@ -90,7 +89,6 @@ class WindowsDistributionBuilder { String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${buildContext.bootClassPathJarNames[0]}\n" classPath += buildContext.bootClassPathJarNames[1..-1].collect { "SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\$it" }.join("\n") - def jvmArgs = getAdditionalJvmArguments() if (buildContext.productProperties.toolsJarRequired) { classPath += "\nSET CLASS_PATH=%CLASS_PATH%;%JDK%\\lib\\tools.jar" } @@ -105,7 +103,7 @@ class WindowsDistributionBuilder { filter(token: "vm_options", value: vmOptionsFileName) filter(token: "isEap", value: buildContext.applicationInfo.isEAP) filter(token: "system_selector", value: buildContext.systemSelector) - filter(token: "ide_jvm_args", value: jvmArgs) + filter(token: "ide_jvm_args", value: buildContext.additionalJvmArguments) filter(token: "class_path", value: classPath) filter(token: "script_name", value: batName) } @@ -124,14 +122,6 @@ class WindowsDistributionBuilder { buildContext.ant.fixcrlf(srcdir: "$winDistPath/bin", includes: "*.bat", eol: "dos") } - private String getAdditionalJvmArguments() { - def jvmArgs = buildContext.productProperties.additionalIdeJvmArguments - if (buildContext.productProperties.toolsJarRequired) { - return "$jvmArgs -Didea.jre.check=true".trim() - } - return jvmArgs - } - //todo[nik] rename private void winVMOptions() { JvmArchitecture.values().each { @@ -149,17 +139,7 @@ class WindowsDistributionBuilder { def launcherPropertiesPath = "${buildContext.paths.temp}/launcher${arch.fileSuffix}.properties" def upperCaseProductName = buildContext.applicationInfo.upperCaseProductName def lowerCaseProductName = buildContext.applicationInfo.shortProductName.toLowerCase() - String vmOptions - if (buildContext.productProperties.platformPrefix != null -//todo[nik] remove later. This is added to keep current behavior (platform prefix for CE is set in MainImpl anyway) - && buildContext.productProperties.platformPrefix != "Idea") { - vmOptions = "-Didea.platform.prefix=${buildContext.productProperties.platformPrefix}" - } - else { - vmOptions = "" - } - - vmOptions = "$vmOptions -Didea.paths.selector=${buildContext.systemSelector} ${getAdditionalJvmArguments()}".trim() + String vmOptions = "$buildContext.additionalJvmArguments -Didea.paths.selector=${buildContext.systemSelector}".trim() def productName = buildContext.applicationInfo.upperCaseProductName //todo[nik] use '.productName' instead String jdkEnvVarSuffix = arch == JvmArchitecture.x64 ? "_64" : ""; From 262ef8de80156e63ce5d0bc51c43aba3a4dcab8b Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 Jul 2016 16:54:30 +0200 Subject: [PATCH 14/41] cache LambdaUtil.findFunctionCandidates --- .../src/com/intellij/psi/LambdaUtil.java | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index c1864e69373e..7376042ef16e 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -216,36 +216,46 @@ public class LambdaUtil { } @Nullable - public static List findFunctionCandidates(PsiClass psiClass) { + public static List findFunctionCandidates(final PsiClass psiClass) { if (psiClass != null && psiClass.isInterface() && !psiClass.isAnnotationType()) { - final List methods = new ArrayList(); - final Map> overrideEquivalents = PsiSuperMethodUtil.collectOverrideEquivalents(psiClass); - final Collection visibleSignatures = psiClass.getVisibleSignatures(); - for (HierarchicalMethodSignature signature : visibleSignatures) { - final PsiMethod psiMethod = signature.getMethod(); - if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue; - if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) continue; - final Set equivalentMethods = overrideEquivalents.get(signature); - if (equivalentMethods != null && equivalentMethods.size() > 1) { - boolean hasNonAbstractOverrideEquivalent = false; - for (PsiMethod method : equivalentMethods) { - if (!method.hasModifierProperty(PsiModifier.ABSTRACT) && !MethodSignatureUtil.isSuperMethod(method, psiMethod)) { - hasNonAbstractOverrideEquivalent = true; - break; - } - } - if (hasNonAbstractOverrideEquivalent) continue; + return CachedValuesManager.getCachedValue(psiClass, new CachedValueProvider>() { + @Nullable + @Override + public Result> compute() { + return Result.create(calcFunctionCandidates(psiClass), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } - if (!overridesPublicObjectMethod(signature)) { - methods.add(signature); - } - } - - return hasSubsignature(methods); + }); } return null; } + private static List calcFunctionCandidates(PsiClass psiClass) { + final List methods = new ArrayList(); + final Map> overrideEquivalents = PsiSuperMethodUtil.collectOverrideEquivalents(psiClass); + final Collection visibleSignatures = psiClass.getVisibleSignatures(); + for (HierarchicalMethodSignature signature : visibleSignatures) { + final PsiMethod psiMethod = signature.getMethod(); + if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue; + if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) continue; + final Set equivalentMethods = overrideEquivalents.get(signature); + if (equivalentMethods != null && equivalentMethods.size() > 1) { + boolean hasNonAbstractOverrideEquivalent = false; + for (PsiMethod method : equivalentMethods) { + if (!method.hasModifierProperty(PsiModifier.ABSTRACT) && !MethodSignatureUtil.isSuperMethod(method, psiMethod)) { + hasNonAbstractOverrideEquivalent = true; + break; + } + } + if (hasNonAbstractOverrideEquivalent) continue; + } + if (!overridesPublicObjectMethod(signature)) { + methods.add(signature); + } + } + + return hasSubsignature(methods); + } + @Nullable private static PsiType getReturnType(PsiClass psiClass, MethodSignature methodSignature) { From 0a4f995460be0a9f52d447fc71e265740167fa89 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 Jul 2016 17:10:03 +0200 Subject: [PATCH 15/41] find lambdas passed into vararg methods --- .../psi/impl/java/stubs/JavaMethodElementType.java | 4 ++-- .../psi/impl/source/JavaFileElementType.java | 2 +- .../lambda/findUsages/VarargPosition.java | 6 ++++++ .../daemon/lambda/FindFunctionalInterfaceTest.java | 13 +++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/VarargPosition.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java index 4de4dbeec1f5..68f20356704a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java @@ -20,6 +20,7 @@ import com.intellij.lang.LighterAST; import com.intellij.lang.LighterASTNode; import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiNameHelper; import com.intellij.psi.impl.cache.RecordUtil; import com.intellij.psi.impl.cache.TypeInfo; import com.intellij.psi.impl.java.stubs.impl.PsiMethodStubImpl; @@ -169,8 +170,7 @@ public abstract class JavaMethodElementType extends JavaStubElementType 0) continue; - String typeName = type.getShortTypeText(); + String typeName = PsiNameHelper.getShortClassName(type.text); if (TypeConversionUtil.isPrimitive(typeName) || TypeConversionUtil.isPrimitiveWrapper(typeName)) continue; sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, typeName); if (methodTypeParams != null && methodTypeParams.contains(typeName)) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java index 85fbce060fb7..d6074403ef3e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java @@ -38,7 +38,7 @@ import java.io.IOException; * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 27; + public static final int STUB_VERSION = 28; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/VarargPosition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/VarargPosition.java new file mode 100644 index 000000000000..cc7662348b80 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/VarargPosition.java @@ -0,0 +1,6 @@ +public interface I { + void m(); +} + +interface J extends I {} + diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java index cc967135b311..04d24f20de34 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java @@ -57,6 +57,19 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase doTestOneExpression(); } + public void testVarargPosition() throws Exception { + myFixture.addClass("\n" + + "class A { \n" + + " void foo(T... r) {}\n" + + " void bar(J i){foo(i, i, () -> {});}\n" + + "}"); + for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 1; i++) { + myFixture.addClass("class B" + i + " { {Runnable r = () -> {};}}"); //ensure common case is used + } + + doTestOneExpression(); + } + private void doTestOneExpression() { myFixture.configureByFile(getTestName(false) + ".java"); final PsiElement elementAtCaret = myFixture.getElementAtCaret(); From 1c451db9ad6609195833ee186228bb1238ae2716 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 Jul 2016 17:22:32 +0200 Subject: [PATCH 16/41] a test that lambdas in constructor calls are found --- .../findUsages/ConstructorReferences.java | 9 ++++ .../lambda/FindFunctionalInterfaceTest.java | 48 ++++++++++++++----- 2 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/ConstructorReferences.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/ConstructorReferences.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/ConstructorReferences.java new file mode 100644 index 000000000000..e51e0df8af9b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/findUsages/ConstructorReferences.java @@ -0,0 +1,9 @@ +class Foo { + Foo() { this(() -> 4); } + + Foo(I i) {} +} + +interface I { + int foo(); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java index 04d24f20de34..7ab0bf361c20 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java @@ -50,9 +50,7 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase myFixture.addClass("public class A {" + " public I r;" + "}"); - for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 1; i++) { - myFixture.addClass("class B" + i + " { {Runnable r = () -> {};}}"); //ensure common case is used - } + addManyLambdas(); doTestOneExpression(); } @@ -63,19 +61,14 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase " void foo(T... r) {}\n" + " void bar(J i){foo(i, i, () -> {});}\n" + "}"); - for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 1; i++) { - myFixture.addClass("class B" + i + " { {Runnable r = () -> {};}}"); //ensure common case is used - } + addManyLambdas(); doTestOneExpression(); } private void doTestOneExpression() { myFixture.configureByFile(getTestName(false) + ".java"); - final PsiElement elementAtCaret = myFixture.getElementAtCaret(); - assertNotNull(elementAtCaret); - final PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class, false); - assertTrue(psiClass != null && psiClass.isInterface()); + final PsiClass psiClass = findClassAtCaret(); final Collection expressions = FunctionalExpressionSearch.search(psiClass).findAll(); int size = expressions.size(); assertEquals(1, size); @@ -84,6 +77,15 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase assertEquals("() -> {}", next.getText()); } + @NotNull + private PsiClass findClassAtCaret() { + final PsiElement elementAtCaret = myFixture.getElementAtCaret(); + assertNotNull(elementAtCaret); + final PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class, false); + assertTrue(psiClass != null && psiClass.isInterface()); + return psiClass; + } + public void testFieldFromAnonymousClassScope() throws Exception { myFixture.configureByFile(getTestName(false) + ".java"); final PsiElement elementAtCaret = myFixture.getElementAtCaret(); @@ -108,9 +110,7 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase public void doTestIndexSearch(String expected) { myFixture.configureByFile(getTestName(false) + ".java"); - for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 5; i++) { - myFixture.addFileToProject("a" + i + ".java", "class Goo {{ Runnable r = () -> {} }}"); - } + addManyLambdas(); PsiClass predicate = JavaPsiFacade.getInstance(getProject()).findClass(Predicate.class.getName(), GlobalSearchScope.allScope(getProject())); assert predicate != null; @@ -118,6 +118,28 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase assertEquals(expected, next.getText()); } + public void testConstructorReferences() { + myFixture.configureByFile(getTestName(false) + ".java"); + + myFixture.addClass("class Bar extends Foo {\n" + + " public Bar() { super(() -> 1); }\n" + + "\n" + + " {\n" + + " new Foo(() -> 2) { };\n" + + " new Foo(() -> 3);\n" + + " }\n" + + "}"); + addManyLambdas(); + + assertSize(4, FunctionalExpressionSearch.search(findClassAtCaret()).findAll()); + } + + private void addManyLambdas() { + for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 5; i++) { + myFixture.addFileToProject("a" + i + ".java", "class Goo {{ Runnable r = () -> {} }}"); + } + } + @Override protected String getBasePath() { return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/lambda/findUsages/"; From d1a70e6b65e41ef7f219fcae4a8d2233a41d6e14 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 21 Jul 2016 13:33:53 +0300 Subject: [PATCH 17/41] lower FJ threads priority --- .../intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java b/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java index 13c040f79e71..cc536f329982 100644 --- a/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java +++ b/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java @@ -41,6 +41,7 @@ public class IdeaForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWor } }; thread.setName("JobScheduler FJ pool " + n + "/" + PARALLELISM); + thread.setPriority(Thread.NORM_PRIORITY - 1); return thread; } From 384f3ca19cfb758a3a6368493154375f6a6e6de2 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Jul 2016 13:54:15 +0300 Subject: [PATCH 18/41] build scripts: class renamed --- ...roductModules.groovy => CommunityRepositoryModules.groovy} | 2 +- .../org/jetbrains/intellij/build/ProductModulesLayout.groovy | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename build/groovy/org/jetbrains/intellij/build/{CommonProductModules.groovy => CommunityRepositoryModules.groovy} (99%) diff --git a/build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy b/build/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy similarity index 99% rename from build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy rename to build/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy index da7596d7922d..dab0cb97491a 100644 --- a/build/groovy/org/jetbrains/intellij/build/CommonProductModules.groovy +++ b/build/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy @@ -40,7 +40,7 @@ import static org.jetbrains.intellij.build.impl.PluginLayout.plugin /** * @author nik */ -class CommonProductModules { +class CommunityRepositoryModules { static List PLATFORM_API_MODULES = [ "analysis-api", "built-in-server-api", diff --git a/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy b/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy index 900b21eb4bbf..abb4673f0397 100644 --- a/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy @@ -46,13 +46,13 @@ class ProductModulesLayout { /** * Names of the modules which need to be packed into openapi.jar in the product's 'lib' directory. - * @see CommonProductModules#PLATFORM_API_MODULES + * @see CommunityRepositoryModules#PLATFORM_API_MODULES */ List platformApiModules = [] /** * Names of the modules which need to be included into {@link #mainJarName} in the product's 'lib' directory - * @see CommonProductModules#PLATFORM_IMPLEMENTATION_MODULES + * @see CommunityRepositoryModules#PLATFORM_IMPLEMENTATION_MODULES */ List platformImplementationModules = [] From a77525eb047ecf4310b03b8beb44a5817ee6f33e Mon Sep 17 00:00:00 2001 From: Konstantin Ulitin Date: Thu, 21 Jul 2016 14:22:08 +0300 Subject: [PATCH 19/41] update wip protocol to chromium 51 (WEB-22491) --- .../script-debugger/backend/src/SuspendContextManager.kt | 6 ------ .../script-debugger/debugger-ui/src/DebugProcessImpl.kt | 2 +- .../protocol/protocol-model-generator/src/TypeMap.kt | 4 +++- .../src/org/jetbrains/jsonProtocol/OutMessage.kt | 3 ++- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/platform/script-debugger/backend/src/SuspendContextManager.kt b/platform/script-debugger/backend/src/SuspendContextManager.kt index fb13b95f15f5..a9d1c6413e15 100644 --- a/platform/script-debugger/backend/src/SuspendContextManager.kt +++ b/platform/script-debugger/backend/src/SuspendContextManager.kt @@ -68,12 +68,6 @@ enum class StepAction { */ IN, - /** - * Step into first scheduled async handler. - * @see Chrome debugger suggestion - */ - IN_ASYNC, - /** * Step over the current statement. */ diff --git a/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt b/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt index a50e2397a791..8104b203fceb 100644 --- a/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt +++ b/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt @@ -137,7 +137,7 @@ abstract class DebugProcessImpl>(session: XDebugSession, override final fun startStepInto(context: XSuspendContext?) { val vm = context.vm updateLastCallFrame(vm) - continueVm(vm, if (vm.captureAsyncStackTraces) StepAction.IN_ASYNC else StepAction.IN) + continueVm(vm, StepAction.IN) } override final fun startStepOut(context: XSuspendContext?) { diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/TypeMap.kt b/platform/script-debugger/protocol/protocol-model-generator/src/TypeMap.kt index 74e0977c91b0..48834773f002 100644 --- a/platform/script-debugger/protocol/protocol-model-generator/src/TypeMap.kt +++ b/platform/script-debugger/protocol/protocol-model-generator/src/TypeMap.kt @@ -18,7 +18,9 @@ internal class TypeMap { val domainGenerator = domainGeneratorMap!!.get(domainName) if (domainGenerator == null) { val qName = "$domainName.$typeName"; - if (qName == "IO.StreamHandle" || qName == "Security.SecurityState") return BoxableType.ANY_STRING // ignore + if (qName == "IO.StreamHandle" || qName == "Security.SecurityState" || qName == "Emulation.ScreenOrientation") { + return BoxableType.ANY_STRING // ignore + } throw RuntimeException("Failed to find domain generator: $domainName for type $typeName") } return direction.get(getTypeData(domainName, typeName)).resolve(this, domainGenerator) diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.kt b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.kt index 63a17b083aa4..31f8c204d278 100644 --- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.kt +++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.kt @@ -153,7 +153,8 @@ open class OutMessage() { writer.endArray() } - fun writeStringList(name: String, value: Collection) { + fun writeStringList(name: String, value: Collection?) { + if (value == null) return beginArguments() JsonWriters.writeStringList(writer, name, value) } From b97d27f6e71a448ecab3caf35986c766a0599d41 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 21 Jul 2016 14:14:58 +0300 Subject: [PATCH 20/41] diff: do not access invalid RangeMarker --- .../diff/actions/DocumentFragmentContent.java | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java b/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java index fad819b10401..19b618f7d2bc 100644 --- a/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java +++ b/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java @@ -41,6 +41,7 @@ public class DocumentFragmentContent extends DiffContentBase implements Document // TODO: reuse DocumentWindow ? @NotNull private final DocumentContent myOriginal; + @NotNull private final RangeMarker myRangeMarker; @NotNull private final MyDocumentsSynchronizer mySynchonizer; @@ -54,11 +55,11 @@ public class DocumentFragmentContent extends DiffContentBase implements Document Document document2 = EditorFactory.getInstance().createDocument(""); document2.putUserData(UndoManager.ORIGINAL_DOCUMENT, document1); - RangeMarker rangeMarker = document1.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); - rangeMarker.setGreedyToLeft(true); - rangeMarker.setGreedyToRight(true); + myRangeMarker = document1.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); + myRangeMarker.setGreedyToLeft(true); + myRangeMarker.setGreedyToRight(true); - mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker, document1, document2); + mySynchonizer = new MyDocumentsSynchronizer(project, myRangeMarker, document1, document2); } @NotNull @@ -76,8 +77,9 @@ public class DocumentFragmentContent extends DiffContentBase implements Document @Nullable @Override public Navigatable getNavigatable(@NotNull LineCol position) { + if (!myRangeMarker.isValid()) return null; int offset = position.toOffset(getDocument()); - int originalOffset = offset + mySynchonizer.getStartOffset(); + int originalOffset = offset + myRangeMarker.getStartOffset(); LineCol originalPosition = LineCol.fromOffset(myOriginal.getDocument(), originalOffset); return myOriginal.getNavigatable(originalPosition); } @@ -130,14 +132,6 @@ public class DocumentFragmentContent extends DiffContentBase implements Document myRangeMarker = range; } - public int getStartOffset() { - return myRangeMarker.getStartOffset(); - } - - public int getEndOffset() { - return myRangeMarker.getEndOffset(); - } - @Override protected void onDocumentChanged1(@NotNull DocumentEvent event) { if (!myRangeMarker.isValid()) { @@ -152,9 +146,7 @@ public class DocumentFragmentContent extends DiffContentBase implements Document @Override protected void onDocumentChanged2(@NotNull DocumentEvent event) { - if (!myRangeMarker.isValid()) { - return; - } + if (!myRangeMarker.isValid()) return; if (!myDocument1.isWritable()) return; CharSequence newText = event.getNewFragment(); From a63a419037c89a828ce474e507fda85cadf154f0 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 21 Jul 2016 14:22:09 +0300 Subject: [PATCH 21/41] diff: fix typo in field name --- .../intellij/diff/actions/DocumentFragmentContent.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java b/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java index 19b618f7d2bc..dd39c1782008 100644 --- a/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java +++ b/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java @@ -43,7 +43,7 @@ public class DocumentFragmentContent extends DiffContentBase implements Document @NotNull private final DocumentContent myOriginal; @NotNull private final RangeMarker myRangeMarker; - @NotNull private final MyDocumentsSynchronizer mySynchonizer; + @NotNull private final MyDocumentsSynchronizer mySynchronizer; private int myAssignments = 0; @@ -59,13 +59,13 @@ public class DocumentFragmentContent extends DiffContentBase implements Document myRangeMarker.setGreedyToLeft(true); myRangeMarker.setGreedyToRight(true); - mySynchonizer = new MyDocumentsSynchronizer(project, myRangeMarker, document1, document2); + mySynchronizer = new MyDocumentsSynchronizer(project, myRangeMarker, document1, document2); } @NotNull @Override public Document getDocument() { - return mySynchonizer.getDocument2(); + return mySynchronizer.getDocument2(); } @Nullable @@ -111,12 +111,12 @@ public class DocumentFragmentContent extends DiffContentBase implements Document @Override public void onAssigned(boolean isAssigned) { if (isAssigned) { - if (myAssignments == 0) mySynchonizer.startListen(); + if (myAssignments == 0) mySynchronizer.startListen(); myAssignments++; } else { myAssignments--; - if (myAssignments == 0) mySynchonizer.stopListen(); + if (myAssignments == 0) mySynchronizer.stopListen(); } assert myAssignments >= 0; } From 26bcbb6e8c4a7bc502ceb26907b94eefa8d76e88 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Jul 2016 13:38:46 +0200 Subject: [PATCH 22/41] Cleanup (annotations) --- .../formatter/java/AbstractJavaFormatterTest.java | 13 ++++++------- .../psi/formatter/java/JavaIndenterTest.java | 11 ++++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java index 94d4a659674b..d4c3e9980fbd 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java @@ -36,7 +36,6 @@ import com.intellij.testFramework.LightIdeaTestCase; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.LineReader; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -147,11 +146,11 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { doTest(getTestName(false) + ".java", getTestName(false) + "_after.java"); } - public void doTest(@NonNls String fileNameBefore, @NonNls String fileNameAfter) { + public void doTest(@NotNull String fileNameBefore, @NotNull String fileNameAfter) { doTextTest(Action.REFORMAT, loadFile(fileNameBefore), loadFile(fileNameAfter)); } - public void doTestWithDetectableIndentOptions(@NonNls String text, @NonNls String textAfter) { + public void doTestWithDetectableIndentOptions(@NotNull String text, @NotNull String textAfter) { DetectableIndentOptionsProvider provider = DetectableIndentOptionsProvider.getInstance(); assertNotNull("DetectableIndentOptionsProvider not found", provider); provider.setEnabledInTest(true); @@ -163,11 +162,11 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { } } - public void doTextTest(@NonNls final String text, @NonNls String textAfter) throws IncorrectOperationException { + public void doTextTest(@NotNull String text, @NotNull String textAfter) throws IncorrectOperationException { doTextTest(Action.REFORMAT, text, textAfter); } - public void doTextTest(@NotNull final Action action, @NotNull String text, @NotNull String textAfter) throws IncorrectOperationException { + public void doTextTest(@NotNull Action action, @NotNull String text, @NotNull String textAfter) throws IncorrectOperationException { final PsiFile file = createFile("A.java", text); final PsiDocumentManager manager = PsiDocumentManager.getInstance(getProject()); final Document document = manager.getDocument(file); @@ -226,7 +225,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { return document.getText(); } - public void doMethodTest(@NonNls final String before, @NonNls final String after) { + public void doMethodTest(@NotNull String before, @NotNull String after) { doTextTest( Action.REFORMAT, "class Foo{\n" + " void foo() {\n" + before + '\n' + " }\n" + "}", @@ -234,7 +233,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { ); } - public void doClassTest(@NonNls final String before, @NonNls final String after) { + public void doClassTest(@NotNull String before, @NotNull String after) { doTextTest( Action.REFORMAT, "class Foo{\n" + before + '\n' + "}", diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaIndenterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaIndenterTest.java index 6961877d7bae..625dce1c0c43 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaIndenterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaIndenterTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.psi.formatter.java; import com.intellij.openapi.util.TextRange; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; /** * @author Denis Zhdanov @@ -43,7 +44,7 @@ public class JavaIndenterTest extends AbstractJavaFormatterTest { int end = initial.indexOf("\n", start); myTextRange = new TextRange(start, end); - doTextTest(initial, + doTextTest(initial, "class BrokenAlignment {\n" + " public\n" + "\tstatic int foo(String a, String b, String c,\n" + @@ -64,7 +65,7 @@ public class JavaIndenterTest extends AbstractJavaFormatterTest { "\n" + " }" + "}", - + "class Test {\n" + " // some comment\n" + " public void doSmth(int[] p) {\n" + @@ -74,7 +75,7 @@ public class JavaIndenterTest extends AbstractJavaFormatterTest { } @Override - public void doTextTest(String text, String textAfter) throws IncorrectOperationException { + public void doTextTest(@NotNull String text, @NotNull String textAfter) throws IncorrectOperationException { doTextTest(Action.INDENT, adjustTextIfNecessary(text), textAfter); } @@ -91,4 +92,4 @@ public class JavaIndenterTest extends AbstractJavaFormatterTest { myTextRange = new TextRange(caretIndex, caretIndex); return text.substring(0, caretIndex) + text.substring(caretIndex + CARET_TOKEN.length()); } -} +} \ No newline at end of file From 10c0da8451e6a65bd9a2578e76b614717c3c75a4 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 21 Jul 2016 10:24:16 +0200 Subject: [PATCH 23/41] suppress inspection for testdata --- .../siyeh/ig/style/ProblematicWhitespaceInspectionTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java index c813c05d7879..dcc4a5206b68 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java @@ -27,6 +27,7 @@ import com.siyeh.ig.LightInspectionTestCase; /** * @author Bas Leijdekkers */ +@SuppressWarnings("InfiniteRecursion") public class ProblematicWhitespaceInspectionTest extends LightInspectionTestCase { public void testHtml() { @@ -113,7 +114,7 @@ public class ProblematicWhitespaceInspectionTest extends LightInspectionTestCase final CommonCodeStyleSettings.IndentOptions options = settings.getIndentOptions(JavaFileType.INSTANCE); options.USE_TAB_CHARACTER = true; options.SMART_TABS = true; - doTest("class X {{\n" + + doTest("class X {static{\n" + "\tSystem.out.println(\"asdf\" +\n" + "\t\t\t \"asdf\");\n" + "}}"); From d8def3334c535e436567a09e598b4daadcb0895b Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 21 Jul 2016 12:47:07 +0200 Subject: [PATCH 24/41] exceptions declared by try with resources should collect all close methods from the resource class and choose exceptions in the intersection (IDEA-158762) --- .../dataFlow/ControlFlowAnalyzer.java | 29 +++++---- .../TryWithResourcesPostfixTemplate.java | 7 +-- .../src/com/intellij/psi/util/PsiUtil.java | 18 ++---- .../intellij/codeInsight/ExceptionUtil.java | 62 +++++++++++++------ ...hResourcesWithMultipleCloseInterfaces.java | 48 ++++++++++++++ .../daemon/LightAdvHighlightingJdk7Test.java | 1 + .../com/siyeh/ig/psiutils/ExceptionUtils.java | 28 ++------- 7 files changed, 120 insertions(+), 73 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/TryWithResourcesWithMultipleCloseInterfaces.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index fe68c1c00278..464abd6f8ca5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.openapi.diagnostic.Logger; @@ -1041,9 +1042,9 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { ((PsiResourceExpression)resource).getExpression().accept(this); } - PsiMethod closer = PsiUtil.getResourceCloserMethod(resource); - if (closer != null) { - addMethodThrows(closer, null); + final List closerExceptions = ExceptionUtil.getCloserExceptions(resource); + if (!closerExceptions.isEmpty()) { + addThrows(null, findNextCatch(false), closerExceptions.toArray(new PsiClassType[closerExceptions.size()])); } } } @@ -1411,15 +1412,19 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { CatchDescriptor cd = findNextCatch(false); if (method != null) { PsiClassType[] refs = method.getThrowsList().getReferencedTypes(); - for (PsiClassType ref : refs) { - pushUnknown(); - ConditionalGotoInstruction cond = new ConditionalGotoInstruction(null, false, null); - addInstruction(cond); - addInstruction(new EmptyStackInstruction()); - initException(ref, cd); - addThrowCode(cd, explicitCall); - cond.setOffset(myCurrentFlow.getInstructionCount()); - } + addThrows(explicitCall, cd, refs); + } + } + + private void addThrows(@Nullable PsiElement explicitCall, CatchDescriptor cd, PsiClassType[] refs) { + for (PsiClassType ref : refs) { + pushUnknown(); + ConditionalGotoInstruction cond = new ConditionalGotoInstruction(null, false, null); + addInstruction(cond); + addInstruction(new EmptyStackInstruction()); + initException(ref, cd); + addThrowCode(cd, explicitCall); + cond.setOffset(myCurrentFlow.getInstructionCount()); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java index 3b2ffe5a6832..e6b2e95de45a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java @@ -100,11 +100,6 @@ public class TryWithResourcesPostfixTemplate extends PostfixTemplate { @NotNull private static Collection getUnhandled(@NotNull PsiExpression expression) { assert expression.getType() != null; - PsiMethod methodCloser = PsiUtil.getResourceCloserMethodForType((PsiClassType)expression.getType()); - PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(expression.getType()).getSubstitutor(); - - return methodCloser != null - ? ExceptionUtil.getUnhandledExceptions(methodCloser, expression, null, substitutor) - : Collections.emptyList(); + return ExceptionUtil.getUnhandledCloserExceptions(expression, null, expression.getType()); } } diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java index 5360eb550f29..289154d7e930 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java @@ -1137,20 +1137,9 @@ public final class PsiUtil extends PsiUtilCore { return name != null && IGNORED_NAMES.contains(name); } - @Nullable - public static PsiMethod getResourceCloserMethod(@NotNull PsiResourceListElement resource) { - PsiType resourceType = resource.getType(); - return resourceType instanceof PsiClassType ? getResourceCloserMethodForType((PsiClassType)resourceType) : null; - } - - /** @deprecated use {@link #getResourceCloserMethod(PsiResourceListElement)} (to be removed in IDEA 17) */ - @SuppressWarnings("unused") - public static PsiMethod getResourceCloserMethod(@NotNull PsiResourceVariable resource) { - return getResourceCloserMethod((PsiResourceListElement)resource); - } @Nullable - public static PsiMethod getResourceCloserMethodForType(@NotNull final PsiClassType resourceType) { + public static PsiMethod[] getResourceCloserMethodsForType(@NotNull final PsiClassType resourceType) { final PsiClass resourceClass = resourceType.resolve(); if (resourceClass == null) return null; @@ -1162,7 +1151,10 @@ public final class PsiUtil extends PsiUtilCore { if (JavaClassSupers.getInstance().getSuperClassSubstitutor(autoCloseable, resourceClass, resourceType.getResolveScope(), PsiSubstitutor.EMPTY) == null) return null; final PsiMethod[] closes = autoCloseable.findMethodsByName("close", false); - return closes.length == 1 ? resourceClass.findMethodBySignature(closes[0], true) : null; + if (closes.length == 1) { + return resourceClass.findMethodsBySignature(closes[0], true); + } + return null; } @Nullable diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 7f9c6cc8194c..fc9083936d24 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -38,8 +38,6 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -import static com.intellij.openapi.util.Pair.pair; - /** * @author mike */ @@ -533,38 +531,66 @@ public class ExceptionUtil { if (psiType instanceof PsiClassType) { ex.add((PsiClassType)psiType); } + else if (psiType instanceof PsiCapturedWildcardType) { + final PsiCapturedWildcardType capturedWildcardType = (PsiCapturedWildcardType)psiType; + final PsiType upperBound = capturedWildcardType.getUpperBound(); + if (upperBound instanceof PsiClassType) { + ex.add((PsiClassType)upperBound); + } + } } return ex; } @NotNull public static List getCloserExceptions(@NotNull PsiResourceListElement resource) { - Pair closer = resolveCloser(resource); - return closer != null ? getExceptionsByMethod(closer.first, closer.second, resource) : Collections.emptyList(); + List ex = getExceptionsFromClose(resource); + return ex != null ? ex : Collections.emptyList(); } @NotNull public static List getUnhandledCloserExceptions(@NotNull PsiResourceListElement resource, @Nullable PsiElement topElement) { - Pair closer = resolveCloser(resource); - return closer != null ? getUnhandledExceptions(closer.first, resource, topElement, closer.second) : Collections.emptyList(); + final PsiType type = resource.getType(); + return getUnhandledCloserExceptions(resource, topElement, type); } - private static Pair resolveCloser(PsiResourceListElement resource) { - PsiMethod method = PsiUtil.getResourceCloserMethod(resource); - if (method != null) { - PsiClass closerClass = method.getContainingClass(); - if (closerClass != null) { - PsiClassType.ClassResolveResult resourceType = PsiUtil.resolveGenericsClassInType(resource.getType()); - if (resourceType != null) { - PsiClass resourceClass = resourceType.getElement(); - if (resourceClass != null) { - PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(closerClass, resourceClass, resourceType.getSubstitutor()); - if (substitutor != null) { - return pair(method, substitutor); + @NotNull + public static List getUnhandledCloserExceptions(PsiElement place, @Nullable PsiElement topElement, PsiType type) { + List ex = type instanceof PsiClassType ? getExceptionsFromClose(type, place.getResolveScope()) : null; + return ex != null ? getUnhandledExceptions(place, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])) : Collections.emptyList(); + } + + private static List getExceptionsFromClose(PsiResourceListElement resource) { + final PsiType type = resource.getType(); + return type instanceof PsiClassType ? getExceptionsFromClose(type, resource.getResolveScope()) : null; + } + + private static List getExceptionsFromClose(PsiType type, GlobalSearchScope scope) { + PsiClassType.ClassResolveResult resourceType = PsiUtil.resolveGenericsClassInType(type); + PsiClass resourceClass = resourceType.getElement(); + if (resourceClass == null) return null; + + PsiMethod[] methods = PsiUtil.getResourceCloserMethodsForType((PsiClassType)type); + if (methods != null) { + List ex = null; + for (PsiMethod method : methods) { + PsiClass closerClass = method.getContainingClass(); + if (closerClass != null) { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(closerClass, resourceClass, resourceType.getSubstitutor()); + if (substitutor != null) { + final PsiClassType[] exceptionTypes = method.getThrowsList().getReferencedTypes(); + if (exceptionTypes.length == 0) return Collections.emptyList(); + + if (ex == null) { + ex = collectSubstituted(substitutor, exceptionTypes, scope); + } + else { + retainExceptions(ex, collectSubstituted(substitutor, exceptionTypes, scope)); } } } } + return ex; } return null; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/TryWithResourcesWithMultipleCloseInterfaces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/TryWithResourcesWithMultipleCloseInterfaces.java new file mode 100644 index 000000000000..2ff36864df68 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/TryWithResourcesWithMultipleCloseInterfaces.java @@ -0,0 +1,48 @@ +import java.io.IOException; + +class Ex extends Exception {} + +interface IOCloseable { + void close() throws IOException; +} + +interface ExCloseable { + void close() throws Ex; +} + +interface NoExCloseable { + void close(); +} + +interface TCloseable { + void close() throws T; +} + +interface I1 extends AutoCloseable, IOCloseable {} +interface I1R extends IOCloseable, AutoCloseable {} +interface I2 extends AutoCloseable, IOCloseable, ExCloseable {} +interface I3 extends AutoCloseable, NoExCloseable {} +interface I3R extends NoExCloseable, AutoCloseable {} + +interface IT extends AutoCloseable, TCloseable {} + +class Main { + { + try (I1 i1 = null) {} + try (I1 i11 = null) { + } catch (IOException e){} + try (I1R i11r = null) { + } catch (IOException e){} + + try (I2 i2 = null) {} + try (I2 i21 = null) { + } catch (IOException e) {} + try (I2 i22 = null) { + } catch (Ex e) {} + + try (I3 i3 = null) {} + try (I3R i3r = null) {} + + try (IT it = null) {} + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index c7611febe7f0..9f94acbbdd8e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -180,6 +180,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testUncheckedExtendedWarnings() { doTest(true, false); } public void testInaccessibleInferredTypeForVarargsArgument() { doTest(false, false);} public void testRuntimeClassCast() { doTest(true, false);} + public void testTryWithResourcesWithMultipleCloseInterfaces() { doTest(false, false);} public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExceptionUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExceptionUtils.java index 4bd074c13634..a4a392190344 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExceptionUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExceptionUtils.java @@ -15,8 +15,8 @@ */ package com.siyeh.ig.psiutils; +import com.intellij.codeInsight.ExceptionUtil; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,8 +48,7 @@ public class ExceptionUtils { if (element instanceof PsiResourceList) { final PsiResourceList resourceList = (PsiResourceList)element; for (PsiResourceListElement resource : resourceList) { - final PsiMethod method = PsiUtil.getResourceCloserMethod(resource); - collectExceptionsThrown(method, PsiSubstitutor.EMPTY, out); + out.addAll(ExceptionUtil.getCloserExceptions(resource)); } } final ExceptionsThrownVisitor visitor = new ExceptionsThrownVisitor(out); @@ -202,26 +201,6 @@ public class ExceptionUtils { return false; } - private static void collectExceptionsThrown(@Nullable PsiMethod method, @NotNull PsiSubstitutor substitutor, - @NotNull Set out) { - if (method == null) { - return; - } - for (PsiClassType type : method.getThrowsList().getReferencedTypes()) { - final PsiType substitute = substitutor.substitute(type); - if (substitute instanceof PsiClassType) { - out.add((PsiClassType)substitute); - } - else if (substitute instanceof PsiCapturedWildcardType) { - final PsiCapturedWildcardType capturedWildcardType = (PsiCapturedWildcardType)substitute; - final PsiType upperBound = capturedWildcardType.getUpperBound(); - if (upperBound instanceof PsiClassType) { - out.add((PsiClassType)upperBound); - } - } - } - } - public static Set getExceptionTypesHandled(PsiTryStatement statement) { final Set out = new HashSet<>(5); for (PsiParameter parameter : statement.getCatchBlockParameters()) { @@ -258,7 +237,8 @@ public class ExceptionUtils { if (!(target instanceof PsiMethod)) { return; } - collectExceptionsThrown((PsiMethod)target, resolveResult.getSubstitutor(), m_exceptionsThrown); + final PsiClassType[] referencedTypes = ((PsiMethod)target).getThrowsList().getReferencedTypes(); + m_exceptionsThrown.addAll(ExceptionUtil.collectSubstituted(resolveResult.getSubstitutor(), referencedTypes, callExpression.getResolveScope())); } @Override From 4d47108723af6e2548398234c70486800252faef Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Thu, 21 Jul 2016 14:56:05 +0300 Subject: [PATCH 25/41] Java inspection: In "Remove Braces" inspection handle the case where if/loop body contains another if/loop in a code block, and the quick fix is invoked at the closing brace of the code block. Tests added. (IDEA-157727) --- .../ig/style/SingleStatementInBlockInspection.java | 11 +++++++++-- .../single_statement_block/ElseWithLoop.after.java | 8 ++++++++ .../igfixes/single_statement_block/ElseWithLoop.java | 10 ++++++++++ .../igfixes/single_statement_block/IfElse3.after.java | 8 ++++++++ .../siyeh/igfixes/single_statement_block/IfElse3.java | 10 ++++++++++ .../single_statement_block/IfWithLoop.after.java | 9 +++++++++ .../igfixes/single_statement_block/IfWithLoop.java | 10 ++++++++++ .../fixes/braces/SingleStatementInBlockFixTest.java | 3 +++ 8 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SingleStatementInBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SingleStatementInBlockInspection.java index 5205a4e29a2c..a3b88a9d362d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SingleStatementInBlockInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SingleStatementInBlockInspection.java @@ -161,14 +161,21 @@ public class SingleStatementInBlockInspection extends BaseInspection { else if (startParent instanceof PsiLoopStatement) { body = ((PsiLoopStatement)startParent).getBody(); } - else { - assert startElement instanceof PsiKeyword; + else if (startElement instanceof PsiKeyword) { assert startParent instanceof PsiIfStatement; PsiIfStatement ifStatement = (PsiIfStatement)startParent; body = ((PsiKeyword)startElement).getTokenType() == JavaTokenType.IF_KEYWORD ? ifStatement.getThenBranch() : ifStatement.getElseBranch(); } + else if (startElement instanceof PsiJavaToken && + ((PsiJavaToken)startElement).getTokenType() == JavaTokenType.RBRACE) { // at the end of the omitted body + assert startParent instanceof PsiCodeBlock; + body = startParent.getParent(); + } + else { + return; + } assert body instanceof PsiBlockStatement; doFixImpl((PsiBlockStatement)body); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.after.java new file mode 100644 index 000000000000..1f7d66bfcd0c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.after.java @@ -0,0 +1,8 @@ +class X { + void f(int[] a) { + if (a.length != 0) { + System.out.println(a.length); + } else for (int i = 0; i < 3; i++) + System.out.print(i); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.java new file mode 100644 index 000000000000..4fbe1800de64 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/ElseWithLoop.java @@ -0,0 +1,10 @@ +class X { + void f(int[] a) { + if (a.length != 0) { + System.out.println(a.length); + } else { + for (int i = 0; i < 3; i++) + System.out.print(i); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.after.java new file mode 100644 index 000000000000..b3cd166c8dec --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.after.java @@ -0,0 +1,8 @@ +class X { + { + if (true) { + System.out.println(1); + } + else System.out.println(2); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.java new file mode 100644 index 000000000000..275772dad861 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfElse3.java @@ -0,0 +1,10 @@ +class X { + { + if (true) { + System.out.println(1); + } + else { + System.out.println(2); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.after.java new file mode 100644 index 000000000000..945ed9eb0ac6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.after.java @@ -0,0 +1,9 @@ +class X { + void f(int[] a) { + if (a.length != 0) for (int i : a) + System.out.println(i); + else { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.java new file mode 100644 index 000000000000..b07658ba6ff5 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/single_statement_block/IfWithLoop.java @@ -0,0 +1,10 @@ +class X { + void f(int[] a) { + if (a.length != 0) { + for (int i : a) + System.out.println(i); + } else { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/SingleStatementInBlockFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/SingleStatementInBlockFixTest.java index c72c24ac6c50..d9ebda08bae7 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/SingleStatementInBlockFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/SingleStatementInBlockFixTest.java @@ -29,10 +29,13 @@ public class SingleStatementInBlockFixTest extends IGQuickFixesTestCase { public void testBetweenIfAndElse() { assertQuickfixNotAvailable(getMessagePrefix());} public void testIfElse() { doTest("if"); } public void testIfElse2() { doTest("if"); } + public void testIfElse3() { doTest("else"); } public void testWhile() { doTest("while"); } public void testForEach() { doTest("for"); } public void testForIndex() { doTest("for"); } public void testDoWhile() { doTest("do"); } + public void testIfWithLoop() { doTest("if"); } + public void testElseWithLoop() { doTest("else"); } @Override protected void setUp() throws Exception { From 55feba636fdff57d5ec9c8e82216d5cd4e3fb8c6 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 21 Jul 2016 15:14:29 +0300 Subject: [PATCH 26/41] cleanup --- .../com/intellij/usages/impl/GroupNode.java | 21 ++-- .../src/com/intellij/usages/impl/Node.java | 2 +- ...yntaxHighlighterOverEditorHighlighter.java | 2 +- .../impl/UsageFilteringRuleProviderImpl.java | 10 +- .../impl/UsageGroupingRuleProviderImpl.java | 2 +- .../com/intellij/usages/impl/UsageNode.java | 2 +- .../usages/impl/UsageNodeTreeBuilder.java | 2 +- .../intellij/usages/impl/UsageViewImpl.java | 113 ++++++++---------- .../usages/impl/UsageViewManagerImpl.java | 8 +- .../impl/UsageViewTreeCellRenderer.java | 2 +- .../impl/UsageViewTreeModelBuilder.java | 15 ++- 11 files changed, 80 insertions(+), 99 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java index 4592f0f06702..616aaea0d961 100644 --- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java @@ -41,8 +41,8 @@ public class GroupNode extends Node implements Navigatable, Comparable mySubgroupNodes = new THashMap(); - private final List myUsageNodes = new SmartList(); + private final Map mySubgroupNodes = new THashMap<>(); + private final List myUsageNodes = new SmartList<>(); @NotNull private final UsageViewTreeModelBuilder myUsageTreeModel; private volatile int myRecursiveUsageCount; @@ -67,7 +67,7 @@ public class GroupNode extends Node implements Navigatable, Comparable edtQueue) { @@ -85,7 +85,7 @@ public class GroupNode extends Node implements Navigatable, Comparable edtQueue) { if (!getBuilder().isDetachedMode()) { - edtQueue.consume(() -> myTreeModel.insertNodeInto(node, GroupNode.this, getNodeInsertionIndex(node))); + edtQueue.consume(() -> myTreeModel.insertNodeInto(node, this, getNodeInsertionIndex(node))); } } @@ -105,7 +105,8 @@ public class GroupNode extends Node implements Navigatable, Comparable groupNodes = mySubgroupNodes.values(); for(Iterator iterator = groupNodes.iterator();iterator.hasNext();) { @@ -151,7 +152,7 @@ public class GroupNode extends Node implements Navigatable, Comparable usages) { + boolean removeUsagesBulk(@NotNull Set usages) { boolean removed; synchronized (lock) { removed = myUsageNodes.removeAll(usages); @@ -201,7 +202,7 @@ public class GroupNode extends Node implements Navigatable, Comparable { - myTreeModel.insertNodeInto(node, GroupNode.this, getNodeIndex(node)); + myTreeModel.insertNodeInto(node, this, getNodeIndex(node)); incrementUsageCount(); }); } @@ -247,7 +248,7 @@ public class GroupNode extends Node implements Navigatable, Comparable myTreeModel.nodeChanged(Node.this)); + edtQueue.consume(() -> myTreeModel.nodeChanged(this)); } setFlag(UPDATED_MASK, true); } diff --git a/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java b/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java index 04690cc6fa20..9d9e4bde67bd 100644 --- a/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java +++ b/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java @@ -37,7 +37,7 @@ import org.jetbrains.annotations.NotNull; */ public class SyntaxHighlighterOverEditorHighlighter implements SyntaxHighlighter { private final Lexer lexer; - private LayeredHighlighterIterator layeredHighlighterIterator = null; + private LayeredHighlighterIterator layeredHighlighterIterator; private final SyntaxHighlighter highlighter; public SyntaxHighlighterOverEditorHighlighter(SyntaxHighlighter _highlighter, VirtualFile file, Project project) { diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageFilteringRuleProviderImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageFilteringRuleProviderImpl.java index 7c2d235ec58b..f10e65091860 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageFilteringRuleProviderImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageFilteringRuleProviderImpl.java @@ -45,7 +45,7 @@ public class UsageFilteringRuleProviderImpl implements UsageFilteringRuleProvide @Override @NotNull public UsageFilteringRule[] getActiveRules(@NotNull Project project) { - final List rules = new ArrayList(); + final List rules = new ArrayList<>(); if (!myReadWriteState.isShowReadAccess()) { rules.add(new ReadAccessFilteringRule()); @@ -77,22 +77,22 @@ public class UsageFilteringRuleProviderImpl implements UsageFilteringRuleProvide private boolean myShowReadAccess = true; private boolean myShowWriteAccess = true; - public boolean isShowReadAccess() { + boolean isShowReadAccess() { return myShowReadAccess; } - public void setShowReadAccess(final boolean showReadAccess) { + void setShowReadAccess(final boolean showReadAccess) { myShowReadAccess = showReadAccess; if (!showReadAccess) { myShowWriteAccess = true; } } - public boolean isShowWriteAccess() { + boolean isShowWriteAccess() { return myShowWriteAccess; } - public void setShowWriteAccess(final boolean showWriteAccess) { + void setShowWriteAccess(final boolean showWriteAccess) { myShowWriteAccess = showWriteAccess; if (!showWriteAccess) { myShowReadAccess = true; diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java index 11713b812523..af472d1b3cb4 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java @@ -55,7 +55,7 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider @Override @NotNull public UsageGroupingRule[] getActiveRules(Project project) { - List rules = new ArrayList(); + List rules = new ArrayList<>(); if (supportsNonCodeRule()) { rules.add(new NonCodeUsageGroupingRule(project)); } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageNode.java b/platform/usageView/src/com/intellij/usages/impl/UsageNode.java index fc09c2939ab6..4060c9de1533 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageNode.java @@ -98,7 +98,7 @@ public class UsageNode extends Node implements Comparable, Navigatabl } } - public void setUsageExcluded(boolean usageExcluded) { + void setUsageExcluded(boolean usageExcluded) { myUsageExcluded = usageExcluded; } } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageNodeTreeBuilder.java b/platform/usageView/src/com/intellij/usages/impl/UsageNodeTreeBuilder.java index 55211390e0ac..d073f277b6d0 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageNodeTreeBuilder.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageNodeTreeBuilder.java @@ -54,7 +54,7 @@ class UsageNodeTreeBuilder { myGroupingRules = rules; } - public void setFilteringRules(@NotNull UsageFilteringRule[] rules) { + void setFilteringRules(@NotNull UsageFilteringRule[] rules) { myFilteringRules = rules; } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index 64f0286a6290..537f40e33475 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -61,7 +61,6 @@ import com.intellij.usages.*; import com.intellij.usages.rules.*; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.Convertor; import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.util.enumeration.EmptyEnumeration; import com.intellij.util.messages.MessageBusConnection; @@ -74,7 +73,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.*; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import javax.swing.plaf.TreeUI; import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.tree.*; @@ -108,7 +110,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private final ExclusionHandler myExclusionHandler; private final UsageModelTracker myModelTracker; - private final Map myUsageNodes = new ConcurrentHashMap(); + private final Map myUsageNodes = new ConcurrentHashMap<>(); public static final UsageNode NULL_NODE = new UsageNode(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY)); private final ButtonPanel myButtonPanel = new ButtonPanel(); private final JComponent myAdditionalComponent = new JPanel(new BorderLayout()); @@ -189,7 +191,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra // hack to avoid quadratic expandAll() @Override public Enumeration getExpandedDescendants(TreePath parent) { - return expandingAll ? EmptyEnumeration.getInstance() : super.getExpandedDescendants(parent); + return expandingAll ? EmptyEnumeration.getInstance() : super.getExpandedDescendants(parent); } }; myRootPanel = new MyPanel(myTree); @@ -202,7 +204,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra myBuilder = new UsageNodeTreeBuilder(myTargets, getActiveGroupingRules(project), getActiveFilteringRules(project), myRoot, myProject); final MessageBusConnection messageBusConnection = myProject.getMessageBus().connect(this); - messageBusConnection.subscribe(UsageFilteringRuleProvider.RULES_CHANGED, () -> rulesChanged()); + messageBusConnection.subscribe(UsageFilteringRuleProvider.RULES_CHANGED, this::rulesChanged); myUsageViewTreeCellRenderer = new UsageViewTreeCellRenderer(this); if (!myPresentation.isDetachedMode()) { @@ -231,10 +233,10 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra myTree.setCellRenderer(myUsageViewTreeCellRenderer); collapseAll(); - myModelTracker.addListener(UsageViewImpl.this); + myModelTracker.addListener(this); if (myPresentation.isShowCancelButton()) { - addButtonToLowerPane(() -> close(), UsageViewBundle.message("usage.view.cancel.button")); + addButtonToLowerPane(this::close, UsageViewBundle.message("usage.view.cancel.button")); } myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { @@ -249,7 +251,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } }); } - myTransferToEDTQueue = new TransferToEDTQueue("Insert usages", runnable -> { + myTransferToEDTQueue = new TransferToEDTQueue<>("Insert usages", runnable -> { runnable.run(); return true; }, o -> isDisposed || project.isDisposed(), 200); @@ -336,12 +338,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra // add reaction to scrolling: // since the UsageViewTreeCellRenderer ignores invisible nodes (outside the viewport), their preferred size is incorrect // and we need to recalculate them when the node scrolled into the visible rectangle - treePane.getViewport().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - clearRendererCache(); - } - }); + treePane.getViewport().addChangeListener(e -> clearRendererCache()); myTree.addTreeExpansionListener(new TreeExpansionListener() { @Override public void treeExpanded(TreeExpansionEvent event) { @@ -370,7 +367,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra }; UsageContextPanel.Provider[] extensions = Extensions.getExtensions(UsageContextPanel.Provider.EP_NAME, myProject); - myUsageContextPanelProviders = ContainerUtil.filter(extensions, provider -> provider.isAvailableFor(UsageViewImpl.this)); + myUsageContextPanelProviders = ContainerUtil.filter(extensions, provider -> provider.isAvailableFor(this)); for (UsageContextPanel.Provider provider : myUsageContextPanelProviders) { JComponent component; if (myCurrentUsageContextProvider == null || myCurrentUsageContextProvider == provider) { @@ -386,14 +383,11 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } int index = myUsageContextPanelProviders.indexOf(myCurrentUsageContextProvider); tabbedPane.setSelectedIndex(index); - tabbedPane.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - int currentIndex = tabbedPane.getSelectedIndex(); - UsageContextPanel.Provider selectedProvider = myUsageContextPanelProviders.get(currentIndex); - if (selectedProvider != myCurrentUsageContextProvider) { - tabSelected(selectedProvider); - } + tabbedPane.addChangeListener(e -> { + int currentIndex = tabbedPane.getSelectedIndex(); + UsageContextPanel.Provider selectedProvider = myUsageContextPanelProviders.get(currentIndex); + if (selectedProvider != myCurrentUsageContextProvider) { + tabSelected(selectedProvider); } }); tabbedPane.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT)); @@ -426,7 +420,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private static UsageFilteringRule[] getActiveFilteringRules(final Project project) { final UsageFilteringRuleProvider[] providers = Extensions.getExtensions(UsageFilteringRuleProvider.EP_NAME); - List list = new ArrayList(providers.length); + List list = new ArrayList<>(providers.length); for (UsageFilteringRuleProvider provider : providers) { ContainerUtil.addAll(list, provider.getActiveRules(project)); } @@ -435,7 +429,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private static UsageGroupingRule[] getActiveGroupingRules(@NotNull final Project project) { final UsageGroupingRuleProvider[] providers = Extensions.getExtensions(UsageGroupingRuleProvider.EP_NAME); - List list = new ArrayList(providers.length); + List list = new ArrayList<>(providers.length); for (UsageGroupingRuleProvider provider : providers) { ContainerUtil.addAll(list, provider.getActiveRules(project)); } @@ -515,17 +509,14 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } }); - TreeUIHelper.getInstance().installTreeSpeedSearch(myTree, new Convertor() { - @Override - public String convert(TreePath o) { - Object value = o.getLastPathComponent(); - TreeCellRenderer renderer = myTree.getCellRenderer(); - if (renderer instanceof UsageViewTreeCellRenderer) { - UsageViewTreeCellRenderer coloredRenderer = (UsageViewTreeCellRenderer)renderer; - return coloredRenderer.getPlainTextForNode(value); - } - return value == null ? null : value.toString(); + TreeUIHelper.getInstance().installTreeSpeedSearch(myTree, o -> { + Object value = o.getLastPathComponent(); + TreeCellRenderer renderer = myTree.getCellRenderer(); + if (renderer instanceof UsageViewTreeCellRenderer) { + UsageViewTreeCellRenderer coloredRenderer = (UsageViewTreeCellRenderer)renderer; + return coloredRenderer.getPlainTextForNode(value); } + return value == null ? null : value.toString(); }, true); } @@ -594,7 +585,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } } - public void scheduleDisposeOnClose(@NotNull Disposable disposable) { + private void scheduleDisposeOnClose(@NotNull Disposable disposable) { Disposer.register(this, disposable); } @@ -631,12 +622,9 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, component); final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, component); - scheduleDisposeOnClose(new Disposable() { - @Override - public void dispose() { - expandAllAction.unregisterCustomShortcutSet(component); - collapseAllAction.unregisterCustomShortcutSet(component); - } + scheduleDisposeOnClose(() -> { + expandAllAction.unregisterCustomShortcutSet(component); + collapseAllAction.unregisterCustomShortcutSet(component); }); @@ -709,7 +697,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @NotNull private AnAction[] createGroupingActions() { final UsageGroupingRuleProvider[] providers = Extensions.getExtensions(UsageGroupingRuleProvider.EP_NAME); - List list = new ArrayList(providers.length); + List list = new ArrayList<>(providers.length); for (UsageGroupingRuleProvider provider : providers) { ContainerUtil.addAll(list, provider.createGroupingActions(this)); } @@ -718,9 +706,9 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private void rulesChanged() { ApplicationManager.getApplication().assertIsDispatchThread(); - final List states = new ArrayList(); + final List states = new ArrayList<>(); captureUsagesExpandState(new TreePath(myTree.getModel().getRoot()), states); - final List allUsages = new ArrayList(myUsageNodes.keySet()); + final List allUsages = new ArrayList<>(myUsageNodes.keySet()); Collections.sort(allUsages, USAGE_COMPARATOR); final Set excludedUsages = getExcludedUsages(); reset(); @@ -974,7 +962,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override public void removeUsagesBulk(@NotNull Collection usages) { - final Set nodes = new THashSet(usages.size()); + final Set nodes = new THashSet<>(usages.size()); for (Usage usage : usages) { UsageNode node = myUsageNodes.remove(usage); if (node != null && node != NULL_NODE) { @@ -1001,7 +989,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override public void includeUsages(@NotNull Usage[] usages) { - List nodes = new ArrayList(usages.length); + List nodes = new ArrayList<>(usages.length); for (Usage usage : usages) { final UsageNode node = myUsageNodes.get(usage); if (node != NULL_NODE && node != null) { @@ -1014,7 +1002,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override public void excludeUsages(@NotNull Usage[] usages) { - List nodes = new ArrayList(usages.length); + List nodes = new ArrayList<>(usages.length); for (Usage usage : usages) { final UsageNode node = myUsageNodes.get(usage); if (node != NULL_NODE && node != null) { @@ -1027,7 +1015,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override public void selectUsages(@NotNull Usage[] usages) { - List paths = new LinkedList(); + List paths = new LinkedList<>(); for (Usage usage : usages) { final UsageNode node = myUsageNodes.get(usage); @@ -1128,7 +1116,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra myUpdateAlarm.addRequest(() -> { if (myProject.isDisposed()) return; PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); - documentManager.cancelAndRunWhenAllCommitted("UpdateUsageView", () -> updateImmediately()); + documentManager.cancelAndRunWhenAllCommitted("UpdateUsageView", this::updateImmediately); }, 300); } @@ -1280,7 +1268,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @NotNull private Set getReadOnlyUsages() { - final Set result = new THashSet(); + final Set result = new THashSet<>(); final Set> usages = myUsageNodes.entrySet(); for (Map.Entry entry : usages) { Usage usage = entry.getKey(); @@ -1295,7 +1283,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @NotNull private Set getReadOnlyUsagesFiles() { Set usages = getReadOnlyUsages(); - Set result = new THashSet(); + Set result = new THashSet<>(); for (Usage usage : usages) { if (usage instanceof UsageInFile) { UsageInFile usageInFile = (UsageInFile)usage; @@ -1319,7 +1307,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override @NotNull public Set getExcludedUsages() { - Set result = new THashSet(); + Set result = new THashSet<>(); for (Map.Entry entry : myUsageNodes.entrySet()) { UsageNode node = entry.getValue(); Usage usage = entry.getKey(); @@ -1349,7 +1337,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra TreePath[] leadSelectionPath = myTree.getSelectionPaths(); if (leadSelectionPath == null || leadSelectionPath.length == 0) return null; - final List result = new ArrayList(); + final List result = new ArrayList<>(); for (TreePath comp : leadSelectionPath) { final Object lastPathComponent = comp.getLastPathComponent(); if (lastPathComponent instanceof Node) { @@ -1368,7 +1356,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra return null; } - Set usages = new THashSet(); + Set usages = new THashSet<>(); for (TreePath selectionPath : selectionPaths) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectionPath.getLastPathComponent(); collectUsages(node, usages); @@ -1386,7 +1374,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override @NotNull public List getSortedUsages() { - List usages = new ArrayList(getUsages()); + List usages = new ArrayList<>(getUsages()); Collections.sort(usages, USAGE_COMPARATOR); return usages; } @@ -1410,7 +1398,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra TreePath[] selectionPaths = myTree.getSelectionPaths(); if (selectionPaths == null) return null; - Set targets = new THashSet(); + Set targets = new THashSet<>(); for (TreePath selectionPath : selectionPaths) { Object lastPathComponent = selectionPath.getLastPathComponent(); if (lastPathComponent instanceof UsageTargetNode) { @@ -1440,7 +1428,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra if (nodes == null) { return null; } - final List result = new ArrayList(); + final List result = new ArrayList<>(); for (final Node node : nodes) { /* if (!node.isDataValid()) { @@ -1461,7 +1449,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private class MyPanel extends JPanel implements TypeSafeDataProvider, OccurenceNavigator,Disposable{ @Nullable private OccurenceNavigatorSupport mySupport; - private CopyProvider myCopyProvider; + private final CopyProvider myCopyProvider; private MyPanel(@NotNull JTree tree) { mySupport = new OccurenceNavigatorSupport(tree) { @@ -1618,12 +1606,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra DumbService.getInstance(myProject).makeDumbAware(button, UsageViewImpl.this); button.setFocusable(false); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - runnable.run(); - } - }); + button.addActionListener(e -> runnable.run()); add(button, index); diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index f5ac066cf8b4..08f12fbdd601 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -122,7 +122,7 @@ public class UsageViewManagerImpl extends UsageViewManager { @NotNull final FindUsagesProcessPresentation processPresentation, @Nullable final UsageViewStateListener listener) { final SearchScope searchScopeToWarnOfFallingOutOf = getMaxSearchScopeToWarnOfFallingOutOf(searchFor); - final AtomicReference usageViewRef = new AtomicReference(); + final AtomicReference usageViewRef = new AtomicReference<>(); Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) { @Override @@ -243,7 +243,7 @@ public class UsageViewManagerImpl extends UsageViewManager { if (file != null) { return isFileInScope(file, searchScope); } - else if(element != null) { + if (element != null) { return searchScope instanceof EverythingGlobalScope || searchScope instanceof ProjectScopeImpl || searchScope instanceof ProjectAndLibrariesScope; @@ -258,9 +258,7 @@ public class UsageViewManagerImpl extends UsageViewManager { if (searchScope instanceof LocalSearchScope) { return ((LocalSearchScope)searchScope).isInScope(file); } - else { - return ((GlobalSearchScope)searchScope).contains(file); - } + return ((GlobalSearchScope)searchScope).contains(file); } @NotNull diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java index 7408e9b69f6b..5d05d7f8a0fc 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java @@ -49,7 +49,7 @@ class UsageViewTreeCellRenderer extends ColoredTreeCellRenderer { private static final SimpleTextAttributes ourNumberOfUsagesAttribute = SimpleTextAttributes.fromTextAttributes(ourColorsScheme.getAttributes(UsageTreeColors.NUMBER_OF_USAGES)); private static final SimpleTextAttributes ourInvalidAttributesDarcula = new SimpleTextAttributes(null, DarculaColors.RED, null, ourInvalidAttributes.getStyle()); private static final Insets STANDARD_IPAD_NOWIFI = new Insets(1, 2, 1, 2); - private boolean myRowBoundsCalled = false; + private boolean myRowBoundsCalled; private final UsageViewPresentation myPresentation; private final UsageView myView; diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java index 321690e41082..5631564c4d86 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java @@ -18,7 +18,6 @@ package com.intellij.usages.impl; import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageViewPresentation; import com.intellij.usages.UsageViewSettings; -import com.intellij.util.Consumer; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -55,8 +54,8 @@ public class UsageViewTreeModelBuilder extends DefaultTreeModel { myDetachedMode = presentation.isDetachedMode(); } - public static class TargetsRootNode extends DefaultMutableTreeNode { - public TargetsRootNode(String name) { + static class TargetsRootNode extends DefaultMutableTreeNode { + TargetsRootNode(String name) { super(name); } } @@ -71,10 +70,10 @@ public class UsageViewTreeModelBuilder extends DefaultTreeModel { myTargetsNode.add(targetNode); myTargetNodes[i] = targetNode; } - myRootNode.addNode(myTargetsNode, runnable -> UIUtil.invokeLaterIfNeeded(runnable)); + myRootNode.addNode(myTargetsNode, UIUtil::invokeLaterIfNeeded); } - public UsageNode getFirstUsageNode() { + UsageNode getFirstUsageNode() { return (UsageNode)getFirstChildOfType(myRootNode, UsageNode.class); } @@ -93,7 +92,7 @@ public class UsageViewTreeModelBuilder extends DefaultTreeModel { return null; } - public boolean areTargetsValid() { + boolean areTargetsValid() { if (myTargetNodes == null) return true; for (UsageTargetNode targetNode : myTargetNodes) { if (!targetNode.isValid()) return false; @@ -119,11 +118,11 @@ public class UsageViewTreeModelBuilder extends DefaultTreeModel { } } - public boolean isDetachedMode() { + boolean isDetachedMode() { return myDetachedMode; } - public boolean isFilterDuplicatedLine() { + boolean isFilterDuplicatedLine() { return myPresentation.isMergeDupLinesAvailable() && UsageViewSettings.getInstance().isFilterDuplicatedLine(); } } From fcc94ac9eeaae666a25acba3638f6f37300db2a8 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Thu, 21 Jul 2016 13:02:30 +0300 Subject: [PATCH 27/41] IDEA-158422 Keymap: for non-QWERTY keyboard layouts Ctrl is processed as Ctrl+Alt (Windows) or Alt (Mac OS) when combined with symbols --- .../src/com/intellij/ide/CharToVKeyMap.java | 2 +- .../src/com/intellij/ide/IdeEventQueue.java | 100 ++++++------------ 2 files changed, 34 insertions(+), 68 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java b/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java index 3d15ec4ca98f..92e85cab47d0 100644 --- a/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java +++ b/platform/platform-impl/src/com/intellij/ide/CharToVKeyMap.java @@ -29,7 +29,7 @@ class CharToVKeyMap { new HashMap(); public static Integer get (Character ch) { - return charToVKeyMap.get(ch); + return charToVKeyMap.containsKey(ch) ? charToVKeyMap.get(ch) : KeyEvent.VK_UNDEFINED; } static { diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index ce09b77acbe0..9b4dfaa3e9b2 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -439,83 +439,49 @@ public class IdeEventQueue extends EventQueue { // Try to get it from editor Component sourceComponent = WindowManagerEx.getInstanceEx().getMostRecentFocusedWindow(); - if (ke.getID() == KeyEvent.KEY_PRESSED) { - switch (ke.getKeyCode()) { - case KeyEvent.VK_CONTROL: - if ((ke.getModifiersEx() & (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) != (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) { - ctrlIsPressedCount++; - } - break; - case KeyEvent.VK_ALT: - if (ke.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { - if ((ke.getModifiersEx() & (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) != (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) { - leftAltIsPressed = true; - } - } - break; - } - } - else if (ke.getID() == KeyEvent.KEY_RELEASED) { - switch (ke.getKeyCode()) { - case KeyEvent.VK_CONTROL: - ctrlIsPressedCount = 0; - break; - case KeyEvent.VK_ALT: - if (ke.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { - leftAltIsPressed = false; - } - break; - } + switch (ke.getID()) { + case KeyEvent.KEY_PRESSED: + break; + case KeyEvent.KEY_RELEASED: + break; } - if (!leftAltIsPressed && KeyboardSettingsExternalizable.getInstance().isUkrainianKeyboard(sourceComponent)) { - if ('ґ' == ke.getKeyChar() || ke.getKeyCode() == KeyEvent.VK_U) { - ke = new KeyEvent(ke.getComponent(), ke.getID(), ke.getWhen(), 0, - KeyEvent.VK_UNDEFINED, 'ґ', ke.getKeyLocation()); - ke.setKeyCode(KeyEvent.VK_U); - ke.setKeyChar('ґ'); - return ke; - } - } + //if (!leftAltIsPressed && KeyboardSettingsExternalizable.getInstance().isUkrainianKeyboard(sourceComponent)) { + // if ('ґ' == ke.getKeyChar() || ke.getKeyCode() == KeyEvent.VK_U) { + // ke = new KeyEvent(ke.getComponent(), ke.getID(), ke.getWhen(), 0, + // KeyEvent.VK_UNDEFINED, 'ґ', ke.getKeyLocation()); + // ke.setKeyCode(KeyEvent.VK_U); + // ke.setKeyChar('ґ'); + // return ke; + // } + //} + + // NB: Standard keyboard layout is an English keyboard layout. If such + // layout is active every KeyEvent that is received has + // a @{code KeyEvent.getKeyCode} key code corresponding to + // the @{code KeyEvent.getKeyChar} key char in the event. + // For example, VK_MINUS key code and '-' character + // + // We have a key char. On some non standard layouts it does not correspond to + // key code in the event. Integer keyCodeFromChar = CharToVKeyMap.get(ke.getKeyChar()); + + // Now we have a correct key code as if we'd gotten a KeyEvent for + // standard English layout + + if (keyCodeFromChar == ke.getKeyCode() || keyCodeFromChar == KeyEvent.VK_UNDEFINED) { + return e; + } + + // Farther we handle a non standard layout + if (keyCodeFromChar != null) { if (keyCodeFromChar != ke.getKeyCode()) { // non-english layout ke.setKeyCode(keyCodeFromChar); } - - //for (int i = 0; sourceComponent == null && i < WindowManagerEx.getInstanceEx().getAllProjectFrames().length; i++) { - // sourceComponent = WindowManagerEx.getInstanceEx().getAllProjectFrames()[i].getComponent(); - //} - - if (sourceComponent != null) { - if (KeyboardSettingsExternalizable.isSupportedKeyboardLayout(sourceComponent)) { - if ((ke.getModifiersEx() & (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) != 0 /*&& ke.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT*/) { - // On German keyboard layout on Windows we are getting on key press - // ctrl + alt instead of AltGr - - int modifiers = ke.getModifiers() ^ InputEvent.ALT_DOWN_MASK ^ InputEvent.CTRL_DOWN_MASK; - - if (ctrlIsPressedCount > 1) { - modifiers |= InputEvent.CTRL_DOWN_MASK; - } - - if (leftAltIsPressed) { - modifiers |= InputEvent.ALT_MASK; - } - - int oldKeyCode = ke.getKeyCode(); - - //noinspection MagicConstant - ke = new KeyEvent(ke.getComponent(), ke.getID(), ke.getWhen(), modifiers, - KeyEvent.VK_UNDEFINED, ke.getKeyChar(), KeyEvent.KEY_LOCATION_UNKNOWN); - - ke.setKeyCode(oldKeyCode); - } - } } - } return ke; } From b9426526628f64affe2a725597b7671af572b9a5 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Thu, 21 Jul 2016 16:05:30 +0300 Subject: [PATCH 28/41] IDEA-156735 Bookmarks causing typing slowness (use document as storage, add some synchronization) --- .../ide/bookmarks/BookmarkManager.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java index 34299445c9ef..d88bb7ed9732 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java @@ -35,10 +35,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; @@ -63,9 +60,9 @@ import java.util.List; ) public class BookmarkManager extends AbstractProjectComponent implements PersistentStateComponent { private static final int MAX_AUTO_DESCRIPTION_SIZE = 50; + public static Key> BOOKMARKS_KEY = Key.create("bookmarks"); private final List myBookmarks = new ArrayList(); - private final Map> myDocumentsMap = new WeakHashMap<>(); private final Map, Bookmark> myDeletedDocumentBookmarks = new HashMap, Bookmark>(); private final Map>> myBeforeChangeData = new HashMap<>(); @@ -127,21 +124,21 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist }, project); } - private void map(Document document, Bookmark bookmark) { + private static void map(Document document, Bookmark bookmark) { if (document == null || bookmark == null) return; - List list = myDocumentsMap.get(document); + List list = document.getUserData(BOOKMARKS_KEY); if (list == null) { - myDocumentsMap.put(document, list = new ArrayList()); + document.putUserData(BOOKMARKS_KEY, list = Collections.synchronizedList(new ArrayList())); } list.add(bookmark); } - private void unmap(Document document, Bookmark bookmark) { + private static void unmap(Document document, Bookmark bookmark) { if (document == null || bookmark == null) return; - List list = myDocumentsMap.get(document); + List list = document.getUserData(BOOKMARKS_KEY); if (list != null && list.remove(bookmark) && list.isEmpty()) { - myDocumentsMap.remove(document); + document.putUserData(BOOKMARKS_KEY, null); } } @@ -232,7 +229,7 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist @Nullable public Bookmark findEditorBookmark(@NotNull Document document, int line) { - List bookmarks = myDocumentsMap.get(document); + List bookmarks = document.getUserData(BOOKMARKS_KEY); if (bookmarks != null) { for (Bookmark bookmark : bookmarks) { if (bookmark.getLine() == line) { @@ -294,8 +291,8 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist for (Bookmark bookmark : myBookmarks) { bookmark.release(); publisher.bookmarkRemoved(bookmark); + unmap(bookmark.getDocument(), bookmark); } - myDocumentsMap.clear(); myBookmarks.clear(); readExternal(state); @@ -406,7 +403,7 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist @Nullable public Bookmark findLineBookmark(@NotNull Editor editor, boolean isWrapped, boolean next) { - List bookmarksForDocument = myDocumentsMap.get(editor.getDocument()); + List bookmarksForDocument = editor.getDocument().getUserData(BOOKMARKS_KEY); if (bookmarksForDocument == null) return null; int sign = next ? 1 : -1; Collections.sort(bookmarksForDocument, (o1, o2) -> sign * (o1.getLine() - o2.getLine())); From 601f057d4ec40d2e8f1326f346aacc57a6b39b25 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 21 Jul 2016 16:12:49 +0300 Subject: [PATCH 29/41] IDEA-152049 add more debugging info --- .../intellij/ide/util/treeView/TreeState.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java index 1411eaa4439e..597f0311144c 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java @@ -492,5 +492,39 @@ public class TreeState implements JDOMExternalizable { public void setScrollToSelection(boolean scrollToSelection) { myScrollToSelection = scrollToSelection; } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TreeState(").append(myScrollToSelection).append(")"); + append(sb, " expanded:", myExpandedPaths); + append(sb, " selected:", mySelectedPaths); + return sb.toString(); + } + + private static void append(StringBuilder sb, String prefix, Object object) { + if (prefix != null) { + sb.append(prefix); + } + if (object instanceof List) { + appendList(sb, (List)object); + } + else { + sb.append(object); + } + } + + private static void appendList(StringBuilder sb, List list) { + if (list.isEmpty()) { + sb.append("{}"); + } + else { + String prefix = "{"; + for (Object object : list) { + append(sb, prefix, object); + prefix = ", "; + } + sb.append("}"); + } + } } From 22f0f80163a6adc19c2f390b2c54a1170b5b797a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 21 Jul 2016 16:20:51 +0300 Subject: [PATCH 30/41] IDEA-152049 Project view collapses in unpinned mode after some time and changes in editor --- .../ide/projectView/impl/AbstractProjectViewPane.java | 8 +++----- .../src/com/intellij/ide/util/treeView/TreeState.java | 4 ++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java index 051f42c3ebe9..67fc45cc4613 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java @@ -438,7 +438,7 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl String subId = subPane.getAttributeValue(ATTRIBUTE_SUBID); TreeState treeState = new TreeState(); treeState.readExternal(subPane); - myReadTreeState.put(subId, treeState); + if (!treeState.isEmpty()) myReadTreeState.put(subId, treeState); } } @@ -458,15 +458,13 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl protected void saveExpandedPaths() { if (myTree != null) { TreeState treeState = TreeState.createOn(myTree); - myReadTreeState.put(getSubId(), treeState); + if (!treeState.isEmpty()) myReadTreeState.put(getSubId(), treeState); } } public final void restoreExpandedPaths(){ TreeState treeState = myReadTreeState.get(getSubId()); - if (treeState != null) { - treeState.applyTo(myTree); - } + if (treeState != null && !treeState.isEmpty()) treeState.applyTo(myTree); } public void installComparator() { diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java index 597f0311144c..538916f6aefd 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java @@ -110,6 +110,10 @@ public class TreeState implements JDOMExternalizable { this(new ArrayList>(), new ArrayList>()); } + public boolean isEmpty() { + return myExpandedPaths.isEmpty() && mySelectedPaths.isEmpty(); + } + @Override public void readExternal(Element element) throws InvalidDataException { readExternal(element, myExpandedPaths, PATH); From a77222e172049023a437fbbf3fb0ce100a393c16 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Thu, 21 Jul 2016 16:45:39 +0300 Subject: [PATCH 31/41] inspection configurable: use one-px splitter --- .../ui/SingleInspectionProfilePanel.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 3696a69c043a..54dd3a37ee36 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -58,7 +58,6 @@ import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigT import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeRenderer; import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeTable; import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable; -import com.intellij.psi.PsiElement; import com.intellij.psi.search.scope.packageSet.NamedScope; import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; @@ -66,6 +65,8 @@ import com.intellij.util.Alarm; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.Queue; +import com.intellij.util.ui.JBInsets; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import gnu.trove.THashSet; @@ -676,6 +677,7 @@ public class SingleInspectionProfilePanel extends JPanel { final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable); myTreeTable.getTree().setShowsRootHandles(true); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.BOTTOM + SideBorder.LEFT + SideBorder.TOP)); TreeUtil.collapseAll(myTreeTable.getTree(), 1); myTreeTable.getTree().addTreeExpansionListener(new TreeExpansionListener() { @@ -895,21 +897,21 @@ public class SingleInspectionProfilePanel extends JPanel { severityPanel.add(new JLabel(InspectionsBundle.message("inspection.severity")), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, - new Insets(10, 0, 10, 0), 0, 0)); + JBUI.insets(10, 0), 0, 0)); final JComponent severityLevelChooserComponent = severityLevelChooser.createCustomComponent(severityLevelChooser.getTemplatePresentation()); severityPanel.add(severityLevelChooserComponent, new GridBagConstraints(1, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, - new Insets(10, 0, 10, 0), 0, 0)); + JBUI.insets(10, 0), 0, 0)); final JComponent scopesChooserComponent = scopesChooser.createCustomComponent(scopesChooser.getTemplatePresentation()); severityPanel.add(scopesChooserComponent, new GridBagConstraints(2, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, - new Insets(10, 0, 10, 0), 0, 0)); + JBUI.insets(10, 0), 0, 0)); final JLabel label = new JLabel("", SwingConstants.RIGHT); severityPanel.add(label, new GridBagConstraints(3, 0, 1, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.BOTH, - new Insets(2, 0, 2, 0), 0, 0)); + JBUI.insets(2, 0), 0, 0)); severityPanelWeightY = 0.0; if (singleNode != null) { setConfigPanel(configPanelAnchor, mySelectedProfile.getToolDefaultState(singleNode.getDefaultDescriptor().getKey().toString(), @@ -985,19 +987,20 @@ public class SingleInspectionProfilePanel extends JPanel { panel.setMinimumSize(new Dimension(getMinimumSize().width, 3 * scopesAndScopesAndSeveritiesTable.getRowHeight())); severityPanel.add(new JBLabel("Severity by Scope"), new GridBagConstraints(0, 0, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, - new Insets(5, 0, 2, 10), 0, 0)); + JBUI.insets(5, 0, 2, 10), 0, 0)); severityPanel.add(panel, new GridBagConstraints(0, 1, 1, 1, 0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, - new Insets(0, 0, 0, 0), 0, 0)); + JBUI.insets(0, 0, 0, 0), 0, 0)); severityPanelWeightY = 0.3; } - myOptionsPanel.add(severityPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, severityPanelWeightY, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + myOptionsPanel.add(severityPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, severityPanelWeightY, GridBagConstraints.WEST, GridBagConstraints.BOTH, + JBUI.insets(0, 2, 0, 0), 0, 0)); if (configPanelAnchor.getComponentCount() != 0) { - configPanelAnchor.setBorder(IdeBorderFactory.createTitledBorder("Options", false, new Insets(7, 0, 0, 0))); + configPanelAnchor.setBorder(IdeBorderFactory.createTitledBorder("Options", false, new JBInsets(7, 0, 0, 0))); } GuiUtils.enableChildren(myOptionsPanel, isThoughOneNodeEnabled(nodes)); if (configPanelAnchor.getComponentCount() != 0 || scopesNames.isEmpty()) { myOptionsPanel.add(configPanelAnchor, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, - new Insets(0, 0, 0, 0), 0, 0)); + JBUI.insets(0, 2, 0, 0), 0, 0)); } myOptionsPanel.revalidate(); } @@ -1086,7 +1089,7 @@ public class SingleInspectionProfilePanel extends JPanel { JPanel descriptionPanel = new JPanel(new BorderLayout()); descriptionPanel.setBorder(IdeBorderFactory.createTitledBorder(InspectionsBundle.message("inspection.description.title"), false, - new Insets(2, 0, 0, 0))); + new JBInsets(2, 2, 0, 0))); descriptionPanel.add(ScrollPaneFactory.createScrollPane(myBrowser), BorderLayout.CENTER); myRightSplitter = new JBSplitter(true, "SingleInspectionProfilePanel.HORIZONTAL_DIVIDER_PROPORTION", DIVIDER_PROPORTION_DEFAULT); @@ -1102,10 +1105,12 @@ public class SingleInspectionProfilePanel extends JPanel { final JPanel northPanel = new JPanel(new GridBagLayout()); northPanel.setBorder(IdeBorderFactory.createEmptyBorder(2, 0, 2, 0)); myProfileFilter.setPreferredSize(new Dimension(20, myProfileFilter.getPreferredSize().height)); - northPanel.add(myProfileFilter, new GridBagConstraints(0, 0, 1, 1, 0.5, 1, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - northPanel.add(createTreeToolbarPanel().getComponent(), new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.BASELINE_LEADING, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + northPanel.add(myProfileFilter, new GridBagConstraints(0, 0, 1, 1, 0.5, 1, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.HORIZONTAL, + JBUI.emptyInsets(), 0, 0)); + northPanel.add(createTreeToolbarPanel().getComponent(), new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.BASELINE_LEADING, GridBagConstraints.HORIZONTAL, + JBUI.emptyInsets(), 0, 0)); - myMainSplitter = new JBSplitter(false, DIVIDER_PROPORTION_DEFAULT, 0.01f, 0.99f); + myMainSplitter = new OnePixelSplitter(false, DIVIDER_PROPORTION_DEFAULT, 0.01f, 0.99f); myMainSplitter.setSplitterProportionKey("SingleInspectionProfilePanel.VERTICAL_DIVIDER_PROPORTION"); myMainSplitter.setFirstComponent(tree); myMainSplitter.setSecondComponent(myRightSplitter); From 6ed35065d7c73af23772d5498ce16b7324b559ef Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 21 Jul 2016 16:51:08 +0300 Subject: [PATCH 32/41] Throw real OutOfMemoryError --- .../intellij/diagnostic/DropAnOutOfMemoryErrorAction.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/DropAnOutOfMemoryErrorAction.java b/platform/platform-impl/src/com/intellij/diagnostic/DropAnOutOfMemoryErrorAction.java index f8a7a790fc96..d2d83ac31261 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/DropAnOutOfMemoryErrorAction.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/DropAnOutOfMemoryErrorAction.java @@ -15,7 +15,6 @@ */ package com.intellij.diagnostic; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAwareAction; @@ -26,6 +25,10 @@ public class DropAnOutOfMemoryErrorAction extends DumbAwareAction { } public void actionPerformed(AnActionEvent e) { + Object[] array = new Object[Integer.MAX_VALUE]; + for (int i = 0; i < array.length; i++) { + array[i] = new Object[Integer.MAX_VALUE]; + } throw new OutOfMemoryError(); } } \ No newline at end of file From 1dd2dccafefdc08210903b079e227ad401833cdf Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 21 Jul 2016 16:16:07 +0300 Subject: [PATCH 33/41] diff: move fragmented contents to api --- .../com/intellij/diff/DiffContentFactory.java | 7 ++++++ .../intellij/diff/DiffContentFactoryImpl.java | 24 +++++++++++++++---- .../CompareClipboardWithSelectionAction.java | 2 +- .../diff/actions/DocumentFragmentContent.java | 17 +++++++++---- .../ui/models/SelectionDifferenceModel.java | 4 +--- .../vcs/ex/ShowLineStatusRangeDiffAction.java | 3 +-- .../ide/commander/PsiDiffContentFactory.java | 12 +++++----- 7 files changed, 49 insertions(+), 20 deletions(-) diff --git a/platform/diff-api/src/com/intellij/diff/DiffContentFactory.java b/platform/diff-api/src/com/intellij/diff/DiffContentFactory.java index 270150b7103c..95f2bd14b528 100644 --- a/platform/diff-api/src/com/intellij/diff/DiffContentFactory.java +++ b/platform/diff-api/src/com/intellij/diff/DiffContentFactory.java @@ -23,6 +23,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,6 +78,12 @@ public abstract class DiffContentFactory { @Nullable public abstract FileContent createFile(@Nullable Project project, @NotNull VirtualFile file); + @NotNull + public abstract DocumentContent createFragment(@Nullable Project project, @NotNull Document document, @NotNull TextRange range); + + @NotNull + public abstract DocumentContent createFragment(@Nullable Project project, @NotNull DocumentContent content, @NotNull TextRange range); + @NotNull public abstract DiffContent createClipboardContent(); diff --git a/platform/diff-impl/src/com/intellij/diff/DiffContentFactoryImpl.java b/platform/diff-impl/src/com/intellij/diff/DiffContentFactoryImpl.java index b33b4b0e54f9..b2ff4f6ac40d 100644 --- a/platform/diff-impl/src/com/intellij/diff/DiffContentFactoryImpl.java +++ b/platform/diff-impl/src/com/intellij/diff/DiffContentFactoryImpl.java @@ -15,17 +15,20 @@ */ package com.intellij.diff; +import com.intellij.diff.actions.DocumentFragmentContent; import com.intellij.diff.contents.*; import com.intellij.ide.highlighter.ArchiveFileType; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.BinaryFileTypeDecompilers; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FilePath; @@ -143,6 +146,19 @@ public class DiffContentFactoryImpl extends DiffContentFactory { return (FileContent)create(project, file); } + @NotNull + @Override + public DocumentContent createFragment(@Nullable Project project, @NotNull Document document, @NotNull TextRange range) { + DocumentContent content = create(project, document); + return new DocumentFragmentContent(project, content, range); + } + + @NotNull + @Override + public DocumentContent createFragment(@Nullable Project project, @NotNull DocumentContent content, @NotNull TextRange range) { + return new DocumentFragmentContent(project, content, range); + } + @Override @NotNull public DiffContent createClipboardContent() { @@ -225,10 +241,10 @@ public class DiffContentFactoryImpl extends DiffContentFactory { } @NotNull - public static VirtualFile createTemporalFile(@Nullable Project project, - @NotNull String prefix, - @NotNull String suffix, - @NotNull byte[] content) throws IOException { + private static VirtualFile createTemporalFile(@Nullable Project project, + @NotNull String prefix, + @NotNull String suffix, + @NotNull byte[] content) throws IOException { File tempFile = FileUtil.createTempFile(PathUtil.suggestFileName(prefix + "_", true, false), PathUtil.suggestFileName("_" + suffix, true, false), true); if (content.length != 0) { diff --git a/platform/diff-impl/src/com/intellij/diff/actions/CompareClipboardWithSelectionAction.java b/platform/diff-impl/src/com/intellij/diff/actions/CompareClipboardWithSelectionAction.java index 6594d1786778..db6c656d0eb0 100644 --- a/platform/diff-impl/src/com/intellij/diff/actions/CompareClipboardWithSelectionAction.java +++ b/platform/diff-impl/src/com/intellij/diff/actions/CompareClipboardWithSelectionAction.java @@ -106,7 +106,7 @@ public class CompareClipboardWithSelectionAction extends BaseShowDiffAction { SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasSelection()) { TextRange range = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()); - content = new DocumentFragmentContent(project, content, range); + content = DiffContentFactory.getInstance().createFragment(project, content, range); } return content; diff --git a/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java b/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java index dd39c1782008..0bd09104f464 100644 --- a/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java +++ b/platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java @@ -48,20 +48,29 @@ public class DocumentFragmentContent extends DiffContentBase implements Document private int myAssignments = 0; public DocumentFragmentContent(@Nullable Project project, @NotNull DocumentContent original, @NotNull TextRange range) { + this(project, original, createRangeMarker(original.getDocument(), range)); + } + + public DocumentFragmentContent(@Nullable Project project, @NotNull DocumentContent original, @NotNull RangeMarker rangeMarker) { myOriginal = original; + myRangeMarker = rangeMarker; Document document1 = myOriginal.getDocument(); Document document2 = EditorFactory.getInstance().createDocument(""); document2.putUserData(UndoManager.ORIGINAL_DOCUMENT, document1); - myRangeMarker = document1.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); - myRangeMarker.setGreedyToLeft(true); - myRangeMarker.setGreedyToRight(true); - mySynchronizer = new MyDocumentsSynchronizer(project, myRangeMarker, document1, document2); } + @NotNull + private static RangeMarker createRangeMarker(@NotNull Document document, @NotNull TextRange range) { + RangeMarker rangeMarker = document.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true); + rangeMarker.setGreedyToLeft(true); + rangeMarker.setGreedyToRight(true); + return rangeMarker; + } + @NotNull @Override public Document getDocument() { diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/SelectionDifferenceModel.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/SelectionDifferenceModel.java index a98f2dd27168..20f04f3726fa 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/SelectionDifferenceModel.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/SelectionDifferenceModel.java @@ -17,7 +17,6 @@ package com.intellij.history.integration.ui.models; import com.intellij.diff.DiffContentFactory; -import com.intellij.diff.actions.DocumentFragmentContent; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.contents.DocumentContent; import com.intellij.history.core.revisions.Revision; @@ -98,8 +97,7 @@ public class SelectionDifferenceModel extends FileDifferenceModel { int fromOffset = d.getLineStartOffset(myFrom); int toOffset = d.getLineEndOffset(myTo); - DocumentContent documentContent = DiffContentFactory.getInstance().create(myProject, d); - return new DocumentFragmentContent(myProject, documentContent, new TextRange(fromOffset, toOffset)); + return DiffContentFactory.getInstance().createFragment(myProject, d, new TextRange(fromOffset, toOffset)); } private DocumentContent getDiffContent(Revision r, RevisionProcessingProgress p) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java index a2fec889aed5..15f376cb9bca 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java @@ -17,7 +17,6 @@ package com.intellij.openapi.vcs.ex; import com.intellij.diff.DiffContentFactory; import com.intellij.diff.DiffManager; -import com.intellij.diff.actions.DocumentFragmentContent; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.contents.DocumentContent; import com.intellij.diff.requests.DiffRequest; @@ -70,7 +69,7 @@ public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction { private DiffContent createDiffContent(@NotNull Document document, @NotNull TextRange textRange, @Nullable VirtualFile file) { final Project project = myLineStatusTracker.getProject(); DocumentContent content = DiffContentFactory.getInstance().create(project, document, file); - return new DocumentFragmentContent(project, content, textRange); + return DiffContentFactory.getInstance().createFragment(project, content, textRange); } @NotNull diff --git a/plugins/commander/src/com/intellij/ide/commander/PsiDiffContentFactory.java b/plugins/commander/src/com/intellij/ide/commander/PsiDiffContentFactory.java index e841d19f0214..8184a9c7a04c 100644 --- a/plugins/commander/src/com/intellij/ide/commander/PsiDiffContentFactory.java +++ b/plugins/commander/src/com/intellij/ide/commander/PsiDiffContentFactory.java @@ -16,7 +16,6 @@ package com.intellij.ide.commander; import com.intellij.diff.DiffContentFactory; -import com.intellij.diff.actions.DocumentFragmentContent; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.contents.DocumentContent; import com.intellij.diff.requests.DiffRequest; @@ -42,21 +41,22 @@ public class PsiDiffContentFactory { @Nullable private static DiffContent fromPsiElement(@NotNull PsiElement psiElement) { + DiffContentFactory factory = DiffContentFactory.getInstance(); if (psiElement instanceof PsiFile) { - return DiffContentFactory.getInstance().create(psiElement.getProject(), ((PsiFile)psiElement).getVirtualFile()); + return factory.create(psiElement.getProject(), ((PsiFile)psiElement).getVirtualFile()); } else if (psiElement instanceof PsiDirectory) { - return DiffContentFactory.getInstance().create(psiElement.getProject(), ((PsiDirectory)psiElement).getVirtualFile()); + return factory.create(psiElement.getProject(), ((PsiDirectory)psiElement).getVirtualFile()); } PsiFile containingFile = psiElement.getContainingFile(); if (containingFile == null) { String text = psiElement.getText(); if (text == null) return null; - return DiffContentFactory.getInstance().create(text, psiElement.getLanguage().getAssociatedFileType(), false); + return factory.create(text, psiElement.getLanguage().getAssociatedFileType(), false); } - DocumentContent wholeFileContent = DiffContentFactory.getInstance().createDocument(psiElement.getProject(), containingFile.getVirtualFile()); + DocumentContent wholeFileContent = factory.createDocument(psiElement.getProject(), containingFile.getVirtualFile()); if (wholeFileContent == null) return null; - return new DocumentFragmentContent(psiElement.getProject(), wholeFileContent, psiElement.getTextRange()); + return factory.createFragment(psiElement.getProject(), wholeFileContent, psiElement.getTextRange()); } @Nullable From c16b666549a1e05d81463eccba48123c0c3cc11f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Jul 2016 16:09:53 +0200 Subject: [PATCH 34/41] Cleanup (warning) --- .../formatter/java/JavaFormatterSpaceTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java index 9e60b9a5fc4c..63668f03d60c 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterSpaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -150,6 +150,7 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { doTextTest(initial, formatted); // Expect spaces to be inserted after unary operators } + @SuppressWarnings("unused") public void _testJavadocMethodParams() { // Inspired by IDEA-42167 // Disabled because the contents of the {@code tag} is not necessarily Java code and @@ -591,7 +592,7 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { "};" ); } - + public void testCommentBetweenAnnotationAndModifierList() { getSettings().KEEP_LINE_BREAKS = false; getSettings().KEEP_FIRST_COLUMN_COMMENT = false; @@ -607,7 +608,7 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { " int a = 2;\n" + "}"); } - + public void testSpace_BeforeSemicolon_InsideFor() { getSettings().SPACE_BEFORE_SEMICOLON = true; doMethodTest( @@ -619,7 +620,7 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { "}\n" ); } - + public void testSpace_BeforeSemicolon_InsideFor_IfSpacesWithinForIsOn() { getSettings().SPACE_WITHIN_FOR_PARENTHESES = true; doMethodTest( @@ -631,7 +632,7 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { "}\n" ); } - + public void testSpaceBeforeTypeArgumentList() { getSettings().SPACE_BEFORE_TYPE_PARAMETER_LIST = true; doMethodTest( @@ -643,7 +644,7 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { "Bar. call();" ); } - + public void testKeepLineBreaksWorks_InsidePolyExpression() { getSettings().KEEP_LINE_BREAKS = false; doMethodTest( @@ -652,5 +653,4 @@ public class JavaFormatterSpaceTest extends AbstractJavaFormatterTest { "int x = (1 + 2 + 3) * (1 + 2 + 2) * (1 + 2);" ); } - -} +} \ No newline at end of file From efea9cb13b61db3b467481842e4b1178b235e4e6 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 21 Jul 2016 16:36:38 +0200 Subject: [PATCH 35/41] magic numbers -> constants; WEB-19898 Add code completion for eslintrc section inside package.json file --- .../jsonSchema/extension/JsonSchemaFileProvider.java | 8 ++++++++ .../extension/JsonSchemaImportedProviderFactory.java | 2 +- .../extension/JsonSchemaProjectSelfProviderFactory.java | 2 +- .../com/jetbrains/jsonSchema/JsonSchemaTestProvider.java | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java index 96b7ce7bdd2d..d2e88f1ea066 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java @@ -16,4 +16,12 @@ public interface JsonSchemaFileProvider { SchemaType getSchemaType(); int getOrder(); + + interface Orders { + int CORE = -1000; + int EMBEDDED_BASE = 1; + int PACKAGE_JSON = 2; + int TEST = 10; + int USER = 1000; + } } diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaImportedProviderFactory.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaImportedProviderFactory.java index 7883df39f83e..d520f021fc18 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaImportedProviderFactory.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaImportedProviderFactory.java @@ -77,7 +77,7 @@ public class JsonSchemaImportedProviderFactory implements JsonSchemaProviderFact @Override public int getOrder() { - return 1000; + return Orders.USER; } @NotNull diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java index a4366664e4d1..49a353de5043 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java @@ -70,7 +70,7 @@ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderF @Override public int getOrder() { - return -1000; + return Orders.CORE; } } } diff --git a/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java b/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java index e598f876b197..b4e8b661daed 100644 --- a/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java +++ b/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java @@ -39,6 +39,6 @@ public class JsonSchemaTestProvider implements JsonSchemaFileProvider { @Override public int getOrder() { - return 10; + return Orders.TEST; } } From 124285ee2a5d455901d9b7fbce7b3989c332ee9b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Jul 2016 16:40:52 +0200 Subject: [PATCH 36/41] [java] missing annotations on method return types --- .../impl/source/tree/JavaSharedImplUtil.java | 24 ++++++++++++------- .../codeInsight/psi/AnnotatedTypeTest.groovy | 12 ++++------ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java index 063242381fc3..1cf442943e97 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java @@ -28,6 +28,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.util.CharTable; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.JBIterable; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,7 +93,9 @@ public class JavaSharedImplUtil { if (modifierList != null) { PsiAnnotation[] annotations = modifierList.getAnnotations(); if (annotations.length > 0) { - TypeAnnotationProvider provider = new FilteringTypeAnnotationProvider(annotations); + TypeAnnotationProvider original = + modifierList.getParent() instanceof PsiMethod ? type.getAnnotationProvider() : TypeAnnotationProvider.EMPTY; + TypeAnnotationProvider provider = new FilteringTypeAnnotationProvider(annotations, original); if (type instanceof PsiArrayType) { Stack types = new Stack(); do { @@ -196,10 +199,12 @@ public class JavaSharedImplUtil { private static class FilteringTypeAnnotationProvider implements TypeAnnotationProvider { private final PsiAnnotation[] myCandidates; + private final TypeAnnotationProvider myOriginalProvider; private volatile PsiAnnotation[] myCache; - private FilteringTypeAnnotationProvider(PsiAnnotation[] candidates) { + private FilteringTypeAnnotationProvider(PsiAnnotation[] candidates, TypeAnnotationProvider originalProvider) { myCandidates = candidates; + myOriginalProvider = originalProvider; } @NotNull @@ -207,12 +212,15 @@ public class JavaSharedImplUtil { public PsiAnnotation[] getAnnotations() { PsiAnnotation[] result = myCache; if (result == null) { - List filtered = ContainerUtil.filter(myCandidates, new Condition() { - @Override - public boolean value(PsiAnnotation annotation) { - return AnnotationTargetUtil.isTypeAnnotation(annotation); - } - }); + List filtered = JBIterable.of(myCandidates) + .filter(new Condition() { + @Override + public boolean value(PsiAnnotation annotation) { + return AnnotationTargetUtil.isTypeAnnotation(annotation); + } + }) + .append(myOriginalProvider.getAnnotations()) + .toList(); myCache = result = filtered.isEmpty() ? PsiAnnotation.EMPTY_ARRAY : filtered.toArray(new PsiAnnotation[filtered.size()]); } return result; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy index bb2e2ba20a0b..ec5ab5fcd0c5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -36,9 +36,7 @@ class AnnotatedTypeTest extends LightCodeInsightFixtureTestCase { @interface A { } @Target(ElementType.TYPE_USE) @interface TA { int value() default 42; } - class O { - class I { } - } + class O { class I { } } @SuppressWarnings("ExceptionClassNameDoesntEndWithException") class E1 extends Exception { } @SuppressWarnings("ExceptionClassNameDoesntEndWithException") class E2 extends Exception { }""".stripIndent()) @@ -101,9 +99,9 @@ class AnnotatedTypeTest extends LightCodeInsightFixtureTestCase { } public void testMethodReturnType() { - def psi = factory.createMethodFromText("@A @TA(1) String m() { return null; }", context) - assertTypeText psi.returnType, "java.lang.@pkg.TA(1) String", "java.lang.String" - assertAnnotations psi.returnType, "@TA(1)" + def psi = factory.createMethodFromText("@A @TA(1) @TA(2) String m() { return null; }", context) + assertTypeText psi.returnType, "java.lang.@pkg.TA(1) @pkg.TA(2) String", "java.lang.String" + assertAnnotations psi.returnType, "@TA(1)", "@TA(2)" } private void doTest(String text, String annotated, String canonical) { From afc171d39c0d65e295ad228dee6625cfb07006c4 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Thu, 21 Jul 2016 17:57:32 +0300 Subject: [PATCH 37/41] Flaky test fixed Due to precision sleep(1000) may actually take 998 and lead to test error. --- python/testData/testRunner/env/pytest/test1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/testData/testRunner/env/pytest/test1.py b/python/testData/testRunner/env/pytest/test1.py index 1b57c5fd7d9b..9a064ecd9199 100644 --- a/python/testData/testRunner/env/pytest/test1.py +++ b/python/testData/testRunner/env/pytest/test1.py @@ -1,7 +1,7 @@ from time import sleep class TestPyTest: def testOne(self): - sleep(1) # To check duration + sleep(1.5) # To check duration assert 4 == 2*2 def testTwo(self): From ea13b8cbffa0f2ec66543e515dcf3dd5aa75f684 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Jul 2016 17:35:01 +0300 Subject: [PATCH 38/41] build scripts: javadoc corrected --- .../org/jetbrains/intellij/build/ProductModulesLayout.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy b/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy index abb4673f0397..b50770a0ce6f 100644 --- a/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ProductModulesLayout.groovy @@ -57,7 +57,8 @@ class ProductModulesLayout { List platformImplementationModules = [] /** - * Names of the main modules (containing META-INF/plugin.xml) of the plugins which need to be bundled with the product + * Names of the main modules (containing META-INF/plugin.xml) of the plugins which need to be bundled with the product. It may also + * includes names of optional modules from these plugins which need to be included into the plugin distribution for this product. */ List bundledPluginModules = [] From d6e4697c9c4eefaf50854f348f474508750e072f Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Jul 2016 18:10:38 +0300 Subject: [PATCH 39/41] build scripts: correctly exclude files which need to be scrambled from 'lib' directory when building on Windows; added additional check to make sure that such files aren't copied to 'lib' directory --- .../intellij/build/ScrambleTool.groovy | 5 +++++ .../build/impl/DistributionJARsBuilder.groovy | 20 +++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy b/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy index f4b82a995c8b..a885565770f6 100644 --- a/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ScrambleTool.groovy @@ -31,4 +31,9 @@ interface ScrambleTool { * Scramble {@code mainJarName} in {@code "$buildContext.paths.distAll/lib"} directory */ void scramble(String mainJarName, BuildContext buildContext) + + /** + * @return list of names of JAR files which cannot be included into the product 'lib' directory in plain form + */ + List getNamesOfJarsRequiredToBeScrambled() } \ No newline at end of file diff --git a/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy index d55e27903dc3..797f44f48da2 100644 --- a/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy +++ b/build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy @@ -31,6 +31,7 @@ package org.jetbrains.intellij.build.impl import com.intellij.openapi.util.io.FileUtil +import com.intellij.util.PathUtilRt import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.jps.model.java.JpsJavaClasspathKind @@ -125,7 +126,16 @@ class DistributionJARsBuilder { layoutBuilder.patchModuleOutput("platform-resources", FileUtil.toSystemIndependentName(patchedKeyMapDir.absolutePath)) } - Set usedJars = collectUsedJars(includedModules, []) - productLayout.additionalJarsToUnpackIntoMainJar + Set usedJars = collectUsedJars(includedModules, []) - productLayout.additionalJarsToUnpackIntoMainJar.collect {FileUtil.toSystemIndependentName(it)} + + if (buildContext.scrambleTool != null) { + def forbiddenJarNames = buildContext.scrambleTool.namesOfJarsRequiredToBeScrambled + def forbiddenJars = usedJars.findAll { forbiddenJarNames.contains(PathUtilRt.getFileName(it)) } + if (!forbiddenJars.empty) { + buildContext.messages.error("The following JARs cannot be included into the product 'lib' directory, they need to be scrambled with the main jar: ${forbiddenJars}") + } + } + def communityHome = "$buildContext.paths.communityHome" def resourcesIncluded = RESOURCES_INCLUDED def resourcesExcluded = RESOURCES_EXCLUDED @@ -360,12 +370,6 @@ class DistributionJARsBuilder { (["$buildContext.paths.communityHome/lib", "$buildContext.paths.projectHome/lib", "$buildContext.paths.communityHome/xml/relaxng/lib"] as List) + additionalLibFolders - def forbiddenJars = [ -// "/dev/", "/rt/", "/ant/", -// "ls-client-api", "/ideaLicenseDecoder", "jcip-annotations", -// "/eawtstub.jar", "/y.jar", "/ysvg.jar" - ] - modules.each { def module = buildContext.findModule(it) if (module != null) { @@ -373,7 +377,7 @@ class DistributionJARsBuilder { File file = new File(it) if (file.exists()) { String path = FileUtil.toSystemIndependentName(file.canonicalPath) - if (path.endsWith(".jar") && approvedJars.any { FileUtil.startsWith(path, it) } && !forbiddenJars.any { path.contains(it) }) { + if (path.endsWith(".jar") && approvedJars.any { FileUtil.startsWith(path, it) }) { if (usedJars.add(path)) { buildContext.messages.info("\tADDED: $path for $module.name") } From 58613086c5ed7caf388a4948751703bb99ccfcb0 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 21 Jul 2016 17:17:17 +0200 Subject: [PATCH 40/41] cleanup --- lib/annotations/jdk/java/math/annotations.xml | 5 +++++ .../builtInWebServer/BuiltInWebServer.kt | 14 ++----------- .../ide/passwordSafe/PasswordSafe.java | 15 ++----------- .../config/PasswordSafeSettings.java | 1 - .../masterKey/windows/WindowsCryptUtils.java | 5 ++++- .../com/intellij/openapi/util/io/fileUtil.kt | 21 ++++++++++++++++++- .../windows/WindowsCryptUtilTest.java | 18 ++++++++++++++-- 7 files changed, 49 insertions(+), 30 deletions(-) create mode 100644 lib/annotations/jdk/java/math/annotations.xml diff --git a/lib/annotations/jdk/java/math/annotations.xml b/lib/annotations/jdk/java/math/annotations.xml new file mode 100644 index 000000000000..e24dbcf105c1 --- /dev/null +++ b/lib/annotations/jdk/java/math/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt index e8d95620fac7..372e2c8af7c9 100644 --- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt +++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt @@ -32,6 +32,7 @@ import com.intellij.openapi.ui.Messages import com.intellij.openapi.util.SystemInfoRt import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.endsWithName +import com.intellij.openapi.util.io.setOwnerPermissions import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VirtualFile @@ -52,11 +53,8 @@ import java.awt.datatransfer.StringSelection import java.io.IOException import java.math.BigInteger import java.net.InetAddress -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths -import java.nio.file.attribute.PosixFileAttributeView -import java.nio.file.attribute.PosixFilePermission import java.security.SecureRandom import java.util.* import java.util.concurrent.TimeUnit @@ -127,15 +125,7 @@ private val STANDARD_COOKIE by lazy { if (token == null) { token = UUID.randomUUID().toString() file.write(token!!) - val view = Files.getFileAttributeView(file, PosixFileAttributeView::class.java) - if (view != null) { - try { - view.setPermissions(setOf(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)) - } - catch (e: IOException) { - LOG.warn(e) - } - } + file.setOwnerPermissions() } // explicit setting domain cookie on localhost doesn't work for chrome diff --git a/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordSafe.java b/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordSafe.java index 50d503b76411..5e64427a7829 100644 --- a/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordSafe.java +++ b/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordSafe.java @@ -16,21 +16,10 @@ package com.intellij.ide.passwordSafe; import com.intellij.openapi.components.ServiceManager; +import org.jetbrains.annotations.NotNull; -/** - * The password safe component. It allows storing, removing, and retrieving the passwords. - * Note that on the first access to the password safe functions, the dialog asking for the - * master password might have to be shown. So the access should be either done from UI thread, - * or it should be possible to invoke {@link java.awt.EventQueue#invokeAndWait(Runnable)} - * method when password access methods are invoked. - * - * @see com.intellij.ide.passwordSafe.ui.PasswordSafePromptDialog - */ public abstract class PasswordSafe implements PasswordStorage { - - /** - * @return the instance of password safe service - */ + @NotNull public static PasswordSafe getInstance() { return ServiceManager.getService(PasswordSafe.class); } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeSettings.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeSettings.java index 669b99de4955..f1edc303a264 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeSettings.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeSettings.java @@ -22,7 +22,6 @@ import com.intellij.openapi.components.Storage; /** * The password safe settings - * The password database. The internal component for {@link com.intellij.ide.passwordSafe.impl.providers.masterKey.MasterKeyPasswordSafe}. */ @State( name = "PasswordSafe", diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtils.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtils.java index 0b7c5e00e83a..cffa1c8d2c8d 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtils.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtils.java @@ -23,6 +23,7 @@ import com.sun.jna.Structure; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIFunctionMapper; import com.sun.jna.win32.W32APITypeMapper; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.List; @@ -51,7 +52,8 @@ public class WindowsCryptUtils { * @param data the data to protect * @return the the protected form the data */ - public static byte[] protect(byte[] data) { + @NotNull + public static byte[] protect(@NotNull byte[] data) { if(data.length == 0) { return data; } @@ -74,6 +76,7 @@ public class WindowsCryptUtils { * @param data the data to protect * @return the the protected form the data */ + @NotNull public static byte[] unprotect(byte[] data) { if(data.length == 0) { return data; diff --git a/platform/platform-impl/src/com/intellij/openapi/util/io/fileUtil.kt b/platform/platform-impl/src/com/intellij/openapi/util/io/fileUtil.kt index eeb97cb8c019..fc752370b3c0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/util/io/fileUtil.kt +++ b/platform/platform-impl/src/com/intellij/openapi/util/io/fileUtil.kt @@ -15,9 +15,17 @@ */ package com.intellij.openapi.util.io +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.util.text.StringUtil import com.intellij.util.PathUtilRt import java.io.File +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.attribute.PosixFileAttributeView +import java.nio.file.attribute.PosixFilePermission + +private val LOG = Logger.getInstance("#com.intellij.openapi.util.io.FileUtil") val File.systemIndependentPath: String get() = path.replace(File.separatorChar, '/') @@ -30,4 +38,15 @@ fun getParentPath(path: String) = StringUtil.nullize(PathUtilRt.getParentPath(pa fun endsWithSlash(path: String) = path.getOrNull(path.length - 1) == '/' -fun endsWithName(path: String, name: String) = path.endsWith(name) && (path.length == name.length || path.getOrNull(path.length - name.length - 1) == '/') \ No newline at end of file +fun endsWithName(path: String, name: String) = path.endsWith(name) && (path.length == name.length || path.getOrNull(path.length - name.length - 1) == '/') + +fun Path.setOwnerPermissions() { + Files.getFileAttributeView(this, PosixFileAttributeView::class.java)?.let { + try { + it.setPermissions(setOf(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)) + } + catch (e: IOException) { + LOG.warn(e) + } + } +} \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtilTest.java b/platform/platform-tests/testSrc/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtilTest.java index faa1d31b724a..c428b8bb0416 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ide/passwordSafe/impl/providers/masterKey/windows/WindowsCryptUtilTest.java @@ -1,7 +1,21 @@ +/* + * Copyright 2000-2016 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.passwordSafe.impl.providers.masterKey.windows; import com.intellij.openapi.util.SystemInfo; -import com.intellij.ide.passwordSafe.MasterPasswordUnavailableException; import org.junit.Assert; import org.junit.Test; @@ -12,7 +26,7 @@ import java.security.SecureRandom; */ public class WindowsCryptUtilTest { @Test - public void testProtect() throws MasterPasswordUnavailableException { + public void testProtect() { if(SystemInfo.isWindows) { SecureRandom t = new SecureRandom(); byte[] data = new byte[256]; From 99fd06c6af3f8e15ccdf1369305861f059e5c855 Mon Sep 17 00:00:00 2001 From: Alexey Gopachenko Date: Thu, 21 Jul 2016 16:12:02 +0200 Subject: [PATCH 41/41] Fix equals contract x.equals(null) => false (cherry picked from commit 1ad34e5) --- .../util/src/com/intellij/util/containers/SmartHashSet.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/containers/SmartHashSet.java b/platform/util/src/com/intellij/util/containers/SmartHashSet.java index dc68fc0ac14a..974b2e862af7 100644 --- a/platform/util/src/com/intellij/util/containers/SmartHashSet.java +++ b/platform/util/src/com/intellij/util/containers/SmartHashSet.java @@ -19,6 +19,7 @@ import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; import gnu.trove.TObjectProcedure; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.Array; import java.util.Collection; @@ -95,7 +96,7 @@ public class SmartHashSet extends THashSet { } @Override - public boolean equals(@NotNull Object other) { + public boolean equals(@Nullable Object other) { T theElement = this.theElement; if (theElement != null) { return other instanceof Set && ((Set)other).size() == 1 && eq(theElement, (T)((Set)other).iterator().next());