This repository has been archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge commit 'f481cbf2fa27ca7d72ababdccc561b4465bd1660' into 'dev'
- Loading branch information
Showing
23 changed files
with
469 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'package:analyzer/dart/element/element.dart'; | ||
import 'package:analyzer/dart/element/type.dart'; | ||
import 'package:analyzer/src/dart/element/type_algebra.dart'; | ||
import 'package:analyzer/src/dart/element/type_system.dart'; | ||
|
||
class NotWellBoundedTypeResult implements TypeBoundedResult { | ||
final String elementName; | ||
final List<TypeArgumentIssue> issues; | ||
|
||
NotWellBoundedTypeResult._({ | ||
required this.elementName, | ||
required this.issues, | ||
}); | ||
} | ||
|
||
class RegularBoundedTypeResult implements WellBoundedTypeResult { | ||
const RegularBoundedTypeResult._(); | ||
} | ||
|
||
class SuperBoundedTypeResult implements WellBoundedTypeResult { | ||
const SuperBoundedTypeResult._(); | ||
} | ||
|
||
class TypeArgumentIssue { | ||
/// The index for type argument within the passed type arguments. | ||
final int index; | ||
|
||
/// The type parameter with the bound that was violated. | ||
final TypeParameterElement parameter; | ||
|
||
/// The substituted bound of the [parameter]. | ||
final DartType parameterBound; | ||
|
||
/// The type argument that violated the [parameterBound]. | ||
final DartType argument; | ||
|
||
TypeArgumentIssue( | ||
this.index, | ||
this.parameter, | ||
this.parameterBound, | ||
this.argument, | ||
); | ||
|
||
@override | ||
String toString() { | ||
return 'TypeArgumentIssue(index=$index, parameter=$parameter, ' | ||
'parameterBound=$parameterBound, argument=$argument)'; | ||
} | ||
} | ||
|
||
/// Helper for checking whether a type if well-bounded. | ||
/// | ||
/// See `15.2 Super-bounded types` in the language specification. | ||
class TypeBoundedHelper { | ||
final TypeSystemImpl typeSystem; | ||
|
||
TypeBoundedHelper(this.typeSystem); | ||
|
||
TypeBoundedResult isWellBounded( | ||
DartType type, { | ||
required bool allowSuperBounded, | ||
}) { | ||
var result = _isRegularBounded(type); | ||
if (!allowSuperBounded) { | ||
return result; | ||
} | ||
|
||
return _isSuperBounded(type); | ||
} | ||
|
||
TypeBoundedResult _isRegularBounded(DartType type) { | ||
List<TypeArgumentIssue>? issues; | ||
|
||
final String elementName; | ||
final List<TypeParameterElement> typeParameters; | ||
final List<DartType> typeArguments; | ||
final alias = type.alias; | ||
if (alias != null) { | ||
elementName = alias.element.name; | ||
typeParameters = alias.element.typeParameters; | ||
typeArguments = alias.typeArguments; | ||
} else if (type is InterfaceType) { | ||
elementName = type.element.name; | ||
typeParameters = type.element.typeParameters; | ||
typeArguments = type.typeArguments; | ||
} else { | ||
return const RegularBoundedTypeResult._(); | ||
} | ||
|
||
final substitution = Substitution.fromPairs(typeParameters, typeArguments); | ||
for (var i = 0; i < typeParameters.length; i++) { | ||
var typeParameter = typeParameters[i]; | ||
var typeArgument = typeArguments[i]; | ||
|
||
var bound = typeParameter.bound; | ||
if (bound == null) { | ||
continue; | ||
} | ||
|
||
bound = typeSystem.toLegacyType(bound); | ||
bound = substitution.substituteType(bound); | ||
|
||
if (!typeSystem.isSubtypeOf(typeArgument, bound)) { | ||
issues ??= <TypeArgumentIssue>[]; | ||
issues.add( | ||
TypeArgumentIssue(i, typeParameter, bound, typeArgument), | ||
); | ||
} | ||
} | ||
|
||
if (issues == null) { | ||
return const RegularBoundedTypeResult._(); | ||
} else { | ||
return NotWellBoundedTypeResult._( | ||
elementName: elementName, | ||
issues: issues, | ||
); | ||
} | ||
} | ||
|
||
TypeBoundedResult _isSuperBounded(DartType type) { | ||
final invertedType = typeSystem.replaceTopAndBottom(type); | ||
var result = _isRegularBounded(invertedType); | ||
if (result is RegularBoundedTypeResult) { | ||
return const SuperBoundedTypeResult._(); | ||
} else { | ||
return result; | ||
} | ||
} | ||
} | ||
|
||
abstract class TypeBoundedResult {} | ||
|
||
class WellBoundedTypeResult implements TypeBoundedResult {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.