From 0fd0a1e31f6faaf456300b107189ad31e5dfe01d Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Fri, 24 Feb 2023 10:31:31 -0500 Subject: [PATCH 1/7] monarch package: version 3.3 compatible with flutter sdk version 3.8.0-0.0.pre or greater --- packages/monarch/CHANGELOG.md | 3 +++ packages/monarch/lib/src/preview/start_monarch_preview.dart | 3 ++- packages/monarch/pubspec.yaml | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/monarch/CHANGELOG.md b/packages/monarch/CHANGELOG.md index 47dd2764..432b8dba 100644 --- a/packages/monarch/CHANGELOG.md +++ b/packages/monarch/CHANGELOG.md @@ -1,3 +1,6 @@ +## 3.3.0 - 2023-02-24 +- Compatible with flutter sdk version 3.8.0-0.0.pre or greater. + ## 3.0.1 - 2023-02-24 - Flutter sdk version 3.8.0-0.0.pre introduces a new API for WidgetsBinding which is not compatible with this diff --git a/packages/monarch/lib/src/preview/start_monarch_preview.dart b/packages/monarch/lib/src/preview/start_monarch_preview.dart index 3037588c..e8b1f7f6 100644 --- a/packages/monarch/lib/src/preview/start_monarch_preview.dart +++ b/packages/monarch/lib/src/preview/start_monarch_preview.dart @@ -39,7 +39,8 @@ void _startMonarchPreview(ProjectData Function() getProjectData) async { }); Timer.run(() { - monarchBinding.attachRootWidget(MonarchPreview()); + monarchBinding + .attachRootWidget(monarchBinding.wrapWithDefaultView(MonarchPreview())); }); monarchBinding.scheduleWarmUpFrame(); diff --git a/packages/monarch/pubspec.yaml b/packages/monarch/pubspec.yaml index 9ff19e66..8100cefd 100644 --- a/packages/monarch/pubspec.yaml +++ b/packages/monarch/pubspec.yaml @@ -1,6 +1,6 @@ name: monarch description: Code generator for Monarch. Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. -version: 3.0.1 +version: 3.3.0 homepage: https://monarchapp.io repository: https://github.com/Dropsource/monarch issue_tracker: https://github.com/Dropsource/monarch/issues @@ -9,7 +9,7 @@ documentation: https://monarchapp.io/docs/introduction environment: sdk: '>=2.12.0 <4.0.0' - flutter: '>=2.12.0-4.1.pre' + flutter: '>=3.8.0-0.0.pre' dependencies: flutter: From 24c5bd471aff81febdf7bfb30b625b844d6e3da7 Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Tue, 25 Apr 2023 12:48:50 -0400 Subject: [PATCH 2/7] Faster code generation and reload (#90) - do not use source_gen which resolves too much of the element tree which is slow - only resolve element tree when needed - better logging - Nullable StoryFunction - Validate and filter null story functions - Similar pattern to themes and locales, MetaStories.user constructor - Warning message - Builder uses MetaStories.user constructor - Remove story if story function is not expected type - Filter out private functions when generating meta stories - meta themes builder: optimize meta theme code gen - meta localization builder: optimize meta localization code gen - removed old generators based on source_gen - monarch package: Update vm_service dependency to >=9.4.0, version bump (cherry picked from commit dd2942a4487f4016d032c8f51fde680b4bca1e7d) --- packages/monarch/CHANGELOG.md | 10 ++ .../lib/src/builders/builder_helper.dart | 8 ++ .../monarch/lib/src/builders/builders.dart | 19 ++-- ...r.dart => meta_localizations_builder.dart} | 48 +++++++-- .../src/builders/meta_stories_builder.dart | 101 ++++++++++++++++++ .../src/builders/meta_stories_generator.dart | 66 ------------ ...enerator.dart => meta_themes_builder.dart} | 43 ++++++-- .../monarch/lib/src/preview/project_data.dart | 11 +- .../lib/src/preview/project_data_manager.dart | 28 ++++- packages/monarch/pubspec.yaml | 4 +- 10 files changed, 237 insertions(+), 101 deletions(-) rename packages/monarch/lib/src/builders/{meta_locales_generator.dart => meta_localizations_builder.dart} (69%) create mode 100644 packages/monarch/lib/src/builders/meta_stories_builder.dart delete mode 100644 packages/monarch/lib/src/builders/meta_stories_generator.dart rename packages/monarch/lib/src/builders/{meta_themes_generator.dart => meta_themes_builder.dart} (64%) diff --git a/packages/monarch/CHANGELOG.md b/packages/monarch/CHANGELOG.md index 432b8dba..436134b6 100644 --- a/packages/monarch/CHANGELOG.md +++ b/packages/monarch/CHANGELOG.md @@ -1,6 +1,16 @@ +## 3.4.0 - 2023-04-25 +- Faster code generation +- Update vm_service dependency to `>=9.4.0` +- Compatible with Flutter 3.8 or greater + ## 3.3.0 - 2023-02-24 - Compatible with flutter sdk version 3.8.0-0.0.pre or greater. +## 3.1.0 - 2023-04-20 +- Faster code generation +- Update vm_service dependency to `>=9.4.0` +- Compatible with Flutter 3.7 + ## 3.0.1 - 2023-02-24 - Flutter sdk version 3.8.0-0.0.pre introduces a new API for WidgetsBinding which is not compatible with this diff --git a/packages/monarch/lib/src/builders/builder_helper.dart b/packages/monarch/lib/src/builders/builder_helper.dart index 9baf7784..4187c499 100644 --- a/packages/monarch/lib/src/builders/builder_helper.dart +++ b/packages/monarch/lib/src/builders/builder_helper.dart @@ -36,3 +36,11 @@ const monarchWarningBegin = const monarchWarningEnd = '════════════════════════════════════════════════════════════════════════════════════════════════════'; + +String generatedCodeHeader(String builderName) => ''' +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// $builderName - monarch +// ************************************************************************** +'''; \ No newline at end of file diff --git a/packages/monarch/lib/src/builders/builders.dart b/packages/monarch/lib/src/builders/builders.dart index 74819612..08fb8cb2 100644 --- a/packages/monarch/lib/src/builders/builders.dart +++ b/packages/monarch/lib/src/builders/builders.dart @@ -1,22 +1,15 @@ import 'package:build/build.dart'; -import 'package:source_gen/source_gen.dart'; import 'main_builder.dart'; -import 'meta_stories_generator.dart'; -import 'meta_themes_generator.dart'; -import 'meta_locales_generator.dart'; +import 'meta_stories_builder.dart'; +import 'meta_themes_builder.dart'; +import 'meta_localizations_builder.dart'; Builder metaLocalizationsBuilder(BuilderOptions options) => - LibraryBuilder(MetaLocalizationsGenerator(), - generatedExtension: '.meta_localizations.g.dart', - allowSyntaxErrors: true); + MetaLocalizationsBuilder(); -Builder metaThemesBuilder(BuilderOptions options) => - LibraryBuilder(MetaThemesGenerator(), - generatedExtension: '.meta_themes.g.dart', allowSyntaxErrors: true); +Builder metaThemesBuilder(BuilderOptions options) => MetaThemesBuilder(); -Builder metaStoriesBuilder(BuilderOptions options) => - LibraryBuilder(MetaStoriesGenerator(), - generatedExtension: '.meta_stories.g.dart', allowSyntaxErrors: true); +Builder metaStoriesBuilder(BuilderOptions options) => MetaStoriesBuilder(); Builder mainBuilder(BuilderOptions options) => MainBuilder(options); diff --git a/packages/monarch/lib/src/builders/meta_locales_generator.dart b/packages/monarch/lib/src/builders/meta_localizations_builder.dart similarity index 69% rename from packages/monarch/lib/src/builders/meta_locales_generator.dart rename to packages/monarch/lib/src/builders/meta_localizations_builder.dart index 99290749..758bb2cc 100644 --- a/packages/monarch/lib/src/builders/meta_locales_generator.dart +++ b/packages/monarch/lib/src/builders/meta_localizations_builder.dart @@ -1,20 +1,43 @@ -import 'package:build/build.dart'; -import 'package:source_gen/source_gen.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'dart:async'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:build/build.dart'; import 'package:monarch_annotations/monarch_annotations.dart'; +import 'package:source_gen/source_gen.dart'; import 'builder_helper.dart'; -const TypeChecker monarchLocalizationsTypeChecker = - TypeChecker.fromRuntime(MonarchLocalizations); +const metaLocalizationsExtension = '.meta_localizations.g.dart'; -class MetaLocalizationsGenerator extends Generator { +class MetaLocalizationsBuilder implements Builder { @override - String? generate(LibraryReader library, BuildStep buildStep) { + Map> get buildExtensions => const { + '.dart': [metaLocalizationsExtension] + }; + + @override + FutureOr build(BuildStep buildStep) async { + /// @GOTCHA: Optimization: + /// This is a quick-and-rough way to check for the presence of an annotation. + /// The proper way is to resolve the compilation unit. However, that is + /// slow to do on every file in the user's project. + var contents = await buildStep.readAsString(buildStep.inputId); + if (!contents.contains('@MonarchLocalizations')) { + return; + } + + /// Calling `resolver.libraryFor` is expensive. + /// Therefore, we are only calling it on dart libraries that we suspect + /// have a monarch annotation. + var libraryElement = await buildStep.resolver + .libraryFor(buildStep.inputId, allowSyntaxErrors: true); + var library = LibraryReader(libraryElement); + var monarchLocalizationsTypeChecker = + TypeChecker.fromRuntime(MonarchLocalizations); + final annotations = library.annotatedWith(monarchLocalizationsTypeChecker); if (annotations.isEmpty) { - return null; + return; } final expressions = []; @@ -82,7 +105,10 @@ $monarchWarningEnd } if (isInLib(buildStep.inputId)) { - return _outputContents(buildStep.inputId.uri.toString(), expressions); + var output = _outputContents(buildStep.inputId.uri.toString(), expressions); + var outputId = buildStep.inputId.changeExtension(metaLocalizationsExtension); + + await buildStep.writeAsString(outputId, output); } else { // Could not compute import URI to file with MonarchLocalizations annotation // outside of lib directory. @@ -92,13 +118,15 @@ $monarchWarningBegin The `@MonarchLocalizations` annotation should be used in libraries inside the lib directory. $monarchWarningEnd '''); - return null; + return; } } String _outputContents(String pathToLocalizationsFile, List metaLocalizationExpressions) { return ''' +${generatedCodeHeader('MetaLocalizationsBuilder')} + import 'dart:ui'; import 'package:monarch/monarch.dart'; import '$pathToLocalizationsFile'; diff --git a/packages/monarch/lib/src/builders/meta_stories_builder.dart b/packages/monarch/lib/src/builders/meta_stories_builder.dart new file mode 100644 index 00000000..e18174d1 --- /dev/null +++ b/packages/monarch/lib/src/builders/meta_stories_builder.dart @@ -0,0 +1,101 @@ +import 'dart:async'; + +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:build/build.dart'; + +import 'builder_helper.dart'; + +const metaStoriesExtension = '.meta_stories.g.dart'; + +class MetaStoriesBuilder implements Builder { + @override + Map> get buildExtensions => const { + '.dart': [metaStoriesExtension] + }; + + @override + FutureOr build(BuildStep buildStep) async { + log.fine('Processing ${buildStep.inputId}'); + + var storiesNames = []; + var storiesMap = {}; + + var unit = await buildStep.resolver + .compilationUnitFor(buildStep.inputId, allowSyntaxErrors: true); + + for (var declaration in unit.declarations) { + if (declaration is! FunctionDeclaration) { + log.fine( + 'Skipping: declaration is not a FunctionDeclaration, it is a ${declaration.runtimeType}.'); + continue; + } + + var functionName = declaration.name.lexeme; + var returnType = declaration.returnType; + var parameters = declaration.functionExpression.parameters; + + if (Identifier.isPrivateName(functionName)) { + log.fine('Skipping: function `$functionName` is private.'); + continue; + } + + if (returnType == null) { + log.fine( + 'Skipping: function `$functionName` does not have a return type.'); + continue; + } + + if (returnType is! NamedType) { + log.fine( + 'Skipping: the return type of function `$functionName` is not a NamedType, it is a ${returnType.runtimeType}.'); + continue; + } + + if (parameters == null) { + log.fine( + 'Skipping: function `$functionName` has null parameters, it must be a getter.'); + continue; + } + + if (parameters.parameters.isNotEmpty) { + log.fine( + 'Skipping: function `$functionName` has parameters, story functions should have zero parameters.'); + continue; + } + + /// Potential story function found. It is a potential story because we are not + /// resolving the return type element, which would be expensive. Since we are + /// not resolving the return type element, then we cannot check if it is of type Widget. + /// Instead, we will do a runtime check in [ProjectDataManager.load]. + + var returnTypeName = returnType.name.name; + var storyName = functionName; + var storyNameInSingleQuotes = "'$storyName'"; + log.fine('Found potential story `$returnTypeName $storyName()`.'); + + storiesNames.add(storyNameInSingleQuotes); + storiesMap[storyNameInSingleQuotes] = storyName; + } + + final pathToStoriesFile = getImportUriOrRelativePath(buildStep.inputId); + final output = _outputContents( + pathToStoriesFile, buildStep.inputId, storiesNames, storiesMap); + + var outputId = buildStep.inputId.changeExtension(metaStoriesExtension); + + await buildStep.writeAsString(outputId, output); + } + + String _outputContents(String pathToStoriesFile, AssetId storiesAssetId, + List storiesNames, Map storiesMap) { + return ''' +${generatedCodeHeader('MetaStoriesBuilder')} + +import 'package:monarch/monarch.dart'; +import '$pathToStoriesFile'; + +MetaStories get metaStories => MetaStories.user('${storiesAssetId.package}', '${storiesAssetId.path}', [${storiesNames.join(', ')}], $storiesMap); + +'''; + } +} diff --git a/packages/monarch/lib/src/builders/meta_stories_generator.dart b/packages/monarch/lib/src/builders/meta_stories_generator.dart deleted file mode 100644 index 3fdba4fb..00000000 --- a/packages/monarch/lib/src/builders/meta_stories_generator.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:build/build.dart'; -import 'package:source_gen/source_gen.dart'; -import 'package:analyzer/dart/element/element.dart'; - -import 'builder_helper.dart'; - -const TypeChecker widgetTypeChecker = - TypeChecker.fromUrl('package:flutter/src/widgets/framework.dart#Widget'); - -class MetaStoriesGenerator extends Generator { - @override - String? generate(LibraryReader library, BuildStep buildStep) { - final inputId = buildStep.inputId; - - if (!inputId.path.endsWith('_stories.dart')) { - return null; - } - - log.fine('Processing: ${buildStep.inputId}'); - - var storiesNames = []; - var storiesMap = {}; - - for (var topLevelElement in library.allElements) { - if (topLevelElement is FunctionElement) { - if (topLevelElement.returnType.element != null) { - if (widgetTypeChecker - .isExactly(topLevelElement.returnType.element!)) { - // if (topLevelElement.returnType.element.name == 'Widget') { - final storyName = topLevelElement.name; - final storyNameInSingleQuotes = "'$storyName'"; - log.fine('Found story: $storyName'); - storiesNames.add(storyNameInSingleQuotes); - storiesMap[storyNameInSingleQuotes] = storyName; - } else { - log.fine( - 'Top level function is not story, return type is not Widget: ${topLevelElement.name}'); - } - } else { - log.fine( - 'Could not get return type of top level function, skipping: ${topLevelElement.name}'); - } - } else { - log.fine( - 'Top level element is not story, it is not FunctionElement: ${topLevelElement.name}'); - } - } - - final pathToStoriesFile = getImportUriOrRelativePath(inputId); - - final output = - _outputContents(pathToStoriesFile, inputId, storiesNames, storiesMap); - return output; - } - - String _outputContents(String pathToStoriesFile, AssetId storiesAssetId, - List storiesNames, Map storiesMap) { - return ''' -import 'package:monarch/monarch.dart'; -import '$pathToStoriesFile'; - -MetaStories get metaStories => MetaStories('${storiesAssetId.package}', '${storiesAssetId.path}', [${storiesNames.join(', ')}], $storiesMap); - -'''; - } -} diff --git a/packages/monarch/lib/src/builders/meta_themes_generator.dart b/packages/monarch/lib/src/builders/meta_themes_builder.dart similarity index 64% rename from packages/monarch/lib/src/builders/meta_themes_generator.dart rename to packages/monarch/lib/src/builders/meta_themes_builder.dart index 51bd9ce2..8225075b 100644 --- a/packages/monarch/lib/src/builders/meta_themes_generator.dart +++ b/packages/monarch/lib/src/builders/meta_themes_builder.dart @@ -1,17 +1,39 @@ -import 'package:build/build.dart'; -import 'package:source_gen/source_gen.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'dart:async'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:build/build.dart'; import 'package:monarch_annotations/monarch_annotations.dart'; +import 'package:source_gen/source_gen.dart'; import 'builder_helper.dart'; -const TypeChecker monarchThemeTypeChecker = - TypeChecker.fromRuntime(MonarchTheme); +const metaThemesExtension = '.meta_themes.g.dart'; -class MetaThemesGenerator extends Generator { +class MetaThemesBuilder implements Builder { @override - String? generate(LibraryReader library, BuildStep buildStep) { + Map> get buildExtensions => const { + '.dart': [metaThemesExtension] + }; + + @override + FutureOr build(BuildStep buildStep) async { + /// @GOTCHA: Optimization: + /// This is a quick-and-rough way to check for the presence of an annotation. + /// The proper way is to resolve the compilation unit. However, that is + /// slow to do on every file in the user's project. + var contents = await buildStep.readAsString(buildStep.inputId); + if (!contents.contains('@MonarchTheme')) { + return; + } + + /// Calling `resolver.libraryFor` is expensive. + /// Therefore, we are only calling it on dart libraries that we suspect + /// have a monarch annotation. + var libraryElement = await buildStep.resolver + .libraryFor(buildStep.inputId, allowSyntaxErrors: true); + var library = LibraryReader(libraryElement); + var monarchThemeTypeChecker = TypeChecker.fromRuntime(MonarchTheme); + final annotations = library.annotatedWith(monarchThemeTypeChecker); if (annotations.isEmpty) { return null; @@ -75,12 +97,17 @@ $monarchWarningEnd var pathToThemeFile = getImportUriOrRelativePath(buildStep.inputId); - return _outputContents(pathToThemeFile, expressions); + var output = _outputContents(pathToThemeFile, expressions); + var outputId = buildStep.inputId.changeExtension(metaThemesExtension); + + await buildStep.writeAsString(outputId, output); } String _outputContents( String pathToThemeFile, List metaThemeExpressions) { return ''' +${generatedCodeHeader('MetaThemesBuilder')} + import 'package:monarch/monarch.dart'; import '$pathToThemeFile'; diff --git a/packages/monarch/lib/src/preview/project_data.dart b/packages/monarch/lib/src/preview/project_data.dart index 8b50cf34..04e30eb1 100644 --- a/packages/monarch/lib/src/preview/project_data.dart +++ b/packages/monarch/lib/src/preview/project_data.dart @@ -5,7 +5,7 @@ typedef StoryFunction = Widget Function(); class MetaStories extends MetaStoriesDefinition { /// Maps story name to its function - final Map storiesMap; + final Map storiesMap; MetaStories( String package, @@ -13,6 +13,15 @@ class MetaStories extends MetaStoriesDefinition { List storiesNames, this.storiesMap, ) : super(package: package, path: path, storiesNames: storiesNames); + + MetaStories.user( + String package, + String path, + List storiesNames, + Map dynamicStoriesMap, + ) : storiesMap = dynamicStoriesMap.map((key, value) => + MapEntry(key, value is StoryFunction ? value : null)), + super(package: package, path: path, storiesNames: storiesNames); } class MetaTheme extends MetaThemeDefinition { diff --git a/packages/monarch/lib/src/preview/project_data_manager.dart b/packages/monarch/lib/src/preview/project_data_manager.dart index 725901a8..c418a469 100644 --- a/packages/monarch/lib/src/preview/project_data_manager.dart +++ b/packages/monarch/lib/src/preview/project_data_manager.dart @@ -15,16 +15,42 @@ class ProjectDataManager with Log { void load(ProjectData Function() getData) { var data = getData(); + var validatedMetaStories = + _validateAndFilterMetaStories(data.metaStoriesMap); + var validatedMetaLocalizations = _validateAndFilterMetaLocalizations(data.metaLocalizations); var validatedMetaThemes = _validateAndFilterMetaThemes(data.metaThemes); _data = ProjectData(data.packageName, validatedMetaLocalizations, - validatedMetaThemes, data.metaStoriesMap); + validatedMetaThemes, validatedMetaStories); activeTheme.setMetaThemes([..._data!.metaThemes, ...standardMetaThemes]); } + Map _validateAndFilterMetaStories( + Map metaStoriesMap) { + for (var entry in metaStoriesMap.entries) { + var metaStories = entry.value; + metaStories.storiesMap.removeWhere((storyName, storyFunction) { + if (storyFunction == null) { + _validationMessages.add(''' +$monarchWarningBegin +Function `$storyName` is not of a story function of type `Widget Function()`. It will be ignored. +$monarchWarningEnd +'''); + metaStories.storiesNames + .removeWhere((element) => element == storyName); + return true; + } else { + log.fine('Valid story found: ${metaStories.path} > $storyName'); + return false; + } + }); + } + return metaStoriesMap; + } + List _validateAndFilterMetaLocalizations( List metaLocalizationList) { final list = []; diff --git a/packages/monarch/pubspec.yaml b/packages/monarch/pubspec.yaml index 8100cefd..7d593623 100644 --- a/packages/monarch/pubspec.yaml +++ b/packages/monarch/pubspec.yaml @@ -1,6 +1,6 @@ name: monarch description: Code generator for Monarch. Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. -version: 3.3.0 +version: 3.4.0 homepage: https://monarchapp.io repository: https://github.com/Dropsource/monarch issue_tracker: https://github.com/Dropsource/monarch/issues @@ -25,7 +25,7 @@ dependencies: glob: ^2.0.1 analyzer: ^5.2.0 path: ^1.8.0 - vm_service: ^11.1.0 + vm_service: '>=9.4.0' meta: ^1.3.0 stack_trace: ^1.10.0 flutter_test: From 96dd9893e44b9d8ee93de2d47af8a67b6f82af5e Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Tue, 25 Apr 2023 13:39:36 -0400 Subject: [PATCH 3/7] monarch package: set upper boundery on vm_service dependency (cherry picked from commit 766f20447be334ba3e47d67bc9d1679940a97426) --- packages/monarch/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/monarch/pubspec.yaml b/packages/monarch/pubspec.yaml index 7d593623..0cba4c05 100644 --- a/packages/monarch/pubspec.yaml +++ b/packages/monarch/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: glob: ^2.0.1 analyzer: ^5.2.0 path: ^1.8.0 - vm_service: '>=9.4.0' + vm_service: '>=9.4.0 <12.0.0' meta: ^1.3.0 stack_trace: ^1.10.0 flutter_test: From de1b135a8effc98bb4a8d37d945ae6a6105ef623 Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Wed, 10 May 2023 17:56:16 -0400 Subject: [PATCH 4/7] macos: derive from FlutterAppDelegate --- .../macos/monarch_macos/AppDelegate.swift | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/platform/macos/monarch_macos/AppDelegate.swift b/platform/macos/monarch_macos/AppDelegate.swift index 67edbb79..3bcca8d0 100644 --- a/platform/macos/monarch_macos/AppDelegate.swift +++ b/platform/macos/monarch_macos/AppDelegate.swift @@ -6,14 +6,12 @@ // import Cocoa +import FlutterMacOS @main -class AppDelegate: NSObject, NSApplicationDelegate { +class AppDelegate: FlutterAppDelegate { - - - - func applicationDidFinishLaunching(_ aNotification: Notification) { + override func applicationDidFinishLaunching(_ aNotification: Notification) { // disables buffering so calls to println are flushed automatically // setbuf(__stdoutp, nil); // https://stackoverflow.com/questions/24171362/swift-how-to-flush-stdout-after-println @@ -21,19 +19,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { let windowManager = WindowManager.init() windowManager.launchWindows() } - - func applicationWillTerminate(_ aNotification: Notification) { - - } - func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } - func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { - return true - } - - } From 27a43f406b13821750a1b5819da2e752278b6e1c Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Wed, 10 May 2023 18:37:16 -0400 Subject: [PATCH 5/7] monarch package: adapt MonarchBinding from deprecated TestWindow to TestPlatformDispatcher --- .../lib/src/preview/monarch_binding.dart | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/monarch/lib/src/preview/monarch_binding.dart b/packages/monarch/lib/src/preview/monarch_binding.dart index 053a6713..443f1b85 100644 --- a/packages/monarch/lib/src/preview/monarch_binding.dart +++ b/packages/monarch/lib/src/preview/monarch_binding.dart @@ -26,6 +26,11 @@ class MonarchBinding extends BindingBase SemanticsBinding, RendererBinding, WidgetsBinding { + MonarchBinding() + : platformDispatcher = TestPlatformDispatcher( + platformDispatcher: PlatformDispatcher.instance, + ); + @override void initInstances() { super.initInstances(); @@ -49,17 +54,17 @@ class MonarchBinding extends BindingBase } @override - TestWindow get window => _window; - final _window = TestWindow(window: ui.window); + final TestPlatformDispatcher platformDispatcher; void _onDeviceChanged(DeviceDefinition device) { - window.physicalSizeTestValue = Size( - device.logicalResolution.width * window.devicePixelRatio, - device.logicalResolution.height * window.devicePixelRatio); + var view = platformDispatcher.implicitView!; + view.physicalSize = Size( + device.logicalResolution.width * view.devicePixelRatio, + device.logicalResolution.height * view.devicePixelRatio); } void _onTextScaleFactorChanged(double factor) { - window.platformDispatcher.textScaleFactorTestValue = factor; + platformDispatcher.textScaleFactorTestValue = factor; } final _willReassembleStreamController = StreamController.broadcast(); From 488b6327c9f35ffd04e7dc40693a986e7e53baca Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Wed, 10 May 2023 18:48:45 -0400 Subject: [PATCH 6/7] monarch package: version bump, changelog --- packages/monarch/CHANGELOG.md | 4 ++++ packages/monarch/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/monarch/CHANGELOG.md b/packages/monarch/CHANGELOG.md index 4140d719..577c25e3 100644 --- a/packages/monarch/CHANGELOG.md +++ b/packages/monarch/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.5.0 - 2023-05-10 +- MonarchBinding now uses TestPlatformDispatcher instead of deprecated TestWindow +- The change above was introduced in Flutter 3.9 +- Compatible with Flutter 3.9 or greater ## 3.4.0 - 2023-04-25 - Faster code generation diff --git a/packages/monarch/pubspec.yaml b/packages/monarch/pubspec.yaml index 0cba4c05..8f9effa5 100644 --- a/packages/monarch/pubspec.yaml +++ b/packages/monarch/pubspec.yaml @@ -1,6 +1,6 @@ name: monarch description: Code generator for Monarch. Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. -version: 3.4.0 +version: 3.5.0 homepage: https://monarchapp.io repository: https://github.com/Dropsource/monarch issue_tracker: https://github.com/Dropsource/monarch/issues @@ -9,7 +9,7 @@ documentation: https://monarchapp.io/docs/introduction environment: sdk: '>=2.12.0 <4.0.0' - flutter: '>=3.8.0-0.0.pre' + flutter: '>=3.9.0-0.1.pre' dependencies: flutter: From dbd077606a5460c6866e295aa3f4f361c21927a2 Mon Sep 17 00:00:00 2001 From: Fernando Trigoso Date: Wed, 10 May 2023 19:08:30 -0400 Subject: [PATCH 7/7] dart analyze fixes --- cli/lib/src/config/context_info.dart | 2 +- packages/monarch/lib/src/preview/monarch_binding.dart | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cli/lib/src/config/context_info.dart b/cli/lib/src/config/context_info.dart index d69e9f7d..ab9e1e63 100644 --- a/cli/lib/src/config/context_info.dart +++ b/cli/lib/src/config/context_info.dart @@ -271,7 +271,7 @@ class ContextInfo with Log { log.warning( '"cmake --version" command did not exit successfully, got exit code: ${result.exitCode}'); } - } catch (e, s) { + } catch (_) { log.warning('could not read CMake version'); } } diff --git a/packages/monarch/lib/src/preview/monarch_binding.dart b/packages/monarch/lib/src/preview/monarch_binding.dart index 443f1b85..ccfadee8 100644 --- a/packages/monarch/lib/src/preview/monarch_binding.dart +++ b/packages/monarch/lib/src/preview/monarch_binding.dart @@ -9,7 +9,6 @@ import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'dart:ui' as ui; import 'package:monarch_definitions/monarch_definitions.dart';