mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:31:20 +00:00
Stop using getReadType() in nnbd_migration.
The packages 'analyzer' and 'nnbd_migration' tightly depend on each other via MigrationResolutionHooks. I will publish analyzer 0.40.4 shortly after this CL lands. Change-Id: I6f5e51f88e0020a1674ffb251712658e896170e7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164900 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
e8683d25ed
commit
8de1bc0a07
|
@ -67,6 +67,8 @@ class AssignmentExpressionResolver {
|
|||
_resolver.setReadElement(left, readElement);
|
||||
}
|
||||
_resolver.setWriteElement(left, writeElement);
|
||||
_resolver.migrationResolutionHooks
|
||||
?.setCompoundAssignmentExpressionTypes(node);
|
||||
|
||||
_resolver.setAssignmentBackwardCompatibility(
|
||||
assignment: node,
|
||||
|
|
|
@ -62,6 +62,8 @@ class PostfixExpressionResolver {
|
|||
var operand = node.operand;
|
||||
_resolver.setReadElement(operand, readElement);
|
||||
_resolver.setWriteElement(operand, writeElement);
|
||||
_resolver.migrationResolutionHooks
|
||||
?.setCompoundAssignmentExpressionTypes(node);
|
||||
|
||||
_resolver.setAssignmentBackwardCompatibility(
|
||||
assignment: node,
|
||||
|
@ -82,8 +84,8 @@ class PostfixExpressionResolver {
|
|||
///
|
||||
/// TODO(scheglov) this is duplicate
|
||||
void _checkForInvalidAssignmentIncDec(
|
||||
AstNode node, Expression operand, DartType type) {
|
||||
var operandWriteType = _getWriteType(operand);
|
||||
PostfixExpression node, Expression operand, DartType type) {
|
||||
var operandWriteType = node.writeType;
|
||||
if (!_typeSystem.isAssignableTo2(type, operandWriteType)) {
|
||||
_resolver.errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.INVALID_ASSIGNMENT,
|
||||
|
@ -129,16 +131,6 @@ class PostfixExpressionResolver {
|
|||
}
|
||||
}
|
||||
|
||||
DartType _getWriteType(Expression node) {
|
||||
if (node is SimpleIdentifier) {
|
||||
var element = node.staticElement;
|
||||
if (element is PromotableElement) {
|
||||
return element.type;
|
||||
}
|
||||
}
|
||||
return node.staticType;
|
||||
}
|
||||
|
||||
void _resolve1(PostfixExpression node, DartType receiverType) {
|
||||
Expression operand = node.operand;
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ class PrefixExpressionResolver {
|
|||
var operand = node.operand;
|
||||
_resolver.setReadElement(operand, readElement);
|
||||
_resolver.setWriteElement(operand, writeElement);
|
||||
_resolver.migrationResolutionHooks
|
||||
?.setCompoundAssignmentExpressionTypes(node);
|
||||
|
||||
_resolver.setAssignmentBackwardCompatibility(
|
||||
assignment: node,
|
||||
|
|
|
@ -31,6 +31,10 @@ abstract class MigrationResolutionHooks
|
|||
DartType modifyInferredParameterType(
|
||||
ParameterElement parameter, DartType type);
|
||||
|
||||
/// Called after the resolver has determined the read and write types
|
||||
/// of the assignment expression.
|
||||
void setCompoundAssignmentExpressionTypes(CompoundAssignmentExpression node);
|
||||
|
||||
/// Called when the resolver starts or stops making use of a [FlowAnalysis]
|
||||
/// instance.
|
||||
void setFlowAnalysis(
|
||||
|
|
|
@ -26,7 +26,6 @@ import 'package:analyzer/src/generated/migration.dart';
|
|||
import 'package:analyzer/src/generated/resolver.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:analyzer/src/generated/utilities_dart.dart';
|
||||
import 'package:analyzer/src/task/strong/checker.dart';
|
||||
import 'package:nnbd_migration/fix_reason_target.dart';
|
||||
import 'package:nnbd_migration/instrumentation.dart';
|
||||
import 'package:nnbd_migration/nnbd_migration.dart';
|
||||
|
@ -471,20 +470,18 @@ class MigrationResolutionHooksImpl
|
|||
_wrapExceptions(node, () => type, () {
|
||||
var parent = node.parent;
|
||||
if (parent is AssignmentExpression) {
|
||||
return (_assignmentLikeExpressionHandlers[parent] ??=
|
||||
_AssignmentExpressionHandler(parent))
|
||||
.modifySubexpressionType(this, node, type);
|
||||
if (parent.leftHandSide == node) {
|
||||
return type;
|
||||
}
|
||||
return _assignmentLikeExpressionHandlers[parent]
|
||||
.modifyAssignmentRhs(this, node, type);
|
||||
} else if (parent is PrefixExpression) {
|
||||
if (_isIncrementOrDecrementOperator(parent.operator.type)) {
|
||||
return (_assignmentLikeExpressionHandlers[parent] ??=
|
||||
_PrefixExpressionHandler(parent))
|
||||
.modifySubexpressionType(this, node, type);
|
||||
return type;
|
||||
}
|
||||
} else if (parent is PostfixExpression) {
|
||||
if (_isIncrementOrDecrementOperator(parent.operator.type)) {
|
||||
return (_assignmentLikeExpressionHandlers[parent] ??=
|
||||
_PostfixExpressionHandler(parent))
|
||||
.modifySubexpressionType(this, node, type);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return _modifyRValueType(node, type);
|
||||
|
@ -502,6 +499,30 @@ class MigrationResolutionHooksImpl
|
|||
return type;
|
||||
}
|
||||
|
||||
@override
|
||||
void setCompoundAssignmentExpressionTypes(CompoundAssignmentExpression node) {
|
||||
assert(_assignmentLikeExpressionHandlers[node] == null);
|
||||
if (node is AssignmentExpression) {
|
||||
var handler = _AssignmentExpressionHandler(node);
|
||||
_assignmentLikeExpressionHandlers[node] = handler;
|
||||
handler.handleLValueType(this, node.readType, node.writeType);
|
||||
} else if (node is PrefixExpression) {
|
||||
assert(_isIncrementOrDecrementOperator(node.operator.type));
|
||||
var handler = _PrefixExpressionHandler(node);
|
||||
_assignmentLikeExpressionHandlers[node] = handler;
|
||||
handler.handleLValueType(this, node.readType, node.writeType);
|
||||
handler.handleAssignmentRhs(this, _fixBuilder.typeProvider.intType);
|
||||
} else if (node is PostfixExpression) {
|
||||
assert(_isIncrementOrDecrementOperator(node.operator.type));
|
||||
var handler = _PostfixExpressionHandler(node);
|
||||
_assignmentLikeExpressionHandlers[node] = handler;
|
||||
handler.handleLValueType(this, node.readType, node.writeType);
|
||||
handler.handleAssignmentRhs(this, _fixBuilder.typeProvider.intType);
|
||||
} else {
|
||||
throw StateError('(${node.runtimeType}) $node');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void setFlowAnalysis(
|
||||
FlowAnalysis<AstNode, Statement, Expression, PromotableElement, DartType>
|
||||
|
@ -765,37 +786,21 @@ abstract class _AssignmentLikeExpressionHandler {
|
|||
/// [writeType], and [rhsContextType]. Also verifies that for compound
|
||||
/// assignments, the [readType] is non-nullable, and that for null-aware
|
||||
/// assignments, the [readType] is nullable.
|
||||
void handleLValueType(
|
||||
MigrationResolutionHooksImpl hooks, DartType resolvedType) {
|
||||
assert(resolvedType.nullabilitySuffix != NullabilitySuffix.star);
|
||||
// Provisionally store the resolved type as the type of the target, so that
|
||||
// getReadType can fall back on it if necessary.
|
||||
var target = this.target;
|
||||
target.staticType = resolvedType;
|
||||
// The type passed in by the resolver for the LHS of an assignment is the
|
||||
// "write type".
|
||||
var writeType = resolvedType;
|
||||
if (target is SimpleIdentifier) {
|
||||
var element = target.staticElement;
|
||||
if (element is PromotableElement) {
|
||||
// However, if the LHS is a reference to a local variable that has
|
||||
// been promoted, the resolver passes in the promoted type. We
|
||||
// want to use the variable element's type, so that we consider it
|
||||
// ok to assign a value to the variable that un-does the
|
||||
// promotion. See https://github.com/dart-lang/sdk/issues/41411.
|
||||
writeType = element.type;
|
||||
}
|
||||
}
|
||||
assert(writeType.nullabilitySuffix != NullabilitySuffix.star);
|
||||
this.writeType = writeType;
|
||||
void handleLValueType(MigrationResolutionHooksImpl hooks,
|
||||
DartType readTypeToSet, DartType writeTypeToSet) {
|
||||
assert(writeTypeToSet.nullabilitySuffix != NullabilitySuffix.star);
|
||||
writeType = writeTypeToSet;
|
||||
// TODO(scheglov) Remove this after the analyzer breaking change that
|
||||
// will top setting types for LHS.
|
||||
target.staticType = writeTypeToSet;
|
||||
var fixBuilder = hooks._fixBuilder;
|
||||
if (combinerType == TokenType.EQ) {
|
||||
rhsContextType = writeType;
|
||||
rhsContextType = writeTypeToSet;
|
||||
} else {
|
||||
readType = getReadType(target);
|
||||
readType = readTypeToSet;
|
||||
assert(readType.nullabilitySuffix != NullabilitySuffix.star);
|
||||
if (combinerType == TokenType.QUESTION_QUESTION_EQ) {
|
||||
rhsContextType = writeType;
|
||||
rhsContextType = writeTypeToSet;
|
||||
if (fixBuilder._typeSystem.isNonNullable(readType)) {
|
||||
(fixBuilder._getChange(node) as NodeChangeForAssignment)
|
||||
.isWeakNullAware = true;
|
||||
|
@ -810,26 +815,13 @@ abstract class _AssignmentLikeExpressionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/// Called after visiting the LHS or the RHS of the assignment.
|
||||
DartType modifySubexpressionType(MigrationResolutionHooksImpl hooks,
|
||||
/// Called after visiting the RHS of the assignment.
|
||||
DartType modifyAssignmentRhs(MigrationResolutionHooksImpl hooks,
|
||||
Expression subexpression, DartType type) {
|
||||
if (identical(subexpression, target)) {
|
||||
handleLValueType(hooks, type);
|
||||
if (node is! AssignmentExpression) {
|
||||
// Must be a pre or post increment/decrement, so the "RHS" is implicitly
|
||||
// the integer 1.
|
||||
handleAssignmentRhs(hooks, hooks._fixBuilder.typeProvider.intType);
|
||||
}
|
||||
return type;
|
||||
} else {
|
||||
var node = this.node;
|
||||
assert(node is AssignmentExpression &&
|
||||
identical(subexpression, node.rightHandSide));
|
||||
type =
|
||||
hooks._modifyRValueType(subexpression, type, context: rhsContextType);
|
||||
handleAssignmentRhs(hooks, type);
|
||||
return type;
|
||||
}
|
||||
type =
|
||||
hooks._modifyRValueType(subexpression, type, context: rhsContextType);
|
||||
handleAssignmentRhs(hooks, type);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ environment:
|
|||
sdk: '>=2.6.0 <3.0.0'
|
||||
dependencies:
|
||||
_fe_analyzer_shared: ^4.0.0
|
||||
analyzer: ^0.40.1
|
||||
analyzer: ^0.40.4
|
||||
analyzer_plugin: ^0.2.4
|
||||
args: ^1.4.4
|
||||
charcode: ^1.1.2
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/dart/element/type_provider.dart';
|
||||
import 'package:analyzer/src/dart/element/type_provider.dart';
|
||||
import 'package:analyzer/src/dart/error/hint_codes.dart';
|
||||
import 'package:analyzer/src/generated/element_type_provider.dart';
|
||||
import 'package:analyzer/src/task/strong/checker.dart';
|
||||
import 'package:nnbd_migration/fix_reason_target.dart';
|
||||
import 'package:nnbd_migration/nnbd_migration.dart';
|
||||
import 'package:nnbd_migration/src/edit_plan.dart';
|
||||
|
@ -3364,10 +3362,8 @@ void _f(bool/*?*/ x, bool/*?*/ y) {
|
|||
identical(ElementTypeProvider.current, const ElementTypeProvider()));
|
||||
ElementTypeProvider.current = fixBuilder.migrationResolutionHooks;
|
||||
var assignment = node.thisOrAncestorOfType<AssignmentExpression>();
|
||||
var isReadWrite = assignment.operator.type != TokenType.EQ;
|
||||
var readType =
|
||||
isReadWrite ? getReadType(node) ?? typeProvider.dynamicType : null;
|
||||
var writeType = node.staticType;
|
||||
var readType = assignment.readType;
|
||||
var writeType = assignment.writeType;
|
||||
return AssignmentTargetInfo(readType, writeType);
|
||||
} finally {
|
||||
ElementTypeProvider.current = const ElementTypeProvider();
|
||||
|
|
Loading…
Reference in a new issue