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
f712fecd
Unverified
Commit
f712fecd
authored
Mar 25, 2021
by
Jenn Magder
Committed by
GitHub
Mar 25, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate visual_studio to null safety (#78942)
parent
c49cd271
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
46 deletions
+64
-46
visual_studio.dart
packages/flutter_tools/lib/src/windows/visual_studio.dart
+52
-46
visual_studio_test.dart
..._tools/test/general.shard/windows/visual_studio_test.dart
+12
-0
No files found.
packages/flutter_tools/lib/src/windows/visual_studio.dart
View file @
f712fecd
...
@@ -2,11 +2,9 @@
...
@@ -2,11 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'package:meta/meta.dart'
;
import
'package:process/process.dart'
;
import
'package:process/process.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/logger.dart'
;
...
@@ -18,10 +16,10 @@ import '../convert.dart';
...
@@ -18,10 +16,10 @@ import '../convert.dart';
/// Encapsulates information about the installed copy of Visual Studio, if any.
/// Encapsulates information about the installed copy of Visual Studio, if any.
class
VisualStudio
{
class
VisualStudio
{
VisualStudio
({
VisualStudio
({
@
required
FileSystem
fileSystem
,
required
FileSystem
fileSystem
,
@
required
ProcessManager
processManager
,
required
ProcessManager
processManager
,
@
required
Platform
platform
,
required
Platform
platform
,
@
required
Logger
logger
,
required
Logger
logger
,
})
:
_platform
=
platform
,
})
:
_platform
=
platform
,
_fileSystem
=
fileSystem
,
_fileSystem
=
fileSystem
,
_processUtils
=
ProcessUtils
(
processManager:
processManager
,
logger:
logger
);
_processUtils
=
ProcessUtils
(
processManager:
processManager
,
logger:
logger
);
...
@@ -38,7 +36,7 @@ class VisualStudio {
...
@@ -38,7 +36,7 @@ class VisualStudio {
bool
get
isInstalled
=>
_bestVisualStudioDetails
.
isNotEmpty
;
bool
get
isInstalled
=>
_bestVisualStudioDetails
.
isNotEmpty
;
bool
get
isAtLeastMinimumVersion
{
bool
get
isAtLeastMinimumVersion
{
final
int
installedMajorVersion
=
_majorVersion
;
final
int
?
installedMajorVersion
=
_majorVersion
;
return
installedMajorVersion
!=
null
&&
installedMajorVersion
>=
_minimumSupportedVersion
;
return
installedMajorVersion
!=
null
&&
installedMajorVersion
>=
_minimumSupportedVersion
;
}
}
...
@@ -54,7 +52,7 @@ class VisualStudio {
...
@@ -54,7 +52,7 @@ class VisualStudio {
/// The user-friendly version number of the Visual Studio install.
/// The user-friendly version number of the Visual Studio install.
///
///
/// For instance: "15.4.0".
/// For instance: "15.4.0".
String
get
displayVersion
{
String
?
get
displayVersion
{
if
(
_bestVisualStudioDetails
[
_catalogKey
]
==
null
)
{
if
(
_bestVisualStudioDetails
[
_catalogKey
]
==
null
)
{
return
null
;
return
null
;
}
}
...
@@ -80,7 +78,7 @@ class VisualStudio {
...
@@ -80,7 +78,7 @@ class VisualStudio {
if
(
_bestVisualStudioDetails
.
isEmpty
)
{
if
(
_bestVisualStudioDetails
.
isEmpty
)
{
return
false
;
return
false
;
}
}
return
_bestVisualStudioDetails
[
_isCompleteKey
]
as
bool
??
true
;
return
_bestVisualStudioDetails
[
_isCompleteKey
]
as
bool
?
??
true
;
}
}
/// True if Visual Studio is launchable.
/// True if Visual Studio is launchable.
...
@@ -90,14 +88,14 @@ class VisualStudio {
...
@@ -90,14 +88,14 @@ class VisualStudio {
if
(
_bestVisualStudioDetails
.
isEmpty
)
{
if
(
_bestVisualStudioDetails
.
isEmpty
)
{
return
false
;
return
false
;
}
}
return
_bestVisualStudioDetails
[
_isLaunchableKey
]
as
bool
??
true
;
return
_bestVisualStudioDetails
[
_isLaunchableKey
]
as
bool
?
??
true
;
}
}
/// True if the Visual Studio installation is as pre-release version.
/// True if the Visual Studio installation is as pre-release version.
bool
get
isPrerelease
=>
_bestVisualStudioDetails
[
_isPrereleaseKey
]
as
bool
??
false
;
bool
get
isPrerelease
=>
_bestVisualStudioDetails
[
_isPrereleaseKey
]
as
bool
?
??
false
;
/// True if a reboot is required to complete the Visual Studio installation.
/// True if a reboot is required to complete the Visual Studio installation.
bool
get
isRebootRequired
=>
_bestVisualStudioDetails
[
_isRebootRequiredKey
]
as
bool
??
false
;
bool
get
isRebootRequired
=>
_bestVisualStudioDetails
[
_isRebootRequiredKey
]
as
bool
?
??
false
;
/// The name of the recommended Visual Studio installer workload.
/// The name of the recommended Visual Studio installer workload.
String
get
workloadDescription
=>
'Desktop development with C++'
;
String
get
workloadDescription
=>
'Desktop development with C++'
;
...
@@ -106,8 +104,8 @@ class VisualStudio {
...
@@ -106,8 +104,8 @@ class VisualStudio {
/// found.
/// found.
///
///
/// For instance: 10.0.18362.0.
/// For instance: 10.0.18362.0.
String
getWindows10SDKVersion
()
{
String
?
getWindows10SDKVersion
()
{
final
String
sdkLocation
=
_getWindows10SdkLocation
();
final
String
?
sdkLocation
=
_getWindows10SdkLocation
();
if
(
sdkLocation
==
null
)
{
if
(
sdkLocation
==
null
)
{
return
null
;
return
null
;
}
}
...
@@ -116,13 +114,13 @@ class VisualStudio {
...
@@ -116,13 +114,13 @@ class VisualStudio {
return
null
;
return
null
;
}
}
// The directories in this folder are named by the SDK version.
// The directories in this folder are named by the SDK version.
Version
highestVersion
;
Version
?
highestVersion
;
for
(
final
FileSystemEntity
versionEntry
in
sdkIncludeDirectory
.
listSync
())
{
for
(
final
FileSystemEntity
versionEntry
in
sdkIncludeDirectory
.
listSync
())
{
if
(
versionEntry
.
basename
.
startsWith
(
'10.'
))
{
if
(
versionEntry
.
basename
.
startsWith
(
'10.'
))
{
// Version only handles 3 components; strip off the '10.' to leave three
// Version only handles 3 components; strip off the '10.' to leave three
// components, since they all start with that.
// components, since they all start with that.
final
Version
version
=
Version
.
parse
(
versionEntry
.
basename
.
substring
(
3
));
final
Version
?
version
=
Version
.
parse
(
versionEntry
.
basename
.
substring
(
3
));
if
(
highestVersion
==
null
||
version
>
highestVersion
)
{
if
(
highestVersion
==
null
||
(
version
!=
null
&&
version
>
highestVersion
)
)
{
highestVersion
=
version
;
highestVersion
=
version
;
}
}
}
}
...
@@ -151,7 +149,7 @@ class VisualStudio {
...
@@ -151,7 +149,7 @@ class VisualStudio {
/// The path to CMake, or null if no Visual Studio installation has
/// The path to CMake, or null if no Visual Studio installation has
/// the components necessary to build.
/// the components necessary to build.
String
get
cmakePath
{
String
?
get
cmakePath
{
final
Map
<
String
,
dynamic
>
details
=
_usableVisualStudioDetails
;
final
Map
<
String
,
dynamic
>
details
=
_usableVisualStudioDetails
;
if
(
details
.
isEmpty
)
{
if
(
details
.
isEmpty
)
{
return
null
;
return
null
;
...
@@ -170,7 +168,7 @@ class VisualStudio {
...
@@ -170,7 +168,7 @@ class VisualStudio {
}
}
/// The major version of the Visual Studio install, as an integer.
/// The major version of the Visual Studio install, as an integer.
int
get
_majorVersion
=>
fullVersion
!=
null
?
int
.
tryParse
(
fullVersion
.
split
(
'.'
)[
0
])
:
null
;
int
?
get
_majorVersion
=>
fullVersion
!=
null
?
int
.
tryParse
(
fullVersion
.
split
(
'.'
)[
0
])
:
null
;
/// The path to vswhere.exe.
/// The path to vswhere.exe.
///
///
...
@@ -178,12 +176,18 @@ class VisualStudio {
...
@@ -178,12 +176,18 @@ class VisualStudio {
/// present then there isn't a new enough installation of VS. This path is
/// present then there isn't a new enough installation of VS. This path is
/// not user-controllable, unlike the install location of Visual Studio
/// not user-controllable, unlike the install location of Visual Studio
/// itself.
/// itself.
String
get
_vswherePath
=>
_fileSystem
.
path
.
join
(
String
get
_vswherePath
{
_platform
.
environment
[
'PROGRAMFILES(X86)'
],
const
String
programFilesEnv
=
'PROGRAMFILES(X86)'
;
'Microsoft Visual Studio'
,
if
(!
_platform
.
environment
.
containsKey
(
programFilesEnv
))
{
'Installer'
,
throwToolExit
(
'%
$programFilesEnv
% environment variable not found.'
);
'vswhere.exe'
,
}
);
return
_fileSystem
.
path
.
join
(
_platform
.
environment
[
programFilesEnv
]!,
'Microsoft Visual Studio'
,
'Installer'
,
'vswhere.exe'
,
);
}
/// Workload ID for use with vswhere requirements.
/// Workload ID for use with vswhere requirements.
///
///
...
@@ -198,7 +202,7 @@ class VisualStudio {
...
@@ -198,7 +202,7 @@ class VisualStudio {
///
///
/// Maps from component IDs to description in the installer UI.
/// Maps from component IDs to description in the installer UI.
/// See https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
/// See https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
Map
<
String
,
String
>
_requiredComponents
([
int
majorVersion
])
{
Map
<
String
,
String
>
_requiredComponents
([
int
?
majorVersion
])
{
// The description of the C++ toolchain required by the template. The
// The description of the C++ toolchain required by the template. The
// component name is significantly different in different versions.
// component name is significantly different in different versions.
// When a new major version of VS is supported, its toolchain description
// When a new major version of VS is supported, its toolchain description
...
@@ -273,15 +277,17 @@ class VisualStudio {
...
@@ -273,15 +277,17 @@ class VisualStudio {
/// Returns the details dictionary for the newest version of Visual Studio.
/// Returns the details dictionary for the newest version of Visual Studio.
/// If [validateRequirements] is set, the search will be limited to versions
/// If [validateRequirements] is set, the search will be limited to versions
/// that have all of the required workloads and components.
/// that have all of the required workloads and components.
Map
<
String
,
dynamic
>
_visualStudioDetails
({
Map
<
String
,
dynamic
>
?
_visualStudioDetails
({
bool
validateRequirements
=
false
,
bool
validateRequirements
=
false
,
List
<
String
>
additionalArguments
,
List
<
String
>
?
additionalArguments
,
String
requiredWorkload
String
?
requiredWorkload
})
{
})
{
final
List
<
String
>
requirementArguments
=
validateRequirements
final
List
<
String
>
requirementArguments
=
validateRequirements
?
<
String
>[
?
<
String
>[
'-requires'
,
if
(
requiredWorkload
!=
null
)
...<
String
>[
requiredWorkload
,
'-requires'
,
requiredWorkload
,
],
...
_requiredComponents
(
_minimumSupportedVersion
).
keys
...
_requiredComponents
(
_minimumSupportedVersion
).
keys
]
]
:
<
String
>[];
:
<
String
>[];
...
@@ -296,7 +302,7 @@ class VisualStudio {
...
@@ -296,7 +302,7 @@ class VisualStudio {
_vswherePath
,
_vswherePath
,
...
defaultArguments
,
...
defaultArguments
,
...?
additionalArguments
,
...?
additionalArguments
,
...
?
requirementArguments
,
...
requirementArguments
,
],
encoding:
utf8
);
],
encoding:
utf8
);
if
(
whereResult
.
exitCode
==
0
)
{
if
(
whereResult
.
exitCode
==
0
)
{
final
List
<
Map
<
String
,
dynamic
>>
installations
=
final
List
<
Map
<
String
,
dynamic
>>
installations
=
...
@@ -342,16 +348,16 @@ class VisualStudio {
...
@@ -342,16 +348,16 @@ class VisualStudio {
///
///
/// If no installation is found, the cached VS details are set to an empty map
/// If no installation is found, the cached VS details are set to an empty map
/// to avoid repeating vswhere queries that have already not found an installation.
/// to avoid repeating vswhere queries that have already not found an installation.
Map
<
String
,
dynamic
>
_cachedUsableVisualStudioDetails
;
Map
<
String
,
dynamic
>
?
_cachedUsableVisualStudioDetails
;
Map
<
String
,
dynamic
>
get
_usableVisualStudioDetails
{
Map
<
String
,
dynamic
>
get
_usableVisualStudioDetails
{
if
(
_cachedUsableVisualStudioDetails
!=
null
)
{
if
(
_cachedUsableVisualStudioDetails
!=
null
)
{
return
_cachedUsableVisualStudioDetails
;
return
_cachedUsableVisualStudioDetails
!
;
}
}
final
List
<
String
>
minimumVersionArguments
=
<
String
>[
final
List
<
String
>
minimumVersionArguments
=
<
String
>[
_vswhereMinVersionArgument
,
_vswhereMinVersionArgument
,
_minimumSupportedVersion
.
toString
(),
_minimumSupportedVersion
.
toString
(),
];
];
Map
<
String
,
dynamic
>
visualStudioDetails
;
Map
<
String
,
dynamic
>
?
visualStudioDetails
;
// Check in the order of stable VS, stable BT, pre-release VS, pre-release BT
// Check in the order of stable VS, stable BT, pre-release VS, pre-release BT
for
(
final
bool
checkForPrerelease
in
<
bool
>[
false
,
true
])
{
for
(
final
bool
checkForPrerelease
in
<
bool
>[
false
,
true
])
{
for
(
final
String
requiredWorkload
in
_requiredWorkloads
)
{
for
(
final
String
requiredWorkload
in
_requiredWorkloads
)
{
...
@@ -372,7 +378,7 @@ class VisualStudio {
...
@@ -372,7 +378,7 @@ class VisualStudio {
}
}
}
}
_cachedUsableVisualStudioDetails
??=
<
String
,
dynamic
>{};
_cachedUsableVisualStudioDetails
??=
<
String
,
dynamic
>{};
return
_cachedUsableVisualStudioDetails
;
return
_cachedUsableVisualStudioDetails
!
;
}
}
/// Returns the details dictionary of the latest version of Visual Studio,
/// Returns the details dictionary of the latest version of Visual Studio,
...
@@ -382,14 +388,14 @@ class VisualStudio {
...
@@ -382,14 +388,14 @@ class VisualStudio {
/// If no installation is found, the cached VS details are set to an empty map
/// If no installation is found, the cached VS details are set to an empty map
/// to avoid repeating vswhere queries that have already not found an
/// to avoid repeating vswhere queries that have already not found an
/// installation.
/// installation.
Map
<
String
,
dynamic
>
_cachedAnyVisualStudioDetails
;
Map
<
String
,
dynamic
>
?
_cachedAnyVisualStudioDetails
;
Map
<
String
,
dynamic
>
get
_anyVisualStudioDetails
{
Map
<
String
,
dynamic
>
get
_anyVisualStudioDetails
{
// Search for all types of installations.
// Search for all types of installations.
_cachedAnyVisualStudioDetails
??=
_visualStudioDetails
(
_cachedAnyVisualStudioDetails
??=
_visualStudioDetails
(
additionalArguments:
<
String
>[
_vswherePrereleaseArgument
,
'-all'
]);
additionalArguments:
<
String
>[
_vswherePrereleaseArgument
,
'-all'
]);
// Add a sentinel empty value to avoid querying vswhere again.
// Add a sentinel empty value to avoid querying vswhere again.
_cachedAnyVisualStudioDetails
??=
<
String
,
dynamic
>{};
_cachedAnyVisualStudioDetails
??=
<
String
,
dynamic
>{};
return
_cachedAnyVisualStudioDetails
;
return
_cachedAnyVisualStudioDetails
!
;
}
}
/// Returns the details dictionary of the best available version of Visual
/// Returns the details dictionary of the best available version of Visual
...
@@ -406,7 +412,7 @@ class VisualStudio {
...
@@ -406,7 +412,7 @@ class VisualStudio {
/// Returns the installation location of the Windows 10 SDKs, or null if the
/// Returns the installation location of the Windows 10 SDKs, or null if the
/// registry doesn't contain that information.
/// registry doesn't contain that information.
String
_getWindows10SdkLocation
()
{
String
?
_getWindows10SdkLocation
()
{
try
{
try
{
final
RunResult
result
=
_processUtils
.
runSync
(<
String
>[
final
RunResult
result
=
_processUtils
.
runSync
(<
String
>[
'reg'
,
'reg'
,
...
@@ -417,9 +423,9 @@ class VisualStudio {
...
@@ -417,9 +423,9 @@ class VisualStudio {
]);
]);
if
(
result
.
exitCode
==
0
)
{
if
(
result
.
exitCode
==
0
)
{
final
RegExp
pattern
=
RegExp
(
r'InstallationFolder\s+REG_SZ\s+(.+)'
);
final
RegExp
pattern
=
RegExp
(
r'InstallationFolder\s+REG_SZ\s+(.+)'
);
final
RegExpMatch
match
=
pattern
.
firstMatch
(
result
.
stdout
);
final
RegExpMatch
?
match
=
pattern
.
firstMatch
(
result
.
stdout
);
if
(
match
!=
null
)
{
if
(
match
!=
null
)
{
return
match
.
group
(
1
).
trim
();
return
match
.
group
(
1
)
!
.
trim
();
}
}
}
}
}
on
ArgumentError
{
}
on
ArgumentError
{
...
@@ -434,21 +440,21 @@ class VisualStudio {
...
@@ -434,21 +440,21 @@ class VisualStudio {
/// Windows 10 SDK installation directory.
/// Windows 10 SDK installation directory.
///
///
/// Returns null if no Windows 10 SDKs are found.
/// Returns null if no Windows 10 SDKs are found.
String
findHighestVersionInSdkDirectory
(
Directory
dir
)
{
String
?
findHighestVersionInSdkDirectory
(
Directory
dir
)
{
// This contains subfolders that are named by the SDK version.
// This contains subfolders that are named by the SDK version.
final
Directory
includeDir
=
dir
.
childDirectory
(
'Includes'
);
final
Directory
includeDir
=
dir
.
childDirectory
(
'Includes'
);
if
(!
includeDir
.
existsSync
())
{
if
(!
includeDir
.
existsSync
())
{
return
null
;
return
null
;
}
}
Version
highestVersion
;
Version
?
highestVersion
;
for
(
final
FileSystemEntity
versionEntry
in
includeDir
.
listSync
())
{
for
(
final
FileSystemEntity
versionEntry
in
includeDir
.
listSync
())
{
if
(!
versionEntry
.
basename
.
startsWith
(
'10.'
))
{
if
(!
versionEntry
.
basename
.
startsWith
(
'10.'
))
{
continue
;
continue
;
}
}
// Version only handles 3 components; strip off the '10.' to leave three
// Version only handles 3 components; strip off the '10.' to leave three
// components, since they all start with that.
// components, since they all start with that.
final
Version
version
=
Version
.
parse
(
versionEntry
.
basename
.
substring
(
3
));
final
Version
?
version
=
Version
.
parse
(
versionEntry
.
basename
.
substring
(
3
));
if
(
highestVersion
==
null
||
version
>
highestVersion
)
{
if
(
highestVersion
==
null
||
(
version
!=
null
&&
version
>
highestVersion
)
)
{
highestVersion
=
version
;
highestVersion
=
version
;
}
}
}
}
...
...
packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart
View file @
f712fecd
...
@@ -342,6 +342,18 @@ void setNoViableToolchainInstallation(
...
@@ -342,6 +342,18 @@ void setNoViableToolchainInstallation(
void
main
(
)
{
void
main
(
)
{
group
(
'Visual Studio'
,
()
{
group
(
'Visual Studio'
,
()
{
testWithoutContext
(
'isInstalled throws when PROGRAMFILES(X86) env not set'
,
()
{
final
VisualStudio
visualStudio
=
VisualStudio
(
logger:
BufferLogger
.
test
(),
fileSystem:
MemoryFileSystem
.
test
(
style:
FileSystemStyle
.
windows
),
platform:
FakePlatform
(
operatingSystem:
'windows'
),
processManager:
FakeProcessManager
.
any
(),
);
expect
(()
=>
visualStudio
.
isInstalled
,
throwsToolExit
(
message:
'%PROGRAMFILES(X86)% environment variable not found'
));
});
testWithoutContext
(
'isInstalled and cmakePath correct when vswhere is missing'
,
()
{
testWithoutContext
(
'isInstalled and cmakePath correct when vswhere is missing'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
(
style:
FileSystemStyle
.
windows
);
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
(
style:
FileSystemStyle
.
windows
);
const
Exception
exception
=
ProcessException
(
'vswhere'
,
<
String
>[]);
const
Exception
exception
=
ProcessException
(
'vswhere'
,
<
String
>[]);
...
...
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