flutter-intellij
flutter-intellij copied to clipboard
⚙️ Flip `org.jetbrains.android` to optional
[!TIP] To try out the plugin on other IDEs, head over to https://github.com/AlexV525/flutter-intellij/releases and download the latest release!
Resolves https://github.com/flutter/flutter-intellij/issues/6809 Resolves https://github.com/flutter/flutter-intellij/issues/7205 Resolves https://github.com/flutter/flutter-intellij/issues/7947
Tested with PyCharm 2024.3.2
Pre-launch Checklist
- [x] I read the Contributor Guide and followed the process outlined there for submitting PRs.
- [x] I read the Tree Hygiene wiki page, which explains my responsibilities.
- [x] I read the Flutter Style Guide recently, and have followed its advice.
- [x] I signed the CLA.
- [x] I listed at least one issue that this PR fixes in the description above.
- [ ] I updated/added relevant documentation (doc comments with
///). - [ ] I added new tests to check the change I am making, or this PR is test-exempt.
- [x] All existing and new tests are passing.
WebStorm ready.
👍 That's a great update, which allows us to use JetBrains Community Edition IDEs for coding, as not everyone needs Android support (they can try Android Studio for that).
There seem to be exceptions when running on IntelliJ IDEA Ultimate. Not sure if it's related. Marking as draft for further investigations.
2025-03-07 00:25:59,609 [ 74946] INFO - #c.i.p.s.VulnerableApiService - Error on parsing libraries, retry
2025-03-07 00:26:09,624 [ 84961] INFO - #c.i.p.s.VulnerableApiService - Error on parsing libraries, retry
2025-03-07 00:26:09,624 [ 84961] WARN - #c.i.p.s.VulnerableApiService - retry failed
java.lang.Throwable: Control-flow exceptions (e.g. this class com.intellij.openapi.application.ReadAction$CannotReadException) should never be logged. Instead, these should have been rethrown if caught.
at com.intellij.openapi.diagnostic.Logger.ensureNotControlFlow(Logger.java:493)
at com.intellij.idea.IdeaLogger.warn(IdeaLogger.java:139)
at com.intellij.packageChecker.service.VulnerableApiService$createLibrariesFqnVulnerabilitiesFlow$3.invokeSuspend(VulnerableApiService.kt:141)
at com.intellij.packageChecker.service.VulnerableApiService$createLibrariesFqnVulnerabilitiesFlow$3.invoke(VulnerableApiService.kt)
at com.intellij.packageChecker.service.VulnerableApiService$createLibrariesFqnVulnerabilitiesFlow$3.invoke(VulnerableApiService.kt)
at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catch$$inlined$unsafeFlow$1.collect(SafeCollector.common.kt:113)
at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catch$$inlined$unsafeFlow$1$1.invokeSuspend(SafeCollector.common.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:608)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:873)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:763)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:750)
Caused by: com.intellij.openapi.application.ReadAction$CannotReadException
at com.intellij.openapi.application.ReadAction$CannotReadException.lambda$jobCancellation$0(ReadAction.java:128)
at com.intellij.openapi.progress.util.ProgressIndicatorUtilService.runActionAndCancelBeforeWrite(ProgressIndicatorUtilService.java:55)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:157)
at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal(cancellableReadAction.kt:28)
at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadAction$lambda$0(cancellableReadAction.kt:17)
at com.intellij.openapi.progress.ContextKt.prepareThreadContext(context.kt:85)
at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadAction(cancellableReadAction.kt:16)
at com.intellij.openapi.application.rw.PlatformReadWriteActionSupport.computeCancellable(PlatformReadWriteActionSupport.kt:42)
at com.intellij.openapi.application.ReadAction.computeCancellable(ReadAction.java:115)
at com.intellij.packageChecker.service.VulnerableApiService$createLibrariesFqnVulnerabilitiesFlow$1.invokeSuspend(VulnerableApiService.kt:124)
at com.intellij.packageChecker.service.VulnerableApiService$createLibrariesFqnVulnerabilitiesFlow$1.invoke(VulnerableApiService.kt)
at com.intellij.packageChecker.service.VulnerableApiService$createLibrariesFqnVulnerabilitiesFlow$1.invoke(VulnerableApiService.kt)
at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$1$1.invokeSuspend(Zip.kt:29)
at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$1$1.invoke(Zip.kt)
at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$1$1.invoke(Zip.kt)
at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Combine.kt:73)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
... 4 more
Turns out the built artifacts on Windows will fail with specific projects but not related.
@jwren
This is cool. Since it raises a kind of product question I'll have to defer to folks with more context.
Specifically: are we signing on to support these additional IDEs?
/fyi @anderdobo
What @pq said.
There have been a number of P0 issues that have prevented us from doing anything with the Flutter IJ plugin for bit, but with the release out yesterday, and hopefully a quick resolve on some of the bugs introduced, see the M85.1 milestone, we are happy to take a look at PRs. More time can be spent on issues that are in current milestones. For this PR, what @pq said is right, this is a product question. There are strong arguments on both sides with regard to if the Flutter IJ plugin should increase it's surface area to support more than Android Studio / Community / Ultimate.
For everyone who wants to try the plugin on other IDEs, I've setup the release workflow with my fork, and you can download the plugin through GitHub Release: https://github.com/AlexV525/flutter-intellij/releases
I've been looking over IJ documentation to make sure I understand how extensions work and the consequences of having this dependency.
One thing that I want to clarify - it seems our current setup with only <depends>org.jetbrains.android</depends> is wrong if we aren't also including config-file="idea-contribs.xml", right? If a user does have org.jetbrains.android they will still be missing the things in the config file. Unless the contents of the config file are only needed for Android Studio and not for situations where a user is using IntelliJ with the android plugin?
@AlexV525 I talked to Jaime today about this change. Does org.jetbrains.android and com.intellij.modules.androidstudio contain the same classes? In which case could we include studio-contribs.xml when either are available?
@helin24 Thanks for digging in!
Does
org.jetbrains.androidandcom.intellij.modules.androidstudiocontain the same classes?
They seem similar, but com.intellij.modules.androidstudio has more content than org.jetbrains.android.
In which case could we include
studio-contribs.xmlwhen either are available?
If I understand you correctly, we might also put the following declaration:
<depends optional="true" config-file="studio-contribs.xml">com.intellij.modules.androidstudio</depends>
Correct?
We already have:
<depends optional="true" config-file="studio-contribs.xml">com.intellij.modules.androidstudio</depends>
But I was wondering if we could add:
<depends optional="true" config-file="studio-contribs.xml">org.jetbrains.android</depends>
instead of using a new config file android-contribs.xml.
However, if the contents of the android studio module and the android plugin are different, then we're risking some files missing or versioning issues. Unless the functionality we're using from the android studio module is so basic that it's likely to be available in both? Having not looked into the details, I have no idea.
It seems odd to me that we would check for org.jetbrains.android as a dependency but then add no additional functionality as a result though.
@AlexV525
@helin24
But I was wondering if we could add:
<depends optional="true" config-file="studio-contribs.xml">org.jetbrains.android</depends>instead of using a new config file
android-contribs.xml.
It seems odd to me that we would check for
org.jetbrains.androidas a dependency but then add no additional functionality as a result though.
I guess ~.android stands its place because platform plugins are no longer bundled with editors (there is a standalone Android plugin in the Android Studio).
I haven't take a look about which dep we use for Android integrations. It seems reasonable that we rely on ~.androidstudio only since ~.android looks like a subset of ~.androidstudio. https://github.com/JetBrains/android
(Look like theoratically they are the same).
So we may be able remove the ~.android without breaking anything.
@AlexV525
Hmm.. are you saying now that perhaps we don't need this line entirely? (i.e. are you referring to org.jetbrains.android with ~.android?)
<depends optional="true" config-file="studio-contribs.xml">org.jetbrains.android</depends>
My understanding is this:
- If the flutter plugin is installed into Android Studio, then the dependency
com.intellij.modules.androidstudiois present, because this is bundled into Android Studio. And so therefore we want to includestudio-contribs.xmlto have the functionality that depends on Android Studio-related classes. - If the flutter plugin is installed into IntelliJ IDEA, then the dependency
com.intellij.modules.androidstudiois not present. However, we want to check for the dependencyorg.jetbrains.android, which is the Android plugin. Iforg.jetbrains.androidis present, then (maybe) we should also includestudio-contribs.xml. - Perhaps there are cases where someone would be in Android Studio and also have the Android plugin? In which case it sounds like based on your investigation, this is redundant for them (unrelated to the flutter plugin).
Maybe the outstanding question now is what functionality the line in question:
<depends optional="true" config-file="studio-contribs.xml">org.jetbrains.android</depends>
contributes (or could contribute, with studio-contribs.xml included) to IntelliJ IDEA users.
Let me know if my understanding is in line with your thinking.
Maybe the outstanding question now is what functionality the line in question:
<depends optional="true" config-file="studio-contribs.xml">org.jetbrains.android</depends>contributes (or could contribute, with
studio-contribs.xmlincluded) to IntelliJ IDEA users.Let me know if my understanding is in line with your thinking.
@helin24 : I think you are correct. But how would I test this using the current configuration? I've tried many times to runIde with IC but always starts an Android Studio instance.
@AlexV525 Are you able to build the plugin with bin/plugin make? Then you would have a .zip file that you could install to an instance of IDEA. Let me know if you need some additional info from me on how to make that work
@helin24 Sorry for the delay. I've tested with studio-contribs on IDEA. All actions are working properly like in Android Studio, but none of the extensions are working as far as I can tell. So I've created a new contribs specifically for the base Android plugin that only supports existing <actions> config.
~~Thanks for testing it! That's fine to have a separate file; looking at it again, I think the extensions should only be for Android Studio because it includes things like the new project wizard which we only want to override in Android Studio, not in IntelliJ.~~
~~In that case though, is the actions code exactly the same? I'm hoping we could have studio-contribs.xml depend on android-contribs.xml then.~~
This seems wrong. Let me write a new comment.
Okay, so I see that the actions are for new project wizard, which seem like they shouldn't be needed for IntelliJ. When the Android plugin is installed in IntelliJ, what does new project wizard look like? Does going to File > New project pull up something like this:
Or something like this:
If it's the first scenario, then I think we actually don't need any of the actions that are currently in android-contribs.xml, in which case we could just make it optional without adding a new config file.
Unless we can use the extensions listed in studio-contribs.xml when the android plugin is installed (and want to), why are we even including org.jetbrains.android?
Sorry for this extended discussion; as you can tell I have very little familiarity with the Android parts of this plugin and I want to make sure we're doing the right thing.
I'm also curious, what happens here when the org.jetbrains.android dependency is optional: https://github.com/flutter/flutter-intellij/blob/4c7dcef8c9b3ac15bee177709a5cb0e65fb9350a/src/io/flutter/ProjectOpenActivity.java#L103
This file imports org.jetbrains.android.facet.AndroidFrameworkDetector and the linked line uses that class. So if the org.jetbrains.android plugin is optional, why does this code compile anyway? I guess at runtime the code that uses AndroidFrameworkDetector never runs since we check for the presence of the plugin.
Sorry for this extended discussion; as you can tell I have very little familiarity with the Android parts of this plugin and I want to make sure we're doing the right thing.
No problem at all! There are always some small changes that expose some unthoughtful history. :)
Okay, so I see that the actions are for new project wizard, which seem like they shouldn't be needed for IntelliJ. When the Android plugin is installed in IntelliJ, what does new project wizard look like? Does going to File > New project pull up something like this:
If it's the first scenario, then I think we actually don't need any of the actions that are currently in
android-contribs.xml, in which case we could just make it optional without adding a new config file.
It's the first scenario. Only a new entry will display at this place. Clicking it will navigate to the normal project creation panel.
The problem is, if we don't specify a config file:
That's why I started with an empty contribs.
(P.S. I also found a bug that when the Flutter plugin is installed without the Android plugin installed, clicking "File > New > Project" will result in non-responsive.)
Unless we can use the extensions listed in
studio-contribs.xmlwhen the android plugin is installed (and want to), why are we even includingorg.jetbrains.android?
There are a couple of businesses that still rely on the plugin: https://github.com/flutter/flutter-intellij/blob/dec96dc5e19ea756e12a098da2c6474eda3d6320/src/io/flutter/FlutterInitializer.java#L163-L165
I'm also curious, what happens here when the
org.jetbrains.androiddependency is optional:https://github.com/flutter/flutter-intellij/blob/4c7dcef8c9b3ac15bee177709a5cb0e65fb9350a/src/io/flutter/ProjectOpenActivity.java#L103
This file imports
org.jetbrains.android.facet.AndroidFrameworkDetectorand the linked line uses that class. So if theorg.jetbrains.androidplugin is optional, why does this code compile anyway? I guess at runtime the code that usesAndroidFrameworkDetectornever runs since we check for the presence of the plugin.
Because it requires us (the author of flutter-intellij) to install the plugin at our compile time, rather than end users.
This file imports
org.jetbrains.android.facet.AndroidFrameworkDetectorand the linked line uses that class. So if theorg.jetbrains.androidplugin is optional, why does this code compile anyway? I guess at runtime the code that usesAndroidFrameworkDetectornever runs since we check for the presence of the plugin.
I suspect this is the reason I ran into non-responsive interface.
@AlexV525 can you investigate changing this method to not use the Android dependency? https://github.com/flutter/flutter-intellij/blob/master/src/io/flutter/FlutterUtils.java#L92
I think it will be something like checking ApplicationInfo.getInstance().getFullApplicationName().
I just want to get rid of the error that occurs during File > New Project when a user is on IntelliJ IDEA and has the Flutter plugin installed but not the Android plugin.
@AlexV525 can you investigate changing this method to not use the Android dependency? https://github.com/flutter/flutter-intellij/blob/master/src/io/flutter/FlutterUtils.java#L92
I think it will be something like checking
ApplicationInfo.getInstance().getFullApplicationName().I just want to get rid of the error that occurs during File > New Project when a user is on IntelliJ IDEA and has the Flutter plugin installed but not the Android plugin.
Sure I could try but no time guarantee for now :)
@AlexV525 no problem - if you can't get to it next week either I'll work on it or we may revert this change for this release and try again for next release.