Skip to content

Commit

Permalink
Version 2.19.0-394.0.dev
Browse files Browse the repository at this point in the history
Merge 29c3fea into dev
  • Loading branch information
Dart CI committed Nov 12, 2022
2 parents 7bdd565 + 29c3fea commit 996fe4d
Show file tree
Hide file tree
Showing 35 changed files with 820 additions and 177 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/no-response.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# A workflow to close issues where the author hasn't responded to a request for
# more information; see https://github.com/godofredoc/no-response for docs.

name: No Response

# Both `issue_comment` and `scheduled` event types are required.
on:
issue_comment:
types: [created]
schedule:
# Schedule for five minutes after the hour, every hour
- cron: '5 * * * *'

# All permissions not specified are set to 'none'.
permissions:
issues: write

jobs:
noResponse:
runs-on: ubuntu-latest
if: ${{ github.repository == 'dart-lang/sdk' }}
steps:
- uses: godofredoc/no-response@0ce2dc0e63e1c7d2b87752ceed091f6d32c9df09
with:
responseRequiredLabel: "needs-info"
responseRequiredColor: 4774bc
closeComment: >
Without additional information we're not able to resolve this
issue, so it will be closed at this time. You're still free to add
more info and respond to any questions above, though. We'll re-open
the case if you do. Thanks for your contribution!
daysUntilClose: 14
token: ${{ github.token }}
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ vars = {
"pool_rev": "1ea5b031cfda37786d305292cb8104dffb45d9ae",
"protobuf_rev": "4af1cb3c4e116d02d3b3d005fd9d4995fbc4c564",
"pub_rev": "6ac42d7644dedfcc500147ab47886eecab4b1b38", # manually rev'd
"pub_semver_rev": "5ac4c28f6d5f2ac737ed5443a3ffcb1d18e2b271",
"pub_semver_rev": "28159b8c5b96fc2709d0904389d7932880f68659", # b/258766867
"root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
"shelf_rev": "5fd2593d47120232054ebcc794f3a028d903f1f8",
"source_map_stack_trace_rev": "8d8078fcc81c8f7936805cd277198493e0b7fc62",
Expand Down
1 change: 1 addition & 0 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Global approvers - only to be used as a last resort.
[email protected] #{LAST_RESORT_SUGGESTION}
[email protected] #{LAST_RESORT_SUGGESTION}
[email protected] #{LAST_RESORT_SUGGESTION}
[email protected] #{LAST_RESORT_SUGGESTION}
[email protected] #{LAST_RESORT_SUGGESTION}
[email protected] #{LAST_RESORT_SUGGESTION}
Expand Down
46 changes: 46 additions & 0 deletions benchmarks/StringCompare/dart/LongStringCompare.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Measure performance of string comparison.

import 'package:benchmark_harness/benchmark_harness.dart';

class LongStringCompare extends BenchmarkBase {
late String s, t;

String generateLongString() {
var s = "abcdefgh";
for (int i = 0; i < 20; i++) {
s = "$s ghijkl $s";
}
return s;
}

LongStringCompare() : super('LongStringCompare') {
s = generateLongString();
t = s;
// Difference in two strings goes in the middle.
s += "." + s;
t += "!" + t;
}

@override
void warmup() {
for (int i = 0; i < 4; i++) {
run();
}
}

@override
void run() {
bool b = true;
for (int i = 0; i < 5; i++) {
b &= (s == t);
}
}
}

void main() {
LongStringCompare().report();
}
17 changes: 10 additions & 7 deletions pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1064,12 +1064,12 @@ mixin TypeAnalyzer<
///
/// Stack effect: none.
Type analyzeVariablePattern(
Type matchedType,
MatchContext<Node, Expression, Pattern, Type, Variable> context,
Pattern node,
Variable? variable,
Type? declaredType,
{required bool isFinal}) {
Type matchedType,
MatchContext<Node, Expression, Pattern, Type, Variable> context,
Pattern node,
Variable? variable,
Type? declaredType,
) {
Type staticType =
declaredType ?? variableTypeFromInitializerType(matchedType);
Node? irrefutableContext = context.irrefutableContext;
Expand All @@ -1095,7 +1095,7 @@ mixin TypeAnalyzer<
// TODO(paulberry): do we need to verify that all instances of a
// variable are final or all are not final?
flow?.initialize(variable, matchedType, context.getInitializer(node),
isFinal: context.isFinal || isFinal,
isFinal: context.isFinal || isVariableFinal(variable),
isLate: context.isLate,
isImplicitlyTyped: isImplicitlyTyped);
}
Expand Down Expand Up @@ -1302,6 +1302,9 @@ mixin TypeAnalyzer<
/// `default` clause.
bool isSwitchExhaustive(Node node, Type expressionType);

/// Returns whether [node] is final.
bool isVariableFinal(Variable node);

/// Queries whether [pattern] is a variable pattern.
bool isVariablePattern(Node pattern);

Expand Down
25 changes: 13 additions & 12 deletions pkg/_fe_analyzer_shared/test/mini_ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,9 @@ Statement while_(Expression condition, List<Statement> body) {
location: location);
}

