Skip to content

Commit 8f1a963

Browse files
author
Dart CI
committed
Version 2.11.0-198.0.dev
Merge commit 'b4f265290c75fd6c6370cf1403f2b2649c59ad39' into 'dev'
2 parents c399dbb + b4f2652 commit 8f1a963

File tree

11 files changed

+126
-17
lines changed

11 files changed

+126
-17
lines changed

pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ abstract class FlowAnalysis<Node, Statement extends Node, Expression, Variable,
351351
/// Call this method when visiting a boolean literal expression.
352352
void booleanLiteral(Expression expression, bool value);
353353

354+
/// Call this method just before visiting a conditional expression ("?:").
355+
void conditional_conditionBegin();
356+
354357
/// Call this method upon reaching the ":" part of a conditional expression
355358
/// ("?:"). [thenExpression] should be the expression preceding the ":".
356359
void conditional_elseBegin(Expression thenExpression);
@@ -866,6 +869,12 @@ class FlowAnalysisDebug<Node, Statement extends Node, Expression, Variable,
866869
() => _wrapped.booleanLiteral(expression, value));
867870
}
868871

872+
@override
873+
void conditional_conditionBegin() {
874+
_wrap('conditional_conditionBegin()',
875+
() => _wrapped.conditional_conditionBegin());
876+
}
877+
869878
@override
870879
void conditional_elseBegin(Expression thenExpression) {
871880
_wrap('conditional_elseBegin($thenExpression',
@@ -2731,6 +2740,11 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27312740
: new ExpressionInfo(_current, unreachable, _current));
27322741
}
27332742

2743+
@override
2744+
void conditional_conditionBegin() {
2745+
_current = _current.split();
2746+
}
2747+
27342748
@override
27352749
void conditional_elseBegin(Expression thenExpression) {
27362750
_ConditionalContext<Variable, Type> context =
@@ -2749,9 +2763,9 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27492763
_storeExpressionInfo(
27502764
conditionalExpression,
27512765
new ExpressionInfo(
2752-
_join(thenInfo.after, elseInfo.after),
2753-
_join(thenInfo.ifTrue, elseInfo.ifTrue),
2754-
_join(thenInfo.ifFalse, elseInfo.ifFalse)));
2766+
_merge(thenInfo.after, elseInfo.after),
2767+
_merge(thenInfo.ifTrue, elseInfo.ifTrue),
2768+
_merge(thenInfo.ifFalse, elseInfo.ifFalse)));
27552769
}
27562770

27572771
@override
@@ -2771,9 +2785,9 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27712785
AssignedVariablesNodeInfo<Variable> info =
27722786
_assignedVariables._getInfoForNode(doStatement);
27732787
_BranchTargetContext<Variable, Type> context =
2774-
new _BranchTargetContext<Variable, Type>(_current.reachable.parent);
2788+
new _BranchTargetContext<Variable, Type>(_current.reachable);
27752789
_stack.add(context);
2776-
_current = _current.conservativeJoin(info._written, info._captured);
2790+
_current = _current.conservativeJoin(info._written, info._captured).split();
27772791
_statementToContext[doStatement] = context;
27782792
}
27792793

@@ -2788,7 +2802,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27882802
void doStatement_end(Expression condition) {
27892803
_BranchTargetContext<Variable, Type> context =
27902804
_stack.removeLast() as _BranchTargetContext<Variable, Type>;
2791-
_current = _join(_expressionEnd(condition).ifFalse, context._breakModel);
2805+
_current = _merge(_expressionEnd(condition).ifFalse, context._breakModel);
27922806
}
27932807

27942808
@override
@@ -2868,7 +2882,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
28682882
void for_conditionBegin(Node node) {
28692883
AssignedVariablesNodeInfo<Variable> info =
28702884
_assignedVariables._getInfoForNode(node);
2871-
_current = _current.conservativeJoin(info._written, info._captured);
2885+
_current = _current.conservativeJoin(info._written, info._captured).split();
28722886
}
28732887

28742888
@override
@@ -2879,7 +2893,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
28792893
FlowModel<Variable, Type> breakState = context._breakModel;
28802894
FlowModel<Variable, Type> falseCondition = context._conditionInfo.ifFalse;
28812895

2882-
_current = _join(falseCondition, breakState)
2896+
_current = _merge(falseCondition, breakState)
28832897
.inheritTested(typeOperations, _current);
28842898
}
28852899

@@ -2894,7 +2908,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
28942908
void forEach_bodyBegin(Node node, Variable loopVariable, Type writtenType) {
28952909
AssignedVariablesNodeInfo<Variable> info =
28962910
_assignedVariables._getInfoForNode(node);
2897-
_current = _current.conservativeJoin(info._written, info._captured);
2911+
_current = _current.conservativeJoin(info._written, info._captured).split();
28982912
_SimpleStatementContext<Variable, Type> context =
28992913
new _SimpleStatementContext<Variable, Type>(
29002914
_current.reachable.parent, _current);
@@ -2908,7 +2922,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
29082922
void forEach_end() {
29092923
_SimpleStatementContext<Variable, Type> context =
29102924
_stack.removeLast() as _SimpleStatementContext<Variable, Type>;
2911-
_current = _join(_current, context._previous);
2925+
_current = _merge(_current, context._previous);
29122926
}
29132927

29142928
@override

pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ main() {
7676
var x = h.addVar('x', 'int?');
7777
h.run((flow) {
7878
h.declare(x, initialized: true);
79+
flow.conditional_conditionBegin();
7980
flow.conditional_thenBegin(h.notNull(x, _Type('int?'))());
8081
expect(flow.promotedType(x).type, 'int');
8182
flow.conditional_elseBegin(_Expression());
@@ -90,6 +91,7 @@ main() {
9091
var x = h.addVar('x', 'int?');
9192
h.run((flow) {
9293
h.declare(x, initialized: true);
94+
flow.conditional_conditionBegin();
9395
flow.conditional_thenBegin(h.eqNull(x, _Type('int?'))());
9496
expect(flow.promotedType(x), isNull);
9597
flow.conditional_elseBegin(_Expression());
@@ -109,6 +111,7 @@ main() {
109111
h.declare(x, initialized: true);
110112
h.declare(y, initialized: true);
111113
h.declare(z, initialized: true);
114+
flow.conditional_conditionBegin();
112115
flow.conditional_thenBegin(_Expression());
113116
h.promote(x, 'int');
114117
h.promote(y, 'int');
@@ -4176,6 +4179,7 @@ class _Harness extends TypeOperations<_Var, _Type> {
41764179
LazyExpression cond, LazyExpression ifTrue, LazyExpression ifFalse) {
41774180
return () {
41784181
var expr = _Expression();
4182+
_flow.conditional_conditionBegin();
41794183
_flow.conditional_thenBegin(cond());
41804184
_flow.conditional_elseBegin(ifTrue());
41814185
_flow.conditional_end(expr, ifFalse());

pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,19 @@ void conditional_factor_nullable(num? x) {
2929
x is int? ? /*int?*/ x : /*num*/ x;
3030
x;
3131
}
32+
33+
void conditional_join_then(bool b, Object x) {
34+
if (b ? x is int : x is int) {
35+
/*int*/ x;
36+
} else {
37+
x;
38+
}
39+
}
40+
41+
void conditional_join_else(bool b, Object x) {
42+
if (b ? x is! int : x is! int) {
43+
x;
44+
} else {
45+
/*int*/ x;
46+
}
47+
}

pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/promotion_in_dead_code.dart

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,69 @@
66
// promotion continue to function properly even when used inside unreachable
77
// code.
88

9+
conditionalIs(Object o) {
10+
return;
11+
o is int ? null : throw 'bad';
12+
/*int*/ o;
13+
}
14+
15+
conditionalIsNot(Object o) {
16+
return;
17+
o is! int ? throw 'bad' : null;
18+
/*int*/ o;
19+
}
20+
21+
conditionalJoinFalse(Object o, bool b) {
22+
return;
23+
if (b ? o is! int : o is! int) return;
24+
/*int*/ o;
25+
}
26+
27+
conditionalJoinTrue(Object o, bool b) {
28+
return;
29+
if (!(b ? o is int : o is int)) return;
30+
/*int*/ o;
31+
}
32+
33+
doBreak(Object o) {
34+
return;
35+
do {
36+
if (o is int) break;
37+
} while (true);
38+
/*int*/ o;
39+
}
40+
41+
doContinue(Object o) {
42+
return;
43+
do {
44+
if (o is int) continue;
45+
return;
46+
} while (false);
47+
/*int*/ o;
48+
}
49+
50+
doCondition(Object o) {
51+
return;
52+
do {} while (o is! int);
53+
/*int*/ o;
54+
}
55+
56+
forBreak(Object o) {
57+
return;
58+
for (;;) {
59+
if (o is int) break;
60+
}
61+
/*int*/ o;
62+
}
63+
64+
forContinue(Object o) {
65+
return;
66+
for (;; /*int*/ o) {
67+
if (o is int) continue;
68+
return;
69+
}
70+
}
71+
972
ifIsNot(Object o) {
1073
return;
1174
if (o is! int) return;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,7 @@ class ResolverVisitor extends ScopedVisitor {
10931093
void visitConditionalExpression(ConditionalExpression node) {
10941094
Expression condition = node.condition;
10951095
var flow = _flowAnalysis?.flow;
1096+
flow?.conditional_conditionBegin();
10961097

10971098
// TODO(scheglov) Do we need these checks for null?
10981099
condition?.accept(this);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ class InferenceVisitor
378378
@override
379379
ExpressionInferenceResult visitConditionalExpression(
380380
ConditionalExpression node, DartType typeContext) {
381+
inferrer.flowAnalysis.conditional_conditionBegin();
381382
InterfaceType expectedType =
382383
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
383384
ExpressionInferenceResult conditionResult = inferrer.inferExpression(
@@ -401,7 +402,7 @@ class InferenceVisitor
401402
node.otherwise = otherwiseResult.expression..parent = node;
402403
inferrer.registerIfUnreachableForTesting(node.otherwise,
403404
isReachable: isOtherwiseReachable);
404-
inferrer.flowAnalysis.conditional_end(node.condition, node.otherwise);
405+
inferrer.flowAnalysis.conditional_end(node, node.otherwise);
405406
DartType inferredType = inferrer.typeSchemaEnvironment
406407
.getStandardUpperBound(thenResult.inferredType,
407408
otherwiseResult.inferredType, inferrer.library.library);

pkg/meta/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: meta
2-
version: 1.3.0-nullsafety.3
2+
version: 1.3.0-nullsafety.4
33
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/meta
44
description: >
55
This library contains the declarations of annotations that developers can use

pkg/nnbd_migration/lib/src/edge_builder.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
619619

620620
@override
621621
DecoratedType visitConditionalExpression(ConditionalExpression node) {
622+
_flowAnalysis.conditional_conditionBegin();
622623
_checkExpressionNotNull(node.condition);
623624
NullabilityNode trueGuard;
624625
NullabilityNode falseGuard;

runtime/vm/object.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9361,6 +9361,13 @@ StringPtr Function::QualifiedUserVisibleName() const {
93619361
return Symbols::New(thread, printer.buffer());
93629362
}
93639363

9364+
const char* Function::QualifiedUserVisibleNameCString() const {
9365+
Thread* thread = Thread::Current();
9366+
ZoneTextBuffer printer(thread->zone());
9367+
PrintName(NameFormattingParams(kUserVisibleName), &printer);
9368+
return printer.buffer();
9369+
}
9370+
93649371
void Function::PrintName(const NameFormattingParams& params,
93659372
BaseTextBuffer* printer) const {
93669373
// If |this| is the generated asynchronous body closure, use the
@@ -24410,10 +24417,10 @@ static void PrintSymbolicStackFrame(Zone* zone,
2441024417
intptr_t frame_index) {
2441124418
ASSERT(!function.IsNull());
2441224419
const auto& script = Script::Handle(zone, function.script());
24413-
auto& handle = String::Handle(zone, function.QualifiedUserVisibleName());
24414-
auto const function_name = handle.ToCString();
24415-
handle = script.IsNull() ? String::New("Kernel") : script.url();
24416-
auto url = handle.ToCString();
24420+
const char* function_name = function.QualifiedUserVisibleNameCString();
24421+
const char* url = script.IsNull()
24422+
? "Kernel"
24423+
: String::Handle(zone, script.url()).ToCString();
2441724424

2441824425
// If the URI starts with "data:application/dart;" this is a URI encoded
2441924426
// script so we shouldn't print the entire URI because it could be very long.
@@ -24443,6 +24450,7 @@ const char* StackTrace::ToCString() const {
2444324450
auto& code = Code::Handle(zone);
2444424451
auto& bytecode = Bytecode::Handle(zone);
2444524452

24453+
NoSafepointScope no_allocation;
2444624454
GrowableArray<const Function*> inlined_functions;
2444724455
GrowableArray<TokenPosition> inlined_token_positions;
2444824456
ZoneTextBuffer buffer(zone, 1024);

runtime/vm/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,7 @@ class Function : public Object {
24822482
BaseTextBuffer* printer) const;
24832483
StringPtr QualifiedScrubbedName() const;
24842484
StringPtr QualifiedUserVisibleName() const;
2485+
const char* QualifiedUserVisibleNameCString() const;
24852486

24862487
virtual StringPtr DictionaryName() const { return name(); }
24872488

0 commit comments

Comments
 (0)