Skip to content

Commit 42a1ba7

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Improve the messages from the migration tooling
Change-Id: I8ed53936cf56f154040d53e88190a114a6133555 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120006 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
1 parent 8413a0d commit 42a1ba7

File tree

3 files changed

+469
-31
lines changed

3 files changed

+469
-31
lines changed

pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,83 @@ class InfoBuilder {
7373
return units;
7474
}
7575

76+
/// Return details for a fix built from the given [edge], or `null` if the
77+
/// edge does not have an origin.
78+
String _baseDescriptionForOrigin(AstNode node) {
79+
if (node is DefaultFormalParameter) {
80+
Expression defaultValue = node.defaultValue;
81+
if (defaultValue == null) {
82+
return "This parameter has an implicit default value of 'null'";
83+
} else if (defaultValue is NullLiteral) {
84+
return "This parameter has an explicit default value of 'null'";
85+
}
86+
return "This parameter has a nullable default value";
87+
} else if (node is FieldFormalParameter) {
88+
AstNode parent = node.parent;
89+
if (parent is DefaultFormalParameter) {
90+
Expression defaultValue = parent.defaultValue;
91+
if (defaultValue == null) {
92+
return "This field is initialized by an optional field formal "
93+
"parameter that has an implicit default value of 'null'";
94+
} else if (defaultValue is NullLiteral) {
95+
return "This field is initialized by an optional field formal "
96+
"parameter that has an explicit default value of 'null'";
97+
}
98+
return "This field is initialized by an optional field formal "
99+
"parameter that has a nullable default value";
100+
}
101+
return "This field is initialized by a field formal parameter and a "
102+
"nullable value is passed as an argument";
103+
}
104+
AstNode parent = node.parent;
105+
if (parent is ArgumentList) {
106+
if (node is NullLiteral) {
107+
return "An explicit 'null' is passed as an argument";
108+
}
109+
return "A nullable value is explicitly passed as an argument";
110+
}
111+
112+
/// If the [node] is the return expression for a function body, return the
113+
/// function body. Otherwise return `null`.
114+
AstNode findFunctionBody() {
115+
if (parent is ExpressionFunctionBody) {
116+
return parent;
117+
} else if (parent is ReturnStatement &&
118+
parent.parent?.parent is BlockFunctionBody) {
119+
return parent.parent.parent;
120+
}
121+
return null;
122+
}
123+
124+
AstNode functionBody = findFunctionBody();
125+
if (functionBody != null) {
126+
AstNode function = functionBody.parent;
127+
if (function is MethodDeclaration) {
128+
if (function.isGetter) {
129+
return "This getter returns a nullable value";
130+
}
131+
return "This method returns a nullable value";
132+
}
133+
return "This function returns a nullable value";
134+
} else if (parent is VariableDeclaration) {
135+
AstNode grandparent = parent.parent?.parent;
136+
if (grandparent is FieldDeclaration) {
137+
if (node is NullLiteral) {
138+
return "This field is initialized to null";
139+
}
140+
return "This field is initialized to a nullable value";
141+
}
142+
if (node is NullLiteral) {
143+
return "This variable is initialized to null";
144+
}
145+
return "This variable is initialized to a nullable value";
146+
}
147+
if (node is NullLiteral) {
148+
return "An explicit 'null' is assigned";
149+
}
150+
return "A nullable value is assigned";
151+
}
152+
76153
/// Return details for a fix built from the given [edge], or `null` if the
77154
/// edge does not have an origin.
78155
String _buildDescriptionForDestination(AstNode node) {
@@ -85,24 +162,12 @@ class InfoBuilder {
85162
}
86163
}
87164

88-
/// Return details for a fix built from the given [edge], or `null` if the
89-
/// edge does not have an origin.
90-
String _buildDescriptionForOrigin(AstNode node) {
91-
String /*!*/ description;
92-
if (node.parent is ArgumentList) {
93-
if (node is NullLiteral) {
94-
description = "An explicit 'null' is passed as an argument";
95-
} else {
96-
description = "A nullable value is explicitly passed as an argument";
97-
}
98-
} else {
99-
if (node is NullLiteral) {
100-
description = "An explicit 'null' is assigned";
101-
} else {
102-
description = "A nullable value is assigned";
103-
}
104-
}
105-
if (_inTestCode(node)) {
165+
/// Return a description of the given [origin].
166+
String _buildDescriptionForOrigin(AstNode origin) {
167+
String description = _baseDescriptionForOrigin(origin);
168+
if (_inTestCode(origin)) {
169+
// TODO(brianwilkerson) Don't add this if the graph node with which the
170+
// origin is associated is also in test code.
106171
description += " in test code";
107172
}
108173
return description;
@@ -123,6 +188,9 @@ class InfoBuilder {
123188
// the superclass.
124189
details.add(RegionDetail(_buildDescriptionForOrigin(origin.node),
125190
_targetForNode(origin.source.fullName, origin.node)));
191+
} else {
192+
details.add(
193+
RegionDetail('upstream edge with no origin ($edge)', null));
126194
}
127195
}
128196
}
@@ -133,6 +201,8 @@ class InfoBuilder {
133201
details.add(RegionDetail(
134202
_buildDescriptionForDestination(nodeInfo.astNode),
135203
_targetForNode(nodeInfo.filePath, nodeInfo.astNode)));
204+
} else {
205+
details.add(RegionDetail('node with no info ($destination)', null));
136206
}
137207
} else {
138208
throw UnimplementedError(

pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ h2 {
104104
}
105105
106106
.target {
107-
background-color: #FFFFFF;
107+
background-color: #FFFF99;
108108
position: relative;
109109
visibility: visible;
110110
}
@@ -180,6 +180,8 @@ class InstrumentationRenderer {
180180

181181
/// Builds an HTML view of the instrumentation information in [unitInfo].
182182
String render() {
183+
// TODO(brianwilkerson) Restore syntactic highlighting.
184+
// TODO(brianwilkerson) Add line numbers beside the content.
183185
Map<String, dynamic> mustacheContext = {
184186
'units': <Map<String, dynamic>>[],
185187
'links': migrationInfo.unitLinks(unitInfo),
@@ -314,6 +316,11 @@ class InstrumentationRenderer {
314316

315317
/// Return the URL that will navigate to the given [target].
316318
String _uriForTarget(NavigationTarget target) {
319+
if (target == null) {
320+
// TODO(brianwilkerson) This is temporary support until we can get targets
321+
// for all nodes.
322+
return '';
323+
}
317324
path.Context pathContext = migrationInfo.pathContext;
318325
String targetPath = pathContext.setExtension(target.filePath, '.html');
319326
String sourceDir = pathContext.dirname(unitInfo.path);

0 commit comments

Comments
 (0)