Skip to content

Commit 844c82b

Browse files
author
John Messerly
committed
fix #25573, add option to disable implicit dynamic
[email protected] Review URL: https://codereview.chromium.org/2093523002 .
1 parent 4bae18a commit 844c82b

File tree

7 files changed

+518
-14
lines changed

7 files changed

+518
-14
lines changed

pkg/analyzer/lib/src/context/context.dart

+4
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
281281
((options is AnalysisOptionsImpl)
282282
? this._options.implicitCasts != options.implicitCasts
283283
: false) ||
284+
((options is AnalysisOptionsImpl)
285+
? this._options.implicitDynamic != options.implicitDynamic
286+
: false) ||
284287
this._options.enableStrictCallChecks !=
285288
options.enableStrictCallChecks ||
286289
this._options.enableGenericMethods != options.enableGenericMethods ||
@@ -313,6 +316,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
313316
if (options is AnalysisOptionsImpl) {
314317
this._options.strongModeHints = options.strongModeHints;
315318
this._options.implicitCasts = options.implicitCasts;
319+
this._options.implicitDynamic = options.implicitDynamic;
316320
}
317321
if (needsRecompute) {
318322
for (WorkManager workManager in workManagers) {

pkg/analyzer/lib/src/dart/element/type.dart

+33
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,39 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
926926
}
927927
}
928928

929+
/**
930+
* Given a generic function type [g] and an instantiated function type [f],
931+
* find a list of type arguments TArgs such that `g<TArgs> == f`,
932+
* and return TArgs.
933+
*
934+
* This function must be called with type [f] that was instantiated from [g].
935+
*/
936+
static Iterable<DartType> recoverTypeArguments(
937+
FunctionType g, FunctionType f) {
938+
// TODO(jmesserly): perhaps a better design here would be: instead of
939+
// recording staticInvokeType on InvocationExpression, we could record the
940+
// instantiated type arguments, that way we wouldn't need to recover them.
941+
//
942+
// For now though, this is a pretty quick operation.
943+
assert(identical(g.element, f.element));
944+
assert(g.typeFormals.isNotEmpty && f.typeFormals.isEmpty);
945+
assert(g.typeFormals.length + g.typeArguments.length ==
946+
f.typeArguments.length);
947+
948+
// Instantiation in Analyzer works like this:
949+
// Given:
950+
// {U/T} <S> T -> S
951+
// Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
952+
// and <S> represents the typeFormals.
953+
//
954+
// Now instantiate([V]), and the result should be:
955+
// {U/T, V/S} T -> S.
956+
//
957+
// Therefore, we can recover the typeArguments from our instantiated
958+
// function.
959+
return f.typeArguments.skip(g.typeArguments.length);
960+
}
961+
929962
/**
930963
* Compares two function types [t] and [s] to see if their corresponding
931964
* parameter types match [parameterRelation] and their return types match

pkg/analyzer/lib/src/generated/engine.dart

+13
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,18 @@ class AnalysisOptionsImpl implements AnalysisOptions {
13141314
@override
13151315
bool finerGrainedInvalidation = false;
13161316

1317+
/**
1318+
* A flag indicating whether implicit dynamic type is allowed, on by default.
1319+
*
1320+
* This flag can be used without necessarily enabling [strongMode], but it is
1321+
* designed with strong mode's type inference in mind. Without type inference,
1322+
* it will raise many errors. Also it does not provide type safety without
1323+
* strong mode.
1324+
*
1325+
* This option is experimental and subject to change.
1326+
*/
1327+
bool implicitDynamic = true;
1328+
13171329
/**
13181330
* Initialize a newly created set of analysis options to have their default
13191331
* values.
@@ -1346,6 +1358,7 @@ class AnalysisOptionsImpl implements AnalysisOptions {
13461358
if (options is AnalysisOptionsImpl) {
13471359
strongModeHints = options.strongModeHints;
13481360
implicitCasts = options.implicitCasts;
1361+
implicitDynamic = options.implicitDynamic;
13491362
}
13501363
trackCacheDependencies = options.trackCacheDependencies;
13511364
finerGrainedInvalidation = options.finerGrainedInvalidation;

pkg/analyzer/lib/src/generated/error.dart

+78
Original file line numberDiff line numberDiff line change
@@ -2859,6 +2859,16 @@ abstract class ErrorCode {
28592859
StrongModeCode.DOWN_CAST_IMPLICIT,
28602860
StrongModeCode.DYNAMIC_CAST,
28612861
StrongModeCode.DYNAMIC_INVOKE,
2862+
StrongModeCode.IMPLICIT_DYNAMIC_FIELD,
2863+
StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
2864+
StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
2865+
StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL,
2866+
StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL,
2867+
StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
2868+
StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER,
2869+
StrongModeCode.IMPLICIT_DYNAMIC_RETURN,
2870+
StrongModeCode.IMPLICIT_DYNAMIC_TYPE,
2871+
StrongModeCode.IMPLICIT_DYNAMIC_VARIABLE,
28622872
StrongModeCode.INFERRED_TYPE,
28632873
StrongModeCode.INFERRED_TYPE_ALLOCATION,
28642874
StrongModeCode.INFERRED_TYPE_CLOSURE,
@@ -5874,6 +5884,17 @@ class StrongModeCode extends ErrorCode {
58745884
'The type of {0}.{1} ({2}) is not a '
58755885
'subtype of {3}.{1} ({4}).';
58765886

5887+
/**
5888+
* This is appended to the end of an error message about implicit dynamic.
5889+
*
5890+
* The idea is to make sure the user is aware that this error message is the
5891+
* result of turning on a particular option, and they are free to turn it
5892+
* back off.
5893+
*/
5894+
static const String _implicitDynamicTip =
5895+
". Either add an explicit type like 'dynamic'"
5896+
", or enable implicit-dynamic in your Analyzer options.";
5897+
58775898
static const String _inferredTypeMessage = '{0} has inferred type {1}';
58785899

