Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 5beb49c

Browse files
author
Dart CI
committed
Version 2.18.0-189.0.dev
Merge commit 'd6e5a0fc49cf47a3bfc9dc47c23de6abcbfa3435' into 'dev'
2 parents a4d8cce + d6e5a0f commit 5beb49c

17 files changed

+242
-30
lines changed

pkg/analysis_server/lib/src/utilities/flutter.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ class Flutter {
266266
parent is IfElement && parent.elseElement == node ||
267267
parent is ListLiteral ||
268268
parent is NamedExpression && parent.expression == node ||
269-
parent is Statement) {
269+
parent is Statement ||
270+
parent is VariableDeclaration) {
270271
return node as Expression;
271272
}
272273
}

pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_builder_test.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,27 @@ class FakeFlutter {
133133
}
134134
);
135135
}
136+
''');
137+
}
138+
139+
Future<void> test_variableDeclaration() async {
140+
await resolveTestCode('''
141+
import 'package:flutter/widgets.dart';
142+
143+
void f() {
144+
Widget w = /*caret*/Container();
145+
}
146+
''');
147+
await assertHasAssist('''
148+
import 'package:flutter/widgets.dart';
149+
150+
void f() {
151+
Widget w = Builder(
152+
builder: (context) {
153+
return Container();
154+
}
155+
);
156+
}
136157
''');
137158
}
138159
}

pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,32 @@ class FakeFlutter {
120120
}
121121
''');
122122
}
123+
124+
Future<void> test_variableDeclaration() async {
125+
await resolveTestCode('''
126+
import 'package:flutter/widgets.dart';
127+
128+
void f() {
129+
Widget w = /*caret*/Container();
130+
}
131+
''');
132+
await assertHasAssist('''
133+
import 'package:flutter/widgets.dart';
134+
135+
void f() {
136+
Widget w = Center(child: Container());
137+
}
138+
''');
139+
}
140+
141+
Future<void> test_variableDeclaration_name() async {
142+
await resolveTestCode('''
143+
import 'package:flutter/widgets.dart';
144+
145+
void f() {
146+
Widget /*caret*/w = Container();
147+
}
148+
''');
149+
await assertNoAssist();
150+
}
123151
}

pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_sized_box_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,23 @@ import 'package:flutter/widgets.dart';
120120
class FakeFlutter {
121121
Widget f() => SizedBox(child: Container());
122122
}
123+
''');
124+
}
125+
126+
Future<void> test_variableDeclaration() async {
127+
await resolveTestCode('''
128+
import 'package:flutter/widgets.dart';
129+
130+
void f() {
131+
Widget w = /*caret*/Container();
132+
}
133+
''');
134+
await assertHasAssist('''
135+
import 'package:flutter/widgets.dart';
136+
137+
void f() {
138+
Widget w = SizedBox(child: Container());
139+
}
123140
''');
124141
}
125142
}

pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2689,7 +2689,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
26892689
return unevaluated(
26902690
node,
26912691
new ConditionalExpression(extract(condition), extract(then),
2692-
extract(otherwise), node.staticType));
2692+
extract(otherwise), env.substituteType(node.staticType)));
26932693
} else {
26942694
return createEvaluationErrorConstant(
26952695
node.condition,

pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,36 @@ class InferenceVisitor
4848

4949
Class? mapEntryClass;
5050

51+
/// Context information for the current closure, or `null` if we are not
52+
/// inside a closure.
53+
ClosureContext? _closureContext;
54+
5155
InferenceVisitor(this.inferrer);
5256

57+
ClosureContext get closureContext => _closureContext!;
58+
5359
/// Performs type inference on the given [statement].
5460
///
55-
/// Derived classes should override this method with logic that dispatches on
56-
/// the statement type and calls the appropriate specialized "infer" method.
57-
StatementInferenceResult inferStatement(Statement statement) {
61+
/// If [closureContext] is not null, the [statement] is inferred using
62+
/// [closureContext] as the current context.
63+
StatementInferenceResult inferStatement(Statement statement,
64+
[ClosureContext? closureContext]) {
65+
ClosureContext? oldClosureContext = _closureContext;
66+
if (closureContext != null) {
67+
_closureContext = closureContext;
68+
}
5869
inferrer.registerIfUnreachableForTesting(statement);
5970

6071
// For full (non-top level) inference, we need access to the
6172
// ExpressionGeneratorHelper so that we can perform error recovery.
73+
StatementInferenceResult result;
6274
if (statement is InternalStatement) {
63-
return statement.acceptInference(this);
75+
result = statement.acceptInference(this);
6476
} else {
65-
return statement.accept(this);
77+
result = statement.accept(this);
6678
}
79+
_closureContext = oldClosureContext;
80+
return result;
6781
}
6882

6983
/// Performs type inference on the given [expression].
@@ -6093,7 +6107,6 @@ class InferenceVisitor
60936107
@override
60946108
StatementInferenceResult visitReturnStatement(
60956109
covariant ReturnStatementImpl node) {
6096-
ClosureContext closureContext = inferrer.closureContext!;
60976110
DartType typeContext = closureContext.returnContext;
60986111
DartType inferredType;
60996112
if (node.expression != null) {
@@ -7075,7 +7088,6 @@ class InferenceVisitor
70757088

70767089
@override
70777090
StatementInferenceResult visitYieldStatement(YieldStatement node) {
7078-
ClosureContext closureContext = inferrer.closureContext!;
70797091
ExpressionInferenceResult expressionResult;
70807092
DartType typeContext = closureContext.yieldContext;
70817093
if (node.isYieldStar && typeContext is! UnknownType) {

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,6 @@ class TypeInferrerImpl implements TypeInferrer {
275275

276276
InferenceHelper? _helper;
277277

278-
/// Context information for the current closure, or `null` if we are not
279-
/// inside a closure.
280-
ClosureContext? closureContext;
281-
282278
TypeInferrerImpl(
283279
this.engine,
284280
this.uriForInstrumentation,
@@ -2047,7 +2043,6 @@ class TypeInferrerImpl implements TypeInferrer {
20472043
@override
20482044
ExpressionInferenceResult inferFieldInitializer(
20492045
InferenceHelper helper, DartType declaredType, Expression initializer) {
2050-
assert(closureContext == null);
20512046
assert(!isTopLevel);
20522047
this.helper = helper;
20532048
InferenceVisitor visitor = _createInferenceVisitor();
@@ -2064,24 +2059,23 @@ class TypeInferrerImpl implements TypeInferrer {
20642059
DartType returnType, AsyncMarker asyncMarker, Statement body) {
20652060
// ignore: unnecessary_null_comparison
20662061
assert(body != null);
2067-
// ignore: unnecessary_null_comparison
2068-
assert(closureContext == null);
20692062
this.helper = helper;
2070-
closureContext = new ClosureContext(this, asyncMarker, returnType, false);
2063+
ClosureContext closureContext =
2064+
new ClosureContext(this, asyncMarker, returnType, false);
20712065
InferenceVisitor visitor = _createInferenceVisitor();
2072-
StatementInferenceResult result = visitor.inferStatement(body);
2066+
StatementInferenceResult result =
2067+
visitor.inferStatement(body, closureContext);
20732068
if (dataForTesting != null) {
20742069
if (!flowAnalysis.isReachable) {
20752070
dataForTesting!.flowAnalysisResult.functionBodiesThatDontComplete
20762071
.add(body);
20772072
}
20782073
}
20792074
result =
2080-
closureContext!.handleImplicitReturn(this, body, result, fileOffset);
2081-
DartType? futureValueType = closureContext!.futureValueType;
2075+
closureContext.handleImplicitReturn(this, body, result, fileOffset);
2076+
DartType? futureValueType = closureContext.futureValueType;
20822077
assert(!(asyncMarker == AsyncMarker.Async && futureValueType == null),
20832078
"No future value type computed.");
2084-
closureContext = null;
20852079
_helper = null;
20862080
flowAnalysis.finish();
20872081
return new InferredFunctionBody(
@@ -2913,12 +2907,10 @@ class TypeInferrerImpl implements TypeInferrer {
29132907
// Apply type inference to `B` in return context `N’`, with any references
29142908
// to `xi` in `B` having type `Pi`. This produces `B’`.
29152909
bool needToSetReturnType = hasImplicitReturnType;
2916-
ClosureContext? oldClosureContext = this.closureContext;
29172910
ClosureContext closureContext = new ClosureContext(
29182911
this, function.asyncMarker, returnContext, needToSetReturnType);
2919-
this.closureContext = closureContext;
29202912
StatementInferenceResult bodyResult =
2921-
visitor.inferStatement(function.body!);
2913+
visitor.inferStatement(function.body!, closureContext);
29222914

29232915
// If the closure is declared with `async*` or `sync*`, let `M` be the
29242916
// least upper bound of the types of the `yield` expressions in `B’`, or
@@ -2947,7 +2939,6 @@ class TypeInferrerImpl implements TypeInferrer {
29472939
if (bodyResult.hasChanged) {
29482940
function.body = bodyResult.statement..parent = function;
29492941
}
2950-
this.closureContext = oldClosureContext;
29512942
return function.computeFunctionType(libraryBuilder.nonNullable);
29522943
}
29532944

@@ -4149,7 +4140,6 @@ class TypeInferrerImpl implements TypeInferrer {
41494140
Expression initializer,
41504141
DartType declaredType,
41514142
bool hasDeclaredInitializer) {
4152-
assert(closureContext == null);
41534143
this.helper = helper;
41544144
// ignore: unnecessary_null_comparison
41554145
assert(declaredType != null);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2022, 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+
class Foo<T> {
6+
const Foo(T Function(String)? foo) : _foo = foo ?? bar;
7+
final T Function(String) _foo;
8+
}
9+
10+
T bar<T>(String o) => o as T;
11+
12+
void main() {
13+
const Foo<int> myValue = Foo<int>(
14+
bool.fromEnvironment("baz") ? int.parse : null,
15+
);
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Foo<T> {
2+
const Foo(T Function(String)? foo) : _foo = foo ?? bar;
3+
final T Function(String) _foo;
4+
}
5+
6+
T bar<T>(String o) => o as T;
7+
void main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
T bar<T>(String o) => o as T;
2+
3+
class Foo<T> {
4+
const Foo(T Function(String)? foo) : _foo = foo ?? bar;
5+
final T Function(String) _foo;
6+
}
7+
8+
void main() {}

0 commit comments

Comments
 (0)