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

Commit 57bb12d

Browse files
author
Dart CI
committed
Version 2.12.0-17.0.dev
Merge commit '89de1e82d9073d3f3a96145ad24940e8c311b493' into 'dev'
2 parents a4fbabc + 89de1e8 commit 57bb12d

File tree

164 files changed

+1596
-404
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

164 files changed

+1596
-404
lines changed

DEPS

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ vars = {
6969

7070
# Revisions of /third_party/* dependencies.
7171
"args_tag": "1.6.0",
72-
"async_rev": "6d2de25f208b011d79d056115256d3840229723b",
72+
"async_rev": "695b3ac280f107c84adf7488743abfdfaaeea68f",
7373
"bazel_worker_rev": "26680d5e249b249c7216ab2fed0ac8ed4ee285c5",
7474
"benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
7575
"boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
@@ -101,7 +101,7 @@ vars = {
101101
"dart_style_tag": "1.3.9", # Please see the note above before updating.
102102

103103
"chromedriver_tag": "83.0.4103.39",
104-
"dartdoc_rev" : "72c69f8659ce8823ce2dde9a4f758b0fa617ab5e",
104+
"dartdoc_rev" : "6935dcd8f2d78cf1797e6365b4b71505e6579659",
105105
"ffi_rev": "a90bd424116fb6f416337db67425171f2dc4c98f",
106106
"fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
107107
"glob_rev": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
@@ -147,7 +147,7 @@ vars = {
147147
"source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
148148
"source_span_rev": "cc7c4288a83f71ecef3414199947b52a8c112c65",
149149
"sse_tag": "e5cf68975e8e87171a3dc297577aa073454a91dc",
150-
"stack_trace_tag": "45319bfd2a6da228d8c32b06e1da02ad199373c7",
150+
"stack_trace_tag": "c9c867fa9d5b9c8a059e33d3efe759698aa49d60",
151151
"stagehand_tag": "v3.3.9",
152152
"stream_channel_tag": "d7251e61253ec389ee6e045ee1042311bced8f1d",
153153
"string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",

pkg/analyzer/lib/error/error.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ const List<ErrorCode> errorCodeValues = [
535535
HintCode.NULL_AWARE_BEFORE_OPERATOR,
536536
HintCode.NULL_AWARE_IN_CONDITION,
537537
HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR,
538+
HintCode.NULL_CHECK_ALWAYS_FAILS,
538539
HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
539540
HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
540541
HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD,

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,15 @@ class HintCode extends AnalyzerErrorCode {
14341434
"The value of the '?.' operator can be 'null', which isn't appropriate "
14351435
"as an operand of a logical operator.");
14361436

1437+
/**
1438+
* This hint indicates that a null literal is null-checked with `!`, but null
1439+
* is never not null.
1440+
*/
1441+
static const HintCode NULL_CHECK_ALWAYS_FAILS = HintCode(
1442+
'NULL_CHECK_ALWAYS_FAILS',
1443+
"This null-check will always throw an exception because the expression "
1444+
"will always evaluate to 'null'.");
1445+
14371446
/**
14381447
* No parameters.
14391448
*/

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

Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,60 @@ class PrefixedIdentifierResolver {
3232
hasWrite: false,
3333
);
3434

35+
var element = result.readElement;
36+
3537
var identifier = node.identifier;
36-
identifier.staticElement = result.readElement;
38+
identifier.staticElement = element;
39+
40+
if (element is ExtensionElement) {
41+
_setExtensionIdentifierType(node);
42+
return;
43+
}
3744

38-
_resolve2(node);
45+
if (identical(node.prefix.staticType, NeverTypeImpl.instance)) {
46+
_recordStaticType(identifier, NeverTypeImpl.instance);
47+
_recordStaticType(node, NeverTypeImpl.instance);
48+
return;
49+
}
50+
51+
DartType type = DynamicTypeImpl.instance;
52+
if (element is ClassElement) {
53+
if (_isExpressionIdentifier(node)) {
54+
var type = _typeProvider.typeType;
55+
node.staticType = type;
56+
identifier.staticType = type;
57+
}
58+
return;
59+
} else if (element is DynamicElementImpl) {
60+
var type = _typeProvider.typeType;
61+
node.staticType = type;
62+
identifier.staticType = type;
63+
return;
64+
} else if (element is FunctionTypeAliasElement) {
65+
if (node.parent is TypeName) {
66+
// no type
67+
} else {
68+
var type = _typeProvider.typeType;
69+
node.staticType = type;
70+
identifier.staticType = type;
71+
}
72+
return;
73+
} else if (element is MethodElement) {
74+
type = element.type;
75+
} else if (element is PropertyAccessorElement) {
76+
type = _getTypeOfProperty(element);
77+
} else if (element is ExecutableElement) {
78+
type = element.type;
79+
} else if (element is VariableElement) {
80+
type = element.type;
81+
} else if (result.functionTypeCallType != null) {
82+
type = result.functionTypeCallType;
83+
}
84+
85+
type = _inferenceHelper.inferTearOff(node, identifier, type);
86+
87+
_recordStaticType(identifier, type);
88+
_recordStaticType(node, type);
3989
}
4090

4191
/// Return the type that should be recorded for a node that resolved to the given accessor.
@@ -103,60 +153,6 @@ class PrefixedIdentifierResolver {
103153
_inferenceHelper.recordStaticType(expression, type);
104154
}
105155

106-
void _resolve2(PrefixedIdentifier node) {
107-
SimpleIdentifier prefixedIdentifier = node.identifier;
108-
Element staticElement = prefixedIdentifier.staticElement;
109-
110-
if (staticElement is ExtensionElement) {
111-
_setExtensionIdentifierType(node);
112-
return;
113-
}
114-
115-
if (identical(node.prefix.staticType, NeverTypeImpl.instance)) {
116-
_recordStaticType(prefixedIdentifier, NeverTypeImpl.instance);
117-
_recordStaticType(node, NeverTypeImpl.instance);
118-
return;
119-
}
120-
121-
DartType staticType = DynamicTypeImpl.instance;
122-
if (staticElement is ClassElement) {
123-
if (_isExpressionIdentifier(node)) {
124-
var type = _typeProvider.typeType;
125-
node.staticType = type;
126-
node.identifier.staticType = type;
127-
}
128-
return;
129-
} else if (staticElement is DynamicElementImpl) {
130-
var type = _typeProvider.typeType;
131-
node.staticType = type;
132-
node.identifier.staticType = type;
133-
return;
134-
} else if (staticElement is FunctionTypeAliasElement) {
135-
if (node.parent is TypeName) {
136-
// no type
137-
} else {
138-
var type = _typeProvider.typeType;
139-
node.staticType = type;
140-
node.identifier.staticType = type;
141-
}
142-
return;
143-
} else if (staticElement is MethodElement) {
144-
staticType = staticElement.type;
145-
} else if (staticElement is PropertyAccessorElement) {
146-
staticType = _getTypeOfProperty(staticElement);
147-
} else if (staticElement is ExecutableElement) {
148-
staticType = staticElement.type;
149-
} else if (staticElement is VariableElement) {
150-
staticType = staticElement.type;
151-
}
152-
153-
staticType =
154-
_inferenceHelper.inferTearOff(node, node.identifier, staticType);
155-
156-
_recordStaticType(prefixedIdentifier, staticType);
157-
_recordStaticType(node, staticType);
158-
}
159-
160156
/// TODO(scheglov) this is duplicate
161157
void _setExtensionIdentifierType(Identifier node) {
162158
if (node is SimpleIdentifier && node.inDeclarationContext()) {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,12 @@ class PropertyElementResolver {
329329

330330
var targetType = target.staticType;
331331

332+
if (targetType is FunctionType && propertyName.name == 'call') {
333+
return PropertyElementResolverResult(
334+
functionTypeCallType: targetType,
335+
);
336+
}
337+
332338
if (targetType.isVoid) {
333339
_errorReporter.reportErrorForNode(
334340
CompileTimeErrorCode.USE_OF_VOID_RESULT,
@@ -693,6 +699,7 @@ class PropertyElementResolverResult {
693699
final Element readElementRecovery;
694700
final Element writeElementRequested;
695701
final Element writeElementRecovery;
702+
final FunctionType functionTypeCallType;
696703

697704
/// If [IndexExpression] is resolved, the context type of the index.
698705
/// Might be `null` if `[]` or `[]=` are not resolved or invalid.
@@ -704,6 +711,7 @@ class PropertyElementResolverResult {
704711
this.writeElementRequested,
705712
this.writeElementRecovery,
706713
this.indexContextType,
714+
this.functionTypeCallType,
707715
});
708716

709717
Element get readElement {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,9 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
613613
@override
614614
void visitPostfixExpression(PostfixExpression node) {
615615
_deprecatedVerifier.postfixExpression(node);
616+
if (node.operand.staticType?.isDartCoreNull ?? false) {
617+
_errorReporter.reportErrorForNode(HintCode.NULL_CHECK_ALWAYS_FAILS, node);
618+
}
616619
super.visitPostfixExpression(node);
617620
}
618621

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,8 @@ class ResolverVisitor extends ScopedVisitor {
17431743
type = element.type;
17441744
} else if (element is PropertyAccessorElement && element.isGetter) {
17451745
type = element.returnType;
1746+
} else if (result.functionTypeCallType != null) {
1747+
type = result.functionTypeCallType;
17461748
} else {
17471749
type = DynamicTypeImpl.instance;
17481750
}

pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6218,7 +6218,7 @@ main(double computation(int p)) {
62186218

62196219
SimpleIdentifier methodName = prefixed.identifier;
62206220
expect(methodName.staticElement, isNull);
6221-
expect(methodName.staticType, typeProvider.dynamicType);
6221+
assertType(methodName.staticType, 'double Function(int)');
62226222
}
62236223

62246224
test_prefixedIdentifier_importPrefix_className() async {

pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,11 +614,13 @@ void f(Map<String, int> a) {
614614
}
615615

616616
test_nullCheck_null() async {
617-
await assertNoErrorsInCode('''
617+
await assertErrorsInCode('''
618618
void f(Null x) {
619619
x!;
620620
}
621-
''');
621+
''', [
622+
error(HintCode.NULL_CHECK_ALWAYS_FAILS, 19, 2),
623+
]);
622624

623625
assertType(findNode.postfix('x!'), 'Never');
624626
}

pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ main() {
3333
);
3434
}
3535

36+
test_functionType_call_read() async {
37+
await assertNoErrorsInCode('''
38+
void f(int Function(String) a) {
39+
a.call;
40+
}
41+
''');
42+
43+
assertPrefixedIdentifier(
44+
findNode.prefixed('.call;'),
45+
element: null,
46+
type: 'int Function(String)',
47+
);
48+
}
49+
3650
test_implicitCall_tearOff() async {
3751
newFile('$testPackageLibPath/a.dart', content: r'''
3852
class A {

0 commit comments

Comments
 (0)