<commit_before>// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:dwds/dwds.dart';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:vm_service/vm_service.dart' as vmservice;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
    hide StackTrace;

import '../application_package.dart';
import '../base/async_guard.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/net.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../dart/pub.dart';
import '../devfs.dart';
import '../device.dart';
import '../features.dart';
import '../globals.dart' as globals;
import '../platform_plugins.dart';
import '../plugins.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import '../resident_runner.dart';
import '../run_hot.dart';
import '../vmservice.dart';
import '../web/chrome.dart';
import '../web/compile.dart';
import '../web/web_device.dart';
import '../web/web_runner.dart';
import 'devfs_web.dart';

/// Injectable factory to create a [ResidentWebRunner].
class DwdsWebRunnerFactory extends WebRunnerFactory {
  @override
  ResidentRunner createWebRunner(
    FlutterDevice device, {
    String target,
    @required bool stayResident,
    @required FlutterProject flutterProject,
    @required bool ipv6,
    @required DebuggingOptions debuggingOptions,
    @required UrlTunneller urlTunneller,
  }) {
    return _ResidentWebRunner(
      device,
      target: target,
      flutterProject: flutterProject,
      debuggingOptions: debuggingOptions,
      ipv6: ipv6,
      stayResident: stayResident,
      urlTunneller: urlTunneller,
    );
  }
}

const String kExitMessage =  'Failed to establish connection with the application '
  'instance in Chrome.\nThis can happen if the websocket connection used by the '
  'web tooling is unable to correctly establish a connection, for example due to a firewall.';

/// A hot-runner which handles browser specific delegation.
abstract class ResidentWebRunner extends ResidentRunner {
  ResidentWebRunner(
    FlutterDevice device, {
    String target,
    @required this.flutterProject,
    @required bool ipv6,
    @required DebuggingOptions debuggingOptions,
    bool stayResident = true,
  }) : super(
          <FlutterDevice>[device],
          target: target ?? globals.fs.path.join('lib', 'main.dart'),
          debuggingOptions: debuggingOptions,
          ipv6: ipv6,
          stayResident: stayResident,
        );

  FlutterDevice get device => flutterDevices.first;
  final FlutterProject flutterProject;
  DateTime firstBuildTime;

  // Used with the new compiler to generate a bootstrap file containing plugins
  // and platform initialization.
  Directory _generatedEntrypointDirectory;

  // Only the debug builds of the web support the service protocol.
  @override
  bool get supportsServiceProtocol => isRunningDebug && deviceIsDebuggable;

  @override
  bool get debuggingEnabled => isRunningDebug && deviceIsDebuggable;

  /// WebServer device is debuggable when running with --start-paused.
  bool get deviceIsDebuggable => device.device is! WebServerDevice || debuggingOptions.startPaused;

  @override
  bool get supportsWriteSkSL => false;

  bool get _enableDwds => debuggingEnabled;

  ConnectionResult _connectionResult;
  StreamSubscription<vmservice.Event> _stdOutSub;
  StreamSubscription<vmservice.Event> _stdErrSub;
  bool _exited = false;
  WipConnection _wipConnection;
  ChromiumLauncher _chromiumLauncher;

  vmservice.VmService get _vmService =>
      _connectionResult?.debugConnection?.vmService;

  @override
  bool get canHotRestart {
    return true;
  }

  @override
  Future<Map<String, dynamic>> invokeFlutterExtensionRpcRawOnFirstIsolate(
    String method, {
    Map<String, dynamic> params,
  }) async {
    final vmservice.Response response =
        await _vmService.callServiceExtension(method, args: params);
    return response.toJson();
  }

  @override
  Future<void> cleanupAfterSignal() async {
    await _cleanup();
  }

  @override
  Future<void> cleanupAtFinish() async {
    await _cleanup();
  }

  Future<void> _cleanup() async {
    if (_exited) {
      return;
    }
    await _stdOutSub?.cancel();
    await _stdErrSub?.cancel();
    await device.device.stopApp(null);
    try {
      _generatedEntrypointDirectory?.deleteSync(recursive: true);
    } on FileSystemException {
      // Best effort to clean up temp dirs.
      globals.printTrace(
        'Failed to clean up temp directory: ${_generatedEntrypointDirectory.path}',
      );
    }
    _exited = true;
  }

  Future<void> _cleanupAndExit() async {
    await _cleanup();
    appFinished();
  }

  @override
  void printHelp({bool details = true}) {
    if (details) {
      return printHelpDetails();
    }
    const String fire = '🔥';
    const String rawMessage =
        '  To hot restart changes while running, press "r". '
        'To hot restart (and refresh the browser), press "R".';
    final String message = globals.terminal.color(
      fire + globals.terminal.bolden(rawMessage),
      TerminalColor.red,
    );
    globals.printStatus(
        "Warning: Flutter's support for web development is not stable yet and hasn't");
    globals.printStatus('been thoroughly tested in production environments.');
    globals.printStatus('For more information see https://flutter.dev/web');
    globals.printStatus('');
    globals.printStatus(message);
    const String quitMessage = 'To quit, press "q".';
    globals.printStatus('For a more detailed help message, press "h". $quitMessage');
  }

  @override
  Future<List<FlutterView>> listFlutterViews() async {
    return <FlutterView>[];
  }

