summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.idea/compiler.xml1
-rw-r--r--.idea/kotlinc.xml2
-rw-r--r--.idea/libraries/aia_proto.xml5
-rw-r--r--.idea/libraries/android_test_plugin_host_device_info_proto.xml10
-rw-r--r--.idea/libraries/asm_tools.xml12
-rw-r--r--.idea/libraries/emulator_proto.xml5
-rw-r--r--.idea/libraries/jts_io_common.xml12
-rw-r--r--.idea/libraries/layoutinspector_compose_proto.xml10
-rw-r--r--.idea/libraries/layoutinspector_skia_proto.xml10
-rw-r--r--.idea/libraries/layoutinspector_view_proto.xml10
-rw-r--r--.idea/libraries/layoutlib.xml10
-rw-r--r--.idea/libraries/libam_instrumentation_data_proto.xml5
-rw-r--r--.idea/libraries/libapp_processes_proto.xml10
-rw-r--r--.idea/libraries/network_inspector_java_proto.xml10
-rw-r--r--.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_0_12_0.xml10
-rw-r--r--.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_jsonrpc_0_12_0.xml10
-rw-r--r--.idea/libraries/perfetto_proto.xml5
-rw-r--r--.idea/libraries/sqlite_inspector_proto.xml5
-rw-r--r--.idea/libraries/studio_analytics_proto.xml5
-rw-r--r--.idea/libraries/studio_grpc.xml5
-rw-r--r--.idea/libraries/studio_proto.xml5
-rw-r--r--.idea/libraries/transport_proto.xml5
-rw-r--r--.idea/libraries/xtext_xbase.xml10
-rw-r--r--.idea/modules.xml71
-rw-r--r--.idea/vcs.xml5
-rw-r--r--CIDR_LICENSE.txt7
-rw-r--r--NOTICE.txt10
-rw-r--r--OWNERS4
-rw-r--r--RELEASE.md171
-rw-r--r--adt-branding/icon-robots.txt2
-rw-r--r--adt-branding/intellij.android.adt.branding.iml20
-rw-r--r--adt-branding/src/META-INF/AndroidStudioPlugin.xml11
-rw-r--r--adt-branding/src/artwork/AndroidStudio.icnsbin0 -> 307252 bytes
-rw-r--r--adt-branding/src/artwork/androidstudio-small.svg1
-rw-r--r--adt-branding/src/artwork/androidstudio.icobin0 -> 57310 bytes
-rw-r--r--adt-branding/src/artwork/androidstudio.svg1
-rw-r--r--adt-branding/src/artwork/icon_AS.pngbin0 -> 1604 bytes
-rw-r--r--adt-branding/src/artwork/icon_AS_128.pngbin0 -> 8108 bytes
-rw-r--r--adt-branding/src/artwork/icon_AS_small.pngbin0 -> 415 bytes
-rw-r--r--adt-branding/src/artwork/icon_AS_small@2x.pngbin0 -> 788 bytes
-rw-r--r--adt-branding/src/artwork/preview/AndroidStudio.icnsbin0 -> 439084 bytes
-rw-r--r--adt-branding/src/artwork/preview/androidstudio-small.svg1
-rw-r--r--adt-branding/src/artwork/preview/androidstudio.icobin0 -> 57170 bytes
-rw-r--r--adt-branding/src/artwork/preview/androidstudio.svg1
-rw-r--r--adt-branding/src/artwork/preview/icon_AS_128.pngbin0 -> 9851 bytes
-rw-r--r--adt-branding/src/artwork/studio_about.pngbin0 -> 118679 bytes
-rw-r--r--adt-branding/src/artwork/studio_about@2x.pngbin0 -> 118679 bytes
-rw-r--r--adt-branding/src/artwork/studio_logo_background.pngbin0 -> 4710 bytes
-rw-r--r--adt-branding/src/artwork/studio_progress_tail.pngbin0 -> 15043 bytes
-rw-r--r--adt-branding/src/artwork/studio_splash.pngbin0 -> 93551 bytes
-rw-r--r--adt-branding/src/artwork/studio_splash@2x.pngbin0 -> 336023 bytes
-rw-r--r--adt-branding/src/artwork/toolWindowProject_AS.pngbin0 -> 315 bytes
-rw-r--r--adt-branding/src/artwork/toolWindowProject_AS@2x.pngbin0 -> 1022 bytes
-rw-r--r--adt-branding/src/artwork/welcome.pngbin0 -> 4430 bytes
-rw-r--r--adt-branding/src/artwork/welcome@2x.pngbin0 -> 10551 bytes
-rw-r--r--adt-branding/src/idea/AndroidStudioApplicationInfo.xml58
-rw-r--r--adt-branding/src/idea/ToolWindowManager.xml6
-rwxr-xr-xbin/linux/fsnotifierbin28392 -> 24208 bytes
-rwxr-xr-xbin/mac/fsnotifierbin117752 -> 117512 bytes
-rw-r--r--bin/mac/libnst64.dylibbin218376 -> 218555 bytes
-rwxr-xr-xbin/mac/restarterbin115912 -> 115896 bytes
-rw-r--r--bin/win/IdeaWin32.dllbin74240 -> 74240 bytes
-rw-r--r--bin/win/IdeaWin64.dllbin86016 -> 86016 bytes
-rw-r--r--bin/win/WinProcessListHelper.exebin192000 -> 167936 bytes
-rw-r--r--bin/win/breakgen.dllbin69632 -> 69632 bytes
-rw-r--r--bin/win/breakgen64.dllbin80896 -> 80896 bytes
-rwxr-xr-x[-rw-r--r--]bin/win/restarter.exebin104448 -> 80896 bytes
-rwxr-xr-x[-rw-r--r--]bin/win/runnerw.exebin143360 -> 119296 bytes
-rw-r--r--build.txt2
-rw-r--r--build/dependencies/setupJdk.gradle2
-rw-r--r--build/groovy/org/jetbrains/intellij/build/AndroidStudioBuilder.groovy39
-rw-r--r--build/groovy/org/jetbrains/intellij/build/AndroidStudioLibraryLicenses.groovy185
-rw-r--r--build/groovy/org/jetbrains/intellij/build/AndroidStudioProperties.groovy396
-rw-r--r--build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy4
-rw-r--r--build/scripts/AndroidStudioBuildTarget.kt11
-rw-r--r--build/tasks/src/org/jetbrains/intellij/build/io/ZipArchiveOutputStream.kt2
-rwxr-xr-xbuild_studio.sh55
-rw-r--r--images/src/org/intellij/images/util/imageio/CommonsImagingImageReaderSpi.java3
-rw-r--r--intellij.idea.community.main.iml9
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java22
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java32
-rw-r--r--java/ide-customization/resources/META-INF/plugin.xml4
-rw-r--r--java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml3
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java3
-rw-r--r--java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java37
-rw-r--r--native/MacRestarter/CMakeLists.txt2
-rw-r--r--native/MacTouchBar/CMakeLists.txt2
-rw-r--r--native/README.md51
-rw-r--r--native/WinLauncher/splash.bmpbin768054 -> 256306 bytes
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java6
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java5
-rw-r--r--platform/bootstrap/src/com/intellij/idea/Main.java11
-rw-r--r--platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetails.java163
-rw-r--r--platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetection.java186
-rw-r--r--platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy2
-rw-r--r--platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy2
-rw-r--r--platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/VmOptionsGenerator.groovy7
-rw-r--r--platform/build-scripts/resources/linux/scripts/profiler.sh7
-rw-r--r--platform/build-scripts/resources/mac/Contents/Info.plist2
-rwxr-xr-x[-rw-r--r--]platform/build-scripts/resources/mac/Contents/MacOS/executablebin154216 -> 154216 bytes
-rw-r--r--platform/build-scripts/resources/win/launcher/WinLauncher.exebin1380864 -> 870912 bytes
-rw-r--r--platform/build-scripts/resources/win/scripts/profiler.bat11
-rw-r--r--platform/code-style-api/src/com/intellij/psi/codeStyle/CustomCodeStyleSettingsManager.java8
-rw-r--r--platform/configuration-store-impl/src/defaultProjectElementNormalizer.kt2
-rw-r--r--platform/core-api/src/com/intellij/analytics/AndroidStudioAnalytics.java69
-rw-r--r--platform/core-api/src/com/intellij/analytics/NullAndroidStudioAnalytics.java82
-rw-r--r--platform/core-api/src/com/intellij/openapi/roots/ContentIteratorEx.java1
-rw-r--r--platform/core-api/src/com/intellij/util/PlatformUtils.java9
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java9
-rw-r--r--platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java13
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java6
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java20
-rw-r--r--platform/ide-core-impl/src/com/intellij/diagnostic/VMOptions.java19
-rw-r--r--platform/lang-api/src/com/intellij/execution/testframework/sm/runner/states/TestStateInfo.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/LastRunReformatCodeOptionsProvider.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java41
-rw-r--r--platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java26
-rw-r--r--platform/lang-impl/src/com/intellij/packageDependencies/ui/ModuleNode.java24
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java12
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java1
-rw-r--r--platform/platform-api/resources/messages/IdeBundle.properties8
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java8
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java28
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/LowMemoryNotifier.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ide/AndroidStudioSystemHealthMonitorAdapter.java55
-rw-r--r--platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/EditCustomSettingsAction.kt4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java6
-rw-r--r--platform/platform-impl/src/com/intellij/idea/StartupUtil.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java1
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfo.kt3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateOptions.kt2
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensions.xml8
-rw-r--r--platform/platform-resources/src/META-INF/PlatformLangComponents.xml3
-rw-r--r--platform/platform-resources/src/META-INF/XmlActions.xml8
-rw-r--r--platform/platform-resources/src/consents-Google.json9
-rw-r--r--platform/platform-resources/src/idea/PlatformActions.xml2
-rw-r--r--platform/platform-resources/src/keymaps/$default.xml6
-rw-r--r--platform/platform-resources/src/keymaps/Default for KDE.xml4
-rw-r--r--platform/platform-resources/src/keymaps/Eclipse.xml3
-rw-r--r--platform/platform-resources/src/keymaps/Mac OS X 10.5+.xml4
-rw-r--r--platform/platform-resources/src/keymaps/Mac OS X.xml4
-rw-r--r--platform/platform-resources/src/keymaps/Xcode.xml4
-rw-r--r--platform/statistics/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java6
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java10
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/LeakHunter.java13
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/TestApplicationManager.kt1
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java4
-rw-r--r--platform/util/src/com/intellij/openapi/application/PathManager.java10
-rw-r--r--platform/util/src/com/intellij/openapi/util/SystemInfo.java7
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java8
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/ForCanBeForeachInspectionTest.java7
-rw-r--r--plugins/github/resources/META-INF/plugin.xml6
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRRepositorySelectorComponentFactory.kt5
-rw-r--r--plugins/gradle/java/src/service/resolve/GradleProjectExtensionContributor.kt1
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/GradleConnectorService.kt4
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java2
-rw-r--r--plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy17
-rw-r--r--plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle4
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java8
-rw-r--r--plugins/groovy/src/META-INF/plugin.xml11
-rw-r--r--plugins/maven/src/main/resources/META-INF/plugin.xml2
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertiesInheritorsSearcher.java1
-rwxr-xr-xplugins/webp/lib/libwebp/mac/libwebp_jni64.dylibbin1099460 -> 1168521 bytes
-rw-r--r--resources/src/idea/JavaActions.xml2
-rw-r--r--updater/intellij.platform.updater.iml22
-rw-r--r--updater/src/com/intellij/updater/BaseUpdateAction.java51
-rw-r--r--updater/src/com/intellij/updater/CreateAction.java2
-rw-r--r--updater/src/com/intellij/updater/DeleteAction.java4
-rw-r--r--updater/src/com/intellij/updater/DiffAlgorithm.java207
-rw-r--r--updater/src/com/intellij/updater/Digester.java87
-rw-r--r--updater/src/com/intellij/updater/Patch.java42
-rw-r--r--updater/src/com/intellij/updater/PatchAction.java8
-rw-r--r--updater/src/com/intellij/updater/PatchSpec.java34
-rw-r--r--updater/src/com/intellij/updater/Runner.java59
-rw-r--r--updater/src/com/intellij/updater/StandaloneSwingUpdaterUI.java128
-rw-r--r--updater/src/com/intellij/updater/SwingUpdaterUI.java100
-rw-r--r--updater/src/com/intellij/updater/UpdateZipAction.java4
-rw-r--r--updater/src/com/intellij/updater/ValidationResult.java9
-rw-r--r--updater/src/com/studio/updater/ConsolePatcher.java40
-rw-r--r--updater/src/com/studio/updater/UpdaterService.java33
-rw-r--r--updater/testSrc/com/intellij/updater/DigesterTest.java57
-rw-r--r--updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java42
-rw-r--r--updater/testSrc/com/intellij/updater/PatchCreationTest.java37
-rw-r--r--updater/testSrc/com/intellij/updater/PatchFileCreatorLargeFileTest.java24
-rw-r--r--updater/testSrc/com/intellij/updater/PatchTestCase.java10
-rw-r--r--updater/testSrc/com/intellij/updater/UpdaterTestCase.java67
-rw-r--r--xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeInsertHandler.java5
-rw-r--r--xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java15
192 files changed, 3186 insertions, 396 deletions
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 76144fb5042b..d2e93edbbe36 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -6,6 +6,7 @@
<component name="CompilerConfiguration">
<option name="BUILD_PROCESS_HEAP_SIZE" value="2000" />
<option name="BUILD_PROCESS_ADDITIONAL_VM_OPTIONS" value="-Dgroovyc.in.process=true -Dgroovyc.asm.resolving.only=false" />
+ <addNotNullAssertions enabled="false" />
<excludeFromCompile>
<file url="file://$PROJECT_DIR$/java/execution/jshell-frontend/src/com/intellij/execution/jshell/frontend/Main.java" />
<file url="file://$PROJECT_DIR$/android/tools-base/sdk-common/src/test/java/com/android/ide/common/blame/parser/SourceFragmentPositionRangeJsonTest.java" />
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 170375448c14..564590a6a488 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -8,7 +8,7 @@
<option name="languageVersion" value="1.5" />
</component>
<component name="KotlinCompilerSettings">
- <option name="additionalArguments" value="-version -Xstrict-java-nullability-assertions -Xjvm-default=enable -Xuse-old-backend -Xopt-in=kotlin.io.path.ExperimentalPathApi -Xopt-in=kotlin.RequiresOptIn -Xopt-in=com.intellij.openapi.util.IntellijInternalApi" />
+ <option name="additionalArguments" value="-version -Xno-param-assertions -Xno-call-assertions -Xno-receiver-assertions -Xjvm-default=enable -Xuse-old-backend -Xopt-in=kotlin.io.path.ExperimentalPathApi -Xopt-in=kotlin.RequiresOptIn -Xopt-in=com.intellij.openapi.util.IntellijInternalApi" />
</component>
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.6.10-release-971" />
diff --git a/.idea/libraries/aia_proto.xml b/.idea/libraries/aia_proto.xml
index de9ff85fdd70..4eca7a81e45b 100644
--- a/.idea/libraries/aia_proto.xml
+++ b/.idea/libraries/aia_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="aia-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:proto:27.3.0.0" />
+ <library name="aia-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/proto/27.3.0.0/proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/sdk-common/aia-manifest-jar-generator/proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/android_test_plugin_host_device_info_proto.xml b/.idea/libraries/android_test_plugin_host_device_info_proto.xml
deleted file mode 100644
index 96fb96caf817..000000000000
--- a/.idea/libraries/android_test_plugin_host_device_info_proto.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="android-test-plugin-host-device-info-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libstudio.android-test-plugin-host-device-info-proto:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libstudio.android-test-plugin-host-device-info-proto/27.3.0.0/libstudio.android-test-plugin-host-device-info-proto-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/asm_tools.xml b/.idea/libraries/asm_tools.xml
deleted file mode 100644
index 22eacf936b9b..000000000000
--- a/.idea/libraries/asm_tools.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<component name="libraryTable">
- <library name="asm-tools" type="repository">
- <properties maven-id="org.ow2.asm:asm-analysis:7.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm-analysis/7.0/asm-analysis-7.0.jar!/" />
- <root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm-tree/7.0/asm-tree-7.0.jar!/" />
- <root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/7.0/asm-7.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/emulator_proto.xml b/.idea/libraries/emulator_proto.xml
index fb439cf3b0c3..2284f134f1a9 100644
--- a/.idea/libraries/emulator_proto.xml
+++ b/.idea/libraries/emulator_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="emulator-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:emulator_java_proto:27.3.0.0" />
+ <library name="emulator-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/emulator_java_proto/27.3.0.0/emulator_java_proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/emulator/proto/emulator_java_proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/jts_io_common.xml b/.idea/libraries/jts_io_common.xml
new file mode 100644
index 000000000000..d2b55830e6c1
--- /dev/null
+++ b/.idea/libraries/jts_io_common.xml
@@ -0,0 +1,12 @@
+<component name="libraryTable">
+ <library name="jts-io-common" type="repository">
+ <properties maven-id="org.locationtech.jts.io:jts-io-common:1.17.1" />
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/locationtech/jts/io/jts-io-common/1.17.1/jts-io-common-1.17.1.jar!/" />
+ <root url="jar://$MAVEN_REPOSITORY$/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar!/" />
+ <root url="jar://$MAVEN_REPOSITORY$/org/locationtech/jts/jts-core/1.17.1/jts-core-1.17.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/layoutinspector_compose_proto.xml b/.idea/libraries/layoutinspector_compose_proto.xml
deleted file mode 100644
index b701b4314eb0..000000000000
--- a/.idea/libraries/layoutinspector_compose_proto.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="layoutinspector-compose-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_compose_java_proto:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_compose_java_proto/27.3.0.0/layout_inspector_compose_java_proto-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/layoutinspector_skia_proto.xml b/.idea/libraries/layoutinspector_skia_proto.xml
deleted file mode 100644
index c0f20ffb5c74..000000000000
--- a/.idea/libraries/layoutinspector_skia_proto.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="layoutinspector-skia-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_skia_java_proto:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_skia_java_proto/27.3.0.0/layout_inspector_skia_java_proto-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/layoutinspector_view_proto.xml b/.idea/libraries/layoutinspector_view_proto.xml
deleted file mode 100644
index 1c99583a6861..000000000000
--- a/.idea/libraries/layoutinspector_view_proto.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="layoutinspector-view-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_view_java_proto:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_view_java_proto/27.3.0.0/layout_inspector_view_java_proto-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/layoutlib.xml b/.idea/libraries/layoutlib.xml
deleted file mode 100644
index 0a27535da486..000000000000
--- a/.idea/libraries/layoutlib.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="layoutlib" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:jb-layoutlib-native-jdk11:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/jb-layoutlib-native-jdk11/27.3.0.0/jb-layoutlib-native-jdk11-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/libam_instrumentation_data_proto.xml b/.idea/libraries/libam_instrumentation_data_proto.xml
index 1f7febc8ba51..22ecc789546d 100644
--- a/.idea/libraries/libam_instrumentation_data_proto.xml
+++ b/.idea/libraries/libam_instrumentation_data_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="libam-instrumentation-data-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libam-instrumentation-data-proto:27.3.0.0" />
+ <library name="libam-instrumentation-data-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libam-instrumentation-data-proto/27.3.0.0/libam-instrumentation-data-proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/ddmlib/libam-instrumentation-data-proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/libapp_processes_proto.xml b/.idea/libraries/libapp_processes_proto.xml
deleted file mode 100644
index 27b96b5a9336..000000000000
--- a/.idea/libraries/libapp_processes_proto.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="libapp-processes-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libapp-processes-proto:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libapp-processes-proto/27.3.0.0/libapp-processes-proto-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/network_inspector_java_proto.xml b/.idea/libraries/network_inspector_java_proto.xml
deleted file mode 100644
index 914971042644..000000000000
--- a/.idea/libraries/network_inspector_java_proto.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="network_inspector_java_proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:network_inspector_java_proto:27.3.0.0" />
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/network_inspector_java_proto/27.3.0.0/network_inspector_java_proto-27.3.0.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_0_12_0.xml b/.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_0_12_0.xml
new file mode 100644
index 000000000000..f6e317af67a0
--- /dev/null
+++ b/.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_0_12_0.xml
@@ -0,0 +1,10 @@
+<component name="libraryTable">
+ <library name="org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0" type="repository">
+ <properties include-transitive-deps="false" maven-id="org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0" />
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/eclipse/lsp4j/org.eclipse.lsp4j/0.12.0/org.eclipse.lsp4j-0.12.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_jsonrpc_0_12_0.xml b/.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_jsonrpc_0_12_0.xml
new file mode 100644
index 000000000000..60202a5bf362
--- /dev/null
+++ b/.idea/libraries/org_eclipse_lsp4j_org_eclipse_lsp4j_jsonrpc_0_12_0.xml
@@ -0,0 +1,10 @@
+<component name="libraryTable">
+ <library name="org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.12.0" type="repository">
+ <properties include-transitive-deps="false" maven-id="org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.12.0" />
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/eclipse/lsp4j/org.eclipse.lsp4j.jsonrpc/0.12.0/org.eclipse.lsp4j.jsonrpc-0.12.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/perfetto_proto.xml b/.idea/libraries/perfetto_proto.xml
index 65df136c1867..390817c1c0ae 100644
--- a/.idea/libraries/perfetto_proto.xml
+++ b/.idea/libraries/perfetto_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="perfetto-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:perfetto-protos:27.3.0.0" />
+ <library name="perfetto-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/perfetto-protos/27.3.0.0/perfetto-protos-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/profiler/perfetto-protos.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/sqlite_inspector_proto.xml b/.idea/libraries/sqlite_inspector_proto.xml
index 789f42548f63..0b03a23bb927 100644
--- a/.idea/libraries/sqlite_inspector_proto.xml
+++ b/.idea/libraries/sqlite_inspector_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="sqlite-inspector-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:sqlite_inspector_proto:27.3.0.0" />
+ <library name="sqlite-inspector-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/sqlite_inspector_proto/27.3.0.0/sqlite_inspector_proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/prebuilts/tools/common/app-inspection/androidx/sqlite/sqlite_inspector_proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/studio_analytics_proto.xml b/.idea/libraries/studio_analytics_proto.xml
index 8e6ba1496079..7763414a20c3 100644
--- a/.idea/libraries/studio_analytics_proto.xml
+++ b/.idea/libraries/studio_analytics_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="studio-analytics-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libstudio.proto:27.3.0.0" />
+ <library name="studio-analytics-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libstudio.proto/27.3.0.0/libstudio.proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/analytics-library/protos/src/main/proto/libstudio.proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/studio_grpc.xml b/.idea/libraries/studio_grpc.xml
index 36712d98c559..327305ba2f7d 100644
--- a/.idea/libraries/studio_grpc.xml
+++ b/.idea/libraries/studio_grpc.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="studio-grpc" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:studio-grpc:27.3.0.0" />
+ <library name="studio-grpc">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/studio-grpc/27.3.0.0/studio-grpc-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/bazel/studio-grpc.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/studio_proto.xml b/.idea/libraries/studio_proto.xml
index c690e9690a2f..aafff9c9c873 100644
--- a/.idea/libraries/studio_proto.xml
+++ b/.idea/libraries/studio_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="studio-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:studio-proto:27.3.0.0" />
+ <library name="studio-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/studio-proto/27.3.0.0/studio-proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/bazel/studio-proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/transport_proto.xml b/.idea/libraries/transport_proto.xml
index efd01737f19a..103d71283d97 100644
--- a/.idea/libraries/transport_proto.xml
+++ b/.idea/libraries/transport_proto.xml
@@ -1,8 +1,7 @@
<component name="libraryTable">
- <library name="transport-proto" type="repository">
- <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:transport_java_proto:27.3.0.0" />
+ <library name="transport-proto">
<CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/transport_java_proto/27.3.0.0/transport_java_proto-27.3.0.0.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../bazel-bin/tools/base/transport/proto/transport_java_proto.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/.idea/libraries/xtext_xbase.xml b/.idea/libraries/xtext_xbase.xml
new file mode 100644
index 000000000000..edcd39a12fea
--- /dev/null
+++ b/.idea/libraries/xtext_xbase.xml
@@ -0,0 +1,10 @@
+<component name="libraryTable">
+ <library name="xtext-xbase" type="repository">
+ <properties include-transitive-deps="false" maven-id="org.eclipse.xtext:org.eclipse.xtext.xbase.lib:2.17.0" />
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/eclipse/xtext/org.eclipse.xtext.xbase.lib/2.17.0/org.eclipse.xtext.xbase.lib-2.17.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 3f8a4857d77e..db3c643d17d9 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -324,6 +324,7 @@
</component>
<component name="ProjectModuleManager">
<modules>
+ <module fileurl="file://$PROJECT_DIR$/adt-branding/intellij.android.adt.branding.iml" filepath="$PROJECT_DIR$/adt-branding/intellij.android.adt.branding.iml" />
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-crash.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-crash.iml" />
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-shared.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-shared.iml" />
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-testing.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-testing.iml" />
@@ -494,6 +495,36 @@
<module fileurl="file://$PROJECT_DIR$/android/wizard-model/intellij.android.wizard.model.iml" filepath="$PROJECT_DIR$/android/wizard-model/intellij.android.wizard.model.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/ant/intellij.ant.iml" filepath="$PROJECT_DIR$/plugins/ant/intellij.ant.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/ant/jps-plugin/intellij.ant.jps.iml" filepath="$PROJECT_DIR$/plugins/ant/jps-plugin/intellij.ant.jps.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/intellij.c.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/intellij.c.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/clangd/intellij.c.clangd.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/clangd/intellij.c.clangd.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/clangdBridge/intellij.c.clangdBridge.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/clangdBridge/intellij.c.clangdBridge.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/debugger/intellij.c.debugger.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/debugger/intellij.c.debugger.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang-dfa/intellij.c.dfa.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang-dfa/intellij.c.dfa.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/doxygen/intellij.c.doxygen.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/doxygen/intellij.c.doxygen.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/plugin/intellij.c.plugin.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/plugin/intellij.c.plugin.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/testing/intellij.c.testing.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang/testing/intellij.c.testing.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-base/intellij.cidr.base.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-base/intellij.cidr.base.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-base/plugin/intellij.cidr.base.plugin.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-base/plugin/intellij.cidr.base.plugin.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-common/intellij.cidr.common.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-common/intellij.cidr.common.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-common-testFramework/intellij.cidr.common.testFramework.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-common-testFramework/intellij.cidr.common.testFramework.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-common-testFramework/core/intellij.cidr.common.testFramework.core.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-common-testFramework/core/intellij.cidr.common.testFramework.core.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-core/intellij.cidr.core.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-core/intellij.cidr.core.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/intellij.cidr.debugger.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/intellij.cidr.debugger.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/backend-api/intellij.cidr.debugger.backend.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/backend-api/intellij.cidr.debugger.backend.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/commandInterpreterLang/intellij.cidr.debugger.commandInterpreterLang.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/commandInterpreterLang/intellij.cidr.debugger.commandInterpreterLang.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/plugin/intellij.cidr.debugger.plugin.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-debugger/plugin/intellij.cidr.debugger.plugin.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-execution/intellij.cidr.execution.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-execution/intellij.cidr.execution.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang-base/intellij.cidr.lang.base.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-lang-base/intellij.cidr.lang.base.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-modulemap-language/intellij.cidr.modulemap.language.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-modulemap-language/intellij.cidr.modulemap.language.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-projectModel/intellij.cidr.projectModel.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-projectModel/intellij.cidr.projectModel.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-psi-base/intellij.cidr.psi.base.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-psi-base/intellij.cidr.psi.base.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-resources/intellij.cidr.resources.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-resources/intellij.cidr.resources.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-util/intellij.cidr.util.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-util/intellij.cidr.util.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-util/serializer/intellij.cidr.util.serializer.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-util/serializer/intellij.cidr.util.serializer.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-util/ui/intellij.cidr.util.ui.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-util/ui/intellij.cidr.util.ui.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-workspaceModel/intellij.cidr.workspaceModel.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-workspaceModel/intellij.cidr.workspaceModel.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cidr-workspaceModel/ide/intellij.cidr.workspaceModel.ide.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cidr-workspaceModel/ide/intellij.cidr.workspaceModel.ide.iml" />
+ <module fileurl="file://$PROJECT_DIR$/../vendor/intellij/cidr/cmake-psi/intellij.cmake.psi.iml" filepath="$PROJECT_DIR$/../vendor/intellij/cidr/cmake-psi/intellij.cmake.psi.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/color-schemes/all-hallows-eve-color-scheme/intellij.color.scheme.all_hallows_eve.iml" filepath="$PROJECT_DIR$/plugins/color-schemes/all-hallows-eve-color-scheme/intellij.color.scheme.all_hallows_eve.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/color-schemes/blackboard-color-scheme/intellij.color.scheme.blackboard.iml" filepath="$PROJECT_DIR$/plugins/color-schemes/blackboard-color-scheme/intellij.color.scheme.blackboard.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/color-schemes/cobalt-color-scheme/intellij.color.scheme.cobalt.iml" filepath="$PROJECT_DIR$/plugins/color-schemes/cobalt-color-scheme/intellij.color.scheme.cobalt.iml" />
@@ -530,7 +561,6 @@
<module fileurl="file://$PROJECT_DIR$/plugins/filePrediction/intellij.filePrediction.iml" filepath="$PROJECT_DIR$/plugins/filePrediction/intellij.filePrediction.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/gradle/intellij.gradle.iml" filepath="$PROJECT_DIR$/plugins/gradle/intellij.gradle.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/gradle/intellij.gradle.common.iml" filepath="$PROJECT_DIR$/plugins/gradle/intellij.gradle.common.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/gradle/gradle-dependency-updater/intellij.gradle.dependencyUpdater.iml" filepath="$PROJECT_DIR$/plugins/gradle/gradle-dependency-updater/intellij.gradle.dependencyUpdater.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/gradle/java/intellij.gradle.java.iml" filepath="$PROJECT_DIR$/plugins/gradle/java/intellij.gradle.java.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/gradle-maven/intellij.gradle.java.maven.iml" filepath="$PROJECT_DIR$/plugins/gradle-maven/intellij.gradle.java.maven.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/gradle/java/intellij.gradle.java.tests.iml" filepath="$PROJECT_DIR$/plugins/gradle/java/intellij.gradle.java.tests.iml" />
@@ -627,12 +657,6 @@
<module fileurl="file://$PROJECT_DIR$/uast/uast-java/intellij.java.uast.iml" filepath="$PROJECT_DIR$/uast/uast-java/intellij.java.uast.iml" />
<module fileurl="file://$PROJECT_DIR$/java/idea-ui/intellij.java.ui.iml" filepath="$PROJECT_DIR$/java/idea-ui/intellij.java.ui.iml" />
<module fileurl="file://$PROJECT_DIR$/java/idea-ui/intellij.java.ui.tests.iml" filepath="$PROJECT_DIR$/java/idea-ui/intellij.java.ui.tests.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/javaFX/intellij.javaFX.iml" filepath="$PROJECT_DIR$/plugins/javaFX/intellij.javaFX.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/javaFX/common-javaFX-plugin/intellij.javaFX.common.iml" filepath="$PROJECT_DIR$/plugins/javaFX/common-javaFX-plugin/intellij.javaFX.common.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/javaFX/javaFX-CE/intellij.javaFX.community.iml" filepath="$PROJECT_DIR$/plugins/javaFX/javaFX-CE/intellij.javaFX.community.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/javaFX/javaFX-jps-plugin/intellij.javaFX.jps.iml" filepath="$PROJECT_DIR$/plugins/javaFX/javaFX-jps-plugin/intellij.javaFX.jps.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/javaFX/intellij.javaFX.properties.iml" filepath="$PROJECT_DIR$/plugins/javaFX/intellij.javaFX.properties.iml" />
- <module fileurl="file://$PROJECT_DIR$/plugins/javaFX/sceneBuilder/intellij.javaFX.sceneBuilder.iml" filepath="$PROJECT_DIR$/plugins/javaFX/sceneBuilder/intellij.javaFX.sceneBuilder.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/script-debugger/protocol/protocol-model-generator/intellij.javascript.protocolModelGenerator.iml" filepath="$PROJECT_DIR$/platform/script-debugger/protocol/protocol-model-generator/intellij.javascript.protocolModelGenerator.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/script-debugger/protocol/protocol-reader/intellij.javascript.protocolReader.iml" filepath="$PROJECT_DIR$/platform/script-debugger/protocol/protocol-reader/intellij.javascript.protocolReader.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/script-debugger/protocol/schema-reader-generator/intellij.javascript.schemaReaderGenerator.iml" filepath="$PROJECT_DIR$/platform/script-debugger/protocol/schema-reader-generator/intellij.javascript.schemaReaderGenerator.iml" />
@@ -870,39 +894,6 @@
<module fileurl="file://$PROJECT_DIR$/plugins/properties/properties-psi-impl/intellij.properties.psi.impl.iml" filepath="$PROJECT_DIR$/plugins/properties/properties-psi-impl/intellij.properties.psi.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/properties/properties-resource-bundle-editor/intellij.properties.resource.bundle.editor.iml" filepath="$PROJECT_DIR$/plugins/properties/properties-resource-bundle-editor/intellij.properties.resource.bundle.editor.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/properties/tests/intellij.properties.tests.iml" filepath="$PROJECT_DIR$/plugins/properties/tests/intellij.properties.tests.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.pycharm.community.iml" filepath="$PROJECT_DIR$/python/intellij.pycharm.community.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/build/intellij.pycharm.community.build.iml" filepath="$PROJECT_DIR$/python/build/intellij.pycharm.community.build.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/build/build-debug-binaries/intellij.pycharm.community.build.debugBinaries.iml" filepath="$PROJECT_DIR$/python/build/build-debug-binaries/intellij.pycharm.community.build.debugBinaries.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.pycharm.community.customization.iml" filepath="$PROJECT_DIR$/python/intellij.pycharm.community.customization.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/ide/impl/intellij.pycharm.community.ide.impl.iml" filepath="$PROJECT_DIR$/python/ide/impl/intellij.pycharm.community.ide.impl.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.pycharm.community.main.iml" filepath="$PROJECT_DIR$/python/intellij.pycharm.community.main.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-common-tests/intellij.python.commonTests.iml" filepath="$PROJECT_DIR$/python/python-common-tests/intellij.python.commonTests.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/openapi/intellij.python.community.iml" filepath="$PROJECT_DIR$/python/openapi/intellij.python.community.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.python.community.impl.iml" filepath="$PROJECT_DIR$/python/intellij.python.community.impl.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/pluginCore/intellij.python.community.plugin.iml" filepath="$PROJECT_DIR$/python/pluginCore/intellij.python.community.plugin.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/pluginCore/impl/intellij.python.community.plugin.impl.iml" filepath="$PROJECT_DIR$/python/pluginCore/impl/intellij.python.community.plugin.impl.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/pluginJava/intellij.python.community.plugin.java.iml" filepath="$PROJECT_DIR$/python/pluginJava/intellij.python.community.plugin.java.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.python.community.plugin.main.iml" filepath="$PROJECT_DIR$/python/intellij.python.community.plugin.main.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/pluginMinor/intellij.python.community.plugin.minor.iml" filepath="$PROJECT_DIR$/python/pluginMinor/intellij.python.community.plugin.minor.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.python.community.plugin.modules.iml" filepath="$PROJECT_DIR$/python/intellij.python.community.plugin.modules.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.python.community.plugin.tests.iml" filepath="$PROJECT_DIR$/python/intellij.python.community.plugin.tests.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/testFramework/intellij.python.community.testFramework.iml" filepath="$PROJECT_DIR$/python/testFramework/intellij.python.community.testFramework.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/testSrc/intellij.python.community.tests.iml" filepath="$PROJECT_DIR$/python/testSrc/intellij.python.community.tests.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-copyright/intellij.python.copyright.iml" filepath="$PROJECT_DIR$/python/python-copyright/intellij.python.copyright.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-features-trainer/intellij.python.featuresTrainer.iml" filepath="$PROJECT_DIR$/python/python-features-trainer/intellij.python.featuresTrainer.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-grazie/intellij.python.grazie.iml" filepath="$PROJECT_DIR$/python/python-grazie/intellij.python.grazie.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.python.helpers.iml" filepath="$PROJECT_DIR$/python/intellij.python.helpers.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/helpers/tests/intellij.python.helpers.tests.iml" filepath="$PROJECT_DIR$/python/helpers/tests/intellij.python.helpers.tests.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/IntelliLang-python/intellij.python.langInjection.iml" filepath="$PROJECT_DIR$/python/IntelliLang-python/intellij.python.langInjection.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-markdown/intellij.python.markdown.iml" filepath="$PROJECT_DIR$/python/python-markdown/intellij.python.markdown.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-psi-api/intellij.python.psi.iml" filepath="$PROJECT_DIR$/python/python-psi-api/intellij.python.psi.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-psi-impl/intellij.python.psi.impl.iml" filepath="$PROJECT_DIR$/python/python-psi-impl/intellij.python.psi.impl.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/intellij.python.pydev.iml" filepath="$PROJECT_DIR$/python/intellij.python.pydev.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-rest/intellij.python.reStructuredText.iml" filepath="$PROJECT_DIR$/python/python-rest/intellij.python.reStructuredText.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-sdk/intellij.python.sdk.iml" filepath="$PROJECT_DIR$/python/python-sdk/intellij.python.sdk.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/python-terminal/intellij.python.terminal.iml" filepath="$PROJECT_DIR$/python/python-terminal/intellij.python.terminal.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/tools/intellij.python.tools.iml" filepath="$PROJECT_DIR$/python/tools/intellij.python.tools.iml" />
- <module fileurl="file://$PROJECT_DIR$/python/rest/intellij.reStructuredText.iml" filepath="$PROJECT_DIR$/python/rest/intellij.reStructuredText.iml" />
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/intellij.regexp.iml" filepath="$PROJECT_DIR$/RegExpSupport/intellij.regexp.iml" />
<module fileurl="file://$PROJECT_DIR$/xml/relaxng/intellij.relaxng.iml" filepath="$PROJECT_DIR$/xml/relaxng/intellij.relaxng.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/remoteDev-util/intellij.remoteDev.util.iml" filepath="$PROJECT_DIR$/platform/remoteDev-util/intellij.remoteDev.util.iml" />
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index eac7478ae86e..e7e4d9296544 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -46,11 +46,16 @@
<option name="issueRegexp" value="JDK\-\d+" />
<option name="linkRegexp" value="https://bugs.openjdk.java.net/browse/$0" />
</IssueNavigationLink>
+ <IssueNavigationLink>
+ <option name="issueRegexp" value="(?i:bug|bugfix|issue|fix|fixes|fixing|fixed|google-bug-id):? ?(?:(?:https?://)?(?:b|b.android.com|issuetracker.google.com)/)?(\d+)" />
+ <option name="linkRegexp" value="http://issuetracker.google.com/$1" />
+ </IssueNavigationLink>
</list>
</option>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/android" vcs="Git" />
+ <mapping directory="$PROJECT_DIR$/../vendor/intellij/cidr" vcs="Git" />
</component>
</project>
diff --git a/CIDR_LICENSE.txt b/CIDR_LICENSE.txt
new file mode 100644
index 000000000000..5eeb29a340ac
--- /dev/null
+++ b/CIDR_LICENSE.txt
@@ -0,0 +1,7 @@
+Android Studio, including the binaries in this folder, is licensed to
+you under the Android Software Development Kit License Agreement
+(available at https://developer.android.com/studio/terms) and you may
+not copy (except for backup purposes), modify, adapt, redistribute,
+decompile, reverse engineer, disassemble, or create derivative works
+of the binaries or use the binaries separately from your use of
+Android Studio.
diff --git a/NOTICE.txt b/NOTICE.txt
index d9f5e1dfc3b2..d2e72886cf75 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,3 +1,7 @@
-This software includes code from IntelliJ IDEA Community Edition
-Copyright (C) JetBrains s.r.o.
-https://www.jetbrains.com/idea/
+Android Studio includes proprietary code subject to separate license, including
+JetBrains CLion(R) (www.jetbrains.com/clion) and IntelliJ(R) IDEA Community
+Edition (www.jetbrains.com/idea).
+Copyright (C) 2000 - 2017 JetBrains s.r.o. All Rights Reserved.
+CLion, IntelliJ, and JetBrains are the registered trademarks of JetBrains s.r.o
+
+Google LLC Privacy & Terms: https://www.google.com/policies/
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 000000000000..5fa18a13f507
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,4 @@
+# Gerrit will require approval for changes in this repo from the OWNERS listed.
+dahlstrom@google.com
+ralucas@google.com
+tnorbye@google.com \ No newline at end of file
diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 000000000000..3f313020acf6
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,171 @@
+# Android Studio Release Process
+
+ 1. For every build to be released (canary, beta, rc, or final),
+ on the release branch (e.g. studio-1.4-release),
+ make sure the version number is correct in
+ ./adt-branding/src/idea/AndroidStudioApplicationInfo.xml
+
+ Example:
+
+ ```
+ <version major="1" minor="4" micro="0" patch="7" full="{0}.{1} RC 1" eap="false" />
+ ~~~ ~~~ ~~~ ~~~ ~~~~~~~~~~~~~~
+ ```
+ Make sure `version.full` value contains words `beta` or `RC` (case doesn't matter) for beta, RC releases, and don't have either for stable releases.
+
+ 2. Also make sure that the `eap=` flag in the same file is correct.
+ It should be `true` for canary and beta builds, `false` for rc and final:
+
+ ```
+ <version major="1" minor="4" micro="0" patch="7" full="{0}.{1} RC 1" eap="false" />
+ ~~~~~~~~~~~
+ ```
+ Among other things, in `VmOptionsGenerator.groovy` this causes the `isEAP`
+ conditional to disable assertions.
+
+ Code in AndroidStudioUpdateStrategyCustomization.java computes update channel from `version.eap` and `version.full` values:
+ * If ```eap="true"``` or `version` contains words `canary` or `dev` then update channel is `EAP`
+ * If ```eap="false"``` and `version` contains words `RC` or `beta` then update channel is `BETA`
+ * If ```eap="false"``` and there is neither `canary`, `dev`, `RC` or`beta` in full versions then update channel is `RELEASE`
+
+ 1. Replace `dev` with the appropriate release designator in
+ ../buildSrc/base/version.properties:
+
+ ```
+ baseVersion = 24.4.0-rc01
+ buildVersion = 1.4.0-rc01
+ ~~~~
+ ```
+
+--------------------------------------------------------------------------------
+When a new dev branch (like studio-3.1-dev) is created, update studio-master-dev:
+
+ 1. Make sure the major/minor version is correctly encoded in the build number
+ listed in build.txt file. It is the second number from the end. If major
+ version is X and minor version is Y, the number is simply XY. For example,
+ 31, 32, 33 for 3.1, 3.2, 3.3 respectively.
+
+ ```
+ 181.2784.17.32.SNAPSHOT
+ ~~
+ ```
+
+ 4. Make sure the version number is correct in
+ ../adt/idea/native/installer/win/setup_android_studio.nsi
+
+ ```
+ !define VERSION_MAJOR 3
+ !define VERSION_MINOR 2
+ ```
+
+ 1. Update the version numbers in ../buildSrc/base/version.properties:
+
+ ```
+ baseVersion = 26.2.0-dev
+ buildVersion = 3.2.0-dev
+ ~~~~
+ ```
+
+ 1. Add an entry for the new version in [Kotlin compatibility metadata](https://dl.google.com/android/studio/plugins/compatibility.xml)
+
+--------------------------------------------------------------------------------
+For AOSP push:
+
+ 1. Update the build scripts such that they no longer reference any of
+ the closed source plugins such as the C++ support; this means removing
+ the vendor/ plugin references from .idea/modules.xml, community-main.xml,
+ build/groovy/org/jetbrains/intellij/build/AndroidStudioProperties.groovy,
+ .idea/runConfigurations/OneStudio.xml and the reference in .idea/ant.xml
+ to vendor/google3.
+
+ There are many other smaller tasks to handle as well - updating vcs.xml
+ to not reference unavailable git repositories, etc etc.
+
+ There are three basic tasks:
+ (1) Build the IDE from the command line, and copy the profiler prebuilts
+
+ $ cp tools/idea/out/studio/dist.all/plugins/android/lib/studio-proto.jar \
+ tools/adt/idea/android/lib/
+
+ $ cp tools/idea/out/studio/dist.all/plugins/android/lib/transport_java_proto.jar \
+ tools/adt/idea/android/lib/
+
+ $ cp tools/idea/out/studio/dist.all/plugins/android/lib/studio-grpc.jar \
+ tools/adt/idea/android/lib/
+
+ $ cp tools/idea/out/studio/dist.all/plugins/android/lib/perfetto-protos.jar \
+ tools/adt/idea/android/lib/
+
+ $ cp-recursive tools/idea/out/studio/dist.all/plugins/android/resources/ \
+ prebuilts/tools/common/profiler/$VERSION/
+
+ Also add in a README and license file in the new profiler prebuilts folder.
+
+ Then remove the references from build.xml and .idea/build.xml to
+ the adt build.xml file which would run profiler prebuild steps.
+
+ (2) Open the project in IntelliJ, and fix all warnings in the project
+ structure dialog, then make sure the project builds and runs; for
+ this you may have to fix up source code in case there are any
+ dependencies on closed source code that shouldn't be there.
+ For example, right now the appindexing plugin depends on the
+ url-assistant
+
+ (3) Make the build_studio.sh script compile. This involves removing
+ the various cidr plugins and closed source plugins, as well as
+ removing compilation/copy tasks for the gradle offline repository,
+ lldb, etc. Also add a copy task to place the profiler prebuilts
+ into place.
+
+
+ (4) Ensure that the branch names for the tools/idea and tools/base projects
+ are sensible:
+
+ ```diff
+ diff --git a/.idea/.name b/.idea/.name
+ index 310ac3d20a3..8a1a9797418 100644
+ --- a/.idea/.name
+ +++ b/.idea/.name
+ @@ -1 +1 @@
+ -Android Studio (studio-master-dev)
+ \ No newline at end of file
+ +Android Studio 3.1
+ \ No newline at end of file
+ ```
+
+ Relevant CLs from the 3.1 push:
+ Change-Id: I8ca078c08a4fff0a6ebeae8c6ba7a6fa55bec490
+ Change-Id: I15c8e3ce46099d54e77c17fff0f0d42d11238e3b
+ Change-Id: Ia656d3e023d9887da7aa0486ca934388e75436db
+
+ Relevant CLs from the 3.0 AOSP push:
+ https://android-review.googlesource.com/#/q/topic:studio-30
+
+ Relevant CLs from the 2.3 AOSP push (though they'll need to be adjusted to
+ account for the big build script changes in 2.4) :
+ Change-Id: I364ee67262524aa27f71831e6ed01164826e54ad
+ Change-Id: I9298c7319ce55fb64c29e38636808e57f2a84209
+ Change-Id: Ic60a95a21ea0e483d82f6013539d112b89a7d0c0 (AOSP)
+ Change-Id: I42bcad10589b8172a46a3f74aa1e7a5826ea52fc (AOSP)
+
+ 1. Remove all references to `tools/vendor/google` from
+ `tools/base/bazel/toplevel.WORKSPACE`:
+
+```
+--- a/bazel/toplevel.WORKSPACE
++++ b/bazel/toplevel.WORKSPACE
+@@ -1,13 +1,6 @@
+ load("//tools/base/bazel:repositories.bzl", "setup_external_repositories")
+ setup_external_repositories()
+
+-local_repository(
+- name = "blaze",
+- path = "tools/vendor/google3/blaze",
+-)
+-load("@blaze//:binds.bzl", "blaze_binds")
+-blaze_binds()
+-
+ http_archive(
+ name = "bazel_toolchains",
+ urls = [
+```
diff --git a/adt-branding/icon-robots.txt b/adt-branding/icon-robots.txt
new file mode 100644
index 000000000000..9918ea0b49b6
--- /dev/null
+++ b/adt-branding/icon-robots.txt
@@ -0,0 +1,2 @@
+skip: *
+skipSync: src/tips \ No newline at end of file
diff --git a/adt-branding/intellij.android.adt.branding.iml b/adt-branding/intellij.android.adt.branding.iml
new file mode 100644
index 000000000000..1c389a03ff58
--- /dev/null
+++ b/adt-branding/intellij.android.adt.branding.iml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="intellij.platform.util" />
+ <orderEntry type="module" module-name="intellij.platform.ide" />
+ <orderEntry type="module" module-name="intellij.platform.lang.impl" />
+ <orderEntry type="module" module-name="intellij.java.ui" />
+ <orderEntry type="module" module-name="intellij.xml.impl" />
+ <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
+ <orderEntry type="library" scope="TEST" name="commons-imaging" level="project" />
+ <orderEntry type="library" scope="TEST" name="truth" level="project" />
+ </component>
+</module> \ No newline at end of file
diff --git a/adt-branding/src/META-INF/AndroidStudioPlugin.xml b/adt-branding/src/META-INF/AndroidStudioPlugin.xml
new file mode 100644
index 000000000000..33928476c906
--- /dev/null
+++ b/adt-branding/src/META-INF/AndroidStudioPlugin.xml
@@ -0,0 +1,11 @@
+<!--
+In Android Studio, this file is loaded *instead* of IdeaPlugin.xml.
+If a plugin wants to perform Android-Studio-specific customizations, then it can add an
+optional dependency on the module 'com.intellij.modules.androidstudio' declared below.
+-->
+<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="/META-INF/JavaIdePlugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
+ <module value="com.intellij.modules.androidstudio"/>
+ <module value="com.intellij.modules.java-capable"/>
+ <module value="com.intellij.modules.python-core-capable"/>
+</idea-plugin>
diff --git a/adt-branding/src/artwork/AndroidStudio.icns b/adt-branding/src/artwork/AndroidStudio.icns
new file mode 100644
index 000000000000..9b5b817cd19f
--- /dev/null
+++ b/adt-branding/src/artwork/AndroidStudio.icns
Binary files differ
diff --git a/adt-branding/src/artwork/androidstudio-small.svg b/adt-branding/src/artwork/androidstudio-small.svg
new file mode 100644
index 000000000000..c02b99991d72
--- /dev/null
+++ b/adt-branding/src/artwork/androidstudio-small.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M13.13 3l.866.5-1.618 2.803a7.994 7.994 0 0 1 3.618 6.448l.003.248L0 13l.004-.25a7.994 7.994 0 0 1 3.615-6.445L2 3.5l.866-.5 1.623 2.81A7.968 7.968 0 0 1 8 5c1.258 0 2.449.29 3.508.808L13.13 3zM5 9H4v1h1V9zm7 0h-1v1h1V9z" fill="#3DDC84" fill-rule="evenodd"/></svg> \ No newline at end of file
diff --git a/adt-branding/src/artwork/androidstudio.ico b/adt-branding/src/artwork/androidstudio.ico
new file mode 100644
index 000000000000..6821f8885575
--- /dev/null
+++ b/adt-branding/src/artwork/androidstudio.ico
Binary files differ
diff --git a/adt-branding/src/artwork/androidstudio.svg b/adt-branding/src/artwork/androidstudio.svg
new file mode 100644
index 000000000000..98fc3c6e1947
--- /dev/null
+++ b/adt-branding/src/artwork/androidstudio.svg
@@ -0,0 +1 @@
+<svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="31.677%" y1="34.912%" x2="78.46%" y2="88.594%" id="a"><stop stop-color="#E6E6E6" offset="0%"/><stop stop-color="#FFF" stop-opacity="0" offset="92.575%"/></linearGradient></defs><g transform="translate(6.5 6)" fill-rule="nonzero" fill="none"><ellipse fill="#000" opacity=".2" cx="57.54" cy="58.396" rx="57.54" ry="57.475"/><ellipse fill="#FFF" cx="57.54" cy="57.475" rx="57.54" ry="57.475"/><path d="M114.59 64.987L68.636 19.084l-37.02 60.613 34.637 34.598c25.198-3.824 45.026-23.972 48.337-49.308z" fill="#FFF"/><path d="M83.058 46.114L37.104.211.085 60.824l34.637 34.598c25.197-3.824 45.025-23.972 48.336-49.308z" fill="url(#a)" transform="translate(31.532 18.873)"/><path d="M79.185 41.314h-2.246c-.521-6.21-4.074-11.467-9.266-14.292l-1.128-.563c-2.342-1.069-4.973-1.664-7.78-1.664-2.807 0-5.438.595-7.78 1.664l-.01-.016c-.387.172-.777.334-1.174.483l.056.096a17.836 17.836 0 0 0-3.686 2.666h-10.5c-3.196 0-5.812 2.616-5.812 5.813 0 .078.002.156.005.234-.011-.16-.011-.252-.011-.252v40.175c0 3.198 2.616 5.814 5.813 5.814h10.187l-2.502 5.33c-.878 1.885.498 4.044 2.577 4.044a2.843 2.843 0 0 0 2.578-1.643l3.618-7.731h13.118l3.67 7.626a2.84 2.84 0 0 0 2.558 1.606c2.093 0 3.468-2.188 2.56-4.074l-2.476-5.158h8.156l-.014 8.992c0 .16.13.29.29.29l2.46.013c2.877 0 5.231-2.354 5.231-5.23v-38.62c0-6.333-8.492-5.603-8.492-5.603zM36.04 41.314h4.55-4.549z" fill="#CCC"/><g><path d="M49.693 27.832H33.82c-3.197 0-5.813 2.616-5.813 5.813 0 3.197 2.423 5.813 5.62 5.813H49.83l-.136-11.626z" fill="#073042"/><path d="M85.826 79.616H33.814c-3.197 0-5.813-2.616-5.813-5.814V33.627s-.017 5.831 6.195 5.831h43.137s8.493-.73 8.493 5.603v34.555z" fill="#4285F4"/><path d="M54.712 59.112L45.08 79.637h6.271l4.465-9.542c.82-1.74 3.291-1.747 4.12-.012l4.598 9.554h6.311l-9.91-20.65a5.232 5.232 0 0 0 2.049-4.148c0-2.445-1.684-4.5-3.953-5.076v-3.407a1.008 1.008 0 0 0-2.015 0v3.296c-2.548.355-4.518 2.543-4.518 5.187 0 1.763.877 3.322 2.214 4.273zm3.029-7.501a3.229 3.229 0 1 1 0 6.457 3.229 3.229 0 0 1 0-6.457z" fill="#3870B2"/><path fill="#FFF" d="M46.253 30.687h22.254v4.075H46.253z"/><path d="M65.278 34.284c-.834 0-1.513-.68-1.513-1.514 0-.835.679-1.514 1.513-1.514.835 0 1.514.68 1.514 1.514 0 .835-.679 1.514-1.514 1.514m-16.73 0c-.834 0-1.513-.68-1.513-1.514 0-.835.679-1.514 1.513-1.514.835 0 1.514.68 1.514 1.514 0 .835-.68 1.514-1.514 1.514m17.273-9.118l3.025-5.239a.63.63 0 0 0-1.09-.63l-3.063 5.306c-2.342-1.069-4.973-1.664-7.78-1.664-2.807 0-5.437.595-7.78 1.664l-3.063-5.305a.63.63 0 0 0-1.09.63l3.025 5.238c-5.194 2.825-8.747 8.084-9.267 14.297h36.35c-.52-6.213-4.073-11.472-9.267-14.297" fill="#3DDC84"/><path d="M80.595 50.617h-2.403a.29.29 0 0 0-.289.29l-.058 37.7c0 .16.13.29.289.29l2.46.014c2.878 0 5.232-2.354 5.232-5.23V45.38c0 2.877-2.354 5.236-5.231 5.236zM56.63 51.658a3.229 3.229 0 1 1 0 6.457 3.229 3.229 0 0 1 0-6.457zm1.29-1.93v-3.325a1.008 1.008 0 0 0-2.014 0v3.296c-2.549.355-4.519 2.543-4.519 5.187 0 1.763.877 3.322 2.215 4.273L41.499 84.946c-.878 1.885.498 4.044 2.578 4.044a2.843 2.843 0 0 0 2.578-1.643l8.05-17.205c.82-1.74 3.292-1.747 4.121-.012l8.234 17.112a2.84 2.84 0 0 0 2.558 1.606c2.094 0 3.468-2.188 2.56-4.074l-12.353-25.74a5.232 5.232 0 0 0 2.048-4.148c0-2.445-1.684-4.5-3.953-5.076" fill="#073042"/></g></g></svg> \ No newline at end of file
diff --git a/adt-branding/src/artwork/icon_AS.png b/adt-branding/src/artwork/icon_AS.png
new file mode 100644
index 000000000000..06944dc62ebc
--- /dev/null
+++ b/adt-branding/src/artwork/icon_AS.png
Binary files differ
diff --git a/adt-branding/src/artwork/icon_AS_128.png b/adt-branding/src/artwork/icon_AS_128.png
new file mode 100644
index 000000000000..82de8f4758a3
--- /dev/null
+++ b/adt-branding/src/artwork/icon_AS_128.png
Binary files differ
diff --git a/adt-branding/src/artwork/icon_AS_small.png b/adt-branding/src/artwork/icon_AS_small.png
new file mode 100644
index 000000000000..5589c256fa57
--- /dev/null
+++ b/adt-branding/src/artwork/icon_AS_small.png
Binary files differ
diff --git a/adt-branding/src/artwork/icon_AS_small@2x.png b/adt-branding/src/artwork/icon_AS_small@2x.png
new file mode 100644
index 000000000000..67d70f713bfa
--- /dev/null
+++ b/adt-branding/src/artwork/icon_AS_small@2x.png
Binary files differ
diff --git a/adt-branding/src/artwork/preview/AndroidStudio.icns b/adt-branding/src/artwork/preview/AndroidStudio.icns
new file mode 100644
index 000000000000..4121ce2eb296
--- /dev/null
+++ b/adt-branding/src/artwork/preview/AndroidStudio.icns
Binary files differ
diff --git a/adt-branding/src/artwork/preview/androidstudio-small.svg b/adt-branding/src/artwork/preview/androidstudio-small.svg
new file mode 100644
index 000000000000..a6ba6ba9c38c
--- /dev/null
+++ b/adt-branding/src/artwork/preview/androidstudio-small.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M13.13 3l.866.5-1.618 2.803a7.994 7.994 0 0 1 3.618 6.448l.003.248L0 13l.004-.25a7.994 7.994 0 0 1 3.615-6.445L2 3.5l.866-.5 1.623 2.81A7.968 7.968 0 0 1 8 5c1.258 0 2.449.29 3.508.808L13.13 3zM5 9H4v1h1V9zm7 0h-1v1h1V9z" fill="#F4B400" fill-rule="nonzero"/></svg> \ No newline at end of file
diff --git a/adt-branding/src/artwork/preview/androidstudio.ico b/adt-branding/src/artwork/preview/androidstudio.ico
new file mode 100644
index 000000000000..d4ca59709e49
--- /dev/null
+++ b/adt-branding/src/artwork/preview/androidstudio.ico
Binary files differ
diff --git a/adt-branding/src/artwork/preview/androidstudio.svg b/adt-branding/src/artwork/preview/androidstudio.svg
new file mode 100644
index 000000000000..4d7fd334c4a0
--- /dev/null
+++ b/adt-branding/src/artwork/preview/androidstudio.svg
@@ -0,0 +1 @@
+<svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="35.75%" y1="39.609%" x2="76.587%" y2="86.409%" id="a"><stop stop-color="#E5AF03" offset=".143%"/><stop stop-color="#FFC802" offset="99.961%"/></linearGradient></defs><g transform="translate(6.5 6)" fill-rule="nonzero" fill="none"><ellipse fill="#000" opacity=".2" cx="57.54" cy="58.396" rx="57.54" ry="57.475"/><ellipse fill="#FFC802" cx="57.54" cy="57.475" rx="57.54" ry="57.475"/><path d="M114.59 64.988l-45.974-45.92L31.48 79.706l34.645 34.606c25.258-3.775 45.148-23.947 48.465-49.325z" fill="#FFC802"/><path d="M83.288 46.115L37.314.195.178 60.833 34.823 95.44c25.259-3.775 45.148-23.947 48.465-49.325z" fill="url(#a)" transform="translate(31.302 18.873)"/><path d="M79.185 41.314h-2.246c-.521-6.21-4.074-11.467-9.266-14.292l-1.128-.563c-2.342-1.069-4.973-1.664-7.78-1.664-2.807 0-5.438.595-7.78 1.664l-.01-.016c-.387.172-.777.334-1.174.483l.056.096a17.836 17.836 0 0 0-3.686 2.666h-10.5c-3.196 0-5.812 2.616-5.812 5.813 0 .078.002.156.005.234-.011-.16-.011-.252-.011-.252v40.175c0 3.198 2.616 5.814 5.813 5.814h10.187l-2.502 5.33c-.878 1.885.498 4.044 2.577 4.044a2.843 2.843 0 0 0 2.578-1.643l3.618-7.731h13.118l3.67 7.626a2.84 2.84 0 0 0 2.558 1.606c2.093 0 3.468-2.188 2.56-4.074l-2.476-5.158h8.156l-.014 8.992c0 .16.13.29.29.29l2.46.013c2.877 0 5.231-2.354 5.231-5.23v-38.62c0-6.333-8.492-5.603-8.492-5.603z" fill="#CC9805"/><g><path d="M49.693 27.832H33.82c-3.197 0-5.813 2.616-5.813 5.813 0 3.197 2.423 5.813 5.62 5.813H49.83l-.136-11.626z" fill="#073042"/><path d="M85.826 79.616H33.814c-3.197 0-5.813-2.616-5.813-5.814V33.627s-.017 5.831 6.195 5.831h43.137s8.493-.73 8.493 5.603v34.555z" fill="#4285F4"/><path d="M54.712 59.112L45.08 79.637h6.271l4.465-9.542c.82-1.74 3.291-1.747 4.12-.012l4.598 9.554h6.311l-9.91-20.65a5.232 5.232 0 0 0 2.049-4.148c0-2.445-1.684-4.5-3.953-5.076v-3.407a1.008 1.008 0 0 0-2.015 0v3.296c-2.548.355-4.518 2.543-4.518 5.187 0 1.763.877 3.322 2.214 4.273zm3.029-7.501a3.229 3.229 0 1 1 0 6.457 3.229 3.229 0 0 1 0-6.457z" fill="#3870B2"/><path fill="#FFF" d="M46.253 30.687h22.254v4.075H46.253z"/><path d="M65.278 34.284c-.834 0-1.513-.68-1.513-1.514 0-.835.679-1.514 1.513-1.514.835 0 1.514.68 1.514 1.514 0 .835-.679 1.514-1.514 1.514m-16.73 0c-.834 0-1.513-.68-1.513-1.514 0-.835.679-1.514 1.513-1.514.835 0 1.514.68 1.514 1.514 0 .835-.68 1.514-1.514 1.514m17.273-9.118l3.025-5.239a.63.63 0 0 0-1.09-.63l-3.063 5.306c-2.342-1.069-4.973-1.664-7.78-1.664-2.807 0-5.437.595-7.78 1.664l-3.063-5.305a.63.63 0 0 0-1.09.63l3.025 5.238c-5.194 2.825-8.747 8.084-9.267 14.297h36.35c-.52-6.213-4.073-11.472-9.267-14.297" fill="#3DDC84"/><path d="M80.595 50.617h-2.403a.29.29 0 0 0-.289.29l-.058 37.7c0 .16.13.29.289.29l2.46.014c2.878 0 5.232-2.354 5.232-5.23V45.38c0 2.877-2.354 5.236-5.231 5.236zM56.63 51.658a3.229 3.229 0 1 1 0 6.457 3.229 3.229 0 0 1 0-6.457zm1.29-1.93v-3.325a1.008 1.008 0 0 0-2.014 0v3.296c-2.549.355-4.519 2.543-4.519 5.187 0 1.763.877 3.322 2.215 4.273L41.499 84.946c-.878 1.885.498 4.044 2.578 4.044a2.843 2.843 0 0 0 2.578-1.643l8.05-17.205c.82-1.74 3.292-1.747 4.121-.012l8.234 17.112a2.84 2.84 0 0 0 2.558 1.606c2.094 0 3.468-2.188 2.56-4.074l-12.353-25.74a5.232 5.232 0 0 0 2.048-4.148c0-2.445-1.684-4.5-3.953-5.076" fill="#073042"/></g></g></svg> \ No newline at end of file
diff --git a/adt-branding/src/artwork/preview/icon_AS_128.png b/adt-branding/src/artwork/preview/icon_AS_128.png
new file mode 100644
index 000000000000..4010fffe4cdf
--- /dev/null
+++ b/adt-branding/src/artwork/preview/icon_AS_128.png
Binary files differ
diff --git a/adt-branding/src/artwork/studio_about.png b/adt-branding/src/artwork/studio_about.png
new file mode 100644
index 000000000000..e7a0b1f5c9c7
--- /dev/null
+++ b/adt-branding/src/artwork/studio_about.png
Binary files differ
diff --git a/adt-branding/src/artwork/studio_about@2x.png b/adt-branding/src/artwork/studio_about@2x.png
new file mode 100644
index 000000000000..e7a0b1f5c9c7
--- /dev/null
+++ b/adt-branding/src/artwork/studio_about@2x.png
Binary files differ
diff --git a/adt-branding/src/artwork/studio_logo_background.png b/adt-branding/src/artwork/studio_logo_background.png
new file mode 100644
index 000000000000..0eedb99e1039
--- /dev/null
+++ b/adt-branding/src/artwork/studio_logo_background.png
Binary files differ
diff --git a/adt-branding/src/artwork/studio_progress_tail.png b/adt-branding/src/artwork/studio_progress_tail.png
new file mode 100644
index 000000000000..cc43259d38e3
--- /dev/null
+++ b/adt-branding/src/artwork/studio_progress_tail.png
Binary files differ
diff --git a/adt-branding/src/artwork/studio_splash.png b/adt-branding/src/artwork/studio_splash.png
new file mode 100644
index 000000000000..84b73038b31a
--- /dev/null
+++ b/adt-branding/src/artwork/studio_splash.png
Binary files differ
diff --git a/adt-branding/src/artwork/studio_splash@2x.png b/adt-branding/src/artwork/studio_splash@2x.png
new file mode 100644
index 000000000000..0247a1b3c237
--- /dev/null
+++ b/adt-branding/src/artwork/studio_splash@2x.png
Binary files differ
diff --git a/adt-branding/src/artwork/toolWindowProject_AS.png b/adt-branding/src/artwork/toolWindowProject_AS.png
new file mode 100644
index 000000000000..2613e28cd155
--- /dev/null
+++ b/adt-branding/src/artwork/toolWindowProject_AS.png
Binary files differ
diff --git a/adt-branding/src/artwork/toolWindowProject_AS@2x.png b/adt-branding/src/artwork/toolWindowProject_AS@2x.png
new file mode 100644
index 000000000000..9037a27fff0c
--- /dev/null
+++ b/adt-branding/src/artwork/toolWindowProject_AS@2x.png
Binary files differ
diff --git a/adt-branding/src/artwork/welcome.png b/adt-branding/src/artwork/welcome.png
new file mode 100644
index 000000000000..a9d78d39b4fb
--- /dev/null
+++ b/adt-branding/src/artwork/welcome.png
Binary files differ
diff --git a/adt-branding/src/artwork/welcome@2x.png b/adt-branding/src/artwork/welcome@2x.png
new file mode 100644
index 000000000000..290fdb588bd1
--- /dev/null
+++ b/adt-branding/src/artwork/welcome@2x.png
Binary files differ
diff --git a/adt-branding/src/idea/AndroidStudioApplicationInfo.xml b/adt-branding/src/idea/AndroidStudioApplicationInfo.xml
new file mode 100644
index 000000000000..97596796a066
--- /dev/null
+++ b/adt-branding/src/idea/AndroidStudioApplicationInfo.xml
@@ -0,0 +1,58 @@
+<!--
+ ~ Copyright 2000-2013 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.
+ -->
+<component xmlns="http://jetbrains.org/intellij/schema/application-info"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://jetbrains.org/intellij/schema/application-info http://jetbrains.org/intellij/schema/ApplicationInfo.xsd">
+ <version major="2022" minor="1" micro="0" patch="0" full="dev build" eap="true"/>
+ <company name="Google" url="http://developer.android.com"/>
+ <build number="AI-__BUILD__" date="__BUILD_DATE__"/>
+ <logo url="/artwork/studio_splash.png" textcolor="cccccc" progressColor="d7effe" progressY="397" progressHeight="3" />
+ <about url="/artwork/studio_about.png" foreground="cccccc"/>
+ <icon svg="/artwork/androidstudio.svg" svg-small="/artwork/androidstudio-small.svg" ico="artwork/androidstudio.ico"/>
+ <icon-eap svg="/artwork/preview/androidstudio.svg" svg-small="/artwork/preview/androidstudio-small.svg"/>
+ <package code="AI"/> <!-- used only in adrt -->
+ <names product="Studio" fullname="Android Studio" script="studio"/> <!-- fullname is used by NPW to show default folder for projects as -->
+ <essential-plugin>com.intellij.java</essential-plugin>
+ <essential-plugin>com.intellij.java.ide</essential-plugin>
+ <essential-plugin>org.jetbrains.android</essential-plugin>
+ <essential-plugin>com.android.tools.design</essential-plugin>
+
+ <welcome-screen logo-url="/artwork/welcome.png"/>
+
+ <editor background-url="/artwork/studio_logo_background.png"/>
+
+ <plugins url="https://plugins.jetbrains.com"/>
+ <update-urls check="https://dl.google.com/android/studio/patches/updates.xml"
+ patches="https://dl.google.com/android/studio/patches/"/>
+
+ <documentation url="http://developer.android.com/r/studio-ui/menu-start.html"/>
+ <feedback url="https://issuetracker.google.com/issues/new?component=192708&amp;template=840533&amp;foundIn=$STUDIO_VERSION&amp;format=MARKDOWN&amp;description=%60%60%60%0ABuild%3A%20__BUILD_NUMBER__%2C%20__BUILD_DATE__%2C%20$DESCR%0A%0AIMPORTANT%3A%20Please%20read%20https%3A%2F%2Fdeveloper.android.com%2Fstudio%2Freport-bugs.html%20carefully%20and%20supply%20all%20required%20information.%0A%60%60%60" />
+ <whatsnew url="https://developer.android.com/r/studio-ui/menu-whats-new.html"/>
+ <keymap win="https://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard.pdf"
+ mac="https://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard_Mac.pdf"/>
+ <jetbrains-tv url="https://www.youtube.com/c/AndroidDevelopers"/>
+
+ <!--
+ Temporarily disabled: There is a bug in IDEA which prevents having a single plugins page extension.
+ <plugins-page category="VCS Integration" title="Select VCS Integration Plugins"/>
+ -->
+
+ <statistics settings="https://dl.google.com/android/studio/stats/stat-assistant.xml"
+ service="https://dl.google.com/android/studio/stats/upload"
+ event-log-settings=""
+ service-key="android-studio" />
+
+</component> \ No newline at end of file
diff --git a/adt-branding/src/idea/ToolWindowManager.xml b/adt-branding/src/idea/ToolWindowManager.xml
new file mode 100644
index 000000000000..6408cde3debc
--- /dev/null
+++ b/adt-branding/src/idea/ToolWindowManager.xml
@@ -0,0 +1,6 @@
+<component>
+ <layout>
+ <window_info id="Captures" active="false" anchor="left" order="2" auto_hide="false" internal_type="docked" type="docked" visible="false" weight="0.25" />
+ </layout>
+</component>
+
diff --git a/bin/linux/fsnotifier b/bin/linux/fsnotifier
index ee37ab1f6ce1..534d644a054a 100755
--- a/bin/linux/fsnotifier
+++ b/bin/linux/fsnotifier
Binary files differ
diff --git a/bin/mac/fsnotifier b/bin/mac/fsnotifier
index bd49f69fe566..526144fa5965 100755
--- a/bin/mac/fsnotifier
+++ b/bin/mac/fsnotifier
Binary files differ
diff --git a/bin/mac/libnst64.dylib b/bin/mac/libnst64.dylib
index fd8a1ea6b90f..75e5679a0c02 100644
--- a/bin/mac/libnst64.dylib
+++ b/bin/mac/libnst64.dylib
Binary files differ
diff --git a/bin/mac/restarter b/bin/mac/restarter
index 692f52fce60c..37550c9283fe 100755
--- a/bin/mac/restarter
+++ b/bin/mac/restarter
Binary files differ
diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll
index ae77ff9b2309..94fc8c61a86e 100644
--- a/bin/win/IdeaWin32.dll
+++ b/bin/win/IdeaWin32.dll
Binary files differ
diff --git a/bin/win/IdeaWin64.dll b/bin/win/IdeaWin64.dll
index 62c674fab522..ba11dd14f4e0 100644
--- a/bin/win/IdeaWin64.dll
+++ b/bin/win/IdeaWin64.dll
Binary files differ
diff --git a/bin/win/WinProcessListHelper.exe b/bin/win/WinProcessListHelper.exe
index 914fa5a5ac24..1eb3934a1837 100644
--- a/bin/win/WinProcessListHelper.exe
+++ b/bin/win/WinProcessListHelper.exe
Binary files differ
diff --git a/bin/win/breakgen.dll b/bin/win/breakgen.dll
index 740b76cd215a..cad3d34da42a 100644
--- a/bin/win/breakgen.dll
+++ b/bin/win/breakgen.dll
Binary files differ
diff --git a/bin/win/breakgen64.dll b/bin/win/breakgen64.dll
index 88422067c06c..8e37d3e86d36 100644
--- a/bin/win/breakgen64.dll
+++ b/bin/win/breakgen64.dll
Binary files differ
diff --git a/bin/win/restarter.exe b/bin/win/restarter.exe
index d8553be20bb8..6428ccdcdacc 100644..100755
--- a/bin/win/restarter.exe
+++ b/bin/win/restarter.exe
Binary files differ
diff --git a/bin/win/runnerw.exe b/bin/win/runnerw.exe
index 84549150d69e..07bdb992d94b 100644..100755
--- a/bin/win/runnerw.exe
+++ b/bin/win/runnerw.exe
Binary files differ
diff --git a/build.txt b/build.txt
index cd92bf5f9f93..c4d55ece6d28 100644
--- a/build.txt
+++ b/build.txt
@@ -1 +1 @@
-221.SNAPSHOT \ No newline at end of file
+221.5787.30.2211.SNAPSHOT
diff --git a/build/dependencies/setupJdk.gradle b/build/dependencies/setupJdk.gradle
index e08026ebff0e..ad9b67450835 100644
--- a/build/dependencies/setupJdk.gradle
+++ b/build/dependencies/setupJdk.gradle
@@ -12,7 +12,9 @@ def sdkVersion = System.getProperty('intellij.build.jdk.version', '11').toIntege
def runtimeVersion = System.getProperty("intellij.build.bundled.jre.version", "11").toInteger()
def jbrs = [(sdkVersion): jdkBuild, (runtimeVersion): runtimeBuild]
def setupJdkTasks = jbrs.keySet().collect { "setupJbr$it" }
+task setupJdks(dependsOn: []) /* Android Studio: do not download JDKs
task setupJdks(dependsOn: setupJdkTasks)
+Android Studio: do not download JDKs */
cleanSetupJdks.dependsOn(jbrs.keySet().collectMany { ["cleanSetupJbr$it", "cleanDownloadJbr$it"] })
project.ext.jbrRepo = 'https://cache-redirector.jetbrains.com/intellij-jbr'
def jdkDir = System.getProperty('intellij.build.jdks.target.dir')?.with {
diff --git a/build/groovy/org/jetbrains/intellij/build/AndroidStudioBuilder.groovy b/build/groovy/org/jetbrains/intellij/build/AndroidStudioBuilder.groovy
new file mode 100644
index 000000000000..a734f7bd6811
--- /dev/null
+++ b/build/groovy/org/jetbrains/intellij/build/AndroidStudioBuilder.groovy
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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
+
+/**
+ * Based on IdeaCommunityBuilder, but simplified a bit since we build fewer things
+ * (for example, no intellij-core distribution)
+ */
+class AndroidStudioBuilder {
+ private final BuildContext buildContext
+
+ AndroidStudioBuilder(String home, BuildOptions options = new BuildOptions(), String projectHome = home) {
+ def properties = new AndroidStudioProperties(home, options)
+ buildContext = BuildContext.createContext(home, projectHome, properties, ProprietaryBuildTools.DUMMY, options)
+ }
+
+ void compileModules() {
+ BuildTasks.create(buildContext).compileProjectAndTests(["jps-builders"])
+ }
+
+ void buildDistributions() {
+ def tasks = BuildTasks.create(buildContext)
+ tasks.buildDistributions()
+ tasks.buildUpdaterJar()
+ }
+} \ No newline at end of file
diff --git a/build/groovy/org/jetbrains/intellij/build/AndroidStudioLibraryLicenses.groovy b/build/groovy/org/jetbrains/intellij/build/AndroidStudioLibraryLicenses.groovy
new file mode 100644
index 000000000000..eb69bbcf570f
--- /dev/null
+++ b/build/groovy/org/jetbrains/intellij/build/AndroidStudioLibraryLicenses.groovy
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 groovy.transform.CompileStatic
+
+import static org.jetbrains.intellij.build.LibraryLicense.jetbrainsLibrary
+
+@CompileStatic
+class AndroidStudioLibraryLicenses {
+ public static final List<LibraryLicense> LICENSES_LIST = [
+ new LibraryLicense(name: "AAPT Protos", libraryName: "aapt-proto", license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Am Instrument Data proto", libraryName: "libam-instrumentation-data-proto",
+ license: "Apache 2.0", url: "http://source.android.com/"),
+ // for android-core-proto module library in intellij.android.core
+ new LibraryLicense(name: "Android Core Protos", libraryName: "android-core-proto",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt"),
+ new LibraryLicense(name: "Android Emulator gRPC API", libraryName: "emulator-proto", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt"),
+ // for game-tools-protos module library in android.game-tools.main
+ new LibraryLicense(name: "Android Game Tools Protos", libraryName: "game-tools-protos", license: "Apache 2.0", url: "http://source.android.com/"),
+ // for instantapps-api module library in intellij.android.core
+ new LibraryLicense(name: "Android Instant Apps SDK API", libraryName: "instantapps-api", license: "Apache 2.0"),
+ // for jetifier-core module library in db-compilerCommon
+ new LibraryLicense(name: "Android Jetifier Core", libraryName: "jetifier-core", license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Android Studio Analytics Protos", libraryName: "studio-analytics-proto", license: "Apache 2.0", url: "http://source.android.com/"),
+ // for androidx-test-core-proto module library in intellij.android.core
+ new LibraryLicense(name: "AndroidX Test Library core protos", libraryName: "androidx-test-core-proto", license: "Android Software Development Kit License Agreement", licenseUrl: "https://developer.android.com/studio/terms"),
+ new LibraryLicense(name: "ANTLR 4 Runtime", libraryName: "antlr4-runtime", version: "4.5.3", license: "BSD",
+ url: "http://www.antlr.org", licenseUrl: "http://www.antlr.org/license.html"),
+ // for commons-lang module library in db-compiler
+ new LibraryLicense(name: "Apache Commons Lang", libraryName: "commons-lang", version: "2.6", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "http://commons.apache.org/proper/commons-lang/"),
+ // for bouncycastle module library in android.sdktools.sdk-common
+ new LibraryLicense(name: "Bouncy Castle", libraryName: "bouncycastle", license: "MIT License", url: "http://bouncycastle.org",
+ licenseUrl: "http://bouncycastle.org/licence.html"),
+ new LibraryLicense(name: "CDT", libraryName: "org.eclipse.cdt", license: "Eclipse Public License 1.0"),
+ // for ui-animation-tooling-internal module library in intellij.android.compose-designer
+ new LibraryLicense(name: "Compose Animation Tooling", libraryName: "ui-animation-tooling-internal", version: "0.1.0-SNAPSHOT",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0", url: "http://source.android.com/"),
+ // for compose-compiler-hosted module library in intellij.android.compose-ide-plugin
+ new LibraryLicense(name: "Compose Compiler Hosted", libraryName: "compose-compiler-hosted",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ // For ADB wireless QR Code generation
+ new LibraryLicense(name: "Core barcode encoding/decoding library", libraryName: "zxing-core",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ // for eclipse-layout-kernel module library in intellij.android.designer
+ new LibraryLicense(name: "Eclipse Layout Kernel", libraryName: "eclipse-layout-kernel", license: "Eclipse Public License 1.0"),
+ // for LSP4J module libraries in intellij.c
+ new LibraryLicense(name: "Eclipse LSP4J", libraryName: "org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0", license: "Eclipse Public License 1.0"),
+ new LibraryLicense(name: "Eclipse LSP4J", libraryName: "org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.12.0", license: "Eclipse Public License 1.0"),
+ new LibraryLicense(name: "fetchasgoogle.jar", libraryName: "fetchasgoogle.jar", license: "Apache 2.0"),
+ // for flatbuffers-java module library in android.sdktools.mlkit-common
+ new LibraryLicense(name: "FlatBuffers Java API", libraryName: "flatbuffers-java",
+ version: "1.11.1", url: "https://google.github.io/flatbuffers/",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Google APIs Client Library for Java", version: "min-repackaged-1.20.0",
+ libraryName: "google-api-java-client", url: "https://developers.google.com/api-client-library/java/",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Google Analytics API", version: "v3-rev115-1.20.0",
+ libraryName: "google-api-services-analytics-v3-rev115-1.20.0.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-api-services-appengine", version: "v1-rev9-1.22.0",
+ libraryName: "google-api-services-appengine-v1-rev9-1.22.0.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ // for auto-common module library in db-compiler
+ new LibraryLicense(name: "Google Auto Common Utilities", libraryName: "auto-common", version: "0.10", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://github.com/google/auto/tree/master/common"),
+ new LibraryLicense(name: "Google Cloud Resource Manager API", version: "v1beta1-rev12-1.21.0",
+ libraryName: "google-api-services-cloudresourcemanager-v1beta1-rev12-1.21.0.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-api-services-debugger", version: "",
+ libraryName: "google-api-services-debugger.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-api-services-mobilesdk", version: "v1",
+ libraryName: "google-api-services-mobilesdk-v1.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Google OAuth2 API", version: "v2-rev70-1.18.0-rc",
+ libraryName: "google-api-services-oauth2-v2-rev70-1.18.0-rc.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-api-services-source", version: "",
+ libraryName: "google-api-services-source.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Google Cloud Storage JSON API", version: "v1-rev1-1.18.0-rc",
+ libraryName: "google-api-services-storage-v1-rev1-1.18.0-rc.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-api-services-testing", version: "v1-revsnapshot-1.20.0",
+ libraryName: "google-api-services-testing-v1-revsnapshot-1.20.0.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-api-services-toolresults", version: "v1beta3-rev20151013-1.20.0",
+ libraryName: "google-api-services-toolresults-v1beta3-rev20151013-1.20.0.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google-http-client-jackson", version: "1.18.0-rc",
+ libraryName: "google-http-client-jackson-1.18.0-rc.jar", url: "",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "google.gdt.eclipse.login.common.jar", libraryName: "google.gdt.eclipse.login.common.jar",
+ license: "Eclipse Public License 1.0", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html"),
+ new LibraryLicense(name: "google-gct-login-context-pg.jar", libraryName: "google-gct-login-context-pg.jar",
+ license: "Eclipse Public License 1.0", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html"),
+ new LibraryLicense(name: "Gradle App Engine Tooling Model", version: "0.1.0",
+ libraryName: "gradle-appengine-builder-model-0.1.0.jar",
+ url: "https://github.com/GoogleCloudPlatform/gradle-appengine-plugin",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "HdrHistogram", version: "2.1.4", libraryName: "HdrHistogram",
+ license: "BSD 2-Clause", licenseUrl: "https://opensource.org/licenses/BSD-2-Clause"),
+ new LibraryLicense(name: "Jackson", version: "1.9.11", libraryName: "jackson-core-asl-1.9.11.jar", url: "http://jackson.codehaus.org",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ // for javapoet module library in db-compiler
+ new LibraryLicense(name: "Java Poet", libraryName: "javapoet", version: "1.8.0", license: "Apache 2.0",
+ url: "https://github.com/square/javapoet"),
+ new LibraryLicense(name: "Java Servlet API", libraryName: "javax.servlet-api-3.0.1.jar", license: "CDDL + GPLv2 w/ Classpath Exception",
+ licenseUrl: "https://glassfish.java.net/nonav/public/CDDL+GPL.html"),
+ new LibraryLicense(name: "JTS IO Common", libraryName: "jts-io-common", license: "Eclipse Public License 2.0"),
+ // for juniversalchardet module library in db-compiler
+ new LibraryLicense(name: "Juniversalchardet", libraryName: "juniversalchardet", version: "1.0.3",
+ url: "https://code.google.com/archive/p/juniversalchardet",
+ license: "MPL 1.1", licenseUrl: "http://www.mozilla.org/MPL/MPL-1.1.html"),
+ new LibraryLicense(name: "kotlin-gradle-plugin-model", libraryName: "kotlin-gradle-plugin-model", version: "1.3.0",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Layout Inspector Protos", libraryName: "layoutinspector-proto", license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Layoutlib", libraryName: "layoutlib", version: "1.0", license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Layoutlib Legacy", libraryName: "layoutlib-legacy", version: "1.0", license: "Apache 2.0", url: "http://source.android.com/"),
+ // for moshi module library in intellij.android.core
+ new LibraryLicense(name: "Moshi", libraryName: "moshi", version: "1.6.0", license: "Apache 2.0",
+ url: "https://github.com/square/moshi"),
+ // for okio module library in intellij.android.core
+ new LibraryLicense(name: "Okio", libraryName: "okio", version: "1.14.0", license: "Apache 2.0",
+ url: "https://github.com/square/okio"),
+ // for pepk module library in intellij.android.core
+ new LibraryLicense(name: "PEPK", libraryName: "pepk", license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Perfetto protos", libraryName: "perfetto-proto", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "samplesindex-v1-1.0-SNAPSHOT.jar", libraryName: "samplesindex-v1-1.0-SNAPSHOT.jar",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "SQLite Inspector Proto", libraryName: "sqlite-inspector-proto", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Studio gRPC", libraryName: "studio-grpc", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Studio Protobuf", libraryName: "studio-proto", license: "protobuf",
+ licenseUrl: "https://github.com/protocolbuffers/protobuf/blob/master/LICENSE"),
+ new LibraryLicense(name: "swt.jar", libraryName: "swt.jar",
+ license: "Eclipse Public License 1.0", licenseUrl: "http://www.eclipse.org/legal/epl-v10.html"),
+ new LibraryLicense(name: "uiautomatorviewer.jar", libraryName: "uiautomatorviewer.jar", license: "Apache 2.0"),
+ new LibraryLicense(name: "TightVNC", libraryName: "tightvnc", license: "Commercial License"),
+ // for tensorflow-lite-metadata module library in android.sdktools.mlkit-common
+ new LibraryLicense(name: "TensorFlow Lite Metadata Library", libraryName: "tensorflow-lite-metadata",
+ version: "0.1.0-rc2", url: "https://tensorflow.org/lite",
+ license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ // for traceprocessor-proto module library in intellij.android.profilersAndroid
+ new LibraryLicense(name: "TraceProcessor Daemon Protos", libraryName: "traceprocessor-proto", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Transport Pipeline", libraryName: "transport-proto", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ // for workmanager-inspector-proto module library in intellij.android.app-inspection.inspectors.workmanager.model
+ new LibraryLicense(name: "WorkManager Inspector Proto", libraryName: "workmanager-inspector-proto", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Xtext", libraryName: "xtext-xbase", license: "Eclipse Public License 1.0"),
+ new LibraryLicense(name: "Instant App Proto Manifest", libraryName: "aia-proto",
+ license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Archive Patcher",
+ libraryName: "archive-patcher",
+ url: "https://github.com/andrewhayden/archive-patcher",
+ additionalLibraryNames: ["explainer.jar", "generator.jar", "shared.jar"],
+ license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
+ new LibraryLicense(name: "Instant run protos", libraryName: "deploy_java_proto.jar",
+ license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "Instant run version", libraryName: "libjava_version.jar",
+ license: "Apache 2.0", url: "http://source.android.com/"),
+ new LibraryLicense(name: "R8", libraryName: "r8.jar", license: "BSD"),
+ ] as List<LibraryLicense>
+}
diff --git a/build/groovy/org/jetbrains/intellij/build/AndroidStudioProperties.groovy b/build/groovy/org/jetbrains/intellij/build/AndroidStudioProperties.groovy
new file mode 100644
index 000000000000..7c32a53e87b4
--- /dev/null
+++ b/build/groovy/org/jetbrains/intellij/build/AndroidStudioProperties.groovy
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
+import groovy.transform.TypeCheckingMode
+import org.jetbrains.intellij.build.kotlin.KotlinPluginBuilder
+
+import java.nio.file.Path
+import java.nio.file.Paths
+import org.jetbrains.intellij.build.impl.PluginLayout
+import org.jetbrains.jps.model.module.JpsModule
+
+import static org.jetbrains.intellij.build.impl.PluginLayout.plugin
+
+// Based on the IdeaCommunityProperties definition
+// TODO: Need Windows installer and Mac DMG images
+// TODO: Need uninstaller feedback URL
+// Consider switching from AI to AS code
+// Restore a lot of the custom logic from studio_properties
+// TODO: Use separate bundle identifier for EAP and non-EAP
+@CompileStatic
+class AndroidStudioProperties extends BaseIdeaProperties {
+
+ private static final List<String> INHERITED_PLUGINS = ProductModulesLayout.DEFAULT_BUNDLED_PLUGINS + BUNDLED_PLUGIN_MODULES
+
+ private static final List<String> EXTRA_PLUGINS = List.of(
+ // Android Studio: package CIDR plugins. This list is based on what we have been shipping in Android Studio
+ // and the structure of CIDR plugins.
+ "intellij.c.clangd",
+ "intellij.c.clangdBridge",
+ "intellij.c.plugin",
+ "intellij.cidr.debugger.plugin",
+ "intellij.cidr.base.plugin",
+ )
+
+ private static final List<String> EXCLUDED_PLUGINS = List.of(
+ "intellij.android.gradle.dsl",
+ "intellij.android.plugin",
+ "intellij.android.smali",
+ "intellij.ant",
+ "intellij.devkit",
+ "intellij.eclipse",
+ "intellij.featuresTrainer",
+ "intellij.gradle.dependencyUpdater",
+ "intellij.gradle.java.maven",
+ "intellij.grazie",
+ "intellij.java.byteCodeViewer",
+ "intellij.java.guiForms.designer",
+ "intellij.javaFX.community",
+ "intellij.lombok",
+ "intellij.maven",
+ "intellij.packageSearch",
+ "intellij.platform.tracing.ide",
+ "intellij.searchEverywhereMl",
+ "intellij.statsCollector",
+ "intellij.vcs.git.featuresTrainer",
+ "intellij.xpath",
+ "intellij.xslt.debugger",
+ KotlinPluginBuilder.MAIN_KOTLIN_PLUGIN_MODULE,
+ )
+
+ AndroidStudioProperties(String home, BuildOptions buildOptions) {
+ baseFileName = "studio"
+ platformPrefix = "AndroidStudio"
+ productCode = "AI"
+ applicationInfoModule = "intellij.android.adt.branding"
+ useSplash = true
+ additionalIDEPropertiesFilePaths = ["$home/build/conf/ideaCE.properties".toString()]
+ toolsJarRequired = true
+ scrambleMainJar = false
+ buildSourcesArchive = true;
+ buildCrossPlatformDistribution = true
+
+ allLibraryLicenses.addAll(AndroidStudioLibraryLicenses.LICENSES_LIST)
+ includeIntoSourcesArchiveFilter = { JpsModule module, BuildContext buildContext -> true }
+
+ productLayout.productApiModules = JAVA_IDE_API_MODULES
+ productLayout.productImplementationModules = JAVA_IDE_IMPLEMENTATION_MODULES +
+ ["intellij.platform.duplicates.analysis", "intellij.platform.structuralSearch", "intellij.platform.main"] -
+ ["intellij.platform.jps.model.impl", "intellij.platform.jps.model.serialization"]
+ productLayout.withAdditionalPlatformJar("resources.jar", "intellij.idea.community.resources", "intellij.android.adt.branding")
+
+ def unknownExcludedPlugins = EXCLUDED_PLUGINS - INHERITED_PLUGINS
+ assert unknownExcludedPlugins.empty : "AndroidStudioProperties.EXCLUDED_PLUGINS contains nonexistent plugins: $unknownExcludedPlugins"
+ productLayout.bundledPluginModules = INHERITED_PLUGINS + EXTRA_PLUGINS - EXCLUDED_PLUGINS
+
+ productLayout.mainModules = ["intellij.idea.community.main"]
+ productLayout.prepareCustomPluginRepositoryForPublishedPlugins = false
+ productLayout.buildAllCompatiblePlugins = false
+
+ List<PluginLayout> inheritedPluginLayouts = new ArrayList<>(CommunityRepositoryModules.COMMUNITY_REPOSITORY_PLUGINS)
+ // Remove plugin layouts that reference modules that do not exist in our fork.
+ inheritedPluginLayouts.removeAll {
+ it.mainModule in EXCLUDED_PLUGINS || it.mainModule == "intellij.python.community.plugin"
+ }
+ productLayout.allNonTrivialPlugins = inheritedPluginLayouts + [
+ JavaPluginLayout.javaPlugin(),
+ CommunityRepositoryModules.groovyPlugin([]),
+ plugin("intellij.cidr.debugger.plugin") {
+ withModule("intellij.cidr.debugger", mainJarName)
+ withModule("intellij.cidr.debugger.backend", mainJarName)
+ withModule("intellij.cidr.debugger.commandInterpreterLang", mainJarName)
+ withModule("intellij.cidr.core", mainJarName)
+ withModule("intellij.cidr.util", mainJarName)
+ withModule("intellij.cidr.util.serializer", mainJarName)
+ withModule("intellij.cidr.util.ui", mainJarName)
+ },
+ plugin("intellij.cidr.base.plugin") {
+ withModule("intellij.c.dfa", mainJarName)
+ withModule("intellij.cidr.base", mainJarName)
+ withModule("intellij.cidr.projectModel", mainJarName)
+ withModule("intellij.cidr.workspaceModel", mainJarName)
+ withModule("intellij.cidr.lang.base", mainJarName)
+ withModule("intellij.cidr.execution", mainJarName)
+ // Note the following are in CLionProperties.groovy but we don't include them since
+ // they were never shipped with Android Studio before.
+ // * intellij.cidr.toolchains
+ // * intellij.platform.ssh.nio
+ // * intellij.apple.sdk
+ // The following are not in CLionProperties.groovy for this plugin. Instead they
+ // are put under plugin "intellij.clion" or IDE implementation. We put them under
+ // this base plugin so that they will still be shipped.
+ withModule("intellij.cidr.psi.base", mainJarName)
+ withModule("intellij.cidr.resources", mainJarName)
+ withModule("intellij.cidr.common", mainJarName)
+ withModule("intellij.cmake.psi", mainJarName)
+ // The cidr test framework is included in the IDE base in Clion. But we
+ // include it here to support writing tests in plugins.
+ withModule("intellij.cidr.common.testFramework.core", mainJarName)
+ },
+ plugin("intellij.c.plugin") {
+ withModule("intellij.c", mainJarName)
+ withModule("intellij.c.debugger", mainJarName)
+ withModule("intellij.c.doxygen", mainJarName)
+ withModule("intellij.c.testing", mainJarName)
+ withModule("intellij.cidr.modulemap.language", mainJarName)
+ },
+ ]
+ }
+
+ @Override
+ @CompileDynamic
+ void copyAdditionalFiles(BuildContext buildContext, String targetDirectory) {
+ super.copyAdditionalFiles(buildContext, targetDirectory)
+
+ buildContext.ant.copy(todir: targetDirectory) {
+ fileset(file: "$buildContext.paths.communityHome/LICENSE.txt")
+ fileset(file: "$buildContext.paths.communityHome/NOTICE.txt")
+ }
+ buildContext.ant.copy(todir: "$targetDirectory/bin") {
+ fileset(dir: "$buildContext.paths.communityHome/build/conf/ideaCE/common/bin")
+ }
+ def root = "$buildContext.paths.communityHome/../.."
+ buildContext.ant.copy(todir: "$targetDirectory/bin/lldb/helpers") {
+ fileset(dir: "$root/tools/vendor/intellij/cidr/cidr-debugger/bin/lldb/helpers/")
+ }
+ buildContext.ant.copy(todir: "$targetDirectory/bin/helpers") {
+ fileset(dir: "$root/tools/vendor/intellij/cidr/cidr-debugger/bin/helpers")
+ }
+
+ // Android Studio: copy CIDR license to CIRR plugins
+ buildContext.ant.copy(tofile: "$targetDirectory/plugins/c-clangd/lib/LICENSE.txt") {
+ fileset(file: "$buildContext.paths.communityHome/CIDR_LICENSE.txt")
+ }
+ buildContext.ant.copy(tofile: "$targetDirectory/plugins/c-plugin/lib/LICENSE.txt") {
+ fileset(file: "$buildContext.paths.communityHome/CIDR_LICENSE.txt")
+ }
+ buildContext.ant.copy(tofile: "$targetDirectory/plugins/cidr-base-plugin/lib/LICENSE.txt") {
+ fileset(file: "$buildContext.paths.communityHome/CIDR_LICENSE.txt")
+ }
+ }
+
+ @Override
+ WindowsDistributionCustomizer createWindowsCustomizer(String projectHome) {
+ return new WindowsDistributionCustomizer() {
+ {
+ icoPath = "$projectHome/adt-branding/src/artwork/androidstudio.ico"
+ icoPathForEAP = "$projectHome/adt-branding/src/artwork/preview/androidstudio.ico"
+ zipArchiveWithBundledJre = false
+ installerImagesPath = "$projectHome/build/conf/ideaCE/win/images"
+ fileAssociations = [".java", ".groovy", ".kt"]
+ }
+
+ @Override
+ String getFullNameIncludingEdition(ApplicationInfoProperties applicationInfo) { "Android Studio" }
+
+ @Override
+ String getFullNameIncludingEditionAndVendor(ApplicationInfoProperties applicationInfo) { "Android Studio" }
+
+ @Override
+ String getRootDirectoryName(ApplicationInfoProperties applicationInfo, String buildNumber) { "android-studio" }
+
+ @Override
+ String getUninstallFeedbackPageUrl(ApplicationInfoProperties applicationInfo) {
+// TODO
+ "https://www.jetbrains.com/idea/uninstall/?edition=IC-${applicationInfo.majorVersion}.${applicationInfo.minorVersion}"
+ }
+
+ @Override
+ @CompileDynamic
+ void copyAdditionalFiles(BuildContext context, String targetDirectory) {
+ def root = "$context.paths.communityHome/../.."
+ context.ant.copy(todir: "$targetDirectory/plugins/c-clangd/bin/clang/win") {
+ fileset(dir: "$root/prebuilts/tools/clion/bin/clang/win")
+ }
+
+ // Android Studio: go/project-aplos
+ Path distBinDir = Paths.get(targetDirectory).resolve("bin")
+ buildGameToolsScriptsForWindows(context, distBinDir)
+ }
+ }
+ }
+
+ @Override
+ LinuxDistributionCustomizer createLinuxCustomizer(String projectHome) {
+ return new LinuxDistributionCustomizer() {
+ {
+ buildOnlyBareTarGz = true
+ iconPngPath = "$projectHome/adt-branding/src/artwork/icon_AS_128.png"
+ iconPngPathForEAP = "$projectHome/adt-branding/src/artwork/preview/icon_AS_128.png"
+ }
+
+ @Override
+ String getRootDirectoryName(ApplicationInfoProperties applicationInfo, String buildNumber) { "android-studio" }
+
+ @Override
+ @CompileDynamic
+ void copyAdditionalFiles(BuildContext context, Path targetDirectory) {
+ def root = "$context.paths.communityHome/../.."
+
+ context.ant.copy(todir: "$targetDirectory/plugins/c-clangd/bin/clang/linux") {
+ fileset(dir: "$root/prebuilts/tools/clion/bin/clang/linux")
+ }
+ extraExecutables.add("plugins/c-clangd/bin/clang/linux/clangd")
+ extraExecutables.add("plugins/c-clangd/bin/clang/linux/clang-tidy")
+
+ // Android Studio: go/project-aplos
+ Path distBinDir = targetDirectory.resolve("bin")
+ buildGameToolsScriptsForUnix(context, distBinDir)
+ }
+ }
+ }
+
+ class StudioMacDistributionCustomizer extends MacDistributionCustomizer {
+ StudioMacDistributionCustomizer(String projectHome) {
+ urlSchemes = ["idea"]
+ associateIpr = true
+ bundleIdentifier = "com.google.android.studio"
+ dmgImagePath = "$projectHome/build/conf/ideaCE/mac/images/dmg_background.tiff"
+ // For now we have all 3 platform icons checked in and we change
+ // the icons manually. Fix this when the other platforms have the
+ // same mechanisms for our .ico and .svg files
+ icnsPath = "$projectHome/adt-branding/src/artwork/AndroidStudio.icns"
+ icnsPathForEAP = "$projectHome/adt-branding/src/artwork/preview/AndroidStudio.icns"
+ }
+
+ @Override
+ String getRootDirectoryName(ApplicationInfoProperties applicationInfo, String buildNumber) {
+ applicationInfo.isEAP ? "Android Studio Preview.app" : "Android Studio.app"
+ }
+
+ @Override
+ @CompileDynamic
+ void copyAdditionalFiles(BuildContext context, String targetDirectory) {
+ def root = "$context.paths.communityHome/../.."
+
+ context.ant.copy(todir: "$targetDirectory/plugins/c-clangd/bin/clang/mac") {
+ fileset(dir: "$root/prebuilts/tools/clion/bin/clang/mac")
+ }
+ extraExecutables.add("plugins/c-clangd/bin/clang/mac/clangd")
+ extraExecutables.add("plugins/c-clangd/bin/clang/mac/clang-tidy")
+
+ // Android Studio: go/project-aplos
+ Path distBinDir = Paths.get(targetDirectory).resolve("bin")
+ buildGameToolsScriptsForUnix(context, distBinDir)
+ }
+ }
+
+ @Override
+ MacDistributionCustomizer createMacCustomizer(String projectHome) {
+ new StudioMacDistributionCustomizer(projectHome)
+ }
+
+ @Override
+ String getSystemSelector(ApplicationInfoProperties applicationInfo, String buildNumber) { "AndroidStudio${applicationInfo.isEAP ? "Preview" : ""}${applicationInfo.majorVersion}.${applicationInfo.minorVersionMainPart}" }
+
+ @Override
+ String getBaseArtifactName(ApplicationInfoProperties applicationInfo, String buildNumber) { "android-studio-$buildNumber" }
+
+ @Override
+ String getOutputDirectoryName(ApplicationInfoProperties applicationInfo) { "studio" }
+
+ @CompileStatic(TypeCheckingMode.SKIP)
+ private void buildGameToolsScriptsForWindows(BuildContext buildContext, Path distBinDir) {
+ List<String> classPathJars = buildContext.bootClassPathJarNames
+ String classPath = "SET \"CLASS_PATH=%IDE_HOME%\\lib\\${classPathJars.get(0)}\""
+ for (int i = 1; i < classPathJars.size(); i++) {
+ classPath += "\nSET \"CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${classPathJars.get(i)}\""
+ }
+ String fullName = buildContext.applicationInfo.productName
+ String baseName = buildContext.productProperties.baseFileName
+ String vmOptionsFileName = "${baseName}64.exe"
+
+ // We manually set the classpath to include everything the game tools need and disable all plugin loading at runtime with
+ // `-Didea.load.plugins=false`. This change on classpath is needed since AndroidGameDevelopmentToolsPlugin.xml, the starting plugin XML, is
+ // located in plugins/android/lib/game-tools.jar, which is not in classpath by default. In addition, AndroidGameDevelopmentToolsPlugin.xml
+ // directly references all needed Intellij platform components so that the unneeded ones (for example, shift-shift to find everything)
+ // are ignored. See go/project-aplos-design for more details.
+ String gameToolsClassPath = classPath + "\n" + [
+ "plugins/android/lib/*",
+ "plugins/android/resources/*",
+ "plugins/java/lib/java-api.jar",
+ "plugins/java/lib/java-impl.jar",
+ "plugins/java/lib/resources.jar",
+ "plugins/java/lib/java_resources_en.jar"
+ ].collect { "SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\$it" }.join("\n")
+
+ buildContext.ant.copy(todir: "$distBinDir") {
+ fileset(dir: "$buildContext.paths.communityHome/platform/build-scripts/resources/win/scripts")
+ filterset(begintoken: "@@", endtoken: "@@") {
+ filter(token: "product_full", value: fullName + "GameTools")
+ filter(token: "product_uc", value: buildContext.productProperties.getEnvironmentVariableBaseName(buildContext.applicationInfo))
+ filter(token: "product_vendor", value: buildContext.applicationInfo.shortCompanyName)
+ filter(token: "vm_options", value: vmOptionsFileName)
+ filter(token: "isEap", value: buildContext.applicationInfo.isEAP)
+ filter(token: "system_selector", value: "AndroidGameDevelopmentTools")
+ filter(token: "ide_jvm_args", value: buildContext.additionalJvmArguments + " -Didea.platform.prefix=AndroidGameDevelopmentTools -Didea.load.plugins=false -Didea.initially.ask.config=force-not")
+ filter(token: "class_path", value: gameToolsClassPath)
+ filter(token: "script_name", value: "game-tools.bat")
+ }
+ }
+ buildContext.ant.move(file: "$distBinDir/executable-template.bat", tofile: "$distBinDir/game-tools.bat")
+ buildContext.ant.move(file: "$distBinDir/profiler.bat", tofile: "$distBinDir/profiler.bat")
+
+ // Copy the profiler launcher executable.
+ buildContext.ant.copy(todir: "$distBinDir") {
+ fileset(dir: "$buildContext.paths.communityHome/../../prebuilts/tools/windows/game-tools/GameToolsWinLauncher")
+ }
+ buildContext.ant.move(file: "$distBinDir/ProfilerWinLauncher.exe", tofile: "$distBinDir/profiler.exe")
+ }
+
+ @CompileStatic(TypeCheckingMode.SKIP)
+ static void buildGameToolsScriptsForUnix(BuildContext buildContext, Path distBinDir) {
+ String platformClassPath = "CLASS_PATH=\"\$IDE_HOME/lib/${buildContext.bootClassPathJarNames[0]}\"\n"
+ platformClassPath += buildContext.bootClassPathJarNames[1..-1].collect { "CLASS_PATH=\"\$CLASS_PATH:\$IDE_HOME/lib/${it}\"" }.join("\n")
+
+ // We manually set the classpath to include everything the game tools need and disable all plugin loading at runtime with
+ // `-Didea.load.plugins=false`. This change on classpath is needed since AndroidGameDevelopmentToolsPlugin.xml, the starting plugin XML, is
+ // located in plugins/android/lib/game-tools.jar, which is not in classpath by default. In addition, AndroidGameDevelopmentToolsPlugin.xml
+ // directly references all needed Intellij platform components so that the unneeded ones (for example, shift-shift to find everything)
+ // are ignored. See go/project-aplos-design for more details.
+ String gameToolsClassPath = platformClassPath + "\n" + [
+ "plugins/android/lib/*",
+ "plugins/android/resources/*",
+ "plugins/java/lib/java-api.jar",
+ "plugins/java/lib/java-impl.jar",
+ "plugins/java/lib/resources.jar",
+ "plugins/java/lib/java_resources_en.jar"].
+ collect { "CLASS_PATH=\"\$CLASS_PATH:\$IDE_HOME/${it}\"" }.join("\n")
+
+ buildContext.ant.copy(todir: "${distBinDir}") {
+ fileset(dir: "$buildContext.paths.communityHome/platform/build-scripts/resources/linux/scripts")
+ filterset(begintoken: "__", endtoken: "__") {
+ filter(token: "product_full", value: buildContext.applicationInfo.productName + "GameTools")
+ filter(token: "product_uc", value: buildContext.productProperties.getEnvironmentVariableBaseName(buildContext.applicationInfo))
+ filter(token: "product_vendor", value: buildContext.applicationInfo.shortCompanyName)
+ filter(token: "vm_options", value: buildContext.productProperties.baseFileName)
+ filter(token: "system_selector", value: "AndroidGameDevelopmentTools")
+ // Here we overwrite idea.platform.prefix to start the distinct entry point of game tools.
+ filter(token: "ide_jvm_args", value:
+ buildContext.additionalJvmArguments + " -Didea.platform.prefix=AndroidGameDevelopmentTools -Didea.load.plugins=false -Didea.initially.ask.config=force-not")
+ filter(token: "class_path", value: gameToolsClassPath)
+ filter(token: "script_name", value: "game-tools.sh")
+ }
+ }
+ buildContext.ant.move(file: "${distBinDir}/executable-template.sh", tofile: "${distBinDir}/game-tools.sh")
+ buildContext.ant.move(file: "${distBinDir}/profiler.sh", tofile: "${distBinDir}/profiler.sh")
+ }
+
+
+}
diff --git a/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy b/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy
index 5f807706b63f..972c1e071b4b 100644
--- a/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy
+++ b/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy
@@ -17,7 +17,7 @@ import java.util.function.BiConsumer
*/
@CompileStatic
abstract class BaseIdeaProperties extends JetBrainsProductProperties {
- private static final List<String> JAVA_IDE_API_MODULES = List.of(
+ public static final List<String> JAVA_IDE_API_MODULES = List.of(
"intellij.xml.dom",
"intellij.platform.uast.tests",
"intellij.jsp.base"
@@ -186,9 +186,11 @@ abstract class BaseIdeaProperties extends JetBrainsProductProperties {
@Override
void copyAdditionalFiles(BuildContext context, String targetDirectory) {
+ /* Disabled in Android Studio:
Path targetDir = Path.of(targetDirectory)
// for compatibility with users projects which refer to IDEA_HOME/lib/annotations.jar
Files.move(targetDir.resolve("lib/annotations-java5.jar"), targetDir.resolve("lib/annotations.jar"),
StandardCopyOption.REPLACE_EXISTING)
+ */
}
}
diff --git a/build/scripts/AndroidStudioBuildTarget.kt b/build/scripts/AndroidStudioBuildTarget.kt
new file mode 100644
index 000000000000..bfe1780e23dd
--- /dev/null
+++ b/build/scripts/AndroidStudioBuildTarget.kt
@@ -0,0 +1,11 @@
+import org.jetbrains.intellij.build.AndroidStudioBuilder
+import org.jetbrains.intellij.build.BuildOptions
+import org.jetbrains.intellij.build.IdeaProjectLoaderUtil
+
+object AndroidStudioBuildTarget {
+ @JvmStatic
+ fun main(args: Array<String>) {
+ val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass).toString()
+ AndroidStudioBuilder(communityHome, BuildOptions()).buildDistributions()
+ }
+} \ No newline at end of file
diff --git a/build/tasks/src/org/jetbrains/intellij/build/io/ZipArchiveOutputStream.kt b/build/tasks/src/org/jetbrains/intellij/build/io/ZipArchiveOutputStream.kt
index 8df065dc3e9b..36205afde764 100644
--- a/build/tasks/src/org/jetbrains/intellij/build/io/ZipArchiveOutputStream.kt
+++ b/build/tasks/src/org/jetbrains/intellij/build/io/ZipArchiveOutputStream.kt
@@ -416,8 +416,10 @@ internal class ZipArchiveOutputStream(private val channel: WritableByteChannel,
fun addDirsToIndex(dirNames: Collection<String>) {
assert(withOptimizedMetadataEnabled)
for (dirName in dirNames) {
+/* Android Studio: b/233762164
val key = dirName.toByteArray(Charsets.UTF_8)
indexWriter.add(IndexEntry(key = key, offset = -1, size = 0, keyHash = Xxh3.hash(key)))
+Android Studio: b/233762164 */ addDirEntry(dirName)
}
}
diff --git a/build_studio.sh b/build_studio.sh
new file mode 100755
index 000000000000..f01392b4f77c
--- /dev/null
+++ b/build_studio.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# exit on error
+set -e
+
+PROG_DIR="$(cd "$(dirname "$0")" && pwd)"
+
+function die() {
+ echo "$*" > /dev/stderr
+ echo "Usage: $0 [--incremental]" > /dev/stderr
+ exit 1
+}
+
+function get_absolute_path() {
+ ( unset CDPATH; cd "$1" && pwd ) 2> /dev/null
+}
+
+OUT="${OUT_DIR:-out/studio}"
+DIST="${DIST_DIR:-"${OUT}/dist"}"
+
+cd "$PROG_DIR"
+mkdir -p "$OUT"
+mkdir -p "$DIST"
+# ensure OUT and DIST are absolute paths
+OUT="$(get_absolute_path "$OUT")"
+DIST="$(get_absolute_path "$DIST")"
+
+INCREMENTAL=false
+while [[ $# -gt 0 ]]; do
+ if [[ $1 = "--incremental" ]]; then
+ INCREMENTAL=true
+ else
+ die "[$0] Unknown parameter: $1"
+ fi
+ shift
+done
+
+readonly AS_BUILD_NUMBER="$(sed "s/SNAPSHOT/__BUILD_NUMBER__/" build.txt)"
+
+declare -ar BUILD_PROPERTIES=(
+ "-Dintellij.build.output.root=${OUT}"
+ "-Dbuild.number=${AS_BUILD_NUMBER}"
+ "-Dintellij.build.dev.mode=false"
+ "-Dcompile.parallel=true"
+ "-Dintellij.build.skip.build.steps=mac_dmg,mac_sign,windows_exe_installer,cross_platform_dist"
+ "-Dintellij.build.incremental.compilation=${INCREMENTAL}"
+)
+
+"${PROG_DIR}/platform/jps-bootstrap/jps-bootstrap.sh" "${BUILD_PROPERTIES[@]}" "${PROG_DIR}" intellij.idea.community.build AndroidStudioBuildTarget
+
+"${PROG_DIR}/platform/jps-bootstrap/jps-bootstrap.sh" "-Dintellij.build.output.root=${OUT}/updater" "${PROG_DIR}" intellij.idea.community.build FullUpdaterBuildTarget
+
+mkdir -p "$DIST"
+cp -Rfv "$OUT"/artifacts/android-studio* "$DIST"
+cp -Rfv "$OUT"/updater/artifacts/updater-full.jar "$DIST"/updater-full.jar
diff --git a/images/src/org/intellij/images/util/imageio/CommonsImagingImageReaderSpi.java b/images/src/org/intellij/images/util/imageio/CommonsImagingImageReaderSpi.java
index 374b66bddb9f..c2659b78ae7c 100644
--- a/images/src/org/intellij/images/util/imageio/CommonsImagingImageReaderSpi.java
+++ b/images/src/org/intellij/images/util/imageio/CommonsImagingImageReaderSpi.java
@@ -38,6 +38,9 @@ public class CommonsImagingImageReaderSpi extends ImageReaderSpi {
ImageFormats.TIFF,
ImageFormats.PNG));
+ // Android Studio: BMP reader cannot handle images with negative height (top down images)
+ myFormats.remove(ImageFormats.BMP);
+
names = new String[myFormats.size() * 2];
suffixes = new String[myFormats.size()];
MIMETypes = new String[myFormats.size()];
diff --git a/intellij.idea.community.main.iml b/intellij.idea.community.main.iml
index 9994b99f1126..f929231529f6 100644
--- a/intellij.idea.community.main.iml
+++ b/intellij.idea.community.main.iml
@@ -67,38 +67,31 @@
<orderEntry type="module" module-name="intellij.java.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.copyright" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.testFramework" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.java.guiForms.designer" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.devkit" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.eclipse" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.vcs.git" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.vcs.git.featuresTrainer" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.images" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.groovy" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.junit" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.maven" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.regexp" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.vcs.svn" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.vcs.svn.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.testng" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.java.langInjection" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.xml.langInjection" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.xpath" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.xslt.debugger" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.xslt.debugger.rt" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.java.i18n" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.tasks" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.tasks.java" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.tasks.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.vcs.github" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.vcs.hg" scope="RUNTIME" />
+ <orderEntry type="module" module-name="intellij.android.adt.branding" />
<orderEntry type="module" module-name="intellij.relaxng" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.gradle.java" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.remoteServers.impl" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.properties.resource.bundle.editor" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.xml.dom.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.colorSchemes" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.javaFX.community" scope="RUNTIME" />
- <orderEntry type="module" module-name="intellij.javaFX.jps" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.langInjection.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.manifest" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.yaml" scope="RUNTIME" />
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
index 1c5a13b8fbbd..bd557061ccc9 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
@@ -438,8 +438,12 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
return StreamEx.empty();
}
+ // Android Studio: In some scenarios we need to set a breakpoint in a different class to the one found here.
+ // when that happens we need to allow a custom position manager to change the class at the last minute.
+ // here we call "mapClass" to obtain the final class.
if (!isLocalOrAnonymous) {
- return StreamEx.of(myDebugProcess.getVirtualMachineProxy().classesByName(className));
+ return StreamEx.of(myDebugProcess.getVirtualMachineProxy().classesByName(className))
+ .map(outer -> mapClass(outer));
}
final int depth = requiredDepth;
@@ -449,6 +453,13 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
.nonNull();
}
+ /**
+ * Indirection which allows custom position managers to provide a different class type to represent the vm's class.
+ */
+ protected ReferenceType mapClass(ReferenceType type) {
+ return type;
+ }
+
private static Pair<PsiClass, Integer> getTopOrStaticEnclosingClass(PsiClass aClass) {
int depth = 0;
PsiClass enclosing = getEnclosingClass(aClass);
@@ -513,7 +524,10 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
int rangeBegin = Integer.MAX_VALUE;
int rangeEnd = Integer.MIN_VALUE;
- List<Location> locations = DebuggerUtilsEx.allLineLocations(fromClass);
+ // Android Studio: After recursing to get the right inner class, but before line calculations
+ // happen, we again give the chance to swap the actual class to use.
+ final ReferenceType mapped = mapClass(fromClass);
+ List<Location> locations = DebuggerUtilsEx.allLineLocations(mapped);
if (locations != null) {
for (Location location : locations) {
final int lnumber = DebuggerUtilsEx.getLineNumber(location, false);
@@ -556,12 +570,12 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
// if there's more than one class on the line - try to match by name
for (PsiClass aClass : lineClasses) {
if (classToFind.equals(aClass)) {
- return fromClass;
+ return mapped;
}
}
}
else if (!lineClasses.isEmpty()){
- return classToFind.equals(lineClasses.iterator().next())? fromClass : null;
+ return classToFind.equals(lineClasses.iterator().next())? mapped : null;
}
return null;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java
index c19b7ec72faf..e680c6047034 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import java.awt.GridBagConstraints;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
@@ -43,6 +44,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
private JCheckBox myCbShowStringsType;
private JCheckBox myCbHexValue;
private JCheckBox myCbPopulateThrowableStack;
+ private JCheckBox myCbAndroidRenderer;
private StateRestoringCheckBox myCbShowStaticFinalFields;
//private final ArrayRendererConfigurable myArrayRendererConfigurable;
@@ -117,6 +119,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
myCbHexValue = new JCheckBox(JavaDebuggerBundle.message("label.base.renderer.configurable.show.hex.value"));
myCbShowStringsType = new JCheckBox(JavaDebuggerBundle.message("label.base.renderer.configurable.show.strings.type"));
myCbPopulateThrowableStack = new JCheckBox(JavaDebuggerBundle.message("label.base.renderer.configurable.populate.throwable.stack"));
+ myCbAndroidRenderer = new JCheckBox("Use Android Renderer for integer types");
myCbEnableToString = new JCheckBox(JavaDebuggerBundle.message("label.base.renderer.configurable.enable.toString"));
myRbAllThatOverride = new JRadioButton(JavaDebuggerBundle.message("label.base.renderer.configurable.all.overriding"));
@@ -167,6 +170,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
//panel.add(arraysPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
panel.add(myCbShowStringsType, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBInsets.emptyInsets(), 0, 0));
panel.add(myCbHexValue, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
+ panel.add(myCbAndroidRenderer, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
panel.add(myCbHideNullArrayElements, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
panel.add(myCbPopulateThrowableStack, new GridBagConstraints(0, RELATIVE, 3, 1, 1.0, 0.0, NORTH, HORIZONTAL, JBUI.insetsTop(4), 0, 0));
@@ -209,6 +213,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
PrimitiveRenderer primitiveRenderer = rendererSettings.getPrimitiveRenderer();
primitiveRenderer.setShowHexValue(myCbHexValue.isSelected());
+ rendererSettings.setUseAndroidRenderer(myCbAndroidRenderer.isSelected());
rendererSettings.fireRenderersChanged();
}
@@ -254,6 +259,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
PrimitiveRenderer primitiveRenderer = rendererSettings.getPrimitiveRenderer();
myCbHexValue.setSelected(primitiveRenderer.isShowHexValue());
+ myCbAndroidRenderer.setSelected(rendererSettings.isUsingAndroidRenderer());
}
@Override
@@ -309,6 +315,10 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
return true;
}
+ if (myCbAndroidRenderer.isSelected() != rendererSettings.isUsingAndroidRenderer()) {
+ return true;
+ }
+
return false;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java
index 2f652b3b139f..de41b59cb4f8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java
@@ -17,6 +17,7 @@ import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.render.*;
import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
@@ -65,6 +66,9 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
private final EventDispatcher<NodeRendererSettingsListener> myDispatcher = EventDispatcher.create(NodeRendererSettingsListener.class);
private final RendererConfiguration myCustomRenderers = new RendererConfiguration(this);
+ private static final String USE_ANDROID_RENDERER = "use.android.renderer";
+ private boolean myUseAndroidRenderer = PropertiesComponent.getInstance().getBoolean(USE_ANDROID_RENDERER, false);
+
// base renderers
private final PrimitiveRenderer myPrimitiveRenderer = new PrimitiveRenderer();
private final ArrayRenderer myArrayRenderer = new ArrayRenderer();
@@ -114,6 +118,16 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
return myAlternateCollectionRenderers[0].isEnabled();
}
+ // Addition in Android Studio's fork, do not use from Android plugin
+ void setUseAndroidRenderer(boolean en) {
+ myUseAndroidRenderer = en;
+ PropertiesComponent.getInstance().setValue(USE_ANDROID_RENDERER, Boolean.toString(en));
+ }
+
+ boolean isUsingAndroidRenderer() {
+ return myUseAndroidRenderer;
+ }
+
public boolean equals(Object o) {
if(!(o instanceof NodeRendererSettings)) return false;
@@ -260,6 +274,24 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
allRenderers.add(myToStringRenderer);
allRenderers.add(myArrayRenderer);
allRenderers.add(myClassRenderer);
+
+ // Android Studio: tweak the ordering of the android renderer: unless it is explicitly enabled,
+ // we don't want it to have higher priority over the primitive renderer
+ if (!myUseAndroidRenderer) {
+ int androidIndex = -1;
+ for (int i = 0; i < allRenderers.size(); i++) {
+ if ("android.resource.renderer".equals(allRenderers.get(i).getUniqueId())) {
+ androidIndex = i;
+ break;
+ }
+ }
+
+ if (androidIndex != -1) {
+ NodeRenderer androidRenderer = allRenderers.remove(androidIndex);
+ allRenderers.add(androidRenderer);
+ }
+ }
+
return allRenderers;
}
diff --git a/java/ide-customization/resources/META-INF/plugin.xml b/java/ide-customization/resources/META-INF/plugin.xml
index 2d44be2762dd..cdd6a055450d 100644
--- a/java/ide-customization/resources/META-INF/plugin.xml
+++ b/java/ide-customization/resources/META-INF/plugin.xml
@@ -13,8 +13,10 @@
</content>
<extensions defaultExtensionNs="com.intellij">
+ <!-- Android Studio: sends statistics to JetBrains (find a better way to disable this?)
<applicationInitializedListener implementation="com.intellij.internal.statistic.updater.StatisticsJobsScheduler"/>
<applicationInitializedListener implementation="com.intellij.internal.statistic.updater.StatisticsStateCollectorsScheduler"/>
+ Android Studio: sends statistics to JetBrains (find a better way to disable this?) -->
<projectViewPane implementation="com.intellij.ide.projectView.impl.ProjectViewPane"/>
@@ -90,12 +92,14 @@
<action id="RerunFailedTests" class="com.intellij.execution.testframework.actions.RerunFailedTestsAction"
icon="AllIcons.RunConfigurations.RerunFailedTests"/>
+ <!-- Android Studio: This does not apply to Gradle projects. issuetracker.google.com/37013723
<group>
<separator/>
<action id="SaveProjectAsTemplate" class="com.intellij.platform.templates.SaveProjectAsTemplateAction"/>
<action id="ManageProjectTemplates" class="com.intellij.platform.templates.ManageProjectTemplatesAction"/>
<add-to-group group-id="FileOtherSettingsGroup" anchor="last"/>
</group>
+ -->
<action id="ConsoleView.FoldLinesLikeThis" class="com.intellij.execution.console.FoldLinesLikeThis">
<add-to-group group-id="ConsoleEditorPopupMenu" anchor="after" relative-to-action="$SearchWeb"/>
diff --git a/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml b/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml
index a61f336e069d..d2f1ea58d3d7 100644
--- a/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml
+++ b/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml
@@ -183,11 +183,14 @@
key="inspection.marked.for.removal.display.name" bundle="messages.AnalysisBundle"
groupKey="group.names.code.maturity.issues" groupBundle="messages.InspectionsBundle"
enabledByDefault="true" level="ERROR" implementationClass="com.intellij.codeInspection.deprecation.MarkedForRemovalInspection"/>
+ <!-- Android Studio: disabled by Change Ia2144e9c / commit 195b92c
+ registered via a subclass which does its own filtering
<localInspection groupPath="Java" language="UAST" suppressId="deprecation" shortName="Deprecation"
key="inspection.deprecated.display.name" bundle="messages.AnalysisBundle"
groupKey="group.names.code.maturity.issues" groupBundle="messages.InspectionsBundle"
enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.deprecation.DeprecationInspection"/>
+ -->
<registryKey key="kotlin.deprecation.inspection.enabled" defaultValue="false"/>
<localInspection groupPath="Java" language="JAVA" shortName="LocalCanBeFinal" bundle="messages.JavaAnalysisBundle" key="inspection.local.can.be.final.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.code.style.issues" enabledByDefault="false" level="WARNING"
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
index 6d5cf4beb4c0..75c93805b7c0 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
@@ -135,7 +135,10 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
final String anno = annotated.isDeclaredNotNull ? manager.getDefaultNotNull() : manager.getDefaultNullable();
final List<String> annoToRemove = annotated.isDeclaredNotNull ? nullables : notNulls;
+ /* Android Studio: Disabled. We don't use code generation for @NotNull in Gradle builds,
+ so this is misleading.
if (!checkNonStandardAnnotations(field, annotated, manager, anno, holder)) return;
+ */
checkAccessors(field, annotated, project, manager, anno, annoToRemove, holder);
diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java
index f9975866c3aa..a02a51d4c671 100644
--- a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java
+++ b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageViewModuleNode.java
@@ -1,16 +1,21 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.projectView.impl.nodes;
+import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.AbstractTreeUi;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.IconUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -52,4 +57,36 @@ public class PackageViewModuleNode extends AbstractModuleNode{
public boolean someChildContainsFile(VirtualFile file) {
return true;
}
+
+ @Override
+ public void update(PresentationData presentation) {
+ super.update(presentation);
+ // Android Studio: Change icon to match with module icon
+ Icon icon = getModuleIcon();
+ if (icon != null) {
+ presentation.setIcon(icon);
+ }
+ }
+
+ /**
+ * Android Studio: Use icon based on type of module
+ *
+ * @return And icon based in module type if module is not {@code null} and is not disposed, {@code null} otherwise
+ */
+ @Nullable
+ private Icon getModuleIcon() {
+ Module module = getValue();
+ if (module != null && !module.isDisposed()) {
+ VirtualFile virtualFile = module.getModuleFile();
+ Icon icon = null;
+ if (virtualFile != null) {
+ icon = IconUtil.getIcon(virtualFile, 0, module.getProject());
+ }
+ if (icon == null) {
+ icon = ModuleType.get(module).getIcon();
+ }
+ return icon;
+ }
+ return null;
+ }
}
diff --git a/native/MacRestarter/CMakeLists.txt b/native/MacRestarter/CMakeLists.txt
index e4122085abd8..89f71a806524 100644
--- a/native/MacRestarter/CMakeLists.txt
+++ b/native/MacRestarter/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.1)
-project(restarter OBJC)
+project(restarter C)
if(NOT APPLE)
message(FATAL_ERROR "macOS only.")
diff --git a/native/MacTouchBar/CMakeLists.txt b/native/MacTouchBar/CMakeLists.txt
index ceabf003eb8a..5029156d6eb2 100644
--- a/native/MacTouchBar/CMakeLists.txt
+++ b/native/MacTouchBar/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.1)
-project(MacTouchBar OBJC)
+project(MacTouchBar C)
if(NOT APPLE)
message(FATAL_ERROR "macOS only.")
diff --git a/native/README.md b/native/README.md
new file mode 100644
index 000000000000..330bb1903649
--- /dev/null
+++ b/native/README.md
@@ -0,0 +1,51 @@
+# Building the Native Launchers
+
+The launchers can be built from the command line, with the following prerequisites:
+ * Xcode6 (Mac OS X) with Platform SDK 10.9
+ * Visual Studio 2013 with 64-bit compilers (either use Professional Edition or install Windows SDK 7.1), Microsoft Foundation
+ Classes for C++, and .NET Framework v4 (Windows).
+
+### Mac Launcher
+The JDK still depends on Apple's JavaVM and JRS frameworks: https://bugs.openjdk.java.net/browse/JDK-8024281. Because of this,
+the build is sensitive to particular target and SDK versions (e.g. JavaVM is deprecated in OS X v10.7, thus MACOSX_DEPLOYMENT_TARGET=10.8)
+which impact the dynamic linking.
+
+See https://youtrack.jetbrains.com/issue/IDEA-155856 for a recent regression on OS X Yosemite without Java 6.
+
+```
+tools/idea/native/MacLauncher$ xcodebuild
+```
+
+Optionally, you can verify the resulting binary:
+
+```
+tools/idea/native/MacLauncher$ file build/Release/Launcher.app/Contents/MacOS/Launcher
+build/Release/Launcher.app/Contents/MacOS/Launcher: Mach-O universal binary with 2 architectures
+build/Release/Launcher.app/Contents/MacOS/Launcher (for architecture x86_64): Mach-O 64-bit executable x86_64
+build/Release/Launcher.app/Contents/MacOS/Launcher (for architecture i386): Mach-O executable i386
+```
+
+### Windows Launchers
+Open the Visual Studio Command Prompt; the 32-bit toolchain will be selected by default:
+
+```
+Setting environment for using Microsoft Visual Studio 2010 x86 tools
+tools\idea\native\WinLauncher\WinLauncher> msbuild /p:JdkPath="C:\Program Files\Java\jdk1.8.0_45" /p:Configuration=Release
+```
+
+Switch to the 64-bit compiler toolchain (`vcvarsall.bat amd64`), or open the Windows SDK 7.1 Command Prompt which selects the 64-bit
+toolchain by default:
+
+```
+tools\idea\native\WinLauncher\WinLauncher> msbuild /p:JdkPath="C:\Program Files\Java\jdk1.8.0_45" /p:Configuration=Release /p:Platform=x64
+```
+
+The resulting binaries WinLauncher.exe and WinLauncher64.exe will be available under tools\idea\bin\WinLauncher.
+
+For CMake-based builds, use the checked-in version from prebuilts and make sure to set all the environment variables expected by
+ CMakeLists.txt. For example, here's how to build IdeaWin:
+
+```
+BUILD_NUMBER=0 CMAKE_PATH="D:\src\studio-master-dev\prebuilts\studio\sdk\windows\cmake\3.6.3155560" JDK_18_x64="C:\Program Files\Java\jdk1.8.0_111" winpty build.cmd build64 x64
+BUILD_NUMBER=0 CMAKE_PATH="D:\src\studio-master-dev\prebuilts\studio\sdk\windows\cmake\3.6.3155560" JDK_18="C:\Program Files\Java\jdk1.8.0_111" winpty build.cmd build32 Win32
+``` \ No newline at end of file
diff --git a/native/WinLauncher/splash.bmp b/native/WinLauncher/splash.bmp
index 2b727897b011..a827d0263fde 100644
--- a/native/WinLauncher/splash.bmp
+++ b/native/WinLauncher/splash.bmp
Binary files differ
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
index 48c4c9fdb10e..780750dcd904 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
@@ -2,6 +2,7 @@
package com.intellij.codeInsight.daemon.impl;
import com.intellij.analysis.AnalysisBundle;
+import com.intellij.analytics.AndroidStudioAnalytics;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
@@ -155,6 +156,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
@Override
protected void collectInformationWithProgress(@NotNull ProgressIndicator progress) {
+ long start = System.nanoTime(); // Android Studio: collect metrics for syntax highlighting latency.
List<HighlightInfo> outsideResult = new ArrayList<>(100);
List<HighlightInfo> insideResult = new ArrayList<>(100);
@@ -225,6 +227,10 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
if (myUpdateAll) {
daemonCodeAnalyzer.getFileStatusMap().setErrorFoundFlag(myProject, getDocument(), myErrorFound);
}
+
+ // Android Studio: collect metrics for syntax highlighting latency.
+ long latencyMs = (System.nanoTime() - start) / 1_000_000;
+ AndroidStudioAnalytics.getInstance().recordHighlightingLatency(getDocument(), latencyMs);
}
else {
cancelAndRestartDaemonLater(progress, myProject);
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
index 2c09e7eb3ca0..f97a27bb51d0 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java
@@ -55,9 +55,14 @@ public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implement
if (startElement != endElement) assertPhysical(endElement);
TextRange startElementRange = getAnnotationRange(startElement);
+ // Android Studio: we've removed these text assertions; see https://youtrack.jetbrains.com/issue/IDEA-162940
+ /*
LOG.assertTrue(startElement instanceof ExternallyAnnotated || startElementRange != null, startElement);
+ */
TextRange endElementRange = startElement == endElement ? startElementRange : getAnnotationRange(endElement);
+ /*
LOG.assertTrue(endElement instanceof ExternallyAnnotated || endElementRange != null, endElement);
+ */
if (startElementRange != null
&& endElementRange != null
&& startElementRange.getStartOffset() >= endElementRange.getEndOffset()) {
diff --git a/platform/bootstrap/src/com/intellij/idea/Main.java b/platform/bootstrap/src/com/intellij/idea/Main.java
index 97323651478c..d1944b736b0b 100644
--- a/platform/bootstrap/src/com/intellij/idea/Main.java
+++ b/platform/bootstrap/src/com/intellij/idea/Main.java
@@ -5,6 +5,7 @@ import com.intellij.ide.BootstrapBundle;
import com.intellij.ide.BootstrapClassLoaderUtil;
import com.intellij.ide.WindowsCommandLineProcessor;
import com.intellij.ide.startup.StartupActionScriptManager;
+import com.intellij.internal.statistic.analytics.StudioCrashDetection;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.util.lang.PathClassLoader;
@@ -88,6 +89,11 @@ public final class Main {
startupTimings.put("properties loading", System.nanoTime());
PathManager.loadProperties();
+ /* Android Studio: start crash detection after properly initializing PathManager */
+ if (isStudio() && !isHeadless()) {
+ StudioCrashDetection.start();
+ }
+
startupTimings.put("plugin updates install", System.nanoTime());
// this check must be performed before system directories are locked
if (!isCommandLine || Boolean.getBoolean(FORCE_PLUGIN_UPDATES)) {
@@ -197,6 +203,11 @@ public final class Main {
return HEADLESS_COMMANDS.contains(firstArg) || firstArg.length() < 20 && firstArg.endsWith("inspect"); //NON-NLS
}
+ // TODO: Use PlatformUtils#isAndroidStudio?
+ private static boolean isStudio() {
+ return "AndroidStudio".equalsIgnoreCase(System.getProperty(PLATFORM_PREFIX_PROPERTY));
+ }
+
public static void showMessage(@Nls(capitalization = Nls.Capitalization.Title) String title, Throwable t) {
@Nls(capitalization = Nls.Capitalization.Sentence) StringWriter message = new StringWriter();
diff --git a/platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetails.java b/platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetails.java
new file mode 100644
index 000000000000..c1afd40e7d5a
--- /dev/null
+++ b/platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetails.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.internal.statistic.analytics;
+
+import java.util.Scanner;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.List;
+
+public class StudioCrashDetails {
+
+ /**
+ * Represents a crash for which there is no additional details. Assumed to be not a JVM crash.
+ */
+ public final static StudioCrashDetails UNKNOWN = new StudioCrashDetails("<unknown>", false, -1, "", "", "", "");
+ private final static String JVM_CRASH_FILE_STRING_FORMAT =
+ System.getProperty("user.home") + File.separator + "java_error_in_STUDIO_%d.log";
+
+ private final String myDescription;
+ private final boolean myJvmCrash;
+ private final long myUptimeInMs;
+ private final String myErrorSignal;
+ private final String myErrorFrame;
+ private final String myErrorThread;
+ private final String myNativeStack;
+
+ private StudioCrashDetails(
+ String description,
+ boolean isJvmCrash,
+ long uptimeInMs,
+ String errorSignal,
+ String errorFrame,
+ String errorThread,
+ String nativeStack
+ ) {
+ myDescription = description;
+ myJvmCrash = isJvmCrash;
+ myUptimeInMs = uptimeInMs;
+ myErrorSignal = errorSignal;
+ myErrorFrame = errorFrame;
+ myErrorThread = errorThread;
+ myNativeStack = nativeStack;
+ }
+
+ @NotNull
+ public static StudioCrashDetails loadFromRecordFile(File record) throws IOException {
+ final List<String> lines = Files.readAllLines(record.toPath());
+ String buildNumber = !lines.isEmpty() ? lines.get(0) : "";
+ String runtimeVersion = lines.size() > 1 ? lines.get(1) : "";
+ long startupDateInMs = -1;
+ if (lines.size() > 2) {
+ try {
+ startupDateInMs = Long.parseLong(lines.get(2));
+ }
+ catch (NumberFormatException ignore) {
+ }
+ }
+ long pid = -1;
+ if (lines.size() > 3) {
+ try {
+ pid = Long.parseLong(lines.get(3));
+ }
+ catch (NumberFormatException ignore) {
+ }
+ }
+ boolean isJvmCrash = false;
+ long uptimeInMs = -1;
+ String errorSignal = "";
+ String errorFrame = "";
+ String errorThread = "";
+ String nativeStack = "";
+ // Assume it was not a JVM crash if there is no startup time or pid
+ if (startupDateInMs != -1 && pid >= 0) {
+ // Check time of creation of the crash report file. If it happened after the app startup time then
+ // it is likely a crash report from that run.
+ Path jvmCrashReportFile = Paths.get(String.format(JVM_CRASH_FILE_STRING_FORMAT, pid));
+ if (Files.exists(jvmCrashReportFile)) {
+ BasicFileAttributes attrs = Files.readAttributes(jvmCrashReportFile, BasicFileAttributes.class);
+ long crashDateInMs = attrs.creationTime().toMillis();
+ if (crashDateInMs > startupDateInMs) {
+ isJvmCrash = true;
+ uptimeInMs = crashDateInMs - startupDateInMs;
+ try (Scanner scanner = new Scanner(jvmCrashReportFile)) {
+ while (scanner.hasNext() && (errorSignal.isEmpty() || errorFrame.isEmpty() || errorThread.isEmpty() || nativeStack.isEmpty())) {
+ if (scanner.findInLine("# SIG") != null) {
+ errorSignal = "SIG" + scanner.nextLine();
+ } else if (scanner.findInLine("# EXCEPTION") != null) {
+ errorSignal = "EXCEPTION" + scanner.nextLine();
+ } else if (scanner.findInLine("# Problematic frame:") != null) {
+ scanner.nextLine();
+ errorFrame = scanner.nextLine().substring(2);
+ } else if (scanner.findInLine("Current thread \\(.+\\):") != null) {
+ errorThread = scanner.nextLine().trim();
+ } else if (scanner.findInLine("Native frames:") != null) {
+ scanner.nextLine();
+ StringBuilder nativeStackBuilder = new StringBuilder();
+ while (scanner.hasNext()) {
+ String line = scanner.nextLine();
+ if (line.isEmpty()) {
+ nativeStack = nativeStackBuilder.toString();
+ break;
+ }
+ nativeStackBuilder.append(line.trim()).append('\n');
+ }
+ } else {
+ scanner.nextLine();
+ }
+ }
+ }
+ }
+ }
+ }
+ String description = buildNumber + "\n" + runtimeVersion;
+ return new StudioCrashDetails(description, isJvmCrash, uptimeInMs, errorSignal, errorFrame, errorThread, nativeStack);
+ }
+
+ public boolean isJvmCrash() {
+ return myJvmCrash;
+ }
+
+ public String getDescription() {
+ return myDescription;
+ }
+
+ public long getUptimeInMs() {
+ return myUptimeInMs;
+ }
+
+ public String getErrorSignal() {
+ return myErrorSignal;
+ }
+
+ public String getErrorFrame() {
+ return myErrorFrame;
+ }
+
+ public String getErrorThread() {
+ return myErrorThread;
+ }
+
+ public String getNativeStack() {
+ return myNativeStack;
+ }
+}
diff --git a/platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetection.java b/platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetection.java
new file mode 100644
index 000000000000..31f9f6f12f87
--- /dev/null
+++ b/platform/bootstrap/src/com/intellij/internal/statistic/analytics/StudioCrashDetection.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.internal.statistic.analytics;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.util.SystemInfo;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Static utility methods to detect when Android Studio has crashed.
+ * <p>
+ * File format of the record file:<br>
+ * 1st line: Android Studio build version number<br>
+ * 2nd line: JVM runtime version<br>
+ * 3rd line: JVM start time (milliseconds since 1970) (optional)<br>
+ * 4th line: PID of Android Studio (optional)<br>
+ * </p>
+ */
+public class StudioCrashDetection {
+ private static final String RECORD_FILE_KEY = "studio.record.file";
+ private static final String PLATFORM_PREFIX = "AndroidStudio";
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+ private static ArrayList<StudioCrashDetails> ourCrashes;
+
+ private StudioCrashDetection() {
+ }
+
+ /**
+ * Creates a record of the application starting, unique to this run.
+ *
+ * @throws AssertionError if called more than once per run
+ */
+ public static void start() {
+ if (System.getProperty(RECORD_FILE_KEY) != null) throw new AssertionError("StudioCrashDetection.start called more than once");
+ try {
+ File f = new File(PathManager.getTempPath(),
+ String.format("%s.%s", PLATFORM_PREFIX, UUID.randomUUID().toString()));
+ if (f.createNewFile()) {
+ // We use a system property to pass the filename across classloaders.
+ System.setProperty(RECORD_FILE_KEY, f.getAbsolutePath());
+
+ try (FileWriter fw = new FileWriter(f)) {
+ File buildInfo = new File(PathManager.getHomePath(), "build.txt");
+ if (!buildInfo.exists() && SystemInfo.isMac) {
+ // On a Mac, also try to find it under Resources.
+ buildInfo = new File(PathManager.getHomePath(), "Resources/build.txt");
+ }
+
+ String buildVersion = "<unknown>";
+ if (buildInfo.exists()) {
+ List<String> lines = Files.readAllLines(buildInfo.toPath());
+ if (!lines.isEmpty()) {
+ buildVersion = lines.get(0);
+ }
+ }
+ fw.write(buildVersion);
+ fw.write(LINE_SEPARATOR);
+ fw.write(System.getProperty("java.runtime.version"));
+ fw.write(LINE_SEPARATOR);
+ fw.write(String.valueOf(ManagementFactory.getRuntimeMXBean().getStartTime()));
+ fw.write(LINE_SEPARATOR);
+ fw.write(String.valueOf(getMyPID()));
+ }
+ }
+ }
+ catch (IOException ex) {
+ // continue anyway.
+ }
+ }
+
+ private static long getMyPID() {
+ String pidAndMachineName = ManagementFactory.getRuntimeMXBean().getName();
+ String[] split = pidAndMachineName.split("@");
+ long pid = -1;
+ if (split.length == 2) {
+ try {
+ pid = Long.parseLong(split[0]);
+ }
+ catch (NumberFormatException ignore) {
+ }
+ }
+ return pid;
+ }
+
+ /**
+ * Updates the record created by {@link #start} in this run with the accurate version number.
+ */
+ public static void updateRecordedVersionNumber(@NotNull String version) {
+ String recordFileName = System.getProperty(RECORD_FILE_KEY);
+
+ if (recordFileName != null) {
+ File recordFile = new File(recordFileName);
+ try {
+ List<String> lines = Files.readAllLines(recordFile.toPath());
+ lines.set(0, version);
+
+ try (FileWriter fw = new FileWriter(recordFile)) {
+ for (String line : lines) {
+ fw.write(line);
+ fw.write(LINE_SEPARATOR);
+ }
+ }
+ }
+ catch (IOException ex) {
+ // continue anyway.
+ }
+ }
+ }
+
+ /**
+ * Deletes the record created by {@link #start} for this run, if it exists.
+ */
+ public static void stop() {
+ String recordFileName = System.getProperty(RECORD_FILE_KEY);
+ if (recordFileName != null) {
+ try {
+ Files.deleteIfExists(Paths.get(recordFileName));
+ } catch (IOException ignored) {
+ // Ignore.
+ }
+ System.clearProperty(RECORD_FILE_KEY);
+ }
+ }
+
+ /**
+ * Returns and deletes any records created by {@link #start} in previous runs.
+ */
+ public static List<StudioCrashDetails> reapCrashDescriptions() {
+ if (ourCrashes != null) {
+ return ourCrashes;
+ }
+ File[] previousRecords = new File(PathManager.getTempPath()).listFiles(
+ new FileFilter() {
+ final String recordFile = System.getProperty(RECORD_FILE_KEY);
+
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.getName().startsWith(PLATFORM_PREFIX) && !pathname.getAbsolutePath().equals(recordFile);
+ }
+ });
+ ourCrashes = new ArrayList<>();
+ if (previousRecords != null) {
+ for (File record : previousRecords) {
+ StudioCrashDetails crash;
+ try {
+ crash = StudioCrashDetails.loadFromRecordFile(record);
+ }
+ catch (IOException ignored) {
+ crash = StudioCrashDetails.UNKNOWN;
+ }
+ try {
+ if (Files.deleteIfExists(record.toPath())) {
+ ourCrashes.add(crash);
+ }
+ } catch (IOException ignored) {
+ // Ignore
+ }
+ }
+ }
+ return ourCrashes;
+ }
+}
diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy
index 01f84f775843..bd056cea7ed8 100644
--- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy
@@ -85,7 +85,7 @@ final class BuildContextImpl extends BuildContext {
xBootClassPathJarNames = productProperties.xBootClassPathJarNames
bootClassPathJarNames = List.of("util.jar", "util_rt.jar")
- applicationInfo = new ApplicationInfoProperties(project, productProperties, options, messages).patch(this)
+ applicationInfo = new ApplicationInfoProperties(project, productProperties, options, messages) // Android Studio: don't .patch(this)
if (productProperties.productCode == null && applicationInfo.productCode != null) {
productProperties.productCode = applicationInfo.productCode
}
diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy
index 2773d5c8decc..279d3f38f19c 100644
--- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy
@@ -278,6 +278,7 @@ final class DistributionJARsBuilder {
tasks.add(task)
}
+/* Android Studio: do not patch ApplicationNamesInfo yet
ForkJoinTask.invokeAll(Arrays.asList(
StatisticsRecorderBundledMetadataProvider.createTask(moduleOutputPatcher, context),
buildHelper.createTask(spanBuilder("write patched app info")) {
@@ -290,6 +291,7 @@ final class DistributionJARsBuilder {
return null
},
).findAll { it != null })
+Android Studio: do not patch ApplicationNamesInfo yet */
List<DistributionFileEntry> result = buildLib(moduleOutputPatcher, platform, context)
if (!isUpdateFromSources && context.productProperties.scrambleMainJar) {
diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/VmOptionsGenerator.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/VmOptionsGenerator.groovy
index 112bdb536e54..7362fbe3b70a 100644
--- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/VmOptionsGenerator.groovy
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/VmOptionsGenerator.groovy
@@ -19,11 +19,14 @@ final class VmOptionsGenerator {
'-Djdk.http.auth.tunneling.disabledSchemes=""',
'-Djdk.attach.allowAttachSelf=true',
'-Djdk.module.illegalAccess.silent=true',
+ '-Djna.nosys=true', // Android Studio: added by Change Ie7351d92
+ '-Djna.boot.library.path=', // Android Studio: added by Change Ie7351d92
+ '-Didea.vendor.name=Google', // Android Studio: added by Change Ie6d690b5
'-Dkotlinx.coroutines.debug=off')
static final List<Map.Entry<String, String>> MEMORY_OPTIONS = List.of(
- Map.entry('-Xms', '128m'),
- Map.entry('-Xmx', '750m'),
+ Map.entry('-Xms', '256m'), // Android Studio: modified by Change Ie7351d92
+ Map.entry('-Xmx', '1280m'), // Android Studio: modified by Change Ie7351d92
Map.entry('-XX:ReservedCodeCacheSize=', '512m'))
static List<String> computeVmOptions(boolean isEAP, ProductProperties productProperties) {
diff --git a/platform/build-scripts/resources/linux/scripts/profiler.sh b/platform/build-scripts/resources/linux/scripts/profiler.sh
new file mode 100644
index 000000000000..46ca5d4785f7
--- /dev/null
+++ b/platform/build-scripts/resources/linux/scripts/profiler.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# ------------------------------------------------------
+# Start Android Studio profiler.
+# ------------------------------------------------------
+
+IDE_BIN_HOME="${0%/*}"
+exec "$IDE_BIN_HOME/game-tools.sh" game-tools --mode APP --app-window PROFILER "$@"
diff --git a/platform/build-scripts/resources/mac/Contents/Info.plist b/platform/build-scripts/resources/mac/Contents/Info.plist
index a1b69aa8d4f0..c59466bfff50 100644
--- a/platform/build-scripts/resources/mac/Contents/Info.plist
+++ b/platform/build-scripts/resources/mac/Contents/Info.plist
@@ -31,7 +31,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
- <string>@@bundle_name@@@@product_state@@</string>
+ <string>@@bundle_name@@</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIdentifier</key>
diff --git a/platform/build-scripts/resources/mac/Contents/MacOS/executable b/platform/build-scripts/resources/mac/Contents/MacOS/executable
index 6cb82e22f6f1..34284d079d39 100644..100755
--- a/platform/build-scripts/resources/mac/Contents/MacOS/executable
+++ b/platform/build-scripts/resources/mac/Contents/MacOS/executable
Binary files differ
diff --git a/platform/build-scripts/resources/win/launcher/WinLauncher.exe b/platform/build-scripts/resources/win/launcher/WinLauncher.exe
index 8b3a683729cf..5b915de8a1e5 100644
--- a/platform/build-scripts/resources/win/launcher/WinLauncher.exe
+++ b/platform/build-scripts/resources/win/launcher/WinLauncher.exe
Binary files differ
diff --git a/platform/build-scripts/resources/win/scripts/profiler.bat b/platform/build-scripts/resources/win/scripts/profiler.bat
new file mode 100644
index 000000000000..ee8955ca4278
--- /dev/null
+++ b/platform/build-scripts/resources/win/scripts/profiler.bat
@@ -0,0 +1,11 @@
+@ECHO OFF
+
+::----------------------------------------------------------------------
+:: Start Android Studio profiler.
+::----------------------------------------------------------------------
+
+SET DEFAULT_PROJECT_PATH=%CD%
+
+SET IDE_BIN_DIR=%~dp0
+SET STUDIO_JDK=%IDE_BIN_DIR%..\jre
+CALL "%IDE_BIN_DIR%\game-tools.bat" game-tools --mode APP --app-window PROFILER %*
diff --git a/platform/code-style-api/src/com/intellij/psi/codeStyle/CustomCodeStyleSettingsManager.java b/platform/code-style-api/src/com/intellij/psi/codeStyle/CustomCodeStyleSettingsManager.java
index 91f598a9f2dd..899ed37ed23d 100644
--- a/platform/code-style-api/src/com/intellij/psi/codeStyle/CustomCodeStyleSettingsManager.java
+++ b/platform/code-style-api/src/com/intellij/psi/codeStyle/CustomCodeStyleSettingsManager.java
@@ -23,7 +23,15 @@ class CustomCodeStyleSettingsManager {
void initCustomSettings() {
for (final CustomCodeStyleSettingsFactory factory : CodeStyleSettingsService.getInstance().getCustomCodeStyleSettingsFactories()) {
+ if (!factory.getClass().getSimpleName().startsWith("AndroidStudio")) { // Android Studio: b/175998141
addCustomSettings(myRootSettings, factory);
+ }
+ }
+ // Android Studio: also apply our predefined Android code styles (b/175998141).
+ for (final CustomCodeStyleSettingsFactory factory : CodeStyleSettingsService.getInstance().getCustomCodeStyleSettingsFactories()) {
+ if (factory.getClass().getSimpleName().startsWith("AndroidStudio")) {
+ addCustomSettings(myRootSettings, factory);
+ }
}
}
diff --git a/platform/configuration-store-impl/src/defaultProjectElementNormalizer.kt b/platform/configuration-store-impl/src/defaultProjectElementNormalizer.kt
index 502dd62c3931..0be2c0163c1a 100644
--- a/platform/configuration-store-impl/src/defaultProjectElementNormalizer.kt
+++ b/platform/configuration-store-impl/src/defaultProjectElementNormalizer.kt
@@ -101,7 +101,7 @@ internal fun moveComponentConfiguration(defaultProject: Project,
val storageNameToComponentNames = HashMap<String, MutableSet<String>>()
val workspaceComponentNames = HashSet(listOf("GradleLocalSettings"))
- val ignoredComponentNames = HashSet<String>()
+ val ignoredComponentNames = HashSet<String>(listOf("ProjectCodeStyleConfiguration")) // Android Studio: b/145210466
storageNameToComponentNames.put("workspace.xml", workspaceComponentNames)
fun processComponents(aClass: Class<*>) {
diff --git a/platform/core-api/src/com/intellij/analytics/AndroidStudioAnalytics.java b/platform/core-api/src/com/intellij/analytics/AndroidStudioAnalytics.java
new file mode 100644
index 000000000000..fb22c59b11e9
--- /dev/null
+++ b/platform/core-api/src/com/intellij/analytics/AndroidStudioAnalytics.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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.analytics;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.util.PlatformUtils;
+
+import java.awt.GraphicsEnvironment;
+
+import org.jetbrains.annotations.NotNull;
+
+abstract public class AndroidStudioAnalytics {
+ static AndroidStudioAnalytics INSTANCE;
+
+ public static void initialize(AndroidStudioAnalytics analytics) {
+ INSTANCE = analytics;
+ }
+
+ public static AndroidStudioAnalytics getInstance() {
+ if (INSTANCE == null) {
+ // Android Studio Developers: If you hit this exception, you're trying to find out the status
+ // of AnalyticsSettings before the system has been initialized. Please reach out the the owners
+ // of this code to figure out how best to do these checks instead of getting null values.
+ if (PlatformUtils.isAndroidStudio() && !GraphicsEnvironment.isHeadless()) {
+ throw new RuntimeException("call to AndroidStudioAnalytics before initialization");
+ } else {
+ initialize(new NullAndroidStudioAnalytics());
+ }
+ }
+ return INSTANCE;
+ }
+
+ public abstract void recordHighlightingLatency(Document document, long latencyMs);
+
+ public abstract void logUpdateDialogOpenManually(@NotNull String newBuild);
+
+ public abstract void logNotificationShown(@NotNull String newBuild);
+
+ public abstract void logClickNotification(@NotNull String newBuild);
+
+ public abstract void logUpdateDialogOpenFromNotification(@NotNull String newBuild);
+
+ public abstract void logClickIgnore(String code);
+
+ public abstract void logClickLater(String code);
+
+ public abstract void logDownloadSuccess(String code);
+
+ public abstract void logDownloadFailure(String code);
+
+ public abstract void updateAndroidStudioMetrics();
+
+ public abstract void initializeAndroidStudioUsageTrackerAndPublisher();
+
+ public abstract boolean isAllowed();
+}
diff --git a/platform/core-api/src/com/intellij/analytics/NullAndroidStudioAnalytics.java b/platform/core-api/src/com/intellij/analytics/NullAndroidStudioAnalytics.java
new file mode 100644
index 000000000000..00ba8c4d93b8
--- /dev/null
+++ b/platform/core-api/src/com/intellij/analytics/NullAndroidStudioAnalytics.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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.analytics;
+
+import com.intellij.openapi.editor.Document;
+import org.jetbrains.annotations.NotNull;
+
+public class NullAndroidStudioAnalytics extends AndroidStudioAnalytics {
+
+ @Override
+ public void recordHighlightingLatency(Document document, long latencyMs) {
+
+ }
+
+ @Override
+ public void logUpdateDialogOpenManually(@NotNull String newBuild) {
+
+ }
+
+ @Override
+ public void logNotificationShown(@NotNull String newBuild) {
+
+ }
+
+ @Override
+ public void logClickNotification(@NotNull String newBuild) {
+
+ }
+
+ @Override
+ public void logUpdateDialogOpenFromNotification(@NotNull String newBuild) {
+
+ }
+
+ @Override
+ public void logClickIgnore(String code) {
+
+ }
+
+ @Override
+ public void logClickLater(String code) {
+
+ }
+
+ @Override
+ public void logDownloadSuccess(String code) {
+
+ }
+
+ @Override
+ public void logDownloadFailure(String code) {
+
+ }
+
+ @Override
+ public void updateAndroidStudioMetrics() {
+
+ }
+
+ @Override
+ public void initializeAndroidStudioUsageTrackerAndPublisher() {
+
+ }
+
+ @Override
+ public boolean isAllowed() {
+ return false;
+ }
+}
diff --git a/platform/core-api/src/com/intellij/openapi/roots/ContentIteratorEx.java b/platform/core-api/src/com/intellij/openapi/roots/ContentIteratorEx.java
index c97e28f00afe..4d67a5fef671 100644
--- a/platform/core-api/src/com/intellij/openapi/roots/ContentIteratorEx.java
+++ b/platform/core-api/src/com/intellij/openapi/roots/ContentIteratorEx.java
@@ -25,6 +25,7 @@ public interface ContentIteratorEx extends ContentIterator {
*/
@NotNull Status processFileEx(@NotNull VirtualFile fileOrDir);
+ @SuppressWarnings("FunctionalInterfaceMethodChanged") // incorrect implementation from commit 223801f7
@Override
default boolean processFile(@NotNull VirtualFile fileOrDir) {
throw new IllegalStateException("Call com.intellij.openapi.roots.ContentIteratorEx#processFileEx instead");
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtils.java b/platform/core-api/src/com/intellij/util/PlatformUtils.java
index 5aaed27c8845..693f1a878738 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtils.java
@@ -48,6 +48,7 @@ public final class PlatformUtils {
public static final String RIDER_PREFIX = "Rider";
public static final String GOIDE_PREFIX = "GoLand";
public static final String FLEET_PREFIX = "FleetBackend";
+ public static final String STUDIO_PREFIX = "AndroidStudio";
/**
* @deprecated Code With Me Guest is an old name for JetBrains Client
@@ -108,6 +109,14 @@ public final class PlatformUtils {
return is(IDEA_EDU_PREFIX);
}
+ /**
+ * @deprecated use {@code com.android.tools.idea.IdeInfo#isAndroidStudio} except in analytics and random platform tweaks.
+ */
+ @Deprecated
+ public static boolean isAndroidStudio() {
+ return is(STUDIO_PREFIX);
+ }
+
public static boolean isRubyMine() {
return is(RUBY_PREFIX);
}
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
index 9da18651aba1..2f930ac93118 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
@@ -20,7 +20,7 @@ import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.io.NioFiles;
import com.intellij.openapi.util.text.HtmlChunk;
-import com.intellij.util.PlatformUtils;
+import com.intellij.util.*;
import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.*;
@@ -793,7 +793,12 @@ public final class PluginManagerCore {
}
}
- if (missing != null) {
+ // Android Studio: In unit test mode, the android plugin may not be present, even though it is marked as "essential".
+ if (missing != null && PlatformUtils.isAndroidStudio() && (isUnitTestMode || SystemProperties.getBooleanProperty("java.awt.headless", false))) {
+ missing = missing.stream().filter(id -> !"org.jetbrains.android".equals(id) && !"com.android.tools.design".equals(id))
+ .collect(Collectors.toList());
+ }
+ if (missing != null && !missing.isEmpty()) {
throw new EssentialPluginMissingException(missing);
}
}
diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
index ae9ef24c603c..5afe786be161 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
@@ -15,6 +15,7 @@ import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.serviceContainer.NonInjectable;
+import com.intellij.util.PlatformUtils;
import com.intellij.util.xml.dom.XmlElement;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@@ -439,6 +440,15 @@ public final class ApplicationInfoImpl extends ApplicationInfoEx {
return api;
}
}
+ // Android Studio: Create API version from the first 3 values of build number
+ else if (PlatformUtils.isAndroidStudio()) {
+ assert build.getComponents().length >= 3;
+ BuildNumber apiBuildNumber = new BuildNumber("AI",
+ build.getComponents()[0],
+ build.getComponents()[1],
+ build.getComponents()[2]);
+ return apiBuildNumber;
+ }
return build;
}
@@ -471,9 +481,12 @@ public final class ApplicationInfoImpl extends ApplicationInfoEx {
else {
result = requireNonNullElse(myMajorVersion) + '.' + requireNonNullElse(myMinorVersion);
}
+/* Android Studio: removed by Change I2708044e / commit e1454d7
+ // In Android Studio we don't want the EAP suffix in version names
if (myVersionSuffix != null && !myVersionSuffix.isEmpty()) {
result += " " + myVersionSuffix;
}
+Android Studio: removed by Change I2708044e / commit e1454d7 */
return result;
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java
index d80bb4dfbadf..2329f0a33ce5 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java
@@ -11,8 +11,8 @@ import java.util.List;
*/
public class ExternalModuleBuildClasspathPojo {
- @NotNull private final List<String> myEntries;
@NotNull private String myPath;
+ @NotNull private List<String> myEntries;
@SuppressWarnings("UnusedDeclaration")
public ExternalModuleBuildClasspathPojo() {
@@ -39,6 +39,10 @@ public class ExternalModuleBuildClasspathPojo {
return myEntries;
}
+ public void setEntries(@NotNull List<String> entries) {
+ myEntries = entries;
+ }
+
@Override
public int hashCode() {
int result = myEntries.hashCode();
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java
index a18bb5cc23b6..11bba88ac156 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java
@@ -23,10 +23,8 @@ import com.intellij.openapi.roots.RootPolicy;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
-import com.intellij.openapi.vfs.JarFileSystem;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NotNullFunction;
import com.intellij.util.SmartList;
@@ -263,10 +261,10 @@ public final class LibraryDataService extends AbstractProjectDataService<Library
HashSet<String> toRemovePerType = new HashSet<>();
toRemove.put(ideType, toRemovePerType);
- for (VirtualFile ideFile: ideLibrary.getFiles(ideType)) {
- String idePath = ExternalSystemApiUtil.getLocalFileSystemPath(ideFile);
+ for (String url : ideLibrary.getUrls(ideType)) {
+ String idePath = getLocalPath(url);
if (!toAddPerType.remove(idePath)) {
- toRemovePerType.add(ideFile.getUrl());
+ toRemovePerType.add(url);
}
}
}
@@ -288,4 +286,12 @@ public final class LibraryDataService extends AbstractProjectDataService<Library
registerPaths(false, roots, excludedPaths, libraryModel, externalLibrary.getInternalName());
}
}
+
+ @NotNull
+ private static String getLocalPath(@NotNull String url) {
+ if (url.startsWith(StandardFileSystems.JAR_PROTOCOL_PREFIX)) {
+ url = StringUtil.trimEnd(url, JarFileSystem.JAR_SEPARATOR);
+ }
+ return VfsUtilCore.urlToPath(url);
+ }
}
diff --git a/platform/ide-core-impl/src/com/intellij/diagnostic/VMOptions.java b/platform/ide-core-impl/src/com/intellij/diagnostic/VMOptions.java
index 0bfba7fc6fe4..ce869d689d35 100644
--- a/platform/ide-core-impl/src/com/intellij/diagnostic/VMOptions.java
+++ b/platform/ide-core-impl/src/com/intellij/diagnostic/VMOptions.java
@@ -264,7 +264,7 @@ public final class VMOptions {
@ApiStatus.Internal
public static @Nullable Path getUserOptionsFile() {
- String vmOptionsFile = System.getProperty("jb.vmOptionsFile");
+ String vmOptionsFile = vmOptionsFile(); // Android Studio: multiple paths in jb.vmOptionsFile
if (vmOptionsFile == null) {
// launchers should specify a path to a VM options file used to configure a JVM
return null;
@@ -336,7 +336,7 @@ public final class VMOptions {
return Files.readString(newFile, getFileCharset());
}
- String vmOptionsFile = System.getProperty("jb.vmOptionsFile");
+ String vmOptionsFile = vmOptionsFile(); // Android Studio: multiple paths in jb.vmOptionsFile
if (vmOptionsFile != null) {
return Files.readString(Path.of(vmOptionsFile), getFileCharset());
}
@@ -348,6 +348,21 @@ public final class VMOptions {
return null;
}
+ /**
+ * If the {@code jb.vmOptionsFile} property value contains a comma-separated list, returns the last item of that list;
+ * otherwise, returns the whole value of {@code jb.vmOptionsFile}.
+ * <p>
+ * This is a temporary workaround until WindowsLauncher is updated to supply a single file in {@code jb.vmOptionsFile}.
+ */
+ private static String vmOptionsFile() {
+ String vmOptionsFile = System.getProperty("jb.vmOptionsFile");
+ if (vmOptionsFile == null) {
+ return null;
+ }
+ String[] files = vmOptionsFile.split(",");
+ return files[files.length - 1];
+ }
+
/** @deprecated please see {@link #read()} for details */
@Deprecated(forRemoval = true)
public static @Nullable Path getWriteFile() {
diff --git a/platform/lang-api/src/com/intellij/execution/testframework/sm/runner/states/TestStateInfo.java b/platform/lang-api/src/com/intellij/execution/testframework/sm/runner/states/TestStateInfo.java
index f476ea2e5f61..3226c2c17c8a 100644
--- a/platform/lang-api/src/com/intellij/execution/testframework/sm/runner/states/TestStateInfo.java
+++ b/platform/lang-api/src/com/intellij/execution/testframework/sm/runner/states/TestStateInfo.java
@@ -62,8 +62,12 @@ public interface TestStateInfo {
SKIPPED_INDEX(0, 1, ExecutionBundle.message("sm.test.runner.magnitude.skipped.failed.title")),
COMPLETE_INDEX(1, 3, ExecutionBundle.message("sm.test.runner.magnitude.completed.failed.title")),
NOT_RUN_INDEX(2, 0, ExecutionBundle.message("sm.test.runner.magnitude.not.run.failed.title")),
+ SCHEDULED_INDEX(3, 8, "Scheduled..."), // Android Studio: used in com.google.gct.testing.results
RUNNING_INDEX(3, 7, ExecutionBundle.message("sm.test.runner.magnitude.running.failed.title")),
TERMINATED_INDEX(4, 6, ExecutionBundle.message("sm.test.runner.magnitude.terminated.failed.title")),
+ TIMEOUT_INDEX(4, 6, "Timed out"), // Android Studio: used in com.google.gct.testing.results
+ INFRASTRUCTURE_FAILURE_INDEX(4, 6, "Infrastructure failure"), // Android Studio: used in com.google.gct.testing.results
+ TRIGGERING_ERROR_INDEX(4, 6, "Triggering error"), // Android Studio: used in com.google.gct.testing.results
IGNORED_INDEX(5, 2, ExecutionBundle.message("sm.test.runner.magnitude.ignored.failed.title")),
FAILED_INDEX(6, 4, ExecutionBundle.message("sm.test.runner.magnitude.assertion.failed.title")),
ERROR_INDEX(8, 5, ExecutionBundle.message("sm.test.runner.magnitude.testerror.title")),
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/LastRunReformatCodeOptionsProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/LastRunReformatCodeOptionsProvider.java
index e3701e36411a..fb2ce9ad176e 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/LastRunReformatCodeOptionsProvider.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/LastRunReformatCodeOptionsProvider.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.actions;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -86,7 +87,9 @@ public class LastRunReformatCodeOptionsProvider {
public boolean isRearrangeCode(@NotNull Language language) {
String key = getRearrangeCodeKeyFor(language);
- return myPropertiesComponent.getBoolean(key);
+ // Android Studio: Default rearrange=true for XML files
+ //return myPropertiesComponent.getBoolean(key);
+ return myPropertiesComponent.getBoolean(key, language == StdLanguages.XML);
}
public boolean isDoNotKeepLineBreaks() {
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
index ee1e69a75724..93edb7a6f108 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
@@ -280,6 +280,21 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextEx {
}
}
+ // Android Studio: Is the given file a file we should ignore during batch inspections?
+ private static final String EXPLODED_AAR = "exploded-aar";
+ private static boolean isIgnoredFile(@NotNull PsiFile psiFile) {
+ VirtualFile file = psiFile.getVirtualFile();
+ while (file != null) {
+ if (EXPLODED_AAR.equals(file.getName())) {
+ return true;
+ } else {
+ file = file.getParent();
+ }
+ }
+
+ return false;
+ }
+
@Override
protected void runTools(@NotNull AnalysisScope scope, boolean runGlobalToolsOnly, boolean isOfflineInspections) {
myInspectionStartedTimestamp = System.currentTimeMillis();
@@ -471,6 +486,32 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextEx {
@NotNull List<? extends GlobalInspectionToolWrapper> globalSimpleTools,
@NotNull List<? extends LocalInspectionToolWrapper> localTools,
boolean inspectInjectedPsi) {
+ // Android Studio tweak:
+ // Most "outputs" (such as build/intermediates/) are marked as generated
+ // source roots, which means IntelliJ won't scan those folders for
+ // warnings.
+ //
+ // However, AAR libraries are extracted into special build folders
+ // (currently build/intermediates/exploded-aar) which are *not* marked as
+ // generated; that's necessary such that those folders are scanned (for
+ // indexing purposes), handled as potential go-to-declaration targets
+ // (since resource files there can contain for example themes extended in
+ // the user's application). Therefore, by default, IntelliJ will analyze
+ // all the files in the exploded AAR folders. When you have large
+ // libraries like appcompat or play services, this not only takes a lot
+ // of extra time to analyze. You also end up with a lot of errors in
+ // files you can't edit. For example, with appcompat, you end up with
+ // over 700 spelling mistake warnings, and with play services, you end up
+ // with over a hundred unused namespace warnings, and over a hundred tag
+ // has no children warnings!
+ //
+ // Therefore, in the below this CL tweaks the batch analysis runner which iterates
+ // over PSI files to skip files that are found to be within an AAR
+ // folder. This removes all the false positives and speeds up code
+ // analysis quite significantly!
+ if (isIgnoredFile(file)) {
+ return;
+ }
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
if (document == null) return;
diff --git a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
index 07a0585ff830..d7afa8682b41 100644
--- a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
+++ b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
@@ -17,6 +17,7 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
import com.intellij.openapi.application.ApplicationStarter;
+import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.extensions.PluginId;
@@ -27,6 +28,7 @@ import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.NlsSafe;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.io.URLUtil;
@@ -36,6 +38,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -228,9 +231,9 @@ public final class TraverseUIStarter implements ApplicationStarter {
String path = StringUtil.substringBefore(url, "fileTemplates");
assert path != null : "Template URL doesn't contain 'fileTemplates' directory.";
if (path.startsWith(URLUtil.JAR_PROTOCOL)) {
- path = StringUtil.trimEnd(path, URLUtil.JAR_SEPARATOR);
+ path = URLUtil.splitJarUrl(path).first; // Android Studio: support jars
}
- return PathUtil.getFileName(path);
+ return getModuleByPath(path); // Android Studio: support jars
}
private static void collectOptions(SearchableOptionsRegistrar registrar, Set<? super OptionDescription> options, @NotNull String text, String path) {
@@ -327,9 +330,26 @@ public final class TraverseUIStarter implements ApplicationStarter {
return ROOT_ACTION_MODULE;
}
+ // Android Studio: support jars
+ @NotNull
+ private static String getModuleByPath(@NotNull String path) {
+ // If it is not a directory, the module is already inside a jar, use the full path to disambiguate
+ // different plugins having the same jar names.
+ if (new File(path).isFile()) {
+ String homePath = PathManager.getHomePath();
+ if (FileUtil.isAncestor(homePath, path, true)) {
+ String relative = FileUtil.getRelativePath(homePath, path, File.separatorChar);
+ if (relative != null) {
+ return relative.replaceAll(File.separator, ".");
+ }
+ }
+ }
+ return PathUtil.getFileName(path);
+ }
+
@NotNull
private static String getModuleByClass(@NotNull final Class<?> aClass) {
- return PathUtil.getFileName(PathUtil.getJarPathForClass(aClass));
+ return getModuleByPath(PathUtil.getJarPathForClass(aClass)); // Android Studio: support jars
}
private static void writeOptions(@NotNull Element configurableElement, @NotNull Set<? extends OptionDescription> options) {
diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/ModuleNode.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/ModuleNode.java
index dcbb0d8f74c0..dfb16d731a8a 100644
--- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/ModuleNode.java
+++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/ModuleNode.java
@@ -15,14 +15,16 @@
*/
package com.intellij.packageDependencies.ui;
-import com.intellij.openapi.module.ModuleGrouper;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleGrouper;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.NavigatableWithText;
import com.intellij.psi.PsiFile;
+import com.intellij.util.IconUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,7 +68,25 @@ public class ModuleNode extends PackageDependenciesNode implements NavigatableWi
@Override
public Icon getIcon() {
- return myModule.isDisposed() ? super.getIcon() : ModuleType.get(myModule).getIcon();
+ // Android Studio: Use icons from module
+ return myModule.isDisposed() ? super.getIcon() : getModuleIcon();
+ }
+
+ /**
+ * Android Studio: Try to get Icon from file based on icon providers, if none is returned by providers, then use icon depending on module type
+ *
+ * @return Icon based on module type.
+ */
+ private Icon getModuleIcon() {
+ Icon icon = null;
+ VirtualFile virtualFile = myModule.getModuleFile();
+ if (virtualFile != null) {
+ icon = IconUtil.getIcon(virtualFile, 0, myModule.getProject());
+ }
+ if (icon == null) {
+ icon = ModuleType.get(myModule).getIcon();
+ }
+ return icon;
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java b/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java
index d33c43add2b1..ebc545d877dd 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java
@@ -64,7 +64,17 @@ public abstract class DirectoryAsPackageRenameHandlerBase<T extends PsiDirectory
else {
PsiDirectory[] directories = aPackage.getDirectories();
final VirtualFile[] virtualFiles = occursInPackagePrefixes(aPackage);
- if (virtualFiles.length == 0 && directories.length == 1) {
+ // In Android Studio, don't ask what to do if the additional packages
+ // are all generated: they'll follow the source package.
+ // See IDEA-125147.
+ int nonGeneratedCount = 0;
+ for (PsiDirectory dir : directories) {
+ VirtualFile virtualFile = dir.getVirtualFile();
+ if (!GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(virtualFile, dir.getProject())) {
+ nonGeneratedCount++;
+ }
+ }
+ if (virtualFiles.length == 0 && nonGeneratedCount <= 1) {
PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor);
}
else { // the directory corresponds to a package that has multiple associated directories
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
index 74e54ffa556c..87597de332ba 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
@@ -397,6 +397,7 @@ public class UnindexedFilesUpdater extends DumbModeTask {
return Boolean.TRUE.equals(project.getUserData(CONTENT_SCANNED));
}
+ @SuppressWarnings("ReturnValueIgnored") // commit 6c268108 seems to abuse Collectors.toCollection and Stream.collect
@NotNull
private static List<IndexableFilesIterator> collectProviders(@NotNull Project project, FileBasedIndexImpl index) {
List<IndexableFilesIterator> originalOrderedProviders = index.getIndexableFilesProviders(project);
diff --git a/platform/platform-api/resources/messages/IdeBundle.properties b/platform/platform-api/resources/messages/IdeBundle.properties
index fe4666cac1f7..ada86e389600 100644
--- a/platform/platform-api/resources/messages/IdeBundle.properties
+++ b/platform/platform-api/resources/messages/IdeBundle.properties
@@ -2148,10 +2148,10 @@ notification.content.jit.compiler.disabled=The JVM JIT compiler has been disable
If you see this message again, try increasing the CodeCache size using <code>-XX:ReservedCodeCacheSize</code> option.<br><br>\
For more information about JVM options, see <a href="help">this help topic</a>.
action.text.change.encoding=Change encoding to ''{0}''
-channel.status.eap=Early Access Program
-channel.status.milestone=Milestone EAP Builds
-channel.status.beta=Beta Releases or Public Previews
-channel.status.stable=Stable Releases
+channel.status.eap=Canary Channel
+channel.status.milestone=Dev Channel
+channel.status.beta=Beta Channel
+channel.status.stable=Stable Channel
error.plugin.required.for.project.not.installed=Plugin ''{0}'' required for ''{1}'' project isn''t installed.
error.plugin.required.for.project.disabled=Plugin ''{0}'' required for ''{1}'' project is disabled.
error.project.requires.newer.ide=Project ''{0}'' requires {1}''{2}'' or newer build of the IDE, but the current build is ''{3}''.
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java b/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java
index 951645af0b00..4de4b0d6e872 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java
@@ -2,6 +2,7 @@
package com.intellij.diagnostic;
import com.intellij.diagnostic.VMOptions.MemoryKind;
+import com.intellij.ide.AndroidStudioSystemHealthMonitorAdapter;
import com.intellij.ide.plugins.PluginUtil;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationGroup;
@@ -74,6 +75,13 @@ public class DefaultIdeaErrorLogger implements ErrorLogger {
try {
Throwable throwable = event.getThrowable();
MemoryKind kind = getOOMErrorKind(throwable);
+
+ // Android Studio: track and filer exceptions
+ boolean handled = AndroidStudioSystemHealthMonitorAdapter.handleExceptionEvent(event, kind);
+ if (handled) {
+ return;
+ }
+
if (kind != null) {
ourOomOccurred = true;
LowMemoryNotifier.showNotification(kind, true);
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
index 0fcbe4bd44ab..7fa00813b26a 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
@@ -948,6 +948,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
}
}
+ return getAndroidErrorReporter(); /* Android Studio: use Android instead of Jetbrains
if (plugin == null || PluginManagerCore.isDevelopedByJetBrains(plugin)) {
for (ErrorReportSubmitter reporter : reporters) {
PluginDescriptor descriptor = reporter.getPluginDescriptor();
@@ -958,6 +959,33 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
}
return null;
+ */
+ }
+
+ // NOTE: This API is only present in Android Studio, so don't invoke it from a plugin
+ @Nullable
+ public static ErrorReportSubmitter getAndroidErrorReporter() {
+ final ErrorReportSubmitter[] reporters;
+ try {
+ reporters = ExtensionPoints.ERROR_HANDLER_EP.getExtensions();
+ }
+ catch (Throwable t) {
+ return null;
+ }
+
+ return getErrorReporter(reporters, "android");
+ }
+
+ @Nullable
+ private static ErrorReportSubmitter getErrorReporter(@NotNull ErrorReportSubmitter[] reporters, @NotNull String id) {
+ for (ErrorReportSubmitter reporter : reporters) {
+ PluginDescriptor descriptor = reporter.getPluginDescriptor();
+ if (StringUtil.containsIgnoreCase(descriptor.getPluginId().getIdString(), id)) {
+ return reporter;
+ }
+ }
+
+ return null;
}
public static void appendSubmissionInformation(@NotNull SubmittedReportInfo info, @NotNull StringBuilder out) {
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/LowMemoryNotifier.java b/platform/platform-impl/src/com/intellij/diagnostic/LowMemoryNotifier.java
index c8d5c98a4c0a..87b0ffecda0d 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/LowMemoryNotifier.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/LowMemoryNotifier.java
@@ -8,6 +8,7 @@ import com.intellij.notification.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.util.LowMemoryWatcher;
+import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -15,7 +16,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
import static com.intellij.openapi.util.LowMemoryWatcher.LowMemoryWatcherType.ONLY_AFTER_GC;
final class LowMemoryNotifier implements Disposable {
- private final LowMemoryWatcher myWatcher = LowMemoryWatcher.register(this::onLowMemorySignalReceived, ONLY_AFTER_GC);
+
+ // Android Studio uses a new dialog for low-memory notification
+ private final LowMemoryWatcher myWatcher = PlatformUtils.isAndroidStudio() ? null : LowMemoryWatcher.register(this::onLowMemorySignalReceived, ONLY_AFTER_GC);
private final AtomicBoolean myNotificationShown = new AtomicBoolean();
private void onLowMemorySignalReceived() {
@@ -26,7 +29,10 @@ final class LowMemoryNotifier implements Disposable {
@Override
public void dispose() {
- myWatcher.stop();
+ // Android Studio sets myWatcher to null as it uses a different low-memory watcher.
+ if (myWatcher != null) {
+ myWatcher.stop();
+ }
}
static void showNotification(@NotNull VMOptions.MemoryKind kind, boolean error) {
diff --git a/platform/platform-impl/src/com/intellij/ide/AndroidStudioSystemHealthMonitorAdapter.java b/platform/platform-impl/src/com/intellij/ide/AndroidStudioSystemHealthMonitorAdapter.java
new file mode 100644
index 000000000000..f1677b12b6cb
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/AndroidStudioSystemHealthMonitorAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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;
+
+import com.intellij.diagnostic.VMOptions;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class AndroidStudioSystemHealthMonitorAdapter {
+
+ private static EventsListener ourListener;
+
+ public static void countActionInvocation(Class<? extends AnAction> aClass, Presentation presentation, AnActionEvent event) {
+ if (ourListener != null) {
+ ourListener.countActionInvocation(aClass, presentation, event);
+ }
+ }
+
+ public static boolean handleExceptionEvent(IdeaLoggingEvent event, VMOptions.MemoryKind memoryKind) {
+ if (ourListener != null) {
+ return ourListener.handleExceptionEvent(event, memoryKind);
+ } else {
+ return false;
+ }
+ }
+
+ public static void registerEventsListener(@NotNull EventsListener listener) {
+ if (ourListener != null) {
+ throw new IllegalStateException("listener already registered");
+ }
+ ourListener = listener;
+ }
+
+ public interface EventsListener {
+ void countActionInvocation(Class<? extends AnAction> aClass, Presentation presentation, AnActionEvent event);
+
+ boolean handleExceptionEvent(IdeaLoggingEvent event, VMOptions.MemoryKind memoryKind);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
index 3a89cbeeea60..9ab94fa65724 100644
--- a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
+++ b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
@@ -106,7 +106,7 @@ final class SystemHealthMonitor extends PreloadingActivity {
if (SystemInfo.isMac && CpuArch.isIntel64()) {
NotificationAction downloadAction = NotificationAction.createSimpleExpiring(
IdeBundle.message("bundled.jre.m1.arch.message.download"),
- () -> BrowserUtil.browse("https://www.jetbrains.com/products/#type=ide"));
+ () -> BrowserUtil.browse("https://developer.android.com/studio")); // Android Studio: b/191780967
showNotification("bundled.jre.m1.arch.message", true, downloadAction, ApplicationNamesInfo.getInstance().getFullProductName());
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/EditCustomSettingsAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/EditCustomSettingsAction.kt
index c846ec6aecc9..dc34e2acc190 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/EditCustomSettingsAction.kt
+++ b/platform/platform-impl/src/com/intellij/ide/actions/EditCustomSettingsAction.kt
@@ -25,6 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame
import com.intellij.psi.PsiManager
import com.intellij.ui.EditorTextField
+import com.intellij.util.PlatformUtils
import com.intellij.util.ui.IoErrorText
import java.io.File
import java.io.IOException
@@ -160,6 +161,9 @@ class EditCustomVmOptionsAction : EditCustomSettingsAction() {
override fun file(): Path? = file.value
override fun template(): String =
+ if ("AndroidStudio" == PlatformUtils.getPlatformPrefix())
+ "# custom ${ApplicationNamesInfo.getInstance().fullProductName} VM options, see https://developer.android.com/studio/intro/studio-config.html\n"
+ else
"# custom ${ApplicationNamesInfo.getInstance().fullProductName} VM options (expand/override 'bin${File.separator}${VMOptions.getFileName()}')\n\n"
override fun charset(): Charset = VMOptions.getFileCharset()
diff --git a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java
index ebd1071dcf04..fb3e9a54aa5c 100644
--- a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java
+++ b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java
@@ -4,6 +4,7 @@ package com.intellij.ide.gdpr;
import com.fasterxml.jackson.jr.ob.JSON;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.intellij.analytics.AndroidStudioAnalytics;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
@@ -332,6 +333,11 @@ public final class ConsentOptions {
catch (IOException e) {
LOG.info(e);
}
+ // Android Studio addition:
+ // Update the Android Studio metrics after saving consents in case the IJ Statistics consent
+ // has been updated. This will write any changed settings and reinitialize the UsageTracker
+ // & Publisher if changes were made.
+ AndroidStudioAnalytics.getInstance().updateAndroidStudioMetrics();
}
}
diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
index af1ab9401769..8bcacaa90464 100644
--- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
+++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
@@ -609,7 +609,9 @@ public final class StartupUtil {
else if (ConsentOptions.needToShowUsageStatsConsent()) {
euaFuture = CompletableFuture.supplyAsync(() -> {
setLafToShowPreAppStartUpDialogIfNeeded(baseLaF);
+ /* Android Studio: b/200625563
Agreements.showDataSharingAgreement();
+ Android Studio: b/200625563 */
return false;
}, EventQueue::invokeLater);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
index 0f4853a5e358..feea770eadf8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
@@ -10,6 +10,7 @@ import com.intellij.diagnostic.PluginException;
import com.intellij.diagnostic.StartUpMeasurer;
import com.intellij.icons.AllIcons;
import com.intellij.ide.ActivityTracker;
+import com.intellij.ide.AndroidStudioSystemHealthMonitorAdapter;
import com.intellij.ide.DataManager;
import com.intellij.ide.ProhibitAWTEvents;
import com.intellij.ide.plugins.*;
@@ -26,6 +27,7 @@ import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.*;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.actions.BackspaceAction;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.extensions.ExtensionPointListener;
import com.intellij.openapi.extensions.ExtensionPointName;
@@ -1518,8 +1520,18 @@ public class ActionManagerImpl extends ActionManagerEx implements Disposable {
myActionListeners.remove(listener);
}
+ // we want to exclude some actions (the actual list is somewhat arbitrary) from being counted and reported
+ private static final Map<Class<?>,Boolean> ourActionsExcludedFromTracking;
+ static {
+ ourActionsExcludedFromTracking = new IdentityHashMap<Class<?>, Boolean>();
+ ourActionsExcludedFromTracking.put(BackspaceAction.class, Boolean.TRUE);
+ }
+
@Override
public void fireBeforeActionPerformed(@NotNull AnAction action, @NotNull AnActionEvent event) {
+ if (!ourActionsExcludedFromTracking.containsKey(action.getClass())) {
+ AndroidStudioSystemHealthMonitorAdapter.countActionInvocation(action.getClass(), action.getTemplatePresentation(), event);
+ }
myPrevPerformedActionId = myLastPreformedActionId;
myLastPreformedActionId = getId(action);
if (myLastPreformedActionId == null && action instanceof ActionIdProvider) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java
index 607ff0b70fd4..cb9806049e85 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java
@@ -257,6 +257,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
updateTreeFromPath(newValue);
}
};
+ myPathTextField.getField().setName("FileChooserDialogImpl.myPathTextField"); // Android Studio: for FileChooserDialogFixture
myNorthPanel = new JPanel(new BorderLayout());
myNorthPanel.add(toolbarPanel, BorderLayout.NORTH);
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfo.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfo.kt
index d05c5906e990..b9351b531f41 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfo.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfo.kt
@@ -5,6 +5,7 @@ package com.intellij.openapi.updateSettings.impl
import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.util.*
+import com.intellij.util.system.CpuArch
import org.jdom.Element
import org.jdom.JDOMException
import org.jetbrains.annotations.ApiStatus
@@ -76,7 +77,7 @@ class BuildInfo internal constructor(node: Element, productCode: String) {
class PatchInfo internal constructor(node: Element) {
companion object {
- val OS_SUFFIX = if (SystemInfo.isWindows) "win" else if (SystemInfo.isMac) "mac" else if (SystemInfo.isUnix) "unix" else "unknown"
+ val OS_SUFFIX = if (SystemInfo.isWindows) "win" else if (SystemInfo.isMac) if (CpuArch.isArm64()) "mac_arm" else "mac" else if (SystemInfo.isUnix) "unix" else "unknown" // Android Studio: mac_arm support
}
val fromBuild: BuildNumber = BuildNumber.fromString(node.getMandatoryAttributeValue("fullFrom", "from"))!!
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt
index 3d779473f1b0..aaab1fb87169 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInstaller.kt
@@ -49,7 +49,7 @@ internal object UpdateInstaller {
for (i in 1 until chain.size) {
val from = chain[i - 1].withoutProductCode().asString()
val to = chain[i].withoutProductCode().asString()
- val patchName = "${product}-${from}-${to}-patch${jdk}-${PatchInfo.OS_SUFFIX}.jar"
+ val patchName = "${product}-${from}-${to}-patch-${PatchInfo.OS_SUFFIX}.jar" // Android Studio: no JDK suffix
val patchFile = File(getTempDir(), patchName)
val url = URL(patchesUrl, patchName).toString()
val partIndicator = object : DelegatingProgressIndicator(indicator) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateOptions.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateOptions.kt
index 9a3f4525b3ea..8c3965c2cdd0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateOptions.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateOptions.kt
@@ -31,7 +31,7 @@ class UpdateOptions : BaseState() {
@get:OptionTag("UPDATE_CHANNEL_TYPE")
@get:ReportValue(possibleValues = ["eap", "milestone", "beta", "release"])
- var updateChannelType by string(ChannelStatus.RELEASE.code)
+ var updateChannelType by string(ChannelStatus.EAP.code) // Android Studio: EAP as default unless building beta, RC, stable.
@get:OptionTag("THIRD_PARTY_PLUGINS_ALLOWED")
var isThirdPartyPluginsAllowed by property(false)
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 76e4e3367854..de8c36d4da28 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -419,8 +419,10 @@
<applicationService serviceInterface="com.intellij.ide.UiActivityMonitor" serviceImplementation="com.intellij.ide.UiActivityMonitorImpl"/>
+ <!-- Android Studio: don't register IntelliJ forks
<applicationService serviceImplementation="com.intellij.diagnostic.WindowsDefenderChecker"/>
<applicationService serviceImplementation="com.intellij.diagnostic.GcPauseWatcher"/>
+ Android Studio: don't register IntelliJ forks -->
<applicationService serviceInterface="com.intellij.execution.process.ProcessHandlerFactory"
serviceImplementation="com.intellij.execution.process.ProcessHandlerFactoryImpl" />
@@ -433,7 +435,9 @@
<applicationService serviceInterface="com.intellij.util.io.IoService"
serviceImplementation="com.intellij.util.io.IoServiceImpl" />
+ <!-- Android Studio: don't register IntelliJ fork
<applicationService serviceImplementation="com.intellij.diagnostic.HeapDumpAnalysisSupport"/>
+ Android Studio: don't register IntelliJ fork -->
<applicationService serviceInterface="com.intellij.diagnostic.EventWatcher"
serviceImplementation="com.intellij.diagnostic.EventWatcherImpl"/>
@@ -793,7 +797,9 @@
<applicationInitializedListener implementation="com.intellij.ide.customize.CustomizeIDEWizardCollectorActivity"/>
<statistics.applicationUsagesCollector implementation="com.intellij.featureStatistics.fusCollectors.EAPUsageCollector"/>
+<!-- Android Studio: instead AndroidStudioStatisticsEventLoggerProvider is registered in androidstudio.xml
<statistic.eventLog.eventLoggerProvider implementation="com.intellij.internal.statistic.eventLog.fus.FeatureUsageEventLoggerProvider"/>
+Android Studio: instead AndroidStudioStatisticsEventLoggerProvider is registered in androidstudio.xml -->
<statistics.applicationUsagesCollector implementation="com.intellij.featureStatistics.fusCollectors.OsDataCollector"/>
<statistics.applicationUsagesCollector implementation="com.intellij.featureStatistics.fusCollectors.IdeSessionDataCollector"/>
<statistic.eventLog.fusStateEventTracker implementation="com.intellij.configurationStore.statistic.eventLog.FeatureUsageSettingsEventScheduler"/>
@@ -845,7 +851,9 @@
<postStartupActivity implementation="com.intellij.openapi.fileEditor.impl.EditorHistoryManager$EditorHistoryManagerStartUpActivity"/>
+ <!-- Android Studio: don't register IntelliJ fork
<backgroundPostStartupActivity implementation="com.intellij.diagnostic.WindowsDefenderCheckerActivity" os="windows"/>
+ Android Studio: don't register IntelliJ fork -->
<preloadingActivity implementation="com.intellij.codeInsight.editorActions.TypedHandler$TypedHandlerDelegatePreloader"/>
<actionConfigurationCustomizer implementation="com.intellij.execution.ExecutorRegistryImpl$ExecutorRegistryActionConfigurationTuner"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformLangComponents.xml b/platform/platform-resources/src/META-INF/PlatformLangComponents.xml
index 840c225aa081..7a5efcad5a11 100644
--- a/platform/platform-resources/src/META-INF/PlatformLangComponents.xml
+++ b/platform/platform-resources/src/META-INF/PlatformLangComponents.xml
@@ -152,8 +152,11 @@
activeInHeadlessMode="false"/>
<listener class="com.intellij.openapi.editor.impl.EditorLastActionTracker$MyAnActionListener"
topic="com.intellij.openapi.actionSystem.ex.AnActionListener"/>
+ <!-- Android Studio: disabled by Change I9217935c
+ Not used in Studio.
<listener class="com.intellij.diagnostic.IdeaFreezeReporter" topic="com.intellij.diagnostic.IdePerformanceListener"
activeInTestMode="false" activeInHeadlessMode="false"/>
+ -->
<listener class="com.intellij.notification.impl.NotificationsToolWindowNotificationListener"
topic="com.intellij.notification.Notifications"/>
diff --git a/platform/platform-resources/src/META-INF/XmlActions.xml b/platform/platform-resources/src/META-INF/XmlActions.xml
index 72cc8066d76e..fb5da2e17997 100644
--- a/platform/platform-resources/src/META-INF/XmlActions.xml
+++ b/platform/platform-resources/src/META-INF/XmlActions.xml
@@ -85,10 +85,18 @@
<override-text place="EditorPopup" use-text-of-place="EditorTabPopup"/>
<override-text place="FavoritesPopup" use-text-of-place="EditorTabPopup"/>
</group>
+
+ <!--
+ Disabled in Android Studio:
+ This creates an in-place toolbar which fades in and paints on top of the source editor whenever
+ you edit an XML file. For web developers working on XHTML files this may be useful, but in Android,
+ where most XML files are resource files, this is distracting and not useful.
+
<group id="OpenInBrowserEditorContextBarGroupAction"
class="com.intellij.ide.browsers.actions.OpenInBrowserBaseGroupAction$OpenInBrowserEditorContextBarGroupAction">
<add-to-group group-id="EditorContextBarMenu" anchor="last"/>
</group>
+ -->
<group id="Emmet">
<action id="SurroundWithEmmet" class="com.intellij.codeInsight.template.emmet.SurroundWithEmmetAction"/>
diff --git a/platform/platform-resources/src/consents-Google.json b/platform/platform-resources/src/consents-Google.json
new file mode 100644
index 000000000000..2dd78e62bd7f
--- /dev/null
+++ b/platform/platform-resources/src/consents-Google.json
@@ -0,0 +1,9 @@
+[
+ {
+ "consentId": "rsch.send.usage.stat",
+ "version": "1.0",
+ "text": "Allow Google to collect usage data for Android Studio and its related tools, such as how you use features and resource usage along with software identifiers such as package name and class names and plugin configuration. This data helps improve Android Studio and is collected in accordance with <a href=\"http://www.google.com/policies/privacy/\">Google's Privacy Policy</a>. Anonymous and aggregated usage data may be shared with Google's partners to improve Android Studio.",
+ "printableName": "Send usage statistics to Google",
+ "accepted": "false"
+ }
+]
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index 95e441fce0e5..a21ecf5587f1 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -1410,10 +1410,12 @@
</group>
<group id="Internal.HeapAnalysis" popup="true" internal="true">
+ <!-- Commented out in Android Studio. These are defined in androidstudio.xml
<action id="UserInvokedFullAnalysis" class="com.intellij.diagnostic.hprof.action.InternalUserInvokedFullAnalysisAction"
internal="true"/>
<action id="SilentHeapDumpSnapshot" class="com.intellij.diagnostic.hprof.action.InternalNonuserInvokedHeapDumpSnapshotAction"
internal="true"/>
+ -->
<action id="AnalyzeHeapDumpSnapshot" class="com.intellij.diagnostic.hprof.action.AnalyzeReportAction" internal="true"/>
<add-to-group group-id="Internal"/>
</group>
diff --git a/platform/platform-resources/src/keymaps/$default.xml b/platform/platform-resources/src/keymaps/$default.xml
index 9a81ec4ee562..9525b6428fae 100644
--- a/platform/platform-resources/src/keymaps/$default.xml
+++ b/platform/platform-resources/src/keymaps/$default.xml
@@ -431,7 +431,7 @@
<action id="EditorLeftWithSelection">
<keyboard-shortcut first-keystroke="shift LEFT"/>
</action>
- <action id="Compile">
+ <action id="MakeModule">
<keyboard-shortcut first-keystroke="control shift F9"/>
</action>
<action id="$Cut">
@@ -1026,7 +1026,11 @@
<action id="ForceRefresh">
<keyboard-shortcut first-keystroke="control shift F5"/>
</action>
+ <!-- Android Studio: Switch default Rerun action from "Rerun" to "Android.CleanRun" -->
+ <action id="Android.CleanRun">
+ <!-- Android Studio: removed by Change I886f2788 / commit f4e3c8e
<action id="Rerun">
+ Android Studio: removed by Change I886f2788 / commit f4e3c8e -->
<keyboard-shortcut first-keystroke="control F5"/>
</action>
<action id="RerunTests">
diff --git a/platform/platform-resources/src/keymaps/Default for KDE.xml b/platform/platform-resources/src/keymaps/Default for KDE.xml
index e4e81bcc0ef1..9d6f387824a1 100644
--- a/platform/platform-resources/src/keymaps/Default for KDE.xml
+++ b/platform/platform-resources/src/keymaps/Default for KDE.xml
@@ -73,7 +73,11 @@
<action id="ForceRefresh">
<keyboard-shortcut first-keystroke="control shift 5"/>
</action>
+ <!-- Android Studio: Switch default Rerun action from "Rerun" to "Android.CleanRun" -->
+ <action id="Android.CleanRun">
+ <!-- Android Studio: removed by Change I886f2788 / commit f4e3c8e
<action id="Rerun">
+ Android Studio: removed by Change I886f2788 / commit f4e3c8e -->
<keyboard-shortcut first-keystroke="control 5"/>
</action>
<action id="RestoreDefaultLayout">
diff --git a/platform/platform-resources/src/keymaps/Eclipse.xml b/platform/platform-resources/src/keymaps/Eclipse.xml
index d4c0e1646d27..85c3db15ae37 100644
--- a/platform/platform-resources/src/keymaps/Eclipse.xml
+++ b/platform/platform-resources/src/keymaps/Eclipse.xml
@@ -284,7 +284,8 @@
<keyboard-shortcut first-keystroke="control F"/>
</action>
<action id="ReplaceInPath"/>
- <action id="Rerun">
+ <!-- Android Studio: Switch default Rerun action from "Rerun" to "Android.CleanRun" -->
+ <action id="Android.CleanRun">
<keyboard-shortcut first-keystroke="control F11"/>
</action>
<action id="RerunTests">
diff --git a/platform/platform-resources/src/keymaps/Mac OS X 10.5+.xml b/platform/platform-resources/src/keymaps/Mac OS X 10.5+.xml
index 17b862a76495..65e81787cfa1 100644
--- a/platform/platform-resources/src/keymaps/Mac OS X 10.5+.xml
+++ b/platform/platform-resources/src/keymaps/Mac OS X 10.5+.xml
@@ -314,7 +314,11 @@
<action id="ForceRefresh">
<keyboard-shortcut first-keystroke="meta alt shift R"/>
</action>
+ <!-- Android Studio: Switch default Rerun action from "Rerun" to "Android.CleanRun" -->
+ <action id="Android.CleanRun">
+ <!-- Android Studio: removed by Change I886f2788 / commit f4e3c8e
<action id="Rerun">
+ Android Studio: removed by Change I886f2788 / commit f4e3c8e -->
<keyboard-shortcut first-keystroke="meta R"/>
</action>
<action id="RerunTests">
diff --git a/platform/platform-resources/src/keymaps/Mac OS X.xml b/platform/platform-resources/src/keymaps/Mac OS X.xml
index deb39f9de4c6..b957ec30827c 100644
--- a/platform/platform-resources/src/keymaps/Mac OS X.xml
+++ b/platform/platform-resources/src/keymaps/Mac OS X.xml
@@ -343,7 +343,11 @@
<action id="ForceRefresh">
<keyboard-shortcut first-keystroke="control shift F5"/>
</action>
+ <!-- Android Studio: Switch default Rerun action from "Rerun" to "Android.CleanRun" -->
+ <action id="Android.CleanRun">
+ <!-- Android Studio: removed by Change I886f2788 / commit f4e3c8e
<action id="Rerun">
+ Android Studio: removed by Change I886f2788 / commit f4e3c8e -->
<keyboard-shortcut first-keystroke="control F5"/>
</action>
<action id="RerunTests">
diff --git a/platform/platform-resources/src/keymaps/Xcode.xml b/platform/platform-resources/src/keymaps/Xcode.xml
index 02386f73c1e2..44f2c6faa2a0 100644
--- a/platform/platform-resources/src/keymaps/Xcode.xml
+++ b/platform/platform-resources/src/keymaps/Xcode.xml
@@ -389,7 +389,9 @@
<keyboard-shortcut first-keystroke="ctrl 4" />
<keyboard-shortcut first-keystroke="ctrl 5" />
<keyboard-shortcut first-keystroke="alt HOME" />
- </action> <action id="Rerun">
+ </action>
+ <!-- Android Studio: Switch default Rerun action from "Rerun" to "Android.CleanRun" -->
+ <action id="Android.CleanRun">
<keyboard-shortcut first-keystroke="control alt meta G"/>
</action>
<action id="RerunFailedTests">
diff --git a/platform/statistics/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/statistics/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
index 45b566df260b..f0fb1ac4020e 100644
--- a/platform/statistics/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
+++ b/platform/statistics/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java
@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.internal.statistic.persistence;
+import com.intellij.analytics.AndroidStudioAnalytics;
import com.intellij.ide.ConsentOptionsProvider;
import com.intellij.internal.statistic.eventLog.StatisticsSystemEventIdProvider;
import com.intellij.openapi.application.ApplicationManager;
@@ -126,11 +127,14 @@ public final class UsageStatisticsPersistenceComponent implements PersistentStat
}
public boolean isAllowed() {
+ /* Android Studio: we use our own mechanism
final ConsentOptionsProvider options = getConsentOptionsProvider();
if (options == null) {
return false;
}
return options.isEAP() ? isAllowedForEAP : options.isSendingUsageStatsAllowed();
+ */
+ return AndroidStudioAnalytics.getInstance().isAllowed();
}
public void setShowNotification(boolean showNotification) {
@@ -142,7 +146,7 @@ public final class UsageStatisticsPersistenceComponent implements PersistentStat
}
@Nullable
- private static ConsentOptionsProvider getConsentOptionsProvider() {
+ public static ConsentOptionsProvider getConsentOptionsProvider() { // Android Studio: made public by Change Iab5d02d8 / commit c12f3af8
return ApplicationManager.getApplication().getService(ConsentOptionsProvider.class);
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java
index f2af7a0c4e63..3930cbd6c2be 100644
--- a/platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/HeavyPlatformTestCase.java
@@ -65,6 +65,7 @@ import com.intellij.util.indexing.FileBasedIndexImpl;
import com.intellij.util.indexing.IndexableSetContributor;
import com.intellij.util.io.PathKt;
import com.intellij.util.ui.UIUtil;
+import java.util.Arrays;
import junit.framework.TestCase;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -182,6 +183,9 @@ public abstract class HeavyPlatformTestCase extends UsefulTestCase implements Da
myOldSdks = new SdkLeakTracker();
}
+ // Android Studio: Our classpath matches multiple platform prefixes (CidrCommon, etc.), but the default should be AndroidStudio, and
+ // if adt-branding is not on the classpath, then we should simply run as IDEA.
+ private static final String[] PREFIX_CANDIDATES = {"AndroidStudio", "Idea"}; /*
private static final String[] PREFIX_CANDIDATES = {
"Rider", "GoLand", "CLion", "MobileIDE",
null,
@@ -191,8 +195,14 @@ public abstract class HeavyPlatformTestCase extends UsefulTestCase implements Da
"Ruby",
"PhpStorm",
"UltimateLangXml", "Idea", "PlatformLangXml"};
+ */
public static void doAutodetectPlatformPrefix() {
+ // Android Studio: allow -Didea.platform.prefix to override auto-detection mechanism
+ if (Arrays.asList(PREFIX_CANDIDATES).contains(System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY))) {
+ ourPlatformPrefixInitialized = true;
+ }
+
if (ourPlatformPrefixInitialized) {
return;
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
index 03419fafa7aa..99b8a8420e69 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
@@ -21,8 +21,10 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
+import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.function.Predicate;
@@ -30,6 +32,14 @@ import java.util.function.Supplier;
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public final class LeakHunter {
+
+ // Android Studio: to avoid false positives, the leak checker won't inspect the internal state of mocking libraries.
+ private static final List<String> MOCKING_SUPPORT_CLASSES = Arrays.asList(
+ "org.easymock.internal.MocksBehavior",
+ "org.mockito.internal.stubbing.OngoingStubbingImpl");
+
+ private static final Predicate<Object> SHOULD_EXAMINE_VALUE = o -> !MOCKING_SUPPORT_CLASSES.contains(o.getClass().getName());
+
@TestOnly
public static void checkProjectLeak() throws AssertionError {
checkLeak(allRoots(), ProjectImpl.class, project -> !project.isDefault() && !project.isLight());
@@ -82,7 +92,8 @@ public final class LeakHunter {
PersistentEnumeratorCache.clearCacheForTests();
Runnable runnable = () -> {
try (AccessToken ignored = ProhibitAWTEvents.start("checking for leaks")) {
- DebugReflectionUtil.walkObjects(10000, rootsSupplier.get(), suspectClass, __ -> true, (leaked, backLink) -> {
+ // Android Studio: modified by Change Id988eaf4
+ DebugReflectionUtil.walkObjects(10000, rootsSupplier.get(), suspectClass, SHOULD_EXAMINE_VALUE, (leaked, backLink) -> {
if (isReallyLeak == null || isReallyLeak.test(leaked)) {
return processor.process(leaked, backLink);
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/TestApplicationManager.kt b/platform/testFramework/src/com/intellij/testFramework/TestApplicationManager.kt
index 1ede9219995c..4ef222e1a7c0 100644
--- a/platform/testFramework/src/com/intellij/testFramework/TestApplicationManager.kt
+++ b/platform/testFramework/src/com/intellij/testFramework/TestApplicationManager.kt
@@ -79,6 +79,7 @@ class TestApplicationManager private constructor() {
init {
Java11Shim.INSTANCE = StartupUtil.Java11ShimImpl()
ExtensionNotApplicableException.useFactoryWithStacktrace()
+ System.setProperty("idea.force.use.core.classloader", "true") // Android Studio
}
@Volatile
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 2f1a65ed71bf..8c4fee2092d8 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -1,6 +1,8 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.testFramework;
+import com.intellij.analytics.AndroidStudioAnalytics;
+import com.intellij.analytics.NullAndroidStudioAnalytics;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
import com.intellij.diagnostic.PerformanceWatcher;
@@ -214,6 +216,8 @@ public abstract class UsefulTestCase extends TestCase {
setupTempDir();
+ AndroidStudioAnalytics.initialize(new NullAndroidStudioAnalytics());
+
boolean isStressTest = isStressTest();
ApplicationManagerEx.setInStressTest(isStressTest);
if (isPerformanceTest()) {
diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java
index e11ee6660b8f..59fd7b3eb369 100644
--- a/platform/util/src/com/intellij/openapi/application/PathManager.java
+++ b/platform/util/src/com/intellij/openapi/application/PathManager.java
@@ -146,6 +146,16 @@ public final class PathManager {
if (rootPath == null) return null;
Path root = Paths.get(rootPath).toAbsolutePath();
+ // Android Studio: On Bazel tests, there may be some symlinks that need to be followed.
+ // E.g., rootPath = bazel-out/x64_windows-fastbuild/bin/tools/adt/idea/adt-ui/intellij.android.adt.ui_tests.exe.j/0/util.jar
+ // where the path contains the symlink:
+ // 0 ->  %REPO%/prebuilts/studio/intellij-sdk/ai-202/windows/android-studio/lib/
+ if (SystemInfoRt.isWindows && System.getProperties().containsKey("TEST_WORKSPACE")) {
+ try {
+ root = root.toRealPath();
+ }
+ catch (IOException ignore) { }
+ }
do root = root.getParent(); while (root != null && !isIdeaHome(root));
return root != null ? root.toString() : null;
}
diff --git a/platform/util/src/com/intellij/openapi/util/SystemInfo.java b/platform/util/src/com/intellij/openapi/util/SystemInfo.java
index 2c97b37e568c..c1ffd7aa06f7 100644
--- a/platform/util/src/com/intellij/openapi/util/SystemInfo.java
+++ b/platform/util/src/com/intellij/openapi/util/SystemInfo.java
@@ -42,6 +42,7 @@ public final class SystemInfo {
public static final boolean isIbmJvm = Strings.indexOfIgnoreCase(JAVA_VENDOR, "IBM", 0) >= 0;
public static final boolean isAzulJvm = Strings.indexOfIgnoreCase(JAVA_VENDOR, "Azul", 0) >= 0;
public static final boolean isJetBrainsJvm = Strings.indexOfIgnoreCase(JAVA_VENDOR, "JetBrains", 0) >= 0;
+ public static final boolean isStudioJvm = isStudioJvm();
public static final boolean isMetalRendering = isMac && Boolean.getBoolean("sun.java2d.metal");
public static final boolean isDCEVM = ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+AllowEnhancedClassRedefinition");
@@ -211,6 +212,12 @@ public final class SystemInfo {
return StringUtil.compareVersionNumbers(JAVA_RUNTIME_VERSION, v) >= 0;
}
+ private static boolean isStudioJvm() {
+ final String vendor = JAVA_VENDOR;
+ final String url = System.getProperty("java.vendor.url");
+ return ("Google Inc.".equals(vendor) || ("Google LLC".equals(vendor))) && "http://developer.android.com/sdk/index.html".equals(url);
+ }
+
/** @deprecated may be inaccurate; please use {@link CpuArch} instead */
@Deprecated
@ApiStatus.ScheduledForRemoval
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java
index a8a606add41a..d1b3e1b12b65 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java
@@ -33,8 +33,14 @@ import static com.intellij.util.ObjectUtils.tryCast;
import static com.siyeh.ig.psiutils.ParenthesesUtils.getParentSkipParentheses;
public class ForCanBeForeachInspection extends BaseInspection {
+ /**
+ * Android Studio: Change default from true to false. In Android applications we generally
+ * don't want to encourage people to replace deliberate indexed iteration with for each
+ * since it will add an iterator, which accumulates garbage and can generate jank when done
+ * in drawing/layout code etc.
+ */
@SuppressWarnings("PublicField")
- public boolean REPORT_INDEXED_LOOP = true;
+ public boolean REPORT_INDEXED_LOOP = false;
@SuppressWarnings("PublicField")
public boolean ignoreUntypedCollections;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/ForCanBeForeachInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/ForCanBeForeachInspectionTest.java
index 1f8a7ca25724..c3a8b0d42bb4 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/ForCanBeForeachInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/ForCanBeForeachInspectionTest.java
@@ -14,7 +14,12 @@ public class ForCanBeForeachInspectionTest extends LightJavaInspectionTestCase {
@Override
protected InspectionProfileEntry getInspection() {
- return new ForCanBeForeachInspection();
+ ForCanBeForeachInspection inspection = new ForCanBeForeachInspection();
+
+ // Android Studio: Changed default to false, but this test is for indexed-checks=true.
+ inspection.REPORT_INDEXED_LOOP = true;
+
+ return inspection;
}
@Override
diff --git a/plugins/github/resources/META-INF/plugin.xml b/plugins/github/resources/META-INF/plugin.xml
index 5e437c27861e..502577c53dbb 100644
--- a/plugins/github/resources/META-INF/plugin.xml
+++ b/plugins/github/resources/META-INF/plugin.xml
@@ -184,8 +184,14 @@
<action id="Github.Break.Api.Requests" internal="true"
class="org.jetbrains.plugins.github.api.GHRequestExecutorBreaker$Action"/>
+ <!-- Android Studio: disable web flow for GitHub auth (via account.jetbrains.com and internal web browser redirect) -->
+ <!-- move action out of `Github.Accounts.AddAccount` group, and mark as internal -->
+ <action id="Github.Accounts.AddGHAccount" internal="true" class="org.jetbrains.plugins.github.authentication.ui.AddGHAccountAction"/>
+
<group id="Github.Accounts.AddAccount">
+ <!-- Android Studio: disable web flow for GitHub auth (via account.jetbrains.com and internal web browser redirect)
<action id="Github.Accounts.AddGHAccount" class="org.jetbrains.plugins.github.authentication.ui.AddGHAccountAction"/>
+ Android Studio: disable web flow for GitHub auth (via account.jetbrains.com and internal web browser redirect) -->
<action id="Github.Accounts.AddGHAccountWithToken"
class="org.jetbrains.plugins.github.authentication.ui.AddGHAccountWithTokenAction"/>
<separator/>
diff --git a/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRRepositorySelectorComponentFactory.kt b/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRRepositorySelectorComponentFactory.kt
index e2854ac72b10..d7d6b5dfb90d 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRRepositorySelectorComponentFactory.kt
+++ b/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRRepositorySelectorComponentFactory.kt
@@ -102,7 +102,9 @@ class GHPRRepositorySelectorComponentFactory(private val project: Project,
val actionsPanel = JPanel(HorizontalLayout(UI.scale(16))).apply {
isOpaque = false
add(applyButton)
+ /* Android Studio: disable auth via account.jetbrains.com and internal web browser redirect
add(githubLoginButton)
+ Android Studio: disable auth via account.jetbrains.com and internal web browser redirect */
add(tokenLoginLink)
add(gheLoginButton)
@@ -180,11 +182,14 @@ class GHPRRepositorySelectorComponentFactory(private val project: Project,
private fun getAccountsPopupActions(server: GithubServerPath): List<Action> {
return if (server.isGithubDotCom)
+ /* Android Studio: disable web flow for GitHub auth (via account.jetbrains.com and internal web browser redirect)
listOf(object : AbstractAction(GithubBundle.message("action.Github.Accounts.AddGHAccount.text")) {
override fun actionPerformed(e: ActionEvent?) {
authManager.requestNewAccountForDefaultServer(project)?.let(::trySelectAccount)
}
}, object : AbstractAction(GithubBundle.message("action.Github.Accounts.AddGHAccountWithToken.text")) {
+ Android Studio: disable web flow for GitHub auth (via account.jetbrains.com and internal web browser redirect) */
+ listOf(object : AbstractAction(GithubBundle.message("action.Github.Accounts.AddGHAccountWithToken.text")) {
override fun actionPerformed(e: ActionEvent?) {
authManager.requestNewAccountForDefaultServer(project, true)?.let(::trySelectAccount)
}
diff --git a/plugins/gradle/java/src/service/resolve/GradleProjectExtensionContributor.kt b/plugins/gradle/java/src/service/resolve/GradleProjectExtensionContributor.kt
index 7833c209a5d5..b2ee1b78b26e 100644
--- a/plugins/gradle/java/src/service/resolve/GradleProjectExtensionContributor.kt
+++ b/plugins/gradle/java/src/service/resolve/GradleProjectExtensionContributor.kt
@@ -54,6 +54,7 @@ class GradleProjectExtensionContributor : NonCodeMembersContributor() {
if (processMethods) {
val extensionMethod = GrLightMethodBuilder(manager, extension.name).apply {
returnType = type
+ containingClass = aClass
addAndGetParameter("configuration", createType(GROOVY_LANG_CLOSURE, containingFile))
.putUserData(DELEGATES_TO_KEY, DelegatesToInfo(type, Closure.DELEGATE_FIRST))
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleConnectorService.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleConnectorService.kt
index c18f2cbad04d..29b6f5bd9946 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleConnectorService.kt
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleConnectorService.kt
@@ -245,7 +245,9 @@ internal class GradleConnectorService(@Suppress("UNUSED_PARAMETER") project: Pro
}
// do not spawn gradle daemons during test execution
val app = ApplicationManager.getApplication()
- val ttl = if (app != null && app.isUnitTestMode) 10000 else connectorParams.ttlMs ?: -1
+
+ // Android Studio: Gradle daemon should not auto shutdown while the IDE is indexing SDKs.
+ val ttl = if (app != null && app.isUnitTestMode) 100_000 else connectorParams.ttlMs ?: -1
if (ttl > 0 && connector is DefaultGradleConnector) {
connector.daemonMaxIdleTime(ttl, TimeUnit.MILLISECONDS)
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
index 230c38e1f46a..528ade1f2fc1 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
@@ -565,7 +565,7 @@ public class GradleInstallationManager implements Disposable {
private static boolean isGroovyJar(@NotNull String name) {
name = StringUtil.toLowerCase(name);
- return name.startsWith("groovy-all-") && name.endsWith(".jar") && !name.contains("src") && !name.contains("doc");
+ return name.startsWith("groovy-") && name.endsWith(".jar") && !name.contains("src") && !name.contains("doc");
}
@Nullable
diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy
index bc12c586390d..72b2bca5d1a7 100644
--- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy
+++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy
@@ -16,6 +16,7 @@ import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.api.tasks.testing.AbstractTestTask
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.util.PatternFilterable
import org.gradle.plugins.ide.idea.IdeaPlugin
@@ -104,7 +105,17 @@ class ExternalProjectBuilderImpl extends AbstractModelBuilderService {
defaultExternalProject.group = wrap(project.group)
defaultExternalProject.projectDir = project.projectDir
defaultExternalProject.sourceSets = getSourceSets(project, resolveSourceSetDependencies, sourceSetFinder)
- defaultExternalProject.tasks = getTasks(project, tasksFactory)
+ // Android Studio: provide the option to not build Gradle tasks list, because this triggers full task graph configuration, which is
+ // very slow for large Android projects.
+ def skipTasks;
+ try {
+ skipTasks = Boolean.parseBoolean(String.valueOf(project.getProperties().get("idea.gradle.do.not.build.tasks")).trim())
+ }
+ catch (Throwable ignored) {
+ skipTasks = false
+ }
+ List<Task> tasks = skipTasks ? project.tasks.withType(AbstractTestTask.class).toList() as List<Task> : tasksFactory.getTasks(project).toList();
+ defaultExternalProject.tasks = getTasks(project, tasks)
defaultExternalProject.sourceCompatibility = getSourceCompatibility(project)
defaultExternalProject.targetCompatibility = getTargetCompatibility(project)
@@ -164,10 +175,10 @@ class ExternalProjectBuilderImpl extends AbstractModelBuilderService {
externalProject.setArtifactsByConfiguration(artifactsByConfiguration)
}
- static Map<String, DefaultExternalTask> getTasks(Project project, TasksFactory tasksFactory) {
+ static Map<String, DefaultExternalTask> getTasks(Project project, List<Task> tasks) { // Android Studio: b/235320590
def result = [:] as Map<String, DefaultExternalTask>
- for (Task task in tasksFactory.getTasks(project)) {
+ for (Task task in tasks) { // Android Studio: b/235320590
DefaultExternalTask externalTask = result.get(task.name)
if (externalTask == null) {
externalTask = new DefaultExternalTask()
diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle
index 31d14d30dece..7c94af08b0f4 100644
--- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle
+++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle
@@ -49,9 +49,11 @@ class JetGradlePlugin implements Plugin<Gradle> {
if (jetModelBuilder != null) return jetModelBuilder
Gradle rootGradle = gradle
+/* Android Studio: KTIJ-21050, b/202448739
while (rootGradle.parent != null) {
rootGradle = rootGradle.parent
}
+Android Studio: KTIJ-21050, b/202448739 */
ToolingModelBuilderRegistry rootRegistry = (rootGradle as GradleInternal).services.get(ToolingModelBuilderRegistry)
jetModelBuilder = findJetModelBuilder(rootRegistry)
if(jetModelBuilder == null) {
@@ -95,9 +97,11 @@ class RegistryProcessor implements ProjectEvaluationListener {
void process(ToolingModelBuilderRegistry registry) {
ToolingModelBuilderRegistry rootRegistry = registry
+/* Android Studio: KTIJ-21050, b/202448739
while (rootRegistry.hasProperty('parent') && rootRegistry.parent != null) {
rootRegistry = rootRegistry.parent
}
+Android Studio: KTIJ-21050, b/202448739 */
boolean alreadySeen = !processedRegistries.addIfAbsent(rootRegistry)
if (alreadySeen || extraModelBuilderIsRegistered(rootRegistry)) {
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java
index 062f4e32255b..38b409ceccd0 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java
@@ -187,6 +187,14 @@ public class MissingReturnInspection extends GroovyLocalInspectionTool {
if (!lastChild.isValid() || !lastChild.isPhysical() || range.getStartOffset() >= range.getEndOffset()) {
return;
}
+
+ // Android Studio: Don't report these errors in build.gradle files;
+ // they're usually wrong
+ PsiFile containingFile = lastChild.getContainingFile();
+ if (containingFile != null && containingFile.getName().endsWith(".gradle")) {
+ return;
+ }
+
holder.registerProblem(lastChild, GroovyBundle.message("no.return.message"));
}
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 99f36e4ac0fa..f6c0841b0771 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -384,7 +384,10 @@
<runLineMarkerContributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.testIntegration.GroovyAppLineMarkerContributor"/>
<constructorBodyGenerator language="Groovy"
implementationClass="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.GrConstructorBodyGenerator"/>
+ <!-- In Android Studio, we don't want editor notifications to setup Groovy Path when *.gradle files are opened. This is a temporary
+ hack to remove this until we figure out how to disable it just for gradle scripts.
<editorNotificationProvider implementation="org.jetbrains.plugins.groovy.config.ConfigureGroovyLibraryNotificationProvider"/>
+ -->
<refactoring.introduceParameterMethodUsagesProcessor
implementation="org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.GroovyIntroduceParameterMethodUsagesProcessor"/>
<refactoring.changeSignatureUsageProcessor
@@ -634,7 +637,9 @@
<!--Run/debug-->
<configurationType implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType"/>
+ <!-- Android Studio: disable Groovy script producer - we don't want this to be offered for random .gradle files, esp. build.gradle (Change I5983550c / commit ff49f5d)
<runConfigurationProducer implementation="org.jetbrains.plugins.groovy.runner.ScriptRunConfigurationProducer"/>
+ -->
<quoteHandler fileType="Groovy" className="org.jetbrains.plugins.groovy.editor.GroovyQuoteHandler"/>
@@ -781,11 +786,12 @@
groupKey="inspection.other" enabledByDefault="true"
implementationClass="org.jetbrains.plugins.groovy.codeInspection.resources.TypeCustomizerInspection"/>
+ <!-- Android Studio: Turned off by default. Lots of false positives in build.gradle files, the main use of Groovy in Studio -->
<localInspection language="Groovy"
groupPath="Groovy"
key="inspection.display.name.assignability.check"
groupKey="inspection.assignments"
- enabledByDefault="true"
+ enabledByDefault="false"
implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection"/>
<localInspection language="Groovy" groupPath="Groovy" key="inspection.display.name.result.of.assignment.used"
@@ -1224,9 +1230,10 @@
<localInspection language="Groovy" groupPath="Groovy" key="inspection.display.name.untyped.access"
groupKey="inspection.bugs"
implementationClass="org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection"/>
+ <!-- Android Studio: Turned off by default. Lots of false positives in build.gradle files, the main use of Groovy in Studio -->
<localInspection language="Groovy" groupPath="Groovy" key="inspection.display.name.unresolved.access"
groupKey="inspection.bugs"
- enabledByDefault="true" level="WEAK WARNING"
+ enabledByDefault="false" level="WEAK WARNING"
implementationClass="org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection"/>
<localInspection language="Groovy" groupPath="Groovy" groupKey="inspection.annotations"
diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml
index 3013b3c229ee..599364728a62 100644
--- a/plugins/maven/src/main/resources/META-INF/plugin.xml
+++ b/plugins/maven/src/main/resources/META-INF/plugin.xml
@@ -117,8 +117,10 @@
<externalSystemKeymapProvider implementation="org.jetbrains.idea.maven.tasks.MavenKeymapExtension"/>
<externalSystemWorkspaceContributor implementation="org.jetbrains.idea.maven.importing.MavenWorkspaceContributor"/>
<externalProjectWatcherContributor implementation="org.jetbrains.idea.maven.project.MavenProjectsManager$ExternalWatcherContributor"/>
+ <!-- Disabled in Android Studio
<configurationType implementation="org.jetbrains.idea.maven.execution.MavenRunConfigurationType"/>
<runConfigurationProducer implementation="org.jetbrains.idea.maven.execution.MavenConfigurationProducer"/>
+ -->
<orderEnumerationHandlerFactory implementation="org.jetbrains.idea.maven.execution.MavenOrderEnumeratorHandler$FactoryImpl"/>
<executionTargetLanguageRuntimeType implementation="org.jetbrains.idea.maven.execution.target.MavenRuntimeType" />
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertiesInheritorsSearcher.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertiesInheritorsSearcher.java
index c123859634dc..fe6e17e6ec63 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertiesInheritorsSearcher.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/PropertiesInheritorsSearcher.java
@@ -25,6 +25,7 @@ import java.util.Objects;
public class PropertiesInheritorsSearcher extends QueryExecutorBase<PsiElement, DefinitionsScopedSearch.SearchParameters> {
private static final Logger LOG = Logger.getInstance(PropertiesInheritorsSearcher.class);
+ @SuppressWarnings("ReturnValueIgnored") // apparently abuses anyMatch for control flow, to short-circuit stream processing and return early
@Override
public void processQuery(@NotNull DefinitionsScopedSearch.SearchParameters queryParameters, @NotNull Processor<? super PsiElement> consumer) {
final PsiElement element = queryParameters.getElement();
diff --git a/plugins/webp/lib/libwebp/mac/libwebp_jni64.dylib b/plugins/webp/lib/libwebp/mac/libwebp_jni64.dylib
index 5400547a53b2..5f20b70421c9 100755
--- a/plugins/webp/lib/libwebp/mac/libwebp_jni64.dylib
+++ b/plugins/webp/lib/libwebp/mac/libwebp_jni64.dylib
Binary files differ
diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml
index bd5e0d521ecf..e5454fbc3bc5 100644
--- a/resources/src/idea/JavaActions.xml
+++ b/resources/src/idea/JavaActions.xml
@@ -369,9 +369,11 @@
correctly labeled -->
<action id="AnonymousToInner" class="com.intellij.refactoring.actions.AnonymousToInnerAction"/>
+ <!-- Not available in Android Studio yet, don't clutter menu
<action id="Hotswap" class="com.intellij.debugger.actions.HotSwapAction">
<add-to-group group-id="DebugReloadGroup" anchor="last"/>
</action>
+ -->
<action id="RunToolbarHotSwapAction" class="com.intellij.debugger.actions.RunToolbarHotSwapAction" icon="com.intellij.icons.AllIcons.Actions.BuildAutoReloadChanges">
<add-to-group group-id="RunToolbarAdditionalProcessActions"/>
diff --git a/updater/intellij.platform.updater.iml b/updater/intellij.platform.updater.iml
index 64a5a353f41b..ee4827514fe9 100644
--- a/updater/intellij.platform.updater.iml
+++ b/updater/intellij.platform.updater.iml
@@ -12,5 +12,25 @@
<orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="library" scope="TEST" name="assertJ" level="project" />
- </component>
+ <orderEntry type="module-library">
+ <library name="javaxdelta" type="repository">
+ <properties maven-id="com.nothome:javaxdelta:2.0.1" />
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/com/nothome/javaxdelta/2.0.1/javaxdelta-2.0.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library" scope="RUNTIME">
+ <library name="fastutil" type="repository">
+ <properties maven-id="it.unimi.dsi:fastutil:8.4.0" />
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/it/unimi/dsi/fastutil/8.4.0/fastutil-8.4.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ </component>
</module> \ No newline at end of file
diff --git a/updater/src/com/intellij/updater/BaseUpdateAction.java b/updater/src/com/intellij/updater/BaseUpdateAction.java
index a2c9a0294c30..3d2d0c32d943 100644
--- a/updater/src/com/intellij/updater/BaseUpdateAction.java
+++ b/updater/src/com/intellij/updater/BaseUpdateAction.java
@@ -33,8 +33,6 @@ import static com.intellij.updater.Runner.LOG;
* </p>
*/
public abstract class BaseUpdateAction extends PatchAction {
- private static final byte RAW = 0;
- private static final byte COMPRESSED = 1;
private final String mySource;
private final boolean myIsMove;
@@ -144,45 +142,24 @@ public abstract class BaseUpdateAction extends PatchAction {
}
protected void writeDiff(InputStream olderFileIn, InputStream newerFileIn, OutputStream patchOutput) throws IOException {
- if (isCritical()) {
- LOG.info("critical: " + mySource);
-
- patchOutput.write(RAW);
- Utils.copyStream(newerFileIn, patchOutput);
-
- return;
- }
-
- LOG.info(mySource);
- ByteArrayOutputStream diffOutput = new OpenByteArrayOutputStream();
- byte[] newerFileBuffer = JBDiff.bsdiff(olderFileIn, newerFileIn, diffOutput, myPatch.getTimeout());
- diffOutput.close();
+ DiffAlgorithm algorithm = DiffAlgorithm.determineDiffAlgorithm(null, null, isCritical(), myPatch.getLargeFileCutoff());
+ patchOutput.write(algorithm.getId());
+ algorithm.writeDiff(olderFileIn, newerFileIn, patchOutput);
+ }
- int diffSize = diffOutput.size();
- if (0 < diffSize && diffSize < newerFileBuffer.length) {
- patchOutput.write(COMPRESSED);
- diffOutput.writeTo(patchOutput);
- }
- else {
- patchOutput.write(RAW);
- Utils.writeBytes(newerFileBuffer, newerFileBuffer.length, patchOutput);
- if (diffSize == 0 && newerFileBuffer.length != 0) {
- LOG.warning("*** 'bsdiff' timed out, dumping the file as-is");
- }
- }
+ private static DiffAlgorithm readDiffAlgorithm(InputStream patchInput) throws IOException {
+ int type = patchInput.read();
+ return DiffAlgorithm.getAlgorithmForId(type);
}
protected void applyDiff(InputStream patchInput, InputStream oldFileIn, OutputStream toFileOut) throws IOException {
- int type = patchInput.read();
- if (type == COMPRESSED) {
- JBPatch.bspatch(oldFileIn, toFileOut, patchInput);
- }
- else if (type == RAW) {
- Utils.copyStream(patchInput, toFileOut);
- }
- else {
- throw new IOException("Corrupted patch");
- }
+ DiffAlgorithm algorithm = readDiffAlgorithm(patchInput);
+ algorithm.applyDiff(patchInput, oldFileIn, toFileOut);
+ }
+
+ protected void applyDiff(InputStream patchInput, File oldFileIn, OutputStream toFileOut) throws IOException {
+ DiffAlgorithm algorithm = readDiffAlgorithm(patchInput);
+ algorithm.applyDiff(patchInput, oldFileIn, toFileOut);
}
@Override
diff --git a/updater/src/com/intellij/updater/CreateAction.java b/updater/src/com/intellij/updater/CreateAction.java
index e9e5580fadb4..338ed63199a8 100644
--- a/updater/src/com/intellij/updater/CreateAction.java
+++ b/updater/src/com/intellij/updater/CreateAction.java
@@ -57,7 +57,7 @@ public class CreateAction extends PatchAction {
? new ValidationResult.Option[]{ValidationResult.Option.REPLACE}
: new ValidationResult.Option[]{ValidationResult.Option.REPLACE, ValidationResult.Option.KEEP};
String message = ValidationResult.ALREADY_EXISTS_MESSAGE, details = "checksum 0x" + Long.toHexString(myPatch.digestFile(toFile, myPatch.isNormalized()));
- return new ValidationResult(ValidationResult.Kind.CONFLICT, getPath(), ValidationResult.Action.CREATE, message, details, options);
+ return new ValidationResult(ValidationResult.Kind.CONFLICT, getPath(), toFile, ValidationResult.Action.CREATE, message, details, options);
}
return null;
}
diff --git a/updater/src/com/intellij/updater/DeleteAction.java b/updater/src/com/intellij/updater/DeleteAction.java
index f508e939f1ad..316c3dbc9531 100644
--- a/updater/src/com/intellij/updater/DeleteAction.java
+++ b/updater/src/com/intellij/updater/DeleteAction.java
@@ -40,12 +40,12 @@ public class DeleteAction extends PatchAction {
if (getChecksum() == Digester.INVALID) {
ValidationResult.Action action = ValidationResult.Action.VALIDATE;
String details = "checksum 0x" + Long.toHexString(myPatch.digestFile(toFile, myPatch.isNormalized()));
- return new ValidationResult(ValidationResult.Kind.CONFLICT, getPath(), action, "Unexpected file", details, options);
+ return new ValidationResult(ValidationResult.Kind.CONFLICT, getPath(), toFile, action, "Unexpected file", details, options);
}
else {
ValidationResult.Action action = ValidationResult.Action.DELETE;
String details = "expected 0x" + Long.toHexString(getChecksum()) + ", actual 0x" + Long.toHexString(myPatch.digestFile(toFile, myPatch.isNormalized()));
- return new ValidationResult(ValidationResult.Kind.CONFLICT, getPath(), action, ValidationResult.MODIFIED_MESSAGE, details, options);
+ return new ValidationResult(ValidationResult.Kind.CONFLICT, getPath(), toFile, action, ValidationResult.MODIFIED_MESSAGE, details, options);
}
}
diff --git a/updater/src/com/intellij/updater/DiffAlgorithm.java b/updater/src/com/intellij/updater/DiffAlgorithm.java
new file mode 100644
index 000000000000..f84f72d89afb
--- /dev/null
+++ b/updater/src/com/intellij/updater/DiffAlgorithm.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2000-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.updater;
+
+import com.intellij.updater.Utils.OpenByteArrayOutputStream;
+import com.nothome.delta.Delta;
+import com.nothome.delta.GDiffPatcher;
+import com.nothome.delta.GDiffWriter;
+import com.nothome.delta.RandomAccessFileSeekableSource;
+import ie.wombat.jbdiff.JBDiff;
+import ie.wombat.jbdiff.JBPatch;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+
+public abstract class DiffAlgorithm {
+ private static final byte RAW = 0;
+ private static final byte COMPRESSED = 1;
+ private static final byte X_DELTA = 2;
+
+ public abstract void writeDiff(InputStream oldFileIn, InputStream newFileIn, OutputStream diffFileOut) throws IOException;
+ public abstract void writeDiff(File olderFile, File newerFile, OutputStream patchOutput) throws IOException;
+
+ public abstract void applyDiff(InputStream patchInput, File oldFileIn, OutputStream toFileOut) throws IOException;
+ public abstract void applyDiff(InputStream patchInput, InputStream oldFileIn, OutputStream toFileOut) throws IOException;
+
+ public abstract int getId();
+
+ public static DiffAlgorithm getAlgorithmForId(int type) {
+ switch (type) {
+ case RAW:
+ return new DiffAlgorithm.NullDiffAlgorithm();
+ case COMPRESSED:
+ return new DiffAlgorithm.JBDiffAlgorithm();
+ case X_DELTA:
+ return new DiffAlgorithm.XDeltaAlgorithm();
+ default:
+ return null;
+ }
+ }
+
+ public static DiffAlgorithm determineDiffAlgorithm(File olderFile, boolean isCritical, long largeFileCutoff) {
+ return determineDiffAlgorithm(olderFile, null, isCritical, largeFileCutoff);
+ }
+
+ public static DiffAlgorithm determineDiffAlgorithm(File olderFile, File newerFile, boolean isCritical, long largeFileCutoff) {
+ if (isCritical) {
+ return new DiffAlgorithm.NullDiffAlgorithm();
+ }
+ else if ((olderFile != null && olderFile.length() > largeFileCutoff) ||
+ (newerFile != null && newerFile.length() > largeFileCutoff)) {
+ return new DiffAlgorithm.XDeltaAlgorithm();
+ }
+ else {
+ return new DiffAlgorithm.JBDiffAlgorithm();
+ }
+ }
+
+ private static class JBDiffAlgorithm extends DiffAlgorithm {
+
+ @Override
+ public void writeDiff(InputStream oldFileIn, InputStream newFileIn, OutputStream diffFileOut) throws IOException {
+ ByteArrayOutputStream diffOutput = new OpenByteArrayOutputStream();
+ byte[] newerFileBuffer = JBDiff.bsdiff(oldFileIn, newFileIn, diffOutput, 0);
+ diffOutput.close();
+
+ if (diffOutput.size() < newerFileBuffer.length) {
+ diffFileOut.write(COMPRESSED);
+ diffOutput.writeTo(diffFileOut);
+ }
+ else {
+ diffFileOut.write(RAW);
+ Utils.writeBytes(newerFileBuffer, newerFileBuffer.length, diffFileOut);
+ }
+ }
+
+ @Override
+ public void writeDiff(File olderFile, File newerFile, OutputStream patchOutput) throws IOException {
+ try (InputStream oldFileIn = new BufferedInputStream(new FileInputStream(olderFile));
+ InputStream newFileIn = new BufferedInputStream(new FileInputStream(newerFile))) {
+ writeDiff(oldFileIn, newFileIn, patchOutput);
+ }
+ }
+
+ @Override
+ public void applyDiff(InputStream patchInput, File olderFile, OutputStream toFileOut) throws IOException {
+ InputStream oldFileIn = null;
+ try {
+ oldFileIn = new BufferedInputStream(new FileInputStream(olderFile));
+ applyDiff(patchInput, oldFileIn, toFileOut);
+ }
+ finally {
+ if (oldFileIn != null) {
+ oldFileIn.close();
+ }
+ }
+ }
+
+ @Override
+ public void applyDiff(InputStream patchInput, InputStream oldFileIn, OutputStream toFileOut) throws IOException {
+ int type = patchInput.read();
+ if (type == COMPRESSED) {
+ JBPatch.bspatch(oldFileIn, toFileOut, patchInput);
+ }
+ else if (type == RAW) {
+ new NullDiffAlgorithm().applyDiff(patchInput, oldFileIn, toFileOut);
+ }
+ else {
+ throw new IOException("Corrupted patch");
+ }
+ }
+
+ @Override
+ public int getId() {
+ return COMPRESSED;
+ }
+ }
+
+ private static class XDeltaAlgorithm extends DiffAlgorithm {
+
+ @Override
+ public void writeDiff(InputStream oldFileIn, InputStream newFileIn, OutputStream diffFileOut) throws IOException {
+ throw new UnsupportedOperationException("XDelta can only diff files.");
+ }
+
+ @Override
+ public void writeDiff(File olderFile, File newerFile, OutputStream patchOutput) throws IOException {
+ Delta delta = new Delta();
+ delta.compute(olderFile, newerFile, new GDiffWriter(patchOutput));
+ }
+
+ @Override
+ public void applyDiff(InputStream patchInput, File oldFileIn, OutputStream toFileOut) throws IOException {
+ GDiffPatcher patcher = new GDiffPatcher();
+ patcher.patch(new RandomAccessFileSeekableSource(new RandomAccessFile(oldFileIn, "r")), patchInput, toFileOut);
+ }
+
+ @Override
+ public void applyDiff(InputStream patchInput, InputStream oldFileIn, OutputStream toFileOut) throws IOException {
+ Path temp = null;
+ try {
+ temp = Files.createTempFile("updater", "diff");
+ Files.copy(oldFileIn, temp, StandardCopyOption.REPLACE_EXISTING);
+ applyDiff(patchInput, temp.toFile(), toFileOut);
+ }
+ finally {
+ Files.delete(temp);
+ }
+ }
+
+ @Override
+ public int getId() {
+ return X_DELTA;
+ }
+ }
+
+ private static class NullDiffAlgorithm extends DiffAlgorithm {
+ @Override
+ public void writeDiff(InputStream oldFileIn, InputStream newFileIn, OutputStream diffFileOut) throws IOException {
+ Utils.copyStream(newFileIn, diffFileOut);
+ }
+
+ @Override
+ public void writeDiff(File olderFile, File newerFile, OutputStream patchOutput) throws IOException {
+ BufferedInputStream newFileIn = null;
+ try {
+ newFileIn = new BufferedInputStream(new FileInputStream(newerFile));
+ writeDiff(null, newFileIn, patchOutput);
+ }
+ finally {
+ if (newFileIn != null) {
+ newFileIn.close();
+ }
+ }
+ }
+
+ @Override
+ public void applyDiff(InputStream patchInput, File oldFileIn, OutputStream toFileOut) throws IOException {
+ applyDiff(patchInput, (InputStream)null, toFileOut);
+ }
+
+ @Override
+ public void applyDiff(InputStream patchInput, InputStream oldFileIn, OutputStream toFileOut) throws IOException {
+ Utils.copyStream(patchInput, toFileOut);
+ }
+
+ @Override
+ public int getId() {
+ return RAW;
+ }
+ }
+}
diff --git a/updater/src/com/intellij/updater/Digester.java b/updater/src/com/intellij/updater/Digester.java
index 4b22049d8f91..c308f2eecf1c 100644
--- a/updater/src/com/intellij/updater/Digester.java
+++ b/updater/src/com/intellij/updater/Digester.java
@@ -7,11 +7,14 @@ import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.CRC32;
+import java.util.zip.Checksum;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
@@ -32,7 +35,13 @@ public class Digester {
return (digest & SYM_LINK) == SYM_LINK;
}
- public static long digestRegularFile(File file, boolean normalize) throws IOException {
+ private final String myAlgorithm;
+
+ public Digester(String algorithm) {
+ myAlgorithm = algorithm;
+ }
+
+ public long digestRegularFile(File file, boolean normalize) throws IOException {
Path path = file.toPath();
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
@@ -53,7 +62,7 @@ public class Digester {
}
}
- public static long digestZipFile(File file) throws IOException {
+ public long digestZipFile(File file) throws IOException {
ZipFile zipFile;
try {
zipFile = new ZipFile(file);
@@ -75,30 +84,86 @@ public class Digester {
sorted.sort(Comparator.comparing(ZipEntry::getName));
- CRC32 crc = new CRC32();
+ Checksum checksum = createChecksum(myAlgorithm);
for (ZipEntry each : sorted) {
try (InputStream in = zipFile.getInputStream(each)) {
- doDigestStream(in, crc);
+ doDigestStream(in, checksum);
}
}
- return crc.getValue();
+ return checksum.getValue();
}
finally {
zipFile.close();
}
}
- public static long digestStream(InputStream in) throws IOException {
- CRC32 crc = new CRC32();
- doDigestStream(in, crc);
- return crc.getValue();
+ private static Checksum createChecksum(String algorithm) {
+ if (algorithm != null && !algorithm.equals("crc")) {
+ return new MessageDigestChecksum(algorithm);
+ }
+ return new CRC32();
}
- private static void doDigestStream(InputStream in, CRC32 crc) throws IOException {
+ public long digestStream(InputStream in) throws IOException {
+ Checksum checksum = createChecksum(myAlgorithm);
+ doDigestStream(in, checksum);
+ return checksum.getValue();
+ }
+
+ private static void doDigestStream(InputStream in, Checksum checksum) throws IOException {
byte[] BUFFER = new byte[8192];
int size;
while ((size = in.read(BUFFER)) != -1) {
- crc.update(BUFFER, 0, size);
+ checksum.update(BUFFER, 0, size);
+ }
+ }
+
+ public static boolean isValidAlgorithm(String hashAlgorithm) {
+ try {
+ //noinspection ConstantConditions // Throws exception if not
+ return createChecksum(hashAlgorithm) != null;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static class MessageDigestChecksum implements Checksum {
+ private MessageDigest digest;
+
+ public MessageDigestChecksum(String algorithm) {
+ try {
+ digest = MessageDigest.getInstance(algorithm);
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new IllegalArgumentException("Algorithm must be verified using isValidAlgorithm() before creating a MessageDigestChecksum!");
+ }
+ }
+
+ @Override
+ public void update(int b) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void update(byte[] b, int off, int len) {
+ digest.update(b, off, len);
+ }
+
+ @Override
+ public long getValue() {
+ long result = 0;
+ long mult = 1;
+ for (byte b : digest.digest()) {
+ result += b * mult;
+ mult *= 256;
+ }
+ return result;
+ }
+
+ @Override
+ public void reset() {
+ digest.reset();
}
}
} \ No newline at end of file
diff --git a/updater/src/com/intellij/updater/Patch.java b/updater/src/com/intellij/updater/Patch.java
index e0652bd3f55e..f13549d0239c 100644
--- a/updater/src/com/intellij/updater/Patch.java
+++ b/updater/src/com/intellij/updater/Patch.java
@@ -2,6 +2,7 @@
package com.intellij.updater;
import java.io.*;
+import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
@@ -25,6 +26,9 @@ public class Patch {
private final boolean myIsBinary;
private final boolean myIsStrict;
private final boolean myIsNormalized;
+ private long myLargeFileCutoff;
+ private final String myHashAlgorithm;
+ private Digester myDigester;
private final Map<String, String> myWarnings;
private final List<String> myDeleteFiles;
private final int myTimeout;
@@ -37,6 +41,9 @@ public class Patch {
myIsBinary = spec.isBinary();
myIsStrict = spec.isStrict();
myIsNormalized = spec.isNormalized();
+ myHashAlgorithm = spec.getHashAlgorithm();
+ myDigester = new Digester(myHashAlgorithm);
+ myLargeFileCutoff = spec.getLargeFileCutoff();
myWarnings = spec.getWarnings();
myDeleteFiles = spec.getDeleteFiles();
myTimeout = spec.getTimeout();
@@ -51,12 +58,25 @@ public class Patch {
myIsBinary = in.readBoolean();
myIsStrict = in.readBoolean();
myIsNormalized = in.readBoolean();
+ myHashAlgorithm = readString(in);
+ if (!Digester.isValidAlgorithm(myHashAlgorithm)) {
+ throw new IOException("Failed to find hash algorithm!");
+ }
+ myDigester = new Digester(myHashAlgorithm);
+ myLargeFileCutoff = in.readLong();
myWarnings = readMap(in);
myDeleteFiles = readList(in);
myTimeout = 0;
myActions = readActions(in);
}
+ private static String readString(DataInputStream dataIn) throws IOException {
+ int len = dataIn.readInt();
+ byte[] bytes = new byte[len];
+ dataIn.readFully(bytes);
+ return new String(bytes, Charset.forName("UTF-8"));
+ }
+
private List<PatchAction> calculateActions(PatchSpec spec, UpdaterUI ui) throws IOException {
LOG.info("Calculating difference...");
ui.startProcess("Calculating difference...");
@@ -130,6 +150,8 @@ public class Patch {
dataOut.writeBoolean(myIsBinary);
dataOut.writeBoolean(myIsStrict);
dataOut.writeBoolean(myIsNormalized);
+ writeString(dataOut, myHashAlgorithm);
+ dataOut.writeLong(myLargeFileCutoff);
writeMap(dataOut, myWarnings);
writeList(dataOut, myDeleteFiles);
writeActions(dataOut, myActions);
@@ -139,6 +161,14 @@ public class Patch {
}
}
+ private static void writeString(DataOutputStream dataOut, String s) throws IOException {
+ byte[] bytes = s.getBytes(Charset.forName("UTF-8"));
+ dataOut.writeInt(bytes.length);
+ for (byte b : bytes) {
+ dataOut.write(b);
+ }
+ }
+
private static void writeList(DataOutputStream dataOut, List<String> list) throws IOException {
dataOut.writeInt(list.size());
for (String string : list) {
@@ -414,10 +444,10 @@ public class Patch {
public long digestFile(File toFile, boolean normalize) throws IOException {
if (!myIsBinary && Utils.isZipFile(toFile.getName())) {
- return Digester.digestZipFile(toFile);
+ return myDigester.digestZipFile(toFile);
}
else {
- return Digester.digestRegularFile(toFile, normalize);
+ return myDigester.digestRegularFile(toFile, normalize);
}
}
@@ -462,6 +492,14 @@ public class Patch {
return true;
}
+ public Digester getDigester() {
+ return myDigester;
+ }
+
+ public long getLargeFileCutoff() {
+ return myLargeFileCutoff;
+ }
+
public int getTimeout() {
return myTimeout;
}
diff --git a/updater/src/com/intellij/updater/PatchAction.java b/updater/src/com/intellij/updater/PatchAction.java
index 76204ef0e99e..1e37b4a80781 100644
--- a/updater/src/com/intellij/updater/PatchAction.java
+++ b/updater/src/com/intellij/updater/PatchAction.java
@@ -148,7 +148,7 @@ public abstract class PatchAction {
String problem = isWritable(toFile.toPath());
if (problem != null) {
ValidationResult.Option[] options = {myPatch.isStrict() ? ValidationResult.Option.NONE : ValidationResult.Option.IGNORE};
- return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), action, ValidationResult.ACCESS_DENIED_MESSAGE, problem, options);
+ return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), toFile, action, ValidationResult.ACCESS_DENIED_MESSAGE, problem, options);
}
}
return null;
@@ -177,7 +177,7 @@ public abstract class PatchAction {
List<NativeFileManager.Process> processes = NativeFileManager.getProcessesUsing(toFile);
if (processes.isEmpty()) return null;
String message = "Locked by: " + processes.stream().map(p -> "[" + p.pid + "] " + p.name).collect(Collectors.joining(", "));
- return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), action, message, ValidationResult.Option.KILL_PROCESS);
+ return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), toFile, action, message, ValidationResult.Option.KILL_PROCESS);
}
protected ValidationResult doValidateNotChanged(File toFile, ValidationResult.Action action) throws IOException {
@@ -201,12 +201,12 @@ public abstract class PatchAction {
}
}
String details = "expected 0x" + Long.toHexString(myChecksum) + ", actual 0x" + Long.toHexString(myPatch.digestFile(toFile, myPatch.isNormalized()));
- return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), action, ValidationResult.MODIFIED_MESSAGE, details, options);
+ return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), toFile, action, ValidationResult.MODIFIED_MESSAGE, details, options);
}
}
else if (!isOptional()) {
ValidationResult.Option[] options = {myPatch.isStrict() || isStrict() ? ValidationResult.Option.NONE : ValidationResult.Option.IGNORE};
- return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), action, ValidationResult.ABSENT_MESSAGE, options);
+ return new ValidationResult(ValidationResult.Kind.ERROR, getReportPath(), toFile, action, ValidationResult.ABSENT_MESSAGE, options);
}
return null;
diff --git a/updater/src/com/intellij/updater/PatchSpec.java b/updater/src/com/intellij/updater/PatchSpec.java
index ecb88222fe88..7c554efdb979 100644
--- a/updater/src/com/intellij/updater/PatchSpec.java
+++ b/updater/src/com/intellij/updater/PatchSpec.java
@@ -28,6 +28,8 @@ public class PatchSpec {
private String myJarFile;
private boolean myIsBinary;
private boolean myIsStrict;
+ private String myHashAlgorithm = "crc";
+ private long myLargeFileCutoff = Long.MAX_VALUE;
private List<String> myIgnoredFiles = Collections.emptyList();
private List<String> myCriticalFiles = Collections.emptyList();
// A conflict in an essential file makes a patch update impossible; the IDE must be reinstalled from scratch.
@@ -39,6 +41,9 @@ public class PatchSpec {
private String myRoot = "";
private int myTimeout = 0;
+ private static final long DEFAULT_LARGE_FILE_CUTOFF = 50000000L;
+
+
public String getOldVersionDescription() {
return myOldVersionDescription;
}
@@ -102,6 +107,21 @@ public class PatchSpec {
return this;
}
+ public PatchSpec setSupportLargeFiles(boolean supportLargeFiles) {
+ if (supportLargeFiles) {
+ myLargeFileCutoff = DEFAULT_LARGE_FILE_CUTOFF;
+ }
+ else {
+ myLargeFileCutoff = Long.MAX_VALUE;
+ }
+ return this;
+ }
+
+ PatchSpec setLargeFileCutoff(long cutoff) {
+ myLargeFileCutoff = cutoff;
+ return this;
+ }
+
public List<String> getIgnoredFiles() {
return myIgnoredFiles;
}
@@ -156,6 +176,17 @@ public class PatchSpec {
return this;
}
+ public PatchSpec setHashAlgorithm(String hashAlgorithm) {
+ if (hashAlgorithm != null) {
+ myHashAlgorithm = hashAlgorithm;
+ }
+ return this;
+ }
+
+ public String getHashAlgorithm() {
+ return myHashAlgorithm;
+ }
+
public PatchSpec setWarnings(Map<String, String> warnings) {
myWarnings = warnings;
return this;
@@ -191,4 +222,7 @@ public class PatchSpec {
myTimeout = timeout;
return this;
}
+ public long getLargeFileCutoff() {
+ return myLargeFileCutoff;
+ }
}
diff --git a/updater/src/com/intellij/updater/Runner.java b/updater/src/com/intellij/updater/Runner.java
index 919ee7a343d6..a559953c28fd 100644
--- a/updater/src/com/intellij/updater/Runner.java
+++ b/updater/src/com/intellij/updater/Runner.java
@@ -1,6 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.updater;
+import com.studio.updater.UpdaterService;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
@@ -61,7 +62,7 @@ public class Runner {
return logger;
}
- private static void initLogger() throws IOException {
+ public static void initLogger() throws IOException {
System.setProperty("java.util.logging.config.class", Object.class.getName());
String dirPath = System.getProperty("idea.updater.log", System.getProperty("java.io.tmpdir", System.getProperty("user.home", ".")));
@@ -107,10 +108,9 @@ public class Runner {
}
private static void _main(String[] args) {
- String jarFile = getArgument(args, "jar");
- if (jarFile == null) {
- jarFile = resolveJarFile();
- }
+ boolean includeJar = !Arrays.asList(args).contains("--no_jar");
+ String jarFile = includeJar ? getArgument(args, "jar") : null;
+ jarFile = includeJar && jarFile == null ? resolveJarFile() : jarFile;
if (args.length >= 6 && "create".equals(args[0])) {
String oldVersionDesc = args[1];
@@ -127,6 +127,14 @@ public class Runner {
boolean binary = hasArgument(args, "zip_as_binary");
boolean strict = hasArgument(args, "strict");
boolean normalized = hasArgument(args, "normalized");
+ String hashAlgorithm = getArgument(args, "hash_algorithm");
+ // Ensure the hashAlgorithm is valid
+ if (!Digester.isValidAlgorithm(hashAlgorithm)) {
+ //noinspection UseOfSystemOutOrSystemErr
+ System.err.println(hashAlgorithm + " is not a valid hash algorithm.");
+ System.exit(1);
+ }
+ boolean supportLargeFiles = Arrays.asList(args).contains("--large_files");
String root = getArgument(args, "root");
if (root == null) {
@@ -155,6 +163,8 @@ public class Runner {
.setPatchFile(patchFile)
.setJarFile(jarFile)
.setStrict(strict)
+ .setHashAlgorithm(hashAlgorithm)
+ .setSupportLargeFiles(supportLargeFiles)
.setBinary(binary)
.setNormalized(normalized)
.setIgnoredFiles(ignoredFiles)
@@ -170,6 +180,8 @@ public class Runner {
}
else if (args.length >= 2 && ("install".equals(args[0]) || "apply".equals(args[0])) ||
args.length >= 3 && ("batch-install".equals(args[0]))) {
+ // Android Studio: Analytics
+ for (UpdaterService service : UpdaterService.loader) { service.logProcessStart(); }
String destPath = args[1];
Path destDirectory = Paths.get(destPath);
@@ -187,7 +199,7 @@ public class Runner {
UpdaterUI ui;
if ("install".equals(args[0]) || "batch-install".equals(args[0])) {
- ui = new SwingUpdaterUI();
+ ui = new StandaloneSwingUpdaterUI();
}
else if (hasArgument(args, "toolbox-ui")) {
ui = new ToolboxUpdaterUI();
@@ -196,6 +208,9 @@ public class Runner {
ui = new ConsoleUpdaterUI();
}
+ // Android Studio: Analytics
+ for (UpdaterService service : UpdaterService.loader) { ui = service.wrap(ui); }
+
boolean backup = !hasArgument(args, "no-backup");
boolean success;
if (!Files.isDirectory(destDirectory, LinkOption.NOFOLLOW_LINKS)) {
@@ -209,6 +224,8 @@ public class Runner {
String[] patches = args[2].split(File.pathSeparator);
success = install(patches, destDirectory, ui, backup);
}
+ // Android Studio: Analytics
+ for (UpdaterService service : UpdaterService.loader) { service.logProcessFinish(success); }
System.exit(success ? 0 : 1);
}
else {
@@ -296,6 +313,14 @@ public class Runner {
" in a non-binary way to a fully binary patch. This will yield a larger patch, but\n" +
" the generated patch can be applied on versions where non-binary patches have been applied to and it\n" +
" guarantees that the patched version will match exactly the original one.\n" +
+ " --hash_algorithm=<hashAlgorithm>: The digest algorithm used to detect differences in files.\n" +
+ " hashAlgorithm can be any MessageDigest algorithm (MD5, SHA-1, SHA-256), or \n" +
+ " \"crc\" (the default).\n" +
+ " --large_files: Support large files. When encountering a large file, a slightly less-efficient but faster\n" +
+ " diffing algorithm will be used.\n" +
+ " --jar=<jar file>: Include the specified patcher code in the generated patch instead of the currently-running\n" +
+ " patcher jar.\n" +
+ " --no_jar: Do not include the patcher code in the generated patch.\n" +
" --timeout=<T> A time budget for building a 'bsdiff' patch between a pair of files, in seconds.\n" +
" If exceeded, the new version is included into the patch as a whole.\n" +
" <folder>: The folder where product was installed. For example: c:/Program Files/JetBrains/IntelliJ IDEA 2017.3.4");
@@ -312,11 +337,15 @@ public class Runner {
LOG.info("Packing JAR file: " + spec.getPatchFile());
ui.startProcess("Packing JAR file '" + spec.getPatchFile() + "'...");
- try (ZipOutputWrapper out = new ZipOutputWrapper(new FileOutputStream(spec.getPatchFile()));
- ZipInputStream in = new ZipInputStream(new FileInputStream(spec.getJarFile()))) {
- ZipEntry e;
- while ((e = in.getNextEntry()) != null) {
- out.zipEntry(e, in);
+ try (ZipOutputWrapper out = new ZipOutputWrapper(new FileOutputStream(spec.getPatchFile()))) {
+ String jarFile = spec.getJarFile();
+ if (jarFile != null) {
+ try (ZipInputStream in = new ZipInputStream(new FileInputStream(new File(jarFile)))) {
+ ZipEntry e;
+ while ((e = in.getNextEntry()) != null) {
+ out.zipEntry(e, in);
+ }
+ }
}
out.zipFile(PATCH_FILE_NAME, tempPatchFile);
@@ -356,6 +385,10 @@ public class Runner {
Utils.cleanup();
}
+ public static boolean doInstall(String jarFile, UpdaterUI ui, Path destFolder) {
+ return install(jarFile, destFolder, ui, false);
+ }
+
private static boolean install(String patch, Path dest, UpdaterUI ui, boolean doBackup) {
try {
PatchFileCreator.PreparationResult preparationResult;
@@ -399,6 +432,8 @@ public class Runner {
ui.bold("No files were changed. Please retry applying the patch.") + "\n\n" +
"More details in the log: " + logPath;
ui.showError(message);
+ // Android Studio: Analytics
+ for (UpdaterService service : UpdaterService.loader) { service.logException(); }
return false;
}
@@ -613,7 +648,7 @@ public class Runner {
}
}
- private static String resolveJarFile() {
+ public static String resolveJarFile() {
URL url = Runner.class.getResource("");
if (url == null) throw new IllegalArgumentException("Cannot resolve JAR file path");
if (!"jar".equals(url.getProtocol())) throw new IllegalArgumentException("Patch file is not a JAR file");
diff --git a/updater/src/com/intellij/updater/StandaloneSwingUpdaterUI.java b/updater/src/com/intellij/updater/StandaloneSwingUpdaterUI.java
new file mode 100644
index 000000000000..9254ea6e30b1
--- /dev/null
+++ b/updater/src/com/intellij/updater/StandaloneSwingUpdaterUI.java
@@ -0,0 +1,128 @@
+/*
+ * 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.updater;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+@SuppressWarnings({"UndesirableClassUsage", "UseJBColor", "UseDPIAwareInsets", "UseDPIAwareBorders"})
+public class StandaloneSwingUpdaterUI extends SwingUpdaterUI {
+ private static final EmptyBorder FRAME_BORDER = new EmptyBorder(8, 8, 8, 8);
+ private static final EmptyBorder BUTTONS_BORDER = new EmptyBorder(5, 0, 0, 0);
+
+ private final JLabel myProcessTitle;
+ private final JProgressBar myProcessProgress;
+ private final JLabel myProcessStatus;
+
+ private final JButton myCancelButton;
+ private final JFrame myFrame;
+
+ public StandaloneSwingUpdaterUI() {
+
+ myProcessTitle = new JLabel(" ");
+ myProcessProgress = new JProgressBar(0, 100);
+ myProcessStatus = new JLabel(" ");
+
+ myCancelButton = new JButton(CANCEL_BUTTON_TITLE);
+ myCancelButton.addActionListener(e -> doCancel());
+
+ JPanel processPanel = new JPanel();
+ processPanel.setLayout(new BoxLayout(processPanel, BoxLayout.Y_AXIS));
+ processPanel.add(myProcessTitle);
+ processPanel.add(myProcessProgress);
+ processPanel.add(myProcessStatus);
+ for (Component each : processPanel.getComponents()) {
+ ((JComponent)each).setAlignmentX(Component.LEFT_ALIGNMENT);
+ }
+
+ JPanel buttonsPanel = new JPanel();
+ buttonsPanel.setBorder(BUTTONS_BORDER);
+ buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
+ buttonsPanel.add(Box.createHorizontalGlue());
+ buttonsPanel.add(myCancelButton);
+
+ myFrame = new JFrame();
+ myFrame.setTitle(TITLE);
+ myFrame.setLayout(new BorderLayout());
+ myFrame.getRootPane().setBorder(FRAME_BORDER);
+ myFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+ myFrame.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ doCancel();
+ }
+ });
+ myFrame.add(processPanel, BorderLayout.CENTER);
+ myFrame.add(buttonsPanel, BorderLayout.SOUTH);
+ myFrame.setMinimumSize(new Dimension(500, 50));
+ myFrame.pack();
+ myFrame.setLocationRelativeTo(null);
+ myFrame.setVisible(true);
+
+ invokeAndWait(() -> {});
+ }
+
+ @Override
+ public void setDescription(String oldBuildDesc, String newBuildDesc) {
+ invokeLater(() -> myProcessTitle.setText("<html>Updating " + oldBuildDesc + " to " + newBuildDesc + "..."));
+ }
+
+ @Override
+ public void setDescription(String text) {
+ invokeLater(() -> myProcessTitle.setText(text.isEmpty() ? " " : text));
+ }
+
+ @Override
+ public void startProcess(String title) {
+ invokeLater(() -> {
+ myProcessStatus.setText(title);
+ myProcessProgress.setIndeterminate(false);
+ myProcessProgress.setValue(0);
+ });
+ }
+
+ @Override
+ public void setProgress(int percentage) {
+ invokeLater(() -> {
+ myProcessProgress.setIndeterminate(false);
+ myProcessProgress.setValue(percentage);
+ });
+ }
+
+ @Override
+ public void setProgressIndeterminate() {
+ invokeLater(() -> myProcessProgress.setIndeterminate(true));
+ }
+
+ @Override
+ public void checkCancelled() throws OperationCancelledException {
+ while (myPaused) Utils.pause(10);
+ if (myCancelled) throw new OperationCancelledException();
+ }
+
+ @Override
+ protected Component getParentComponent() {
+ return myFrame;
+ }
+
+ @Override
+ protected void notifyCancelled() {
+ myCancelButton.setEnabled(false);
+ }
+}
diff --git a/updater/src/com/intellij/updater/SwingUpdaterUI.java b/updater/src/com/intellij/updater/SwingUpdaterUI.java
index 83e065338705..372bf5df2bbd 100644
--- a/updater/src/com/intellij/updater/SwingUpdaterUI.java
+++ b/updater/src/com/intellij/updater/SwingUpdaterUI.java
@@ -7,8 +7,6 @@ import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel;
import java.awt.*;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -16,7 +14,7 @@ import java.util.List;
import java.util.Map;
@SuppressWarnings({"UseJBColor", "UseDPIAwareBorders", "HardCodedStringLiteral"})
-public class SwingUpdaterUI implements UpdaterUI {
+public abstract class SwingUpdaterUI implements UpdaterUI {
private static final EmptyBorder FRAME_BORDER = new EmptyBorder(8, 8, 8, 8);
private static final EmptyBorder LABEL_BORDER = new EmptyBorder(0, 0, 5, 0);
private static final EmptyBorder BUTTONS_BORDER = new EmptyBorder(5, 0, 0, 0);
@@ -24,78 +22,42 @@ public class SwingUpdaterUI implements UpdaterUI {
private static final Color VALIDATION_ERROR_COLOR = new Color(255, 175, 175);
private static final Color VALIDATION_CONFLICT_COLOR = new Color(255, 240, 240);
- private static final String TITLE = "Update";
- private static final String CANCEL_BUTTON_TITLE = "Cancel";
+ protected static final String TITLE = "Update";
+ protected static final String CANCEL_BUTTON_TITLE = "Cancel";
private static final String EXIT_BUTTON_TITLE = "Exit";
private static final String RETRY_BUTTON_TITLE = "Retry";
private static final String PROCEED_BUTTON_TITLE = "Proceed";
- private final JLabel myProcessTitle;
- private final JProgressBar myProcessProgress;
- private final JLabel myProcessStatus;
- private final JButton myCancelButton;
- private final JFrame myFrame;
-
- private volatile boolean myCancelled = false;
- private volatile boolean myPaused = false;
-
- public SwingUpdaterUI() {
- myProcessTitle = new JLabel(" ");
- myProcessProgress = new JProgressBar(0, 100);
- myProcessStatus = new JLabel(" ");
-
- myCancelButton = new JButton(CANCEL_BUTTON_TITLE);
- myCancelButton.addActionListener(e -> doCancel());
-
- JPanel processPanel = new JPanel();
- processPanel.setLayout(new BoxLayout(processPanel, BoxLayout.Y_AXIS));
- processPanel.add(myProcessTitle);
- processPanel.add(myProcessProgress);
- processPanel.add(myProcessStatus);
- for (Component each : processPanel.getComponents()) {
- ((JComponent)each).setAlignmentX(Component.LEFT_ALIGNMENT);
- }
+ protected volatile boolean myCancelled = false;
+ protected volatile boolean myPaused = false;
+
+ protected abstract Component getParentComponent();
+ protected abstract void notifyCancelled();
- JPanel buttonsPanel = new JPanel();
- buttonsPanel.setBorder(BUTTONS_BORDER);
- buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
- buttonsPanel.add(Box.createHorizontalGlue());
- buttonsPanel.add(myCancelButton);
-
- myFrame = new JFrame();
- myFrame.setTitle(TITLE);
- myFrame.setLayout(new BorderLayout());
- myFrame.getRootPane().setBorder(FRAME_BORDER);
- myFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
- myFrame.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- doCancel();
+ private static Window getParentWindow(Component component) {
+ while (component != null) {
+ if (component instanceof Frame || component instanceof Dialog) {
+ return (Window)component;
}
- });
- myFrame.add(processPanel, BorderLayout.CENTER);
- myFrame.add(buttonsPanel, BorderLayout.SOUTH);
- myFrame.setMinimumSize(new Dimension(500, 50));
- myFrame.pack();
- myFrame.setLocationRelativeTo(null);
- myFrame.setVisible(true);
-
- invokeAndWait(() -> {});
+ component = component.getParent();
+ }
+ return null;
}
- private void doCancel() {
+ protected void doCancel() {
if (!myCancelled) {
myPaused = true;
String message = "The patch has not been applied yet.\nAre you sure you want to abort the operation?";
- int result = JOptionPane.showConfirmDialog(myFrame, message, TITLE, JOptionPane.YES_NO_OPTION);
+ int result = JOptionPane.showConfirmDialog(getParentComponent(), message, TITLE, JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
myCancelled = true;
- myCancelButton.setEnabled(false);
+ notifyCancelled();
}
myPaused = false;
}
}
+/* Android Studio: removed by Change Ia67907f7 / commit 82a9fb9
@Override
public void setDescription(String oldBuildDesc, String newBuildDesc) {
setDescription("Updating " + oldBuildDesc + " to " + newBuildDesc + " ...");
@@ -127,6 +89,7 @@ public class SwingUpdaterUI implements UpdaterUI {
public void setProgressIndeterminate() {
invokeLater(() -> myProcessProgress.setIndeterminate(true));
}
+Android Studio: removed by Change Ia67907f7 / commit 82a9fb9 */
@Override
public void checkCancelled() throws OperationCancelledException {
@@ -137,7 +100,8 @@ public class SwingUpdaterUI implements UpdaterUI {
@Override
public void showError(String message) {
String html = "<html>" + message.replace("\n", "<br>") + "</html>";
- invokeAndWait(() -> JOptionPane.showMessageDialog(myFrame, html, "Update Error", JOptionPane.ERROR_MESSAGE));
+ // Android Studio: modified by Change Ia67907f7 / commit 82a9fb9
+ invokeAndWait(() -> JOptionPane.showMessageDialog(getParentComponent(), html, "Update Error", JOptionPane.ERROR_MESSAGE));
}
@Override
@@ -147,11 +111,11 @@ public class SwingUpdaterUI implements UpdaterUI {
Object[] choices = {RETRY_BUTTON_TITLE, EXIT_BUTTON_TITLE};
int choice = JOptionPane.showOptionDialog(
- myFrame, message, TITLE, JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
+ getParentComponent(), message, TITLE, JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
if (choice != 0) {
myCancelled = true;
- myCancelButton.setEnabled(false);
+ notifyCancelled();
}
});
@@ -166,7 +130,7 @@ public class SwingUpdaterUI implements UpdaterUI {
invokeAndWait(() -> {
if (myCancelled) return;
- JDialog dialog = new JDialog(myFrame, TITLE, true);
+ JDialog dialog = new JDialog(getParentWindow(getParentComponent()), TITLE, Dialog.DEFAULT_MODALITY_TYPE);
dialog.setLayout(new BorderLayout());
dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
@@ -178,7 +142,7 @@ public class SwingUpdaterUI implements UpdaterUI {
JButton cancelButton = new JButton(CANCEL_BUTTON_TITLE);
cancelButton.addActionListener(e -> {
myCancelled = true;
- myCancelButton.setEnabled(false);
+ notifyCancelled();
dialog.setVisible(false);
});
buttonsPanel.add(cancelButton);
@@ -242,11 +206,11 @@ public class SwingUpdaterUI implements UpdaterUI {
return "<b>" + text + "</b>";
}
- private static void invokeLater(Runnable runnable) {
+ protected static void invokeLater(Runnable runnable) {
SwingUtilities.invokeLater(runnable);
}
- private static void invokeAndWait(Runnable runnable) {
+ protected static void invokeAndWait(Runnable runnable) {
try {
SwingUtilities.invokeAndWait(runnable);
}
@@ -371,6 +335,12 @@ public class SwingUpdaterUI implements UpdaterUI {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component result = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+/* Android Studio: Do not customize background colors as everything in that table is an issue, so colors do not add
+ any additional information for the user, but may have suboptimal contrast levels in Darcula.
+ See also com.android.tools.idea.sdk.updater.RepoUpdaterUI, which inherits from this class.
+
+ Issue: https://issuetracker.google.com/issues/112324902
+
if (!isSelected) {
ValidationResult.Kind kind = ((MyTableModel)table.getModel()).getKind(row);
if (kind == ValidationResult.Kind.ERROR) {
@@ -380,7 +350,7 @@ public class SwingUpdaterUI implements UpdaterUI {
result.setBackground(VALIDATION_CONFLICT_COLOR);
}
}
-
+end of Android Studio block: Do not customize background colors, https://issuetracker.google.com/issues/112324902 */
return result;
}
}
diff --git a/updater/src/com/intellij/updater/UpdateZipAction.java b/updater/src/com/intellij/updater/UpdateZipAction.java
index 2f3de6006f7a..9af2a570754f 100644
--- a/updater/src/com/intellij/updater/UpdateZipAction.java
+++ b/updater/src/com/intellij/updater/UpdateZipAction.java
@@ -74,8 +74,8 @@ public class UpdateZipAction extends BaseUpdateAction {
@Override
protected boolean doCalculate(File olderFile, File newerFile) throws IOException {
Map<String, Long> oldCheckSums = new HashMap<>(), newCheckSums = new HashMap<>();
- processZipFile(olderFile, (entry, in) -> oldCheckSums.put(entry.getName(), Digester.digestStream(in)));
- processZipFile(newerFile, (entry, in) -> newCheckSums.put(entry.getName(), Digester.digestStream(in)));
+ processZipFile(olderFile, (entry, in) -> oldCheckSums.put(entry.getName(), myPatch.getDigester().digestStream(in)));
+ processZipFile(newerFile, (entry, in) -> newCheckSums.put(entry.getName(), myPatch.getDigester().digestStream(in)));
DiffCalculator.Result diff = DiffCalculator.calculate(oldCheckSums, newCheckSums);
myFilesToCreate = diff.filesToCreate.keySet();
diff --git a/updater/src/com/intellij/updater/ValidationResult.java b/updater/src/com/intellij/updater/ValidationResult.java
index 4f5867aec244..bb6ac73542db 100644
--- a/updater/src/com/intellij/updater/ValidationResult.java
+++ b/updater/src/com/intellij/updater/ValidationResult.java
@@ -1,6 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.updater;
+import java.io.File;
import java.util.Arrays;
import java.util.List;
@@ -35,18 +36,20 @@ public class ValidationResult implements Comparable<ValidationResult> {
public final Kind kind;
public final String path;
+ public final File toFile;
public final Action action;
public final String message;
public final String details;
public final List<Option> options;
- public ValidationResult(Kind kind, String path, Action action, String message, Option... options) {
- this(kind, path, action, message, "", options);
+ public ValidationResult(Kind kind, String path, File toFile, Action action, String message, Option... options) {
+ this(kind, path, toFile, action, message, "", options);
}
- public ValidationResult(Kind kind, String path, Action action, String message, String details, Option... options) {
+ public ValidationResult(Kind kind, String path, File toFile, Action action, String message, String details, Option... options) {
this.kind = kind;
this.path = path;
+ this.toFile = toFile;
this.action = action;
this.message = message;
this.details = details;
diff --git a/updater/src/com/studio/updater/ConsolePatcher.java b/updater/src/com/studio/updater/ConsolePatcher.java
new file mode 100644
index 000000000000..7b59dba18652
--- /dev/null
+++ b/updater/src/com/studio/updater/ConsolePatcher.java
@@ -0,0 +1,40 @@
+package com.studio.updater;
+
+import com.intellij.updater.*;
+import java.nio.file.Paths;
+
+/**
+ * This class performs the install of an intellij patch. Patches are to be created by the {@link Runner} and can then be applied
+ * using this program. The arguments for this program follow the same argument structure as the {@link Runner}. The primary difference
+ * is the DISPLAY is not required when applying a patch via this class. The intended use of this program is to apply patches where the Java
+ * environment argument DISPLAY is set to empty, as it is in either automation, or on a build server.
+ *
+ * Usage: java --classpath updater.jar com.studio.updater.ConsolePatcher install ../path/to/studio --jar=../path/to/jar.jar
+ */
+public class ConsolePatcher {
+
+ public static void main(String[] args) throws Exception {
+ String jarFile = Runner.getArgument(args, "jar");
+ jarFile = jarFile == null ? Runner.resolveJarFile() : jarFile;
+ if (args.length >= 2 && "install".equals(args[0])) {
+ String destFolder = args[1];
+ UpdaterUI ui = new ConsoleUpdaterUI();
+ Runner.initLogger();
+ Runner.doInstall(jarFile, ui, Paths.get(destFolder));
+ }
+ else {
+ printUsage();
+ }
+ }
+
+ @SuppressWarnings("UseOfSystemOutOrSystemErr")
+ private static void printUsage() {
+ System.err.println(
+ "Usage:\n" +
+ " ConsolePatcher install <folder> --jar=<jar file>\n" +
+ "\n" +
+ "Where:\n" +
+ " <folder>: The folder where to find the old version.\n" +
+ " --jar=<jar file>: Include the specified patcher code in the generated patch instead of the currently-running");
+ }
+}
diff --git a/updater/src/com/studio/updater/UpdaterService.java b/updater/src/com/studio/updater/UpdaterService.java
new file mode 100644
index 000000000000..bc1fb562d4d0
--- /dev/null
+++ b/updater/src/com/studio/updater/UpdaterService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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.studio.updater;
+
+import com.intellij.updater.UpdaterUI;
+import java.util.ServiceLoader;
+
+public abstract class UpdaterService {
+
+ public static ServiceLoader<UpdaterService> loader
+ = ServiceLoader.load(UpdaterService.class);
+
+ public abstract void logProcessStart();
+
+ public abstract UpdaterUI wrap(UpdaterUI ui);
+
+ public abstract void logProcessFinish(boolean success);
+
+ public abstract void logException();
+}
diff --git a/updater/testSrc/com/intellij/updater/DigesterTest.java b/updater/testSrc/com/intellij/updater/DigesterTest.java
index ba37f7e1f3b8..7ae6211c1f12 100644
--- a/updater/testSrc/com/intellij/updater/DigesterTest.java
+++ b/updater/testSrc/com/intellij/updater/DigesterTest.java
@@ -15,23 +15,39 @@ import static org.junit.Assume.assumeFalse;
public class DigesterTest extends UpdaterTestCase {
@Test
public void testBasics() throws Exception {
+ Digester digester = new Digester(null);
File binDir = new File(dataDir, "bin"), libDir = new File(dataDir, "lib");
- assertEquals(Digester.DIRECTORY, Digester.digestRegularFile(binDir, false));
- assertEquals(Digester.DIRECTORY, Digester.digestRegularFile(libDir, true));
-
- assertEquals(CHECKSUMS.README_TXT, Digester.digestRegularFile(new File(dataDir, "Readme.txt"), false));
- assertEquals(CHECKSUMS.BOOTSTRAP_JAR_BIN, Digester.digestRegularFile(new File(libDir, "bootstrap.jar"), false));
- assertEquals(CHECKSUMS.ANNOTATIONS_JAR, Digester.digestRegularFile(new File(libDir, "annotations.jar"), true));
- assertEquals(CHECKSUMS.ANNOTATIONS_CHANGED_JAR, Digester.digestRegularFile(new File(libDir, "annotations_changed.jar"), true));
- assertEquals(CHECKSUMS.BOOT_JAR, Digester.digestRegularFile(new File(libDir, "boot.jar"), true));
- assertEquals(CHECKSUMS.BOOT2_JAR, Digester.digestRegularFile(new File(libDir, "boot2.jar"), true));
- assertEquals(CHECKSUMS.BOOT2_CHANGED_WITH_UNCHANGED_CONTENT_JAR, Digester.digestRegularFile(new File(libDir, "boot2_changed_with_unchanged_content.jar"), true));
- assertEquals(CHECKSUMS.BOOT_WITH_DIRECTORY_BECOMES_FILE_JAR, Digester.digestRegularFile(new File(libDir, "boot_with_directory_becomes_file.jar"), true));
- assertEquals(CHECKSUMS.BOOTSTRAP_JAR, Digester.digestRegularFile(new File(libDir, "bootstrap.jar"), true));
- assertEquals(CHECKSUMS.BOOTSTRAP_DELETED_JAR, Digester.digestRegularFile(new File(libDir, "bootstrap_deleted.jar"), true));
-
- assertEquals(CHECKSUMS.BOOTSTRAP_JAR, Digester.digestZipFile(new File(libDir, "bootstrap.jar")));
+ assertEquals(Digester.DIRECTORY, digester.digestRegularFile(binDir, false));
+ assertEquals(Digester.DIRECTORY, digester.digestRegularFile(libDir, true));
+
+ assertEquals(CHECKSUMS.README_TXT, digester.digestRegularFile(new File(dataDir, "Readme.txt"), false));
+ assertEquals(CHECKSUMS.BOOTSTRAP_JAR_BIN, digester.digestRegularFile(new File(libDir, "bootstrap.jar"), false));
+ assertEquals(CHECKSUMS.ANNOTATIONS_JAR, digester.digestRegularFile(new File(libDir, "annotations.jar"), true));
+ assertEquals(CHECKSUMS.ANNOTATIONS_CHANGED_JAR, digester.digestRegularFile(new File(libDir, "annotations_changed.jar"), true));
+ assertEquals(CHECKSUMS.BOOT_JAR, digester.digestRegularFile(new File(libDir, "boot.jar"), true));
+ assertEquals(CHECKSUMS.BOOT2_JAR, digester.digestRegularFile(new File(libDir, "boot2.jar"), true));
+ assertEquals(CHECKSUMS.BOOT2_CHANGED_WITH_UNCHANGED_CONTENT_JAR, digester.digestRegularFile(new File(libDir, "boot2_changed_with_unchanged_content.jar"), true));
+ assertEquals(CHECKSUMS.BOOT_WITH_DIRECTORY_BECOMES_FILE_JAR, digester.digestRegularFile(new File(libDir, "boot_with_directory_becomes_file.jar"), true));
+ assertEquals(CHECKSUMS.BOOTSTRAP_JAR, digester.digestRegularFile(new File(libDir, "bootstrap.jar"), true));
+ assertEquals(CHECKSUMS.BOOTSTRAP_DELETED_JAR, digester.digestRegularFile(new File(libDir, "bootstrap_deleted.jar"), true));
+
+ assertEquals(CHECKSUMS.BOOTSTRAP_JAR, digester.digestZipFile(new File(libDir, "bootstrap.jar")));
+ }
+
+ @Test
+ public void testMD5() throws Exception {
+ Digester digester = new Digester("md5");
+ assertEquals(MD5CHECKSUMS.README_TXT, digester.digestRegularFile(new File(dataDir, "Readme.txt"), false));
+ assertEquals(MD5CHECKSUMS.BOOTSTRAP_JAR, digester.digestZipFile(new File(dataDir, "/lib/bootstrap.jar")));
+ assertEquals(MD5CHECKSUMS.BOOTSTRAP_JAR_BINARY, digester.digestRegularFile(new File(dataDir, "/lib/bootstrap.jar"), false));
+ }
+
+ @Test
+ public void testBadAlgorithm() throws Exception {
+ assertTrue(Digester.isValidAlgorithm("md5"));
+ assertTrue(Digester.isValidAlgorithm("crc"));
+ assertFalse(Digester.isValidAlgorithm("foo"));
}
@Test
@@ -58,11 +74,12 @@ public class DigesterTest extends UpdaterTestCase {
File absoluteLink = getTempFile("Readme.absolute.link");
IoTestUtil.createSymbolicLink(absoluteLink.toPath(), Paths.get(dataDir.getPath() + "/Readme.txt"));
- assertEquals(CHECKSUMS.LINK_TO_README_TXT, Digester.digestRegularFile(simpleLink, false));
- assertEquals(CHECKSUMS.LINK_TO_DOT_README_TXT, Digester.digestRegularFile(relativeLink, false));
+ Digester digester = new Digester(null);
+ assertEquals(CHECKSUMS.LINK_TO_README_TXT, digester.digestRegularFile(simpleLink, false));
+ assertEquals(CHECKSUMS.LINK_TO_DOT_README_TXT, digester.digestRegularFile(relativeLink, false));
try {
- Digester.digestRegularFile(absoluteLink, false);
+ digester.digestRegularFile(absoluteLink, false);
fail("Absolute links should cause indigestion");
}
catch (IOException e) {
@@ -76,8 +93,8 @@ public class DigesterTest extends UpdaterTestCase {
File testFile = new File(tempDir.getRoot(), "idea.bat");
Utils.copy(new File(dataDir, "bin/idea.bat"), testFile, false);
- assertEquals(CHECKSUMS.IDEA_BAT, Digester.digestRegularFile(testFile, false));
+ assertEquals(CHECKSUMS.IDEA_BAT, new Digester(null).digestRegularFile(testFile, false));
Utils.setExecutable(testFile);
- assertEquals(CHECKSUMS.IDEA_BAT | Digester.EXECUTABLE, Digester.digestRegularFile(testFile, false));
+ assertEquals(CHECKSUMS.IDEA_BAT | Digester.EXECUTABLE, new Digester(null).digestRegularFile(testFile, false));
}
}
diff --git a/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java b/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java
index 30125c802200..3eef9f0c2f05 100644
--- a/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java
+++ b/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java
@@ -29,7 +29,7 @@ import static org.junit.Assume.assumeFalse;
@RunFirst
public abstract class PatchApplyingRevertingTest extends PatchTestCase {
private File myFile;
- private PatchSpec myPatchSpec;
+ PatchSpec myPatchSpec; // Android Studio: used in PatchFileCreatorLargeFileTest
private boolean myDoBackup;
@Before
@@ -64,6 +64,13 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
}
@Test
+ public void testCreatingAndApplyingMD5() throws Exception {
+ myPatchSpec.setHashAlgorithm("md5");
+ createPatch();
+ assertAppliedAndReverted(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+ }
+
+ @Test
public void testCreatingAndApplyingOnADifferentRoot() throws Exception {
myPatchSpec.setRoot("bin/");
myPatchSpec.setStrict(true);
@@ -201,12 +208,14 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
myPatchSpec.setStrict(true);
createPatch();
- FileUtil.delete(new File(myOlderDir, "lib/annotations.jar"));
+ File annotations = new File(myOlderDir, "lib/annotations.jar");
+ FileUtil.delete(annotations);
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(preparationResult.validationResults).containsExactly(
new ValidationResult(ValidationResult.Kind.ERROR,
"lib/annotations.jar",
+ annotations,
ValidationResult.Action.UPDATE,
ValidationResult.ABSENT_MESSAGE,
ValidationResult.Option.NONE));
@@ -346,12 +355,14 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
myPatchSpec.setStrict(true);
createPatch();
- FileUtil.copy(new File(myOlderDir, "lib/bootstrap.jar"), new File(myOlderDir, "lib/boot.jar"));
+ File toFile = new File(myOlderDir, "lib/boot.jar");
+ FileUtil.copy(new File(myOlderDir, "lib/bootstrap.jar"), toFile);
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(preparationResult.validationResults).containsExactly(
new ValidationResult(ValidationResult.Kind.ERROR,
"lib/boot.jar",
+ toFile,
ValidationResult.Action.VALIDATE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.NONE));
@@ -362,12 +373,14 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
myPatchSpec.setStrictFiles(Collections.singletonList("lib/annotations.jar"));
createPatch();
- FileUtil.copy(new File(myOlderDir, "lib/bootstrap.jar"), new File(myOlderDir, "lib/annotations.jar"));
+ File toFile = new File(myOlderDir, "lib/annotations.jar");
+ FileUtil.copy(new File(myOlderDir, "lib/bootstrap.jar"), toFile);
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(preparationResult.validationResults).containsExactly(
new ValidationResult(ValidationResult.Kind.ERROR,
"lib/annotations.jar",
+ toFile,
ValidationResult.Action.UPDATE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.NONE));
@@ -391,13 +404,15 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
createPatch();
- FileUtil.writeToFile(new File(myOlderDir, "new_file.txt"), "hello");
+ File toFile = new File(myOlderDir, "new_file.txt");
+ FileUtil.writeToFile(toFile, "hello");
FileUtil.writeToFile(new File(myOlderDir, "lib/java_pid1234.hprof"), "bye!");
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(preparationResult.validationResults).containsExactly(
new ValidationResult(ValidationResult.Kind.CONFLICT,
"new_file.txt",
+ toFile,
ValidationResult.Action.VALIDATE,
"Unexpected file",
ValidationResult.Option.DELETE));
@@ -425,24 +440,31 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
createPatch();
- FileUtil.writeToFile(new File(myOlderDir, "unexpected_new_dir/unexpected.txt"), "bye!");
+ File unexpectedDir = new File(myOlderDir, "unexpected_new_dir");
+ unexpectedDir.mkdirs();
+ File unexpected = new File(myOlderDir, "unexpected_new_dir/unexpected.txt");
+ FileUtil.writeToFile(unexpected, "bye!");
- FileUtil.createDirectory(new File(myOlderDir, "newDir"));
+ File newDir = new File(myOlderDir, "newDir");
+ FileUtil.createDirectory(newDir);
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(preparationResult.validationResults).containsExactly(
new ValidationResult(ValidationResult.Kind.CONFLICT,
"unexpected_new_dir/unexpected.txt",
+ unexpected,
ValidationResult.Action.VALIDATE,
"Unexpected file",
ValidationResult.Option.DELETE),
new ValidationResult(ValidationResult.Kind.CONFLICT,
"unexpected_new_dir/",
+ unexpectedDir,
ValidationResult.Action.VALIDATE,
"Unexpected file",
ValidationResult.Option.DELETE),
new ValidationResult(ValidationResult.Kind.CONFLICT,
"newDir/",
+ newDir,
ValidationResult.Action.CREATE,
ValidationResult.ALREADY_EXISTS_MESSAGE,
ValidationResult.Option.REPLACE));
@@ -458,7 +480,8 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
FileUtil.writeToFile(new File(myNewerDir, "move/to/this/directory/move.me"), "new_content");
createPatch();
- long hash = Digester.digestStream(new ByteArrayInputStream("new_content".getBytes(StandardCharsets.UTF_8)));
+ long hash = new Digester(myPatchSpec.getHashAlgorithm())
+ .digestStream(new ByteArrayInputStream("new_content".getBytes(StandardCharsets.UTF_8)));
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(findAction(preparationResult.patch, "move/to/this/directory/move.me"))
@@ -507,7 +530,8 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase {
FileUtil.writeToFile(new File(myNewerDir, "move/to/this/directory/move.me"), "different");
createPatch();
- long hash = Digester.digestStream(new ByteArrayInputStream("they".getBytes(StandardCharsets.UTF_8)));
+ long hash = new Digester(myPatchSpec.getHashAlgorithm())
+ .digestStream(new ByteArrayInputStream("they".getBytes(StandardCharsets.UTF_8)));
PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
assertThat(findAction(preparationResult.patch, "move/to/this/directory/move.me"))
diff --git a/updater/testSrc/com/intellij/updater/PatchCreationTest.java b/updater/testSrc/com/intellij/updater/PatchCreationTest.java
index 442ca5c188f1..45982e6202e4 100644
--- a/updater/testSrc/com/intellij/updater/PatchCreationTest.java
+++ b/updater/testSrc/com/intellij/updater/PatchCreationTest.java
@@ -37,6 +37,8 @@ public class PatchCreationTest extends PatchTestCase {
new DeleteAction(patch, "bin/idea.bat", CHECKSUMS.IDEA_BAT),
new CreateAction(patch, "newDir/"),
new CreateAction(patch, "newDir/newFile.txt"),
+ new CreateAction(patch, "newDir2/"),
+ new CreateAction(patch, "newDir2/link"),
new UpdateAction(patch, "Readme.txt", CHECKSUMS.README_TXT),
new UpdateZipAction(patch, "lib/annotations.jar",
singletonList("org/jetbrains/annotations/NewClass.class"),
@@ -61,6 +63,8 @@ public class PatchCreationTest extends PatchTestCase {
assertThat(sortActions(patch.getActions())).containsExactly(
new CreateAction(patch, "newDir/"),
new CreateAction(patch, "newDir/newFile.txt"),
+ new CreateAction(patch, "newDir2/"),
+ new CreateAction(patch, "newDir2/link"),
new UpdateZipAction(patch, "lib/annotations.jar",
singletonList("org/jetbrains/annotations/NewClass.class"),
singletonList("org/jetbrains/annotations/Nullable.class"),
@@ -79,54 +83,69 @@ public class PatchCreationTest extends PatchTestCase {
FileUtil.copy(new File(myOlderDir, "bin/focuskiller.dll"), new File(myNewerDir, "newDir/focuskiller.dll"));
Patch patch = createPatch();
+ File idea = new File(myOlderDir, "bin/idea.bat");
FileUtil.writeToFile(new File(myOlderDir, "bin/idea.bat"), "changed");
+ File focusKiller = new File(myOlderDir, "bin/focuskiller.dll");
FileUtil.writeToFile(new File(myOlderDir, "bin/focuskiller.dll"), "changed");
FileUtil.createDirectory(new File(myOlderDir, "extraDir"));
FileUtil.writeToFile(new File(myOlderDir, "extraDir/extraFile.txt"), "");
- FileUtil.createDirectory(new File(myOlderDir, "newDir"));
- FileUtil.writeToFile(new File(myOlderDir, "newDir/newFile.txt"), "");
- FileUtil.writeToFile(new File(myOlderDir, "Readme.txt"), "changed");
- FileUtil.writeToFile(new File(myOlderDir, "lib/annotations.jar"), "changed");
- FileUtil.delete(new File(myOlderDir, "lib/bootstrap.jar"));
+ File newDir = new File(myOlderDir, "newDir");
+ FileUtil.createDirectory(newDir);
+ File newFile = new File(myOlderDir, "newDir/newFile.txt");
+ FileUtil.writeToFile(newFile, "");
+ File readme = new File(myOlderDir, "Readme.txt");
+ FileUtil.writeToFile(readme, "changed");
+ File annotations = new File(myOlderDir, "lib/annotations.jar");
+ FileUtil.writeToFile(annotations, "changed");
+ File bootstrap = new File(myOlderDir, "lib/bootstrap.jar");
+ FileUtil.delete(bootstrap);
assertThat(sortResults(patch.validate(myOlderDir, TEST_UI))).containsExactly(
new ValidationResult(ValidationResult.Kind.CONFLICT,
"bin/focuskiller.dll",
+ focusKiller,
ValidationResult.Action.DELETE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.DELETE, ValidationResult.Option.KEEP),
new ValidationResult(ValidationResult.Kind.CONFLICT,
"bin/idea.bat",
+ idea,
ValidationResult.Action.DELETE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.DELETE, ValidationResult.Option.KEEP),
new ValidationResult(ValidationResult.Kind.CONFLICT,
"newDir/",
+ newDir,
ValidationResult.Action.CREATE,
ValidationResult.ALREADY_EXISTS_MESSAGE,
ValidationResult.Option.REPLACE, ValidationResult.Option.KEEP),
new ValidationResult(ValidationResult.Kind.CONFLICT,
"newDir/newFile.txt",
+ newFile,
ValidationResult.Action.CREATE,
ValidationResult.ALREADY_EXISTS_MESSAGE,
ValidationResult.Option.REPLACE, ValidationResult.Option.KEEP),
new ValidationResult(ValidationResult.Kind.ERROR,
"Readme.txt",
+ readme,
ValidationResult.Action.UPDATE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.IGNORE),
new ValidationResult(ValidationResult.Kind.ERROR,
"bin/focuskiller.dll",
+ focusKiller,
ValidationResult.Action.UPDATE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.IGNORE),
new ValidationResult(ValidationResult.Kind.ERROR,
"lib/annotations.jar",
+ annotations,
ValidationResult.Action.UPDATE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.IGNORE),
new ValidationResult(ValidationResult.Kind.ERROR,
"lib/bootstrap.jar",
+ bootstrap,
ValidationResult.Action.UPDATE,
ValidationResult.ABSENT_MESSAGE,
ValidationResult.Option.IGNORE));
@@ -150,6 +169,7 @@ public class PatchCreationTest extends PatchTestCase {
assertThat(results).containsExactly(
new ValidationResult(ValidationResult.Kind.CONFLICT,
"bin/IDEA.bat",
+ new File(myOlderDir, "bin/IDEA.bat"),
ValidationResult.Action.CREATE,
ValidationResult.ALREADY_EXISTS_MESSAGE,
ValidationResult.Option.REPLACE, ValidationResult.Option.KEEP));
@@ -162,10 +182,12 @@ public class PatchCreationTest extends PatchTestCase {
@Test
public void testValidationWithOptionalFiles() throws Exception {
Patch patch1 = createPatch();
- FileUtil.copy(new File(myOlderDir, "lib/boot.jar"), new File(myOlderDir, "lib/annotations.jar"));
+ File annotations = new File(myOlderDir, "lib/annotations.jar");
+ FileUtil.copy(new File(myOlderDir, "lib/boot.jar"), annotations);
assertThat(patch1.validate(myOlderDir, TEST_UI)).containsExactly(
new ValidationResult(ValidationResult.Kind.ERROR,
"lib/annotations.jar",
+ annotations,
ValidationResult.Action.UPDATE,
ValidationResult.MODIFIED_MESSAGE,
ValidationResult.Option.IGNORE));
@@ -190,6 +212,7 @@ public class PatchCreationTest extends PatchTestCase {
assertThat(patch.validate(myOlderDir, TEST_UI)).containsExactly(
new ValidationResult(ValidationResult.Kind.ERROR,
"Readme.txt",
+ f,
ValidationResult.Action.UPDATE,
message,
option));
@@ -372,6 +395,6 @@ public class PatchCreationTest extends PatchTestCase {
}
private static long linkHash(String target) throws IOException {
- return Digester.digestStream(new ByteArrayInputStream(target.getBytes(StandardCharsets.UTF_8))) | Digester.SYM_LINK;
+ return new Digester(null).digestStream(new ByteArrayInputStream(target.getBytes(StandardCharsets.UTF_8))) | Digester.SYM_LINK;
}
}
diff --git a/updater/testSrc/com/intellij/updater/PatchFileCreatorLargeFileTest.java b/updater/testSrc/com/intellij/updater/PatchFileCreatorLargeFileTest.java
new file mode 100644
index 000000000000..bc3c071d3219
--- /dev/null
+++ b/updater/testSrc/com/intellij/updater/PatchFileCreatorLargeFileTest.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.updater;
+
+public class PatchFileCreatorLargeFileTest extends PatchApplyingRevertingTest {
+ @Override
+ public void before() throws Exception {
+ super.before();
+ myPatchSpec.setLargeFileCutoff(1);
+ }
+}
diff --git a/updater/testSrc/com/intellij/updater/PatchTestCase.java b/updater/testSrc/com/intellij/updater/PatchTestCase.java
index b4b851133d4d..7a5d7569bb7d 100644
--- a/updater/testSrc/com/intellij/updater/PatchTestCase.java
+++ b/updater/testSrc/com/intellij/updater/PatchTestCase.java
@@ -4,6 +4,9 @@ package com.intellij.updater;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -30,7 +33,12 @@ public abstract class PatchTestCase extends UpdaterTestCase {
FileUtil.delete(new File(myNewerDir, "bin/idea.bat"));
FileUtil.writeToFile(new File(myNewerDir, "Readme.txt"), "hello");
- FileUtil.writeToFile(new File(myNewerDir, "newDir/newFile.txt"), "hello");
+ File newFile = new File(myNewerDir, "newDir/newFile.txt");
+ FileUtil.writeToFile(newFile, "hello");
+ Path link = Paths.get(myNewerDir.getPath(), "newDir2/link");
+ Files.createDirectories(link.getParent());
+
+ Files.createSymbolicLink(link, link.getParent().relativize(Paths.get(newFile.toURI())));
FileUtil.delete(new File(myOlderDir, "lib/annotations_changed.jar"));
FileUtil.delete(new File(myNewerDir, "lib/annotations.jar"));
diff --git a/updater/testSrc/com/intellij/updater/UpdaterTestCase.java b/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
index dfb136c05698..f66be0e79640 100644
--- a/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
+++ b/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
@@ -8,6 +8,11 @@ import org.junit.Before;
import org.junit.Rule;
import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public abstract class UpdaterTestCase {
static {
@@ -28,6 +33,7 @@ public abstract class UpdaterTestCase {
protected File dataDir;
protected TestUpdaterUI TEST_UI;
protected CheckSums CHECKSUMS;
+ protected MD5CheckSums MD5CHECKSUMS;
@Before
public void before() throws Exception {
@@ -40,6 +46,26 @@ public abstract class UpdaterTestCase {
CHECKSUMS = new CheckSums(
new File(dataDir, "Readme.txt").length() == 7132,
File.separatorChar == '\\');
+ boolean windowsLineEnds = new File(dataDir, "Readme.txt").length() == 7132;
+ MD5CHECKSUMS = new MD5CheckSums(windowsLineEnds);
+
+ // Android Studio: Bazel sets the execute permission for test data files when
+ // running remotely, thereby breaking a lot of updater tests.
+ // (See https://github.com/bazelbuild/bazel/issues/5588 for the relevant Bazel discussion.)
+ // We work around this by explicitly removing the execute permission for the test data.
+ // This is somewhat fragile (it could break a future test which needs an executable
+ // file as test data), so we log a warning.
+ try (Stream<Path> paths = Files.walk(dataDir.toPath())) {
+ List<File> files = paths.map(Path::toFile).filter(File::isFile).collect(Collectors.toList());
+ if (files.stream().anyMatch(File::canExecute)) {
+ System.err.println("Warning: removing execute permission from all UpdaterTestCase test data " +
+ "files in order to work around Bazel file permission quirks.");
+ for (File file : files) {
+ //noinspection ResultOfMethodCallIgnored
+ file.setExecutable(false);
+ }
+ }
+ }
}
@After
@@ -75,4 +101,45 @@ public abstract class UpdaterTestCase {
LINK_TO_DOT_README_TXT = backwardSlashes ? 2305843011210142148L : 2305843009503057206L;
}
}
+
+ protected static class MD5CheckSums {
+ public final long README_TXT;
+ public final long IDEA_BAT;
+ public final long ANNOTATIONS_JAR;
+ public final long BOOTSTRAP_JAR;
+ public final long BOOTSTRAP_JAR_BINARY;
+ public final long FOCUS_KILLER_DLL;
+ public final long ANNOTATIONS_JAR_NORM;
+ public final long ANNOTATIONS_CHANGED_JAR_NORM;
+ public final long BOOT_JAR_NORM;
+ public final long BOOT2_JAR_NORM;
+ public final long BOOT2_CHANGED_WITH_UNCHANGED_CONTENT_JAR_NORM;
+ public final long BOOT_WITH_DIRECTORY_BECOMES_FILE_JAR_NORM;
+ public final long BOOTSTRAP_JAR_NORM;
+ public final long BOOTSTRAP_DELETED_JAR_NORM;
+
+ public MD5CheckSums(boolean windowsLineEnds) {
+ if (windowsLineEnds) {
+ README_TXT = 0L;
+ IDEA_BAT = 0L;
+ }
+ else {
+ README_TXT = 4214850287831382927L;
+ IDEA_BAT = 1493936069L;
+ }
+ ANNOTATIONS_JAR = 2119442657L;
+ BOOTSTRAP_JAR = 8164818640246316539L;
+ FOCUS_KILLER_DLL = -5487271991872861862L;
+ BOOTSTRAP_JAR_BINARY = 6765351905979924471L;
+
+ ANNOTATIONS_JAR_NORM = 3039059927629132364L;
+ ANNOTATIONS_CHANGED_JAR_NORM = 3230144557297888639L;
+ BOOT_JAR_NORM = -4103093537316599430L;
+ BOOT2_JAR_NORM = -1992982772856167804L;
+ BOOT2_CHANGED_WITH_UNCHANGED_CONTENT_JAR_NORM = -1992982772856167804L;
+ BOOT_WITH_DIRECTORY_BECOMES_FILE_JAR_NORM = 6109387426094370257L;
+ BOOTSTRAP_JAR_NORM = 8164818640246316539L;
+ BOOTSTRAP_DELETED_JAR_NORM = -7880282130399843809L;
+ }
+ }
}
diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeInsertHandler.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeInsertHandler.java
index 3d88b235efd3..68274c022edc 100644
--- a/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeInsertHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeInsertHandler.java
@@ -55,7 +55,10 @@ public class XmlAttributeInsertHandler implements InsertHandler<LookupElement> {
final CharSequence chars = document.getCharsSequence();
final String quote = XmlEditUtil.getAttributeQuote(file);
- final boolean insertQuotes = WebEditorOptions.getInstance().isInsertQuotesForAttributeValue() && StringUtil.isNotEmpty(quote);
+ // Android Studio: To work around IDEA-113332 and an IJ 15 change which affected
+ // our workaround(b.android.com/195113) we've created a separate option here.
+ //final boolean insertQuotes = WebEditorOptions.getInstance().isInsertQuotesForAttributeValue() && StringUtil.isNotEmpty(quote);
+ final boolean insertQuotes = WebEditorOptions.getInstance().isInsertQuotesForAttributeValueCompletion() && StringUtil.isNotEmpty(quote);
final boolean hasQuotes = CharArrayUtil.regionMatches(chars, caretOffset, "=\"") ||
CharArrayUtil.regionMatches(chars, caretOffset, "='");
if (!hasQuotes) {
diff --git a/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java b/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java
index 865587bdfde3..7f173d46ee06 100644
--- a/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java
+++ b/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java
@@ -25,7 +25,12 @@ public final class WebEditorOptions implements PersistentStateComponent<WebEdito
private boolean myAutoCloseTag = true;
private boolean mySyncTagEditing = true;
private boolean myAutomaticallyStartAttribute = true;
- private boolean myInsertQuotesForAttributeValue = true;
+
+ // Android Studio: Deliberately changing behavior to work around IDEA-113332.
+ //private boolean myInsertQuotesForAttributeValue = true;
+ private boolean myInsertQuotesForAttributeValue = false;
+
+ private boolean myInsertQuotesForAttributeValueCompletion = true;
private boolean myTagTreeHighlightingEnabled = true;
private int myTagTreeHighlightingLevelCount = 6;
@@ -145,6 +150,14 @@ public final class WebEditorOptions implements PersistentStateComponent<WebEdito
myInsertQuotesForAttributeValue = insertQuotesForAttributeValue;
}
+ public boolean isInsertQuotesForAttributeValueCompletion() {
+ return myInsertQuotesForAttributeValueCompletion;
+ }
+
+ public void setInsertQuotesForAttributeValueCompletion(boolean insertQuotesForAttributeValueCompletion) {
+ myInsertQuotesForAttributeValueCompletion = insertQuotesForAttributeValueCompletion;
+ }
+
public boolean isAutoCloseTag() {
return myAutoCloseTag;
}