Skip to content

Commit f74b0cc

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Extract logic from DecoratedType.forElement into a new class, AlreadyMigratedCodeDecorator.
I plan to add unit tests for AlreadyMigratedCodeDecorator in a follow-up CL (I can't add them now because I need to refactor some of the unit tests to avoid code duplication, and that refactoring depends on this CL). Change-Id: Id137f7b003df33306d894fc8771963173757bf45 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112580 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Mike Fairhurst <mfairhurst@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
1 parent 4ebde3f commit f74b0cc

File tree

3 files changed

+90
-64
lines changed

3 files changed

+90
-64
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/dart/element/type.dart';
6+
import 'package:analyzer/src/dart/element/type.dart';
7+
import 'package:nnbd_migration/src/decorated_type.dart';
8+
import 'package:nnbd_migration/src/nullability_node.dart';
9+
10+
/// This class transforms ordinary [DartType]s into their corresponding
11+
/// [DecoratedType]s, assuming the [DartType]s come from code that has already
12+
/// been migrated to NNBD.
13+
class AlreadyMigratedCodeDecorator {
14+
final NullabilityGraph _graph;
15+
16+
AlreadyMigratedCodeDecorator(this._graph);
17+
18+
/// Transforms [type], which should have come from code that has already been
19+
/// migrated to NNBD, into the corresponding [DecoratedType].
20+
DecoratedType decorate(DartType type) {
21+
if (type.isVoid || type.isDynamic) {
22+
return DecoratedType(type, _graph.always);
23+
}
24+
var nullabilitySuffix = (type as TypeImpl).nullabilitySuffix;
25+
if (nullabilitySuffix == NullabilitySuffix.question) {
26+
// TODO(paulberry): add support for depending on already-migrated packages
27+
// containing nullable types.
28+
throw UnimplementedError(
29+
'Migration depends on an already-migrated nullable type');
30+
} else {
31+
// Currently, all types passed to this method have nullability suffix `star`
32+
// because (a) we don't yet have a migrated SDK, and (b) we haven't added
33+
// support to the migrator for analyzing packages that have already been
34+
// migrated with NNBD enabled.
35+
// TODO(paulberry): fix this assertion when things change.
36+
assert(nullabilitySuffix == NullabilitySuffix.star);
37+
}
38+
if (type is FunctionType) {
39+
var positionalParameters = <DecoratedType>[];
40+
var namedParameters = <String, DecoratedType>{};
41+
for (var parameter in type.parameters) {
42+
if (parameter.isPositional) {
43+
positionalParameters.add(decorate(parameter.type));
44+
} else {
45+
namedParameters[parameter.name] = decorate(parameter.type);
46+
}
47+
}
48+
return DecoratedType(type, _graph.never,
49+
returnType: decorate(type.returnType),
50+
namedParameters: namedParameters,
51+
positionalParameters: positionalParameters);
52+
} else if (type is InterfaceType) {
53+
if (type.typeParameters.isNotEmpty) {
54+
// TODO(paulberry)
55+
throw UnimplementedError('Decorating ${type.displayName}');
56+
}
57+
return DecoratedType(type, _graph.never);
58+
} else if (type is TypeParameterType) {
59+
return DecoratedType(type, _graph.never);
60+
} else {
61+
// TODO(paulberry)
62+
throw UnimplementedError(
63+
'Unable to decorate already-migrated type $type');
64+
}
65+
}
66+
}

pkg/nnbd_migration/lib/src/decorated_type.dart

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -83,68 +83,6 @@ class DecoratedType {
8383
}());
8484
}
8585