Pattern wildcard(
{String? type, String? expectInferredType, bool isFinal = false}) =>
Pattern wildcard({String? type, String? expectInferredType}) =>
_VariablePattern(type == null ? null : Type(type), null, expectInferredType,
isFinal: isFinal, location: computeLocation());
location: computeLocation());

typedef SharedMatchContext
= shared.MatchContext<Node, Expression, Pattern, Type, Var>;
Expand Down Expand Up @@ -1252,11 +1251,12 @@ abstract class TryStatement extends Statement implements TryBuilder {
/// analysis testing.
class Var extends Node implements Promotable {
final String name;
final bool isFinal;

/// The type of the variable, or `null` if it is not yet known.
Type? _type;

Var(this.name) : super._(location: computeLocation());
Var(this.name, {this.isFinal = false}) : super._(location: computeLocation());

/// Creates an L-value representing a reference to this variable.
LValue get expr =>
Expand All @@ -1278,11 +1278,10 @@ class Var extends Node implements Promotable {
_type = value;
}

Pattern pattern(
{String? type, String? expectInferredType, bool isFinal = false}) =>
Pattern pattern({String? type, String? expectInferredType}) =>
new _VariablePattern(
type == null ? null : Type(type), this, expectInferredType,
isFinal: isFinal, location: computeLocation());
location: computeLocation());

@override
void preVisit(PreVisitor visitor) {}
Expand Down Expand Up @@ -3220,6 +3219,11 @@ class _MiniAstTypeAnalyzer
return node.isExhaustive;
}

@override
bool isVariableFinal(Var node) {
return node.isFinal;
}

@override
bool isVariablePattern(Node pattern) => pattern is _VariablePattern;

Expand Down Expand Up @@ -3925,10 +3929,8 @@ class _VariablePattern extends Pattern {

final String? expectInferredType;

final bool isFinal;

_VariablePattern(this.declaredType, this.variable, this.expectInferredType,
{this.isFinal = false, required super.location})
{required super.location})
: super._();

