Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
62116f99
Unverified
Commit
62116f99
authored
Mar 09, 2023
by
stuartmorgan
Committed by
GitHub
Mar 09, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve Dart plugin registration handling (#122046)
Improve Dart plugin registration handling
parent
7e000b29
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
248 additions
and
113 deletions
+248
-113
flutter_plugins.dart
packages/flutter_tools/lib/src/flutter_plugins.dart
+80
-40
plugins.dart
packages/flutter_tools/lib/src/plugins.dart
+5
-0
dart_plugin_test.dart
...es/flutter_tools/test/general.shard/dart_plugin_test.dart
+163
-73
No files found.
packages/flutter_tools/lib/src/flutter_plugins.dart
View file @
62116f99
...
@@ -1191,13 +1191,13 @@ bool hasPlugins(FlutterProject project) {
...
@@ -1191,13 +1191,13 @@ bool hasPlugins(FlutterProject project) {
/// Resolves the platform implementation for Dart-only plugins.
/// Resolves the platform implementation for Dart-only plugins.
///
///
/// * If there
are multiple direct pub dependencies on packages that implement
the
/// * If there
is only one dependency on a package that implements
the
/// frontend plugin for the current platform,
fail
.
/// frontend plugin for the current platform,
use that
.
/// * If there is a single direct dependency on a package that implements the
/// * If there is a single direct dependency on a package that implements the
/// frontend plugin for the
target platform, this package is the selected implementation
.
/// frontend plugin for the
current platform, use that
.
/// * If there is no direct dependency on a package that implements the
frontend
/// * If there is no direct dependency on a package that implements the
///
plugin for the target platform, and the frontend plugin has a default implementation
///
frontend plugin, but there is a default for the current platform,
///
for the target platform the default implementation is selected
.
///
use that
.
/// * Else fail.
/// * Else fail.
///
///
/// For more details, https://flutter.dev/go/federated-plugins.
/// For more details, https://flutter.dev/go/federated-plugins.
...
@@ -1214,11 +1214,15 @@ List<PluginInterfaceResolution> resolvePlatformImplementation(
...
@@ -1214,11 +1214,15 @@ List<PluginInterfaceResolution> resolvePlatformImplementation(
MacOSPlugin
.
kConfigKey
,
MacOSPlugin
.
kConfigKey
,
WindowsPlugin
.
kConfigKey
,
WindowsPlugin
.
kConfigKey
,
];
];
final
Map
<
String
,
PluginInterfaceResolution
>
directDependency
Resolutions
final
Map
<
String
,
List
<
PluginInterfaceResolution
>>
possible
Resolutions
=
<
String
,
PluginInterfaceResolution
>{};
=
<
String
,
List
<
PluginInterfaceResolution
>
>{};
final
Map
<
String
,
String
>
defaultImplementations
=
<
String
,
String
>{};
final
Map
<
String
,
String
>
defaultImplementations
=
<
String
,
String
>{};
bool
didFindError
=
false
;
// Generates a key for the maps above.
String
getResolutionKey
({
required
String
platform
,
required
String
packageName
})
{
return
'
$packageName
:
$platform
'
;
}
bool
hasPubspecError
=
false
;
for
(
final
Plugin
plugin
in
plugins
)
{
for
(
final
Plugin
plugin
in
plugins
)
{
for
(
final
String
platform
in
platforms
)
{
for
(
final
String
platform
in
platforms
)
{
if
(
plugin
.
platforms
[
platform
]
==
null
&&
if
(
plugin
.
platforms
[
platform
]
==
null
&&
...
@@ -1257,11 +1261,12 @@ List<PluginInterfaceResolution> resolvePlatformImplementation(
...
@@ -1257,11 +1261,12 @@ List<PluginInterfaceResolution> resolvePlatformImplementation(
'
\n
'
'
\n
'
);
);
}
}
didFind
Error
=
true
;
hasPubspec
Error
=
true
;
continue
;
continue
;
}
}
final
String
defaultImplementationKey
=
getResolutionKey
(
platform:
platform
,
packageName:
plugin
.
name
);
if
(
defaultImplementation
!=
null
)
{
if
(
defaultImplementation
!=
null
)
{
defaultImplementations
[
'
$platform
/
${plugin.name}
'
]
=
defaultImplementation
;
defaultImplementations
[
defaultImplementationKey
]
=
defaultImplementation
;
continue
;
continue
;
}
else
{
}
else
{
// An app-facing package (i.e., one with no 'implements') with an
// An app-facing package (i.e., one with no 'implements') with an
...
@@ -1281,52 +1286,87 @@ List<PluginInterfaceResolution> resolvePlatformImplementation(
...
@@ -1281,52 +1286,87 @@ List<PluginInterfaceResolution> resolvePlatformImplementation(
minFlutterVersion
.
compareTo
(
semver
.
Version
(
2
,
11
,
0
))
>=
0
;
minFlutterVersion
.
compareTo
(
semver
.
Version
(
2
,
11
,
0
))
>=
0
;
if
(!
isDesktop
||
hasMinVersionForImplementsRequirement
)
{
if
(!
isDesktop
||
hasMinVersionForImplementsRequirement
)
{
implementsPackage
=
plugin
.
name
;
implementsPackage
=
plugin
.
name
;
defaultImplementations
[
'
$platform
/
${plugin.name}
'
]
=
plugin
.
name
;
defaultImplementations
[
defaultImplementationKey
]
=
plugin
.
name
;
}
else
{
// If it doesn't meet any of the conditions, it isn't eligible for
// auto-registration.
continue
;
}
}
}
}
}
}
// If there's no Dart implementation, there's nothing to register.
if
(
plugin
.
pluginDartClassPlatforms
[
platform
]
==
null
||
if
(
plugin
.
pluginDartClassPlatforms
[
platform
]
==
null
||
plugin
.
pluginDartClassPlatforms
[
platform
]
==
'none'
)
{
plugin
.
pluginDartClassPlatforms
[
platform
]
==
'none'
)
{
continue
;
continue
;
}
}
final
String
resolutionKey
=
'
$platform
/
$implementsPackage
'
;
if
(
directDependencyResolutions
.
containsKey
(
resolutionKey
))
{
// If it hasn't been skipped, it's a candidate for auto-registration, so
final
PluginInterfaceResolution
?
currResolution
=
directDependencyResolutions
[
resolutionKey
];
// add it as a possible resolution.
if
(
currResolution
!=
null
&&
currResolution
.
plugin
.
isDirectDependency
)
{
final
String
resolutionKey
=
getResolutionKey
(
platform:
platform
,
packageName:
implementsPackage
);
if
(
plugin
.
isDirectDependency
)
{
if
(!
possibleResolutions
.
containsKey
(
resolutionKey
))
{
if
(
throwOnPluginPubspecError
)
{
possibleResolutions
[
resolutionKey
]
=
<
PluginInterfaceResolution
>[];
globals
.
printError
(
'Plugin `
${plugin.name}
` implements an interface for `
$platform
`, which was already '
'implemented by plugin `
${currResolution.plugin.name}
`.
\n
'
'To fix this issue, remove either dependency from pubspec.yaml.'
'
\n\n
'
);
}
didFindError
=
true
;
}
// Use the plugin implementation added by the user as a direct dependency.
continue
;
}
}
}
directDependencyResolutions
[
resolutionKey
]
=
PluginInterfaceResolution
(
possibleResolutions
[
resolutionKey
]!.
add
(
PluginInterfaceResolution
(
plugin:
plugin
,
plugin:
plugin
,
platform:
platform
,
platform:
platform
,
);
)
)
;
}
}
}
}
if
(
didFind
Error
&&
throwOnPluginPubspecError
)
{
if
(
hasPubspec
Error
&&
throwOnPluginPubspecError
)
{
throwToolExit
(
'Please resolve the errors'
);
throwToolExit
(
'Please resolve the errors'
);
}
}
// Now resolve all the possible resolutions to a single option for each
// plugin, or throw if that's not possible.
bool
hasResolutionError
=
false
;
final
List
<
PluginInterfaceResolution
>
finalResolution
=
<
PluginInterfaceResolution
>[];
final
List
<
PluginInterfaceResolution
>
finalResolution
=
<
PluginInterfaceResolution
>[];
for
(
final
MapEntry
<
String
,
PluginInterfaceResolution
>
resolution
in
directDependencyResolutions
.
entries
)
{
for
(
final
MapEntry
<
String
,
List
<
PluginInterfaceResolution
>>
entry
in
possibleResolutions
.
entries
)
{
if
(
resolution
.
value
.
plugin
.
isDirectDependency
)
{
final
List
<
PluginInterfaceResolution
>
candidates
=
entry
.
value
;
finalResolution
.
add
(
resolution
.
value
);
// If there's only one candidate, use it.
}
else
if
(
defaultImplementations
.
containsKey
(
resolution
.
key
))
{
if
(
candidates
.
length
==
1
)
{
// Pick the default implementation.
finalResolution
.
add
(
candidates
.
first
);
if
(
defaultImplementations
[
resolution
.
key
]
==
resolution
.
value
.
plugin
.
name
)
{
continue
;
finalResolution
.
add
(
resolution
.
value
);
}
// Next, try direct dependencies of the resolving application.
final
Iterable
<
PluginInterfaceResolution
>
directDependencies
=
candidates
.
where
((
PluginInterfaceResolution
r
)
{
return
r
.
plugin
.
isDirectDependency
;
});
if
(
directDependencies
.
isNotEmpty
)
{
if
(
directDependencies
.
length
>
1
)
{
globals
.
printError
(
'Plugin
${entry.key}
has conflicting direct dependency implementations:
\n
'
'
${directDependencies.map((PluginInterfaceResolution r) => ' ${r.plugin.name}
\n
'
).
join
()}
'
'
To
fix
this
issue
,
remove
all
but
one
of
these
dependencies
from
pubspec
.
yaml
.
\
n
'
);
hasResolutionError = true;
} else {
finalResolution.add(directDependencies.first);
}
continue;
}
// Next, defer to the default implementation if there is one.
final String? defaultPackageName = defaultImplementations[entry.key];
if (defaultPackageName != null) {
final int defaultIndex = candidates
.indexWhere((PluginInterfaceResolution r) => r.plugin.name == defaultPackageName);
if (defaultIndex != -1) {
finalResolution.add(candidates[defaultIndex]);
continue;
}
}
}
}
// Otherwise, require an explicit choice.
if (candidates.length > 1) {
globals.printError(
'
Plugin
$
{
entry
.
key
}
has
multiple
possible
implementations:
\
n
'
'
$
{
candidates
.
map
((
PluginInterfaceResolution
r
)
=>
'
${r.plugin.name}
\n
'
).
join
()}
'
'
To
fix
this
issue
,
add
one
of
these
dependencies
to
pubspec
.
yaml
.
\
n
'
);
hasResolutionError = true;
continue;
}
}
if (hasResolutionError) {
throwToolExit('
Please
resolve
the
errors
');
}
}
return finalResolution;
return finalResolution;
}
}
...
...
packages/flutter_tools/lib/src/plugins.dart
View file @
62116f99
...
@@ -418,4 +418,9 @@ class PluginInterfaceResolution {
...
@@ -418,4 +418,9 @@ class PluginInterfaceResolution {
'dartClass'
:
plugin
.
pluginDartClassPlatforms
[
platform
]
??
''
,
'dartClass'
:
plugin
.
pluginDartClassPlatforms
[
platform
]
??
''
,
};
};
}
}
@override
String
toString
()
{
return
'<PluginInterfaceResolution
${plugin.name}
for
$platform
>'
;
}
}
}
packages/flutter_tools/test/general.shard/dart_plugin_test.dart
View file @
62116f99
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment