Change UnresolvedNameGenerator to use NonLvalueGenerator.
This avoids the need for custom assignment-handling logic in KernelUnresolvedNameGenerator, and ensures that assignments to unresloved names work properly with analyzer integration. Change-Id: I802270987c90043d021f8560b56f47babf72fb1e Reviewed-on: https://dart-review.googlesource.com/66701 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
e4446d3d0d
commit
232bed3d11
@@ -6459,6 +6459,19 @@ f(int x, int y) {
|
||||
assertElement(findNode.simple('y;'), yElement);
|
||||
}
|
||||
|
||||
test_null_aware_assignment_to_unresolved_name() async {
|
||||
addTestFile('''
|
||||
f(int y) {
|
||||
x ??= y;
|
||||
}
|
||||
''');
|
||||
await resolveTestFile();
|
||||
expect(result.errors, isNotEmpty);
|
||||
assertElement(findNode.simple('x'), null);
|
||||
var yElement = findElement.parameter('y');
|
||||
assertElement(findNode.simple('y;'), yElement);
|
||||
}
|
||||
|
||||
test_postfix_increment_of_non_generator() async {
|
||||
addTestFile('''
|
||||
f() {}
|
||||
@@ -8387,6 +8400,8 @@ main() {
|
||||
var assignment = findNode.assignment('a = b');
|
||||
assertElementNull(assignment);
|
||||
if (useCFE) {
|
||||
assertType(assignment, 'dynamic');
|
||||
} else {
|
||||
assertType(assignment, 'int');
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ import 'kernel_ast_api.dart'
|
||||
TreeNode,
|
||||
TypeParameterType,
|
||||
UnresolvedTargetInvocationJudgment,
|
||||
UnresolvedVariableAssignmentJudgment,
|
||||
UnresolvedVariableUnaryJudgment,
|
||||
VariableDeclaration;
|
||||
|
||||
@@ -868,9 +869,6 @@ abstract class ErroneousExpressionGenerator implements Generator {
|
||||
|
||||
withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
|
||||
|
||||
@override
|
||||
Generator asLvalue() => this;
|
||||
|
||||
@override
|
||||
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
|
||||
return helper.buildInvalidInitializer(new SyntheticExpressionJudgment(
|
||||
@@ -975,6 +973,20 @@ abstract class UnresolvedNameGenerator implements ErroneousExpressionGenerator {
|
||||
return helper.forest.unresolvedNameGenerator(helper, token, name);
|
||||
}
|
||||
|
||||
@override
|
||||
Generator asLvalue() {
|
||||
return new NonLvalueGenerator(
|
||||
helper,
|
||||
token,
|
||||
buildError(new Arguments([]),
|
||||
isSetter: true, offset: offsetForToken(token)),
|
||||
new UnresolvedVariableAssignmentJudgment(
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
)..fileOffset = token.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
String get debugName => "UnresolvedNameGenerator";
|
||||
|
||||
|
||||
@@ -103,7 +103,6 @@ import 'kernel_ast_api.dart'
|
||||
Throw,
|
||||
TreeNode,
|
||||
TypeParameter,
|
||||
UnresolvedVariableAssignmentJudgment,
|
||||
UnresolvedVariableGetJudgment,
|
||||
VariableAssignmentJudgment,
|
||||
VariableDeclaration,
|
||||
@@ -1451,20 +1450,6 @@ class KernelUnresolvedNameGenerator extends KernelGenerator
|
||||
ExpressionGeneratorHelper helper, Token token, this.name)
|
||||
: super(helper, token);
|
||||
|
||||
@override
|
||||
Expression buildAssignment(Expression value, {bool voidContext: false}) {
|
||||
return _buildUnresolvedVariableAssignment(false, value);
|
||||
}
|
||||
|
||||
@override
|
||||
Expression buildCompoundAssignment(Name binaryOperator, Expression value,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget,
|
||||
bool isPreIncDec: false}) {
|
||||
return _buildUnresolvedVariableAssignment(true, value);
|
||||
}
|
||||
|
||||
@override
|
||||
Expression buildSimpleRead() {
|
||||
Expression error = buildError(forest.argumentsEmpty(token), isGetter: true);
|
||||
@@ -1487,15 +1472,6 @@ class KernelUnresolvedNameGenerator extends KernelGenerator
|
||||
sink.write(", name: ");
|
||||
sink.write(name.name);
|
||||
}
|
||||
|
||||
UnresolvedVariableAssignmentJudgment _buildUnresolvedVariableAssignment(
|
||||
bool isCompound, Expression value) {
|
||||
return new UnresolvedVariableAssignmentJudgment(
|
||||
buildError(forest.arguments(<Expression>[value], token), isSetter: true),
|
||||
isCompound,
|
||||
value,
|
||||
)..fileOffset = token.charOffset;
|
||||
}
|
||||
}
|
||||
|
||||
class KernelUnlinkedGenerator extends KernelGenerator with UnlinkedGenerator {
|
||||
|
||||
@@ -171,6 +171,9 @@ class IncompleteErrorGenerator extends IncompleteSendGenerator
|
||||
ExpressionGeneratorHelper helper, Token token, this.member, this.message)
|
||||
: super(helper, token, null);
|
||||
|
||||
@override
|
||||
Generator asLvalue() => this;
|
||||
|
||||
String get debugName => "IncompleteErrorGenerator";
|
||||
|
||||
@override
|
||||
|
||||
@@ -3739,8 +3739,12 @@ class UnresolvedVariableAssignmentJudgment extends SyntheticExpressionJudgment {
|
||||
ShadowTypeInferrer inferrer,
|
||||
Factory<Expression, Statement, Initializer, Type> factory,
|
||||
DartType typeContext) {
|
||||
inferrer.inferExpression(factory, rhs, const UnknownType(), true);
|
||||
inferredType = isCompound ? const DynamicType() : rhs.inferredType;
|
||||
if (rhs != null) {
|
||||
inferrer.inferExpression(factory, rhs, const UnknownType(), true);
|
||||
inferredType = isCompound ? const DynamicType() : rhs.inferredType;
|
||||
} else {
|
||||
inferredType = const DynamicType();
|
||||
}
|
||||
inferrer.listener.variableAssign(
|
||||
this, fileOffset, const DynamicType(), null, null, inferredType);
|
||||
return super.infer(inferrer, factory, typeContext);
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@ Errors: {
|
||||
Setter not found: 'z'. (@0)
|
||||
}
|
||||
static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
|
||||
return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[2]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
|
||||
return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
|
||||
|
||||
@@ -52,7 +52,7 @@ class Fisk extends core::Object {
|
||||
static method main(dynamic arguments) → dynamic {
|
||||
new self::Fisk::•();
|
||||
for (final dynamic #t6 in arguments) {
|
||||
throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t6]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
|
||||
throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
|
||||
core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
|
||||
}
|
||||
for (final dynamic #t7 in arguments) {
|
||||
|
||||
@@ -52,7 +52,7 @@ class Fisk extends core::Object {
|
||||
static method main(dynamic arguments) → dynamic {
|
||||
new self::Fisk::•();
|
||||
for (final dynamic #t6 in arguments) {
|
||||
throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t6]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
|
||||
throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
|
||||
core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
|
||||
}
|
||||
for (final dynamic #t7 in arguments) {
|
||||
|
||||
Reference in New Issue
Block a user