  @override
  Future<void> debugDumpApp() async {
    try {
      await _vmService
        ?.flutterDebugDumpApp(<commit_msg>[flutter_tools] fix incorrect comment on web runner (#57450)<commit_after>// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:dwds/dwds.dart';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:vm_service/vm_service.dart' as vmservice;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
    hide StackTrace;

import '../application_package.dart';
import '../base/async_guard.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/net.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../dart/pub.dart';
import '../devfs.dart';
import '../device.dart';
import '../features.dart';
import '../globals.dart' as globals;
import '../platform_plugins.dart';
import '../plugins.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import '../resident_runner.dart';
import '../run_hot.dart';
import '../vmservice.dart';
import '../web/chrome.dart';
import '../web/compile.dart';
import '../web/web_device.dart';
import '../web/web_runner.dart';
import 'devfs_web.dart';

/// Injectable factory to create a [ResidentWebRunner].
class DwdsWebRunnerFactory extends WebRunnerFactory {
  @override
  ResidentRunner createWebRunner(
    FlutterDevice device, {
    String target,
    @required bool stayResident,
    @required FlutterProject flutterProject,
    @required bool ipv6,
    @required DebuggingOptions debuggingOptions,
    @required UrlTunneller urlTunneller,
  }) {
    return _ResidentWebRunner(
      device,
      target: target,
      flutterProject: flutterProject,
      debuggingOptions: debuggingOptions,
      ipv6: ipv6,
      stayResident: stayResident,
      urlTunneller: urlTunneller,
    );
  }
}

const String kExitMessage =  'Failed to establish connection with the application '
  'instance in Chrome.\nThis can happen if the websocket connection used by the '
  'web tooling is unable to correctly establish a connection, for example due to a firewall.';

/// A hot-runner which handles browser specific delegation.
abstract class ResidentWebRunner extends ResidentRunner {
  ResidentWebRunner(
    FlutterDevice device, {
    String target,
    @required this.flutterProject,
    @required bool ipv6,
    @required DebuggingOptions debuggingOptions,
    bool stayResident = true,
  }) : super(
          <FlutterDevice>[device],
          target: target ?? globals.fs.path.join('lib', 'main.dart'),
          debuggingOptions: debuggingOptions,
          ipv6: ipv6,
          stayResident: stayResident,
        );

  FlutterDevice get device => flutterDevices.first;
  final FlutterProject flutterProject;
  DateTime firstBuildTime;

  // Used with the new compiler to generate a bootstrap file containing plugins
  // and platform initialization.
  Directory _generatedEntrypointDirectory;

  // Only the debug builds of the web support the service protocol.
  @override
  bool get supportsServiceProtocol => isRunningDebug && deviceIsDebuggable;

  @override
  bool get debuggingEnabled => isRunningDebug && deviceIsDebuggable;

  /// WebServer device is debuggable when running with --start-paused.
  bool get deviceIsDebuggable => device.device is! WebServerDevice || debuggingOptions.startPaused;

  @override
  bool get supportsWriteSkSL => false;

  bool get _enableDwds => debuggingEnabled;

  ConnectionResult _connectionResult;
  StreamSubscription<vmservice.Event> _stdOutSub;
  StreamSubscription<vmservice.Event> _stdErrSub;
  bool _exited = false;
  WipConnection _wipConnection;
  ChromiumLauncher _chromiumLauncher;

  vmservice.VmService get _vmService =>
      _connectionResult?.debugConnection?.vmService;

  @override
  bool get canHotRestart {
    return true;
  }

  @override
  Future<Map<String, dynamic>> invokeFlutterExtensionRpcRawOnFirstIsolate(
    String method, {
    Map<String, dynamic> params,
  }) async {
    final vmservice.Response response =
        await _vmService.callServiceExtension(method, args: params);
    return response.toJson();
  }

  @override
  Future<void> cleanupAfterSignal() async {
    await _cleanup();
  }

  @override
  Future<void> cleanupAtFinish() async {
    await _cleanup();
  }

  Future<void> _cleanup() async {
    if (_exited) {
      return;
    }
    await _stdOutSub?.cancel();
    await _stdErrSub?.cancel();
    await device.device.stopApp(null);
    try {
      _generatedEntrypointDirectory?.deleteSync(recursive: true);
    } on FileSystemException {
      // Best effort to clean up temp dirs.
      globals.printTrace(
        'Failed to clean up temp directory: ${_generatedEntrypointDirectory.path}',
      );
    }
    _exited = true;
  }

  Future<void> _cleanupAndExit() async {
    await _cleanup();
    appFinished();
  }

  @override
  void printHelp({bool details = true}) {
    if (details) {
      return printHelpDetails();
    }
    const String fire = '🔥';
    const String rawMessage =
        '  To hot restart changes while running, press "r" or "R".';
    final String message = globals.terminal.color(
      fire + globals.terminal.bolden(rawMessage),
      TerminalColor.red,
    );
    globals.printStatus(
        "Warning: Flutter's support for web development is not stable yet and hasn't");
    globals.printStatus('been thoroughly tested in production environments.');
    globals.printStatus('For more information see https://flutter.dev/web');
    globals.printStatus('');
    globals.printStatus(message);
    const String quitMessage = 'To quit, press "q".';
    globals.printStatus('For a more detailed help message, press "h". $quitMessage');
  }

  @override
  Future<List<FlutterView>> listFlutterViews() async {
    return <FlutterView>[];
  }

  @override
  Future<void> debugDumpApp() async {
    try {
      await _vmService
        ?.flutterDebugDumpApp(
{'fraction_non_alphanumeric': 0.11146393095587039, 'fraction_numerical': 0.002035499104380394, 'mean_word_length': 3.6333459072048284, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 45, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6744426', 'n_tokens_mistral': 3661, 'n_tokens_neox': 3579, 'n_words': 981}