Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/io/flutter/run/LaunchState.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import io.flutter.dart.DartPlugin;
import io.flutter.logging.FlutterLog;
import io.flutter.logging.FlutterLogView;
import io.flutter.pub.PubRoot;
import io.flutter.run.bazel.BazelRunConfig;
import io.flutter.run.daemon.*;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -120,9 +121,21 @@ protected RunContentDescriptor launch(@NotNull ExecutionEnvironment env) throws
final Project project = getEnvironment().getProject();
final FlutterDevice device = DeviceService.getInstance(project).getSelectedDevice();

// Flutter web does not yet support device objects yet, hence the null as the indicator that this might be a flutter web project.
if (device == null) {
showNoDeviceConnectedMessage(project);
return null;
boolean isFlutterWeb = false;
final String filePath = ((SdkRunConfig)runConfig).getFields().getFilePath();
if (filePath != null) {
final MainFile main = MainFile.verify(filePath, project).get();
final PubRoot root = PubRoot.forDirectory(main.getAppDir());
if (root != null) {
isFlutterWeb = FlutterUtils.declaresFlutterWeb(root.getPubspec());
}
}
if (!isFlutterWeb) {
showNoDeviceConnectedMessage(project);
return null;
}
}
final FlutterApp app = myCreateAppCallback.createApp(device);

Expand All @@ -147,7 +160,9 @@ protected RunContentDescriptor launch(@NotNull ExecutionEnvironment env) throws
}
}

device.bringToFront();
if (device != null) {
device.bringToFront();
}

// Check for and display any analysis errors when we launch an app.
if (env.getRunProfile() instanceof SdkRunConfig) {
Expand Down
9 changes: 6 additions & 3 deletions src/io/flutter/run/SdkFields.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.jetbrains.lang.dart.sdk.DartConfigurable;
import com.jetbrains.lang.dart.sdk.DartSdk;
import io.flutter.FlutterBundle;
import io.flutter.FlutterUtils;
import io.flutter.dart.DartPlugin;
import io.flutter.pub.PubRoot;
import io.flutter.run.daemon.FlutterDevice;
Expand Down Expand Up @@ -124,11 +125,13 @@ public GeneralCommandLine createFlutterSdkRunCommand(@NotNull Project project,
throw new ExecutionException("Entrypoint isn't within a Flutter pub root");
}

String[] args = additionalArgs == null ? new String[]{} : additionalArgs.split(" ");
String[] args = additionalArgs == null ? new String[]{ } : additionalArgs.split(" ");
if (buildFlavor != null) {
args = ArrayUtil.append(args, "--flavor=" + buildFlavor);
}
final FlutterCommand command = flutterSdk.flutterRun(root, main.getFile(), device, runMode, flutterLaunchMode, project, args);
final FlutterCommand command = FlutterUtils.declaresFlutterWeb(root.getPubspec()) ?
flutterSdk.flutterRunWeb(root, runMode) :
flutterSdk.flutterRun(root, main.getFile(), device, runMode, flutterLaunchMode, project, args);
return command.createGeneralCommandLine(project);
}

Expand All @@ -150,7 +153,7 @@ public GeneralCommandLine createFlutterSdkAttachCommand(@NotNull Project project
throw new ExecutionException("Entrypoint isn't within a Flutter pub root");
}

String[] args = additionalArgs == null ? new String[]{} : additionalArgs.split(" ");
String[] args = additionalArgs == null ? new String[]{ } : additionalArgs.split(" ");
if (buildFlavor != null) {
args = ArrayUtil.append(args, "--flavor=" + buildFlavor);
}
Expand Down
3 changes: 2 additions & 1 deletion src/io/flutter/run/SdkRunConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ public LaunchState getState(@NotNull Executor executor, @NotNull ExecutionEnviro
final RunMode mode = RunMode.fromEnv(env);
final Module module = ModuleUtilCore.findModuleForFile(mainFile.getFile(), env.getProject());
final LaunchState.CreateAppCallback createAppCallback = (device) -> {
if (device == null) return null;
// Up until the FlutterWeb support, device was checked for null and returned. The device
// can only be null if this is a FlutterWeb execution, this expecation is checked elsewhere.

final GeneralCommandLine command = getCommand(env, device);
{
Expand Down
14 changes: 10 additions & 4 deletions src/io/flutter/run/daemon/FlutterApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public class FlutterApp {
private final @NotNull Project myProject;
private final @Nullable Module myModule;
private final @NotNull RunMode myMode;
private final @NotNull FlutterDevice myDevice;
// TODO(github.com/flutter/flutter-intellij/issues/3293) myDevice is not-null for all run configurations except flutter web configurations
private final @Nullable FlutterDevice myDevice;
private final @NotNull ProcessHandler myProcessHandler;
private final @NotNull ExecutionEnvironment myExecutionEnvironment;
private final @NotNull DaemonApi myDaemonApi;
Expand Down Expand Up @@ -122,7 +123,7 @@ public static FlutterApp fromEnv(@NotNull ExecutionEnvironment env) {
FlutterApp(@NotNull Project project,
@Nullable Module module,
@NotNull RunMode mode,
@NotNull FlutterDevice device,
@Nullable FlutterDevice device,
@NotNull ProcessHandler processHandler,
@NotNull ExecutionEnvironment executionEnvironment,
@NotNull DaemonApi daemonApi,
Expand Down Expand Up @@ -237,7 +238,7 @@ public static FlutterApp start(@NotNull ExecutionEnvironment env,
@NotNull Project project,
@Nullable Module module,
@NotNull RunMode mode,
@NotNull FlutterDevice device,
@Nullable FlutterDevice device,
@NotNull GeneralCommandLine command,
@Nullable String analyticsStart,
@Nullable String analyticsStop)
Expand Down Expand Up @@ -593,7 +594,12 @@ public FlutterDevice device() {
}

public String deviceId() {
return myDevice.deviceId();
return myDevice != null ? myDevice.deviceId() : "";
}

// TODO this should be a temporary hack until there is some mocked out "browser" device
public boolean isWebDev() {
return myDevice == null;
}

public void setFlutterDebugProcess(FlutterDebugProcess flutterDebugProcess) {
Expand Down
66 changes: 56 additions & 10 deletions src/io/flutter/sdk/FlutterCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,28 @@ public class FlutterCommand {
@NotNull
private final List<String> args;

// TODO(https://github.com/flutter/flutter-intellij/issues/3348) This is a temporary "<pub-cache>/bin/webdev" that can be provided to test
// some webdev directly.
@Nullable
private final String localWebDevExe = "webdev";

private final boolean isFlutterWeb;

/**
* @see FlutterSdk for methods to create specific commands.
*/
FlutterCommand(@NotNull FlutterSdk sdk, @Nullable VirtualFile workDir, @NotNull Type type, String... args) {
this(sdk, workDir, type, false, args);
}

/**
* @see FlutterSdk for methods to create specific commands.
*/
FlutterCommand(@NotNull FlutterSdk sdk, @Nullable VirtualFile workDir, @NotNull Type type, boolean isFlutterWeb, String... args) {
this.sdk = sdk;
this.workDir = workDir;
this.type = type;
this.isFlutterWeb = isFlutterWeb;
this.args = ImmutableList.copyOf(args);
}

Expand Down Expand Up @@ -245,23 +260,54 @@ public OSProcessHandler startProcessOrShowError(@Nullable Project project) {
public GeneralCommandLine createGeneralCommandLine(@Nullable Project project) {
final GeneralCommandLine line = new GeneralCommandLine();
line.setCharset(CharsetToolkit.UTF8_CHARSET);

line.withEnvironment(FlutterSdkUtil.FLUTTER_HOST_ENV, FlutterSdkUtil.getFlutterHostEnvValue());

final String androidHome = IntelliJAndroidSdk.chooseAndroidHome(project, false);
if (androidHome != null) {
line.withEnvironment("ANDROID_HOME", androidHome);
if (isFlutterWeb) {
if (workDir != null) {
line.setWorkDirectory(workDir.getPath());
}
if (localWebDevExe != null || !localWebDevExe.isEmpty()) {
line.setExePath(localWebDevExe);
line.addParameters("daemon");
if (args.contains("--debug")) {
line.addParameters("--debug");
}
if (args.contains("--hot-reload")) {
line.addParameters("--hot-reload");
}
}
else {
line.setExePath(FileUtil.toSystemDependentName(sdk.getHomePath() + "/bin/" + FlutterSdkUtil.flutterScriptName()));
line.addParameters(args);
}
}
else {
line.withEnvironment(FlutterSdkUtil.FLUTTER_HOST_ENV, FlutterSdkUtil.getFlutterHostEnvValue());
final String androidHome = IntelliJAndroidSdk.chooseAndroidHome(project, false);
if (androidHome != null) {
line.withEnvironment("ANDROID_HOME", androidHome);
}
line.setExePath(FileUtil.toSystemDependentName(sdk.getHomePath() + "/bin/" + FlutterSdkUtil.flutterScriptName()));
if (workDir != null) {
line.setWorkDirectory(workDir.getPath());
}
if (!isDoctorCommand()) {
line.addParameter("--no-color");
}
line.addParameters(type.subCommand);
line.addParameters(args);
}
return line;
}

line.setExePath(FileUtil.toSystemDependentName(sdk.getHomePath() + "/bin/" + FlutterSdkUtil.flutterScriptName()));
@NotNull
public GeneralCommandLine createFlutterWebCommandLine(@Nullable Project project) {
final GeneralCommandLine line = new GeneralCommandLine();
line.setCharset(CharsetToolkit.UTF8_CHARSET);
if (workDir != null) {
line.setWorkDirectory(workDir.getPath());
}
if (!isDoctorCommand()) {
line.addParameter("--no-color");
}
line.addParameters(type.subCommand);
line.addParameters(args);

return line;
}

Expand Down
13 changes: 13 additions & 0 deletions src/io/flutter/sdk/FlutterSdk.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,19 @@ else if (flutterLaunchMode == FlutterLaunchMode.RELEASE) {
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.ATTACH, args.toArray(new String[]{ }));
}

public FlutterCommand flutterRunWeb(@NotNull PubRoot root, @NotNull RunMode mode) {
// flutter packages pub global run webdev serve [--debug] [--hot-reload]
final List<String> args = new ArrayList<>();
args.add("global");
args.add("run");
args.add("webdev");
args.add("daemon");
// TODO(https://github.com/flutter/flutter-intellij/issues/3349) After debug is supported by webdev, this should be modified to check
// for debug and add any additional needed flags:
// i.e. if (mode == RunMode.DEBUG) { args.add("--debug"); }
return new FlutterCommand(this, root.getRoot(), FlutterCommand.Type.PACKAGES_PUB, true, args.toArray(new String[]{ }));
}

public FlutterCommand flutterRunOnTester(@NotNull PubRoot root, @NotNull String mainPath) {
final List<String> args = new ArrayList<>();
args.add("--machine");
Expand Down
31 changes: 18 additions & 13 deletions src/io/flutter/server/vmService/DartVmServiceDebugProcess.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import gnu.trove.TIntObjectHashMap;
import io.flutter.FlutterBundle;
import io.flutter.FlutterUtils;
import io.flutter.run.FlutterDebugProcess;
import io.flutter.run.FlutterLaunchMode;
import io.flutter.server.vmService.frame.DartVmServiceEvaluator;
import io.flutter.server.vmService.frame.DartVmServiceStackFrame;
Expand Down Expand Up @@ -262,17 +263,21 @@ public void scheduleConnect() {
// because "flutter run" has already connected to it.
final VmService vmService;
final VmOpenSourceLocationListener vmOpenSourceLocationListener;
try {
vmService = VmService.connect(url);
vmOpenSourceLocationListener = VmOpenSourceLocationListener.connect(url);
}
catch (IOException | RuntimeException e) {
onConnectFailed("Failed to connect to the VM observatory service at: " + url + "\n"
+ e.toString() + "\n" +
formatStackTraces(e));
return;
// TODO(github.com/dart-lang/webdev/issues/233) The following check disables the WebSocket connection for all FlutterWeb run
// configurations, for some reason the WebSocket port can't be connected to, see listed issue above.
if (this instanceof FlutterDebugProcess && (!((FlutterDebugProcess)this).getApp().isWebDev())) {
try {
vmService = VmService.connect(url);
vmOpenSourceLocationListener = VmOpenSourceLocationListener.connect(url);
}
catch (IOException | RuntimeException e) {
onConnectFailed("Failed to connect to the VM observatory service at: " + url + "\n"
+ e.toString() + "\n" +
formatStackTraces(e));
return;
}
onConnectSucceeded(vmService, vmOpenSourceLocationListener);
}
onConnectSucceeded(vmService, vmOpenSourceLocationListener);
});
}

Expand Down Expand Up @@ -391,7 +396,7 @@ public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendC

public void isolateSuspended(@NotNull final IsolateRef isolateRef) {
final String id = isolateRef.getId();
assert(!mySuspendedIsolateIds.containsKey(id));
assert (!mySuspendedIsolateIds.containsKey(id));
if (!mySuspendedIsolateIds.containsKey(id)) {
mySuspendedIsolateIds.put(id, new CompletableFuture<>());
}
Expand All @@ -406,10 +411,10 @@ public CompletableFuture<?> whenIsolateResumed(String isolateId) {
if (future == null) {
// Isolate wasn't actually suspended.
return CompletableFuture.completedFuture(null);
} else {
}
else {
return future;
}

}

public boolean isIsolateAlive(@NotNull final String isolateId) {
Expand Down