58795900
static const StrongModeCode DOWN_CAST_COMPOSITE = const StrongModeCode(
@@ -5947,6 +5968,63 @@ class StrongModeCode extends ErrorCode {
59475968
'Field declaration {3}.{1} cannot be '
59485969
'overridden in {0}.');
59495970

5971+
static const StrongModeCode IMPLICIT_DYNAMIC_PARAMETER = const StrongModeCode(
5972+
ErrorType.COMPILE_TIME_ERROR,
5973+
'IMPLICIT_DYNAMIC_PARAMETER',
5974+
"Missing parameter type for '{0}'$_implicitDynamicTip");
5975+
5976+
static const StrongModeCode IMPLICIT_DYNAMIC_RETURN = const StrongModeCode(
5977+
ErrorType.COMPILE_TIME_ERROR,
5978+
'IMPLICIT_DYNAMIC_RETURN',
5979+
"Missing return type for '{0}'$_implicitDynamicTip");
5980+
5981+
static const StrongModeCode IMPLICIT_DYNAMIC_VARIABLE = const StrongModeCode(
5982+
ErrorType.COMPILE_TIME_ERROR,
5983+
'IMPLICIT_DYNAMIC_VARIABLE',
5984+
"Missing variable type for '{0}'$_implicitDynamicTip");
5985+
5986+
static const StrongModeCode IMPLICIT_DYNAMIC_FIELD = const StrongModeCode(
5987+
ErrorType.COMPILE_TIME_ERROR,
5988+
'IMPLICIT_DYNAMIC_FIELD',
5989+
"Missing field type for '{0}'$_implicitDynamicTip");
5990+
5991+
static const StrongModeCode IMPLICIT_DYNAMIC_TYPE =
5992+
const StrongModeCode(
5993+
ErrorType.COMPILE_TIME_ERROR,
5994+
'IMPLICIT_DYNAMIC_TYPE',
5995+
"Missing type arguments for generic type '{0}'"
5996+
"$_implicitDynamicTip");
5997+
5998+
static const StrongModeCode IMPLICIT_DYNAMIC_LIST_LITERAL =
5999+
const StrongModeCode(
6000+
ErrorType.COMPILE_TIME_ERROR,
6001+
'IMPLICIT_DYNAMIC_LIST_LITERAL',
6002+
"Missing type argument for list literal$_implicitDynamicTip");
6003+
6004+
static const StrongModeCode IMPLICIT_DYNAMIC_MAP_LITERAL =
6005+
const StrongModeCode(
6006+
ErrorType.COMPILE_TIME_ERROR,
6007+
'IMPLICIT_DYNAMIC_MAP_LITERAL',
6008+
'Missing type arguments for map literal$_implicitDynamicTip');
6009+
6010+
static const StrongModeCode IMPLICIT_DYNAMIC_FUNCTION = const StrongModeCode(
6011+
ErrorType.COMPILE_TIME_ERROR,
6012+
'IMPLICIT_DYNAMIC_FUNCTION',
6013+
"Missing type arguments for generic function '{0}<{1}>'"
6014+
"$_implicitDynamicTip");
6015+
6016+
static const StrongModeCode IMPLICIT_DYNAMIC_METHOD = const StrongModeCode(
6017+
ErrorType.COMPILE_TIME_ERROR,
6018+
'IMPLICIT_DYNAMIC_METHOD',
6019+
"Missing type arguments for generic method '{0}<{1}>'"
6020+
"$_implicitDynamicTip");
6021+
6022+
static const StrongModeCode IMPLICIT_DYNAMIC_INVOKE = const StrongModeCode(
6023+
ErrorType.COMPILE_TIME_ERROR,
6024+
'IMPLICIT_DYNAMIC_INVOKE',
6025+
"Missing type arguments for calling generic function type '{0}'"
6026+
"$_implicitDynamicTip");
6027+
59506028
@override
59516029
final ErrorType type;
59526030

0 commit comments

Comments
 (0)