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
3fb389c7
Unverified
Commit
3fb389c7
authored
Nov 10, 2020
by
Jonah Williams
Committed by
GitHub
Nov 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[null-safety] implement null-safe autodetection for the web (#70126)
Fixes #69416 Fixes #70121
parent
ff953e4f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
102 additions
and
48 deletions
+102
-48
web.dart
packages/flutter_tools/lib/src/build_system/targets/web.dart
+4
-4
language_version.dart
packages/flutter_tools/lib/src/dart/language_version.dart
+21
-8
resident_web_runner.dart
...s/flutter_tools/lib/src/isolated/resident_web_runner.dart
+5
-4
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+24
-8
flutter_platform.dart
packages/flutter_tools/lib/src/test/flutter_platform.dart
+5
-5
web_test.dart
...ols/test/general.shard/build_system/targets/web_test.dart
+1
-1
language_version_test.dart
..._tools/test/general.shard/dart/language_version_test.dart
+42
-18
No files found.
packages/flutter_tools/lib/src/build_system/targets/web.dart
View file @
3fb389c7
...
...
@@ -95,10 +95,10 @@ class WebEntrypointTarget extends Target {
logger:
environment
.
logger
,
);
final
FlutterProject
flutterProject
=
FlutterProject
.
current
();
final
String
languageVersion
=
determineLanguageVersion
(
final
LanguageVersion
languageVersion
=
determineLanguageVersion
(
environment
.
fileSystem
.
file
(
targetFile
),
packageConfig
[
flutterProject
.
manifest
.
appName
],
)
??
''
;
);
// Use the PackageConfig to find the correct package-scheme import path
// for the user application. If the application has a mix of package-scheme
...
...
@@ -122,7 +122,7 @@ class WebEntrypointTarget extends Target {
final
String
generatedImport
=
packageConfig
.
toPackageUri
(
generatedUri
)?.
toString
()
??
generatedUri
.
toString
();
contents
=
'''
$languageVersion
// @dart=
${languageVersion.major}
.
${languageVersion.minor}
import '
dart:
ui
' as ui;
...
...
@@ -139,7 +139,7 @@ Future<void> main() async {
'''
;
}
else
{
contents
=
'''
$languageVersion
// @dart=
${languageVersion.major}
.
${languageVersion.minor}
import '
dart:
ui
' as ui;
...
...
packages/flutter_tools/lib/src/dart/language_version.dart
View file @
3fb389c7
...
...
@@ -5,22 +5,24 @@
import
'package:file/file.dart'
;
import
'package:package_config/package_config.dart'
;
final
RegExp
_languageVersion
=
RegExp
(
r'\/\/\s*@dart'
);
final
RegExp
_languageVersion
=
RegExp
(
r'\/\/\s*@dart
\s*=\s*([0-9])\.([0-9]+)
'
);
final
RegExp
_declarationEnd
=
RegExp
(
'(import)|(library)|(part)'
);
const
String
_blockCommentStart
=
'/*'
;
const
String
_blockCommentEnd
=
'*/'
;
/// Attempts to read the language version of a dart [file], returning
/// the entire comment.
/// The first language version where null safety was available by default.
final
LanguageVersion
nullSafeVersion
=
LanguageVersion
(
2
,
12
);
/// Attempts to read the language version of a dart [file].
///
/// If this is not present, falls back to the language version defined in
/// [package]. If [package] is not provided and there is no
/// language version header, returns
`null`
. This does not specifically check
/// language version header, returns
2.12
. This does not specifically check
/// for language declarations other than library, part, or import.
///
/// The specification for the language version tag is defined at:
/// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
String
determineLanguageVersion
(
File
file
,
Package
package
)
{
LanguageVersion
determineLanguageVersion
(
File
file
,
Package
package
)
{
int
blockCommentDepth
=
0
;
for
(
final
String
line
in
file
.
readAsLinesSync
())
{
final
String
trimmedLine
=
line
.
trim
();
...
...
@@ -50,7 +52,17 @@ String determineLanguageVersion(File file, Package package) {
// Check for a match with the language version.
final
Match
match
=
_languageVersion
.
matchAsPrefix
(
trimmedLine
);
if
(
match
!=
null
)
{
return
trimmedLine
;
final
String
rawMajor
=
match
.
group
(
1
);
final
String
rawMinor
=
match
.
group
(
2
);
try
{
final
int
major
=
int
.
parse
(
rawMajor
);
final
int
minor
=
int
.
parse
(
rawMinor
);
return
LanguageVersion
(
major
,
minor
);
}
on
FormatException
{
// Language comment was invalid in a way that the regexp did not
// anticipate.
break
;
}
}
// Check for a declaration which ends the search for a language
...
...
@@ -62,7 +74,8 @@ String determineLanguageVersion(File file, Package package) {
// If the language version cannot be found, use the package version.
if
(
package
!=
null
)
{
return
'// @dart =
${package.languageVersion}
'
;
return
package
.
languageVersion
;
}
return
null
;
// Default to 2.12
return
nullSafeVersion
;
}
packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
View file @
3fb389c7
...
...
@@ -669,12 +669,13 @@ class _ResidentWebRunner extends ResidentWebRunner {
path:
'/'
+
mainUri
.
pathSegments
.
last
,
);
}
final
LanguageVersion
languageVersion
=
determineLanguageVersion
(
globals
.
fs
.
file
(
mainUri
),
packageConfig
[
flutterProject
.
manifest
.
appName
],
);
final
String
entrypoint
=
<
String
>[
determineLanguageVersion
(
globals
.
fs
.
file
(
mainUri
),
packageConfig
[
flutterProject
.
manifest
.
appName
],
),
'// @dart=
${languageVersion.major}
.
${languageVersion.minor}
'
,
'// Flutter web bootstrap script for
$importedEntrypoint
.'
,
''
,
"import 'dart:ui' as ui;"
,
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
3fb389c7
...
...
@@ -27,6 +27,8 @@ import 'build_system/targets/localizations.dart';
import
'bundle.dart'
;
import
'cache.dart'
;
import
'compile.dart'
;
import
'dart/language_version.dart'
;
import
'dart/package_map.dart'
;
import
'devfs.dart'
;
import
'device.dart'
;
import
'features.dart'
;
...
...
@@ -101,14 +103,28 @@ class FlutterDevice {
platformDillArtifact
=
Artifact
.
webPlatformSoundKernelDill
;
extraFrontEndOptions
=
buildInfo
.
extraFrontEndOptions
;
}
else
{
// TODO(jonahwilliams): null-safe auto detection does not currently
// work on the web. Always opt out of null safety if it was not
// specifically requested.
platformDillArtifact
=
Artifact
.
webPlatformKernelDill
;
extraFrontEndOptions
=
<
String
>[
...?
buildInfo
.
extraFrontEndOptions
,
'--no-sound-null-safety'
,
];
final
PackageConfig
packageConfig
=
await
loadPackageConfigWithLogging
(
globals
.
fs
.
file
(
buildInfo
.
packagesPath
),
logger:
globals
.
logger
,
);
final
File
entrypointFile
=
globals
.
fs
.
file
(
target
);
final
LanguageVersion
languageVersion
=
determineLanguageVersion
(
entrypointFile
,
packageConfig
.
packageOf
(
entrypointFile
.
absolute
.
uri
),
);
if
(
languageVersion
.
major
>=
nullSafeVersion
.
major
&&
languageVersion
.
minor
>=
nullSafeVersion
.
minor
)
{
platformDillArtifact
=
Artifact
.
webPlatformSoundKernelDill
;
extraFrontEndOptions
=
<
String
>[
...?
buildInfo
.
extraFrontEndOptions
,
'--sound-null-safety'
,
];
}
else
{
platformDillArtifact
=
Artifact
.
webPlatformKernelDill
;
extraFrontEndOptions
=
<
String
>[
...?
buildInfo
.
extraFrontEndOptions
,
'--no-sound-null-safety'
,
];
}
}
generator
=
ResidentCompiler
(
...
...
packages/flutter_tools/lib/src/test/flutter_platform.dart
View file @
3fb389c7
...
...
@@ -713,19 +713,19 @@ class FlutterPlatform extends PlatformPlugin {
})
{
assert
(
testUrl
.
scheme
==
'file'
);
final
File
file
=
globals
.
fs
.
file
(
testUrl
);
final
LanguageVersion
languageVersion
=
determineLanguageVersion
(
file
,
_packageConfig
[
flutterProject
?.
manifest
?.
appName
],
);
return
generateTestBootstrap
(
testUrl:
testUrl
,
testConfigFile:
findTestConfigFile
(
globals
.
fs
.
file
(
testUrl
)),
host:
host
,
updateGoldens:
updateGoldens
,
languageVersionHeader:
determineLanguageVersion
(
file
,
_packageConfig
[
flutterProject
?.
manifest
?.
appName
],
),
languageVersionHeader:
'// @dart=
${languageVersion.major}
.
${languageVersion.minor}
'
);
}
File
_cachedFontConfig
;
@override
...
...
packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
View file @
3fb389c7
...
...
@@ -238,7 +238,7 @@ void main() {
final
String
generated
=
environment
.
buildDir
.
childFile
(
'main.dart'
).
readAsStringSync
();
// Language version
expect
(
generated
,
contains
(
'// @dart
=
2.7'
));
expect
(
generated
,
contains
(
'// @dart
=
2.7'
));
}));
test
(
'WebEntrypointTarget generates an entrypoint without plugins and without init platform'
,
()
=>
testbed
.
run
(()
async
{
...
...
packages/flutter_tools/test/general.shard/dart/language_version_test.dart
View file @
3fb389c7
...
...
@@ -19,10 +19,34 @@ void main() {
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
'// @dart = 2.9'
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
9
)
);
});
testWithoutContext
(
'detects technically invalid language version'
,
()
{
testWithoutContext
(
'detects language version in comment without spacing'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
File
file
=
fileSystem
.
file
(
'example.dart'
)
..
writeAsStringSync
(
'''
// Some license
// @dart=2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
9
));
});
testWithoutContext
(
'detects language version in comment with more numbers'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
File
file
=
fileSystem
.
file
(
'example.dart'
)
..
writeAsStringSync
(
'''
// Some license
// @dart=2.12
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
));
});
testWithoutContext
(
'does not detect invalid language version'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
File
file
=
fileSystem
.
file
(
'example.dart'
)
..
writeAsStringSync
(
'''
...
...
@@ -31,7 +55,7 @@ void main() {
// @dart
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
'// @dart'
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'detects language version with leading whitespace'
,
()
{
...
...
@@ -43,7 +67,7 @@ void main() {
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
'// @dart = 2.9'
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
9
)
);
});
testWithoutContext
(
'detects language version with tabs'
,
()
{
...
...
@@ -55,7 +79,7 @@ void main() {
//
\t
@dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
'//
\t
@dart = 2.9'
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
9
)
);
});
testWithoutContext
(
'detects language version with tons of whitespace'
,
()
{
...
...
@@ -64,10 +88,10 @@ void main() {
..
writeAsStringSync
(
'''
// Some license
// @dart = 23
// @dart = 2
.2
3
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
'// @dart = 23'
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
23
)
);
});
testWithoutContext
(
'does not detect language version in dartdoc'
,
()
{
...
...
@@ -79,7 +103,7 @@ void main() {
/// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not detect language version in block comment'
,
()
{
...
...
@@ -93,7 +117,7 @@ void main() {
*/
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not detect language version in nested block comment'
,
()
{
...
...
@@ -109,7 +133,7 @@ void main() {
*/
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'detects language version after nested block comment'
,
()
{
...
...
@@ -124,7 +148,7 @@ void main() {
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
'// @dart = 2.9'
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
9
)
);
});
testWithoutContext
(
'does not crash with unbalanced opening block comments'
,
()
{
...
...
@@ -139,7 +163,7 @@ void main() {
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not crash with unbalanced closing block comments'
,
()
{
...
...
@@ -154,7 +178,7 @@ void main() {
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not detect language version in single line block comment'
,
()
{
...
...
@@ -166,7 +190,7 @@ void main() {
/* // @dart = 2.9 */
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not detect language version after import declaration'
,
()
{
...
...
@@ -180,7 +204,7 @@ import 'dart:ui' as ui;
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not detect language version after part declaration'
,
()
{
...
...
@@ -194,7 +218,7 @@ part of 'foo.dart';
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'does not detect language version after library declaration'
,
()
{
...
...
@@ -208,7 +232,7 @@ library funstuff;
// @dart = 2.9
'''
);
expect
(
determineLanguageVersion
(
file
,
null
),
null
);
expect
(
determineLanguageVersion
(
file
,
null
),
LanguageVersion
(
2
,
12
)
);
});
testWithoutContext
(
'looks up language version from package if not found in file'
,
()
{
...
...
@@ -223,6 +247,6 @@ library funstuff;
languageVersion:
LanguageVersion
(
2
,
7
),
);
expect
(
determineLanguageVersion
(
file
,
package
),
'// @dart = 2.7'
);
expect
(
determineLanguageVersion
(
file
,
package
),
LanguageVersion
(
2
,
7
)
);
});
}
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