86-
/// Creates a [DecoratedType] corresponding to the given [element], which is
87-
/// presumed to have come from code that is already migrated.
88-
factory DecoratedType.forElement(Element element, NullabilityGraph graph) {
89-
DecoratedType decorate(DartType type) {
90-
if (type.isVoid || type.isDynamic) {
91-
return DecoratedType(type, graph.always);
92-
}
93-
assert((type as TypeImpl).nullabilitySuffix ==
94-
NullabilitySuffix.star); // TODO(paulberry)
95-
if (type is FunctionType) {
96-
var positionalParameters = <DecoratedType>[];
97-
var namedParameters = <String, DecoratedType>{};
98-
for (var parameter in type.parameters) {
99-
if (parameter.isPositional) {
100-
positionalParameters.add(decorate(parameter.type));
101-
} else {
102-
namedParameters[parameter.name] = decorate(parameter.type);
103-
}
104-
}
105-
return DecoratedType(type, graph.never,
106-
returnType: decorate(type.returnType),
107-
namedParameters: namedParameters,
108-
positionalParameters: positionalParameters);
109-
} else if (type is InterfaceType) {
110-
if (type.typeParameters.isNotEmpty) {
111-
// TODO(paulberry)
112-
throw UnimplementedError('Decorating ${type.displayName}');
113-
}
114-
return DecoratedType(type, graph.never);
115-
} else if (type is TypeParameterType) {
116-
return DecoratedType(type, graph.never);
117-
} else {
118-
throw type.runtimeType; // TODO(paulberry)
119-
}
120-
}
121-
122-
// Sanity check:
123-
// Ensure the element is not from a library that is being migrated.
124-
// If this assertion fires, it probably means that the NodeBuilder failed to
125-
// generate the appropriate decorated type for the element when it was
126-
// visiting the source file.
127-
if (graph.isBeingMigrated(element.source)) {
128-
throw 'Internal Error: DecorateType.forElement should not be called'
129-
' for elements being migrated: ${element.runtimeType} :: $element';
130-
}
131-
132-
DecoratedType decoratedType;
133-
if (element is ExecutableElement) {
134-
decoratedType = decorate(element.type);
135-
} else if (element is TopLevelVariableElement) {
136-
decoratedType = decorate(element.type);
137-
} else if (element is TypeParameterElement) {
138-
// By convention, type parameter elements are decorated with the type of
139-
// their bounds.
140-
decoratedType = decorate(element.bound ?? DynamicTypeImpl.instance);
141-
} else {
142-
// TODO(paulberry)
143-
throw UnimplementedError('Decorating ${element.runtimeType}');
144-
}
145-
return decoratedType;
146-
}
147-
14886
/// Creates a decorated type corresponding to [type], with fresh nullability
14987
/// nodes everywhere that don't correspond to any source location. These
15088
/// nodes can later be unioned with other nodes.

pkg/nnbd_migration/lib/src/variables.dart

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import 'package:analyzer/dart/ast/ast.dart';
66
import 'package:analyzer/dart/element/element.dart';
77
import 'package:analyzer/src/dart/element/handle.dart';
8+
import 'package:analyzer/src/dart/element/type.dart';
89
import 'package:analyzer/src/generated/source.dart';
10+
import 'package:nnbd_migration/src/already_migrated_code_decorator.dart';
911
import 'package:nnbd_migration/src/conditional_discard.dart';
1012
import 'package:nnbd_migration/src/decorated_type.dart';
1113
import 'package:nnbd_migration/src/expression_checks.dart';
@@ -26,7 +28,10 @@ class Variables implements VariableRecorder, VariableRepository {
2628

2729
final _potentialModifications = <Source, List<PotentialModification>>{};
2830

29-
Variables(this._graph);
31+
final AlreadyMigratedCodeDecorator _alreadyMigratedCodeDecorator;
32+
33+
Variables(this._graph)
34+
: _alreadyMigratedCodeDecorator = AlreadyMigratedCodeDecorator(_graph);
3035

3136
@override
3237
Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
@@ -169,12 +174,29 @@ class Variables implements VariableRecorder, VariableRepository {
169174
(_potentialModifications[source] ??= []).add(potentialModification);
170175
}
171176

177+
/// Creates a decorated type for the given [element], which should come from
178+
/// an already-migrated library (or the SDK).
172179
DecoratedType _createDecoratedElementType(Element element) {
173180
if (_graph.isBeingMigrated(element.library.source)) {
174181
throw StateError('A decorated type for $element should have been stored '
175182
'by the NodeBuilder via recordDecoratedElementType');
176183
}
177-
return DecoratedType.forElement(element, _graph);
184+
185+
DecoratedType decoratedType;
186+
if (element is ExecutableElement) {
187+
decoratedType = _alreadyMigratedCodeDecorator.decorate(element.type);
188+
} else if (element is TopLevelVariableElement) {
189+
decoratedType = _alreadyMigratedCodeDecorator.decorate(element.type);
190+
} else if (element is TypeParameterElement) {
191+
// By convention, type parameter elements are decorated with the type of
192+
// their bounds.
193+
decoratedType = _alreadyMigratedCodeDecorator
194+
.decorate(element.bound ?? DynamicTypeImpl.instance);
195+
} else {
196+
// TODO(paulberry)
197+
throw UnimplementedError('Decorating ${element.runtimeType}');
198+
}
199+
return decoratedType;
178200
}
179201

180202
/// Creates an entry [_decoratedDirectSupertypes] for an already-migrated

0 commit comments

Comments
 (0)