Type computeSchema(Harness h) =>
Expand All @@ -3949,8 +3951,7 @@ class _VariablePattern extends Pattern {
SharedMatchContext context,
) {
var staticType = h.typeAnalyzer.analyzeVariablePattern(
matchedType, context, this, variable, declaredType,
isFinal: isFinal);
matchedType, context, this, variable, declaredType);
h.typeAnalyzer.handleVariablePattern(this,
matchedType: matchedType, staticType: staticType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,8 @@ HintCode.CAN_BE_NULL_AFTER_NULL_AWARE:
status: hasFix
HintCode.CAST_FROM_NULL_ALWAYS_FAILS:
status: needsEvaluation
HintCode.CAST_FROM_NULLABLE_ALWAYS_FAILS:
status: needsEvaluation
HintCode.DEAD_CODE:
status: hasFix
HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ void main() {
class VariableNameSuggestionTest extends AbstractSingleUnitTest {
Future<void> test_forExpression_cast() async {
await resolveTestCode('''
void f() {
var sortedNodes;
void f(Object sortedNodes) {
var res = sortedNodes as String;
}
''');
Expand Down
3 changes: 1 addition & 2 deletions pkg/analyzer/lib/src/dart/ast/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13563,8 +13563,7 @@ class VariablePatternImpl extends DartPatternImpl implements VariablePattern {
SharedMatchContext context,
) {
resolverVisitor.analyzeVariablePattern(
matchedType, context, this, declaredElement, type?.typeOrThrow,
isFinal: keyword?.keyword == Keyword.FINAL);
matchedType, context, this, declaredElement, type?.typeOrThrow);
}

@override
Expand Down
11 changes: 11 additions & 0 deletions pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ class HintCode extends AnalyzerErrorCode {
correctionMessage: "Replace the '.' with a '?.' in the invocation.",
);

/// Parameters:
/// 0: the name of the unassigned variable
static const HintCode CAST_FROM_NULLABLE_ALWAYS_FAILS = HintCode(
'CAST_FROM_NULLABLE_ALWAYS_FAILS',
"This cast will always throw an exception because the nullable local "
"variable '{0}' is not assigned.",
correctionMessage:
"Try giving it an initializer expression, or ensure that it's assigned "
"on every execution path.",
);

/// No parameters.
static const HintCode CAST_FROM_NULL_ALWAYS_FAILS = HintCode(
'CAST_FROM_NULL_ALWAYS_FAILS',
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer/lib/src/error/error_code_values.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ const List<ErrorCode> errorCodeValues = [
HintCode.BODY_MIGHT_COMPLETE_NORMALLY_CATCH_ERROR,
HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE,
HintCode.CAN_BE_NULL_AFTER_NULL_AWARE,
HintCode.CAST_FROM_NULLABLE_ALWAYS_FAILS,
HintCode.CAST_FROM_NULL_ALWAYS_FAILS,
HintCode.DEAD_CODE,
HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
Expand Down
23 changes: 23 additions & 0 deletions pkg/analyzer/lib/src/generated/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,11 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
bool isSwitchExhaustive(AstNode node, DartType expressionType) =>
switchExhaustiveness!.isExhaustive;

@override
bool isVariableFinal(PromotableElement element) {
return element.isFinal;
}

@override
bool isVariablePattern(AstNode pattern) => pattern is VariablePattern;

Expand Down Expand Up @@ -1570,6 +1575,24 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
_insertImplicitCallReference(
insertGenericFunctionInstantiation(node, contextType: contextType),
contextType: contextType);

var expression = node.expression;
var staticType = node.staticType;
if (staticType != null && expression is SimpleIdentifier) {
var simpleIdentifier = expression as SimpleIdentifier;
var element = simpleIdentifier.staticElement;
if (element is PromotableElement &&
!expression.typeOrThrow.isDartCoreNull &&
typeSystem.isNullable(element.type) &&
typeSystem.isNonNullable(staticType) &&
flowAnalysis.isDefinitelyUnassigned(simpleIdentifier, element)) {
errorReporter.reportErrorForNode(
HintCode.CAST_FROM_NULLABLE_ALWAYS_FAILS,
simpleIdentifier,
[simpleIdentifier.name],
);
}
}
}

@override
Expand Down
7 changes: 7 additions & 0 deletions pkg/analyzer/lib/src/workspace/blaze_watcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -386,17 +386,20 @@ class BlazeSearchInfo {

class BlazeWatcherError implements BlazeWatcherMessage {
final String message;

BlazeWatcherError(this.message);
}

class BlazeWatcherEvents implements BlazeWatcherMessage {
final List<WatchEvent> events;

BlazeWatcherEvents(this.events);
}

/// Sent by the watcher isolate to transfer the [SendPort] to the main isolate.
class BlazeWatcherIsolateStarted implements BlazeWatcherMessage {
final SendPort sendPort;

BlazeWatcherIsolateStarted(this.sendPort);
}

Expand All @@ -407,24 +410,28 @@ class BlazeWatcherShutdownIsolate implements BlazeWatcherMessage {}
class BlazeWatcherStartWatching implements BlazeWatcherMessage {
final String workspace;
final BlazeSearchInfo info;

BlazeWatcherStartWatching(this.workspace, this.info);
}

class BlazeWatcherStopWatching implements BlazeWatcherMessage {
final String workspace;
final String requestedPath;

BlazeWatcherStopWatching(this.workspace, this.requestedPath);
}

class FileInfo {
String path;
_ModifiedInfo modified;

FileInfo(this.path, this.modified);
}

/// Triggers polling every time something appears in the [stream].
abstract class PollTrigger {
Stream<Object> get stream;

void cancel();
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/analyzer/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19897,6 +19897,13 @@ HintCode:
comment: |-
No parameters.
hasPublishedDocs: false
CAST_FROM_NULLABLE_ALWAYS_FAILS:
problemMessage: "This cast will always throw an exception because the nullable local variable '{0}' is not assigned."
correctionMessage: "Try giving it an initializer expression, or ensure that it's assigned on every execution path."
hasPublishedDocs: false
comment: |-
Parameters:
0: the name of the unassigned variable
NULL_CHECK_ALWAYS_FAILS:
problemMessage: "This null-check will always throw an exception because the expression will always evaluate to 'null'."
comment: |-
Expand Down
17 changes: 14 additions & 3 deletions pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,23 @@ m() {
]);
}

test_as_nullable() async {
await assertNoErrorsInCode(r'''
m() {
test_as_nullable_nonNullable() async {
await assertErrorsInCode(r'''
void f() {
num? x;
x as int;
}
''', [
error(HintCode.CAST_FROM_NULLABLE_ALWAYS_FAILS, 23, 1),
]);
}

test_as_nullable_nullable() async {
await assertNoErrorsInCode(r'''
void f() {
num? x;
x as String?;
}
''');
}

Expand Down
Loading

0 comments on commit 996fe4d

Please sign in to comment.