Add type tracking to type inference logging.

This commit updates the type inference logging logic introduced in
https://dart-review.googlesource.com/c/sdk/+/369788 so that it
additionally tracks the context and static type for each inferred
expression.

Tracking the context for each expression is easy, since it is an input
to the type inference algorithm, passed in to each `visit` method of
`ResolverVisitor` through the named parameter `contextType`. However,
there were a few expression types for which the context type *wasn't*
passed in, because it wasn't used (for example
`ResolverVisitor.visitBooleanLiteral`, since boolean literals always
have the same meaning regardless of their context). `contextType`
parameters have been added to these `visit` methods for consistency
with the other expression visit methods, so that the type inference
log shows the context for all expressions, whether it makes a
difference to inference or not.

Tracking the static type for each expression is a little trickier,
since it's not an explicit output of the type inference algorithm, but
rather the static type of each expression is set as a side effect of
the type inference mechanism. To make things more tractable, the
`ExpressionImpl.staticType` field is made private, and instead of
setting it directly, the resolver must set it by either calling
`recordStaticType` or `setPseudoExpressionStaticType`. The former is
used when resolving a real expression; the latter is used for
situations where the analyzer assigns a static type to an AST node
even though that AST node isn't really serving as an expression
according to the official language specification. (For example, when
analyzing the method invocation `x.foo()`, the analyzer stores a
static type on the SimpleIdentifier `foo`, even though according to
the language spec, `foo` in this context actually isn't an expression
in its own right).

Splitting the code paths that set static types into `recordStaticType`
and `setPseudoExpressionStaticType` allows for the type inference
logging mechanism to check some useful invariants: it verifies that
every expression that the resolver visits is either assigned a static
type exactly once through a call to `recordStaticType`, or it's
determined to not be a true expression (and hence not assigned a
static type at all); I believe the latter happens mostly when
analyzing erroneous code, or when the resolver visitor is called upon
to assign a type to an identifier that's in a declaration context.

Change-Id: Icdf023d03fba3c87dbec3a72d00d0e9c7d1da5fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370322
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Paul Berry 2024-06-10 18:07:01 +00:00 committed by Commit Queue
parent 8e219fcd08
commit 172bbe09cd
26 changed files with 423 additions and 334 deletions

View file

@ -2,6 +2,8 @@
// 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.
import '../types/shared_type.dart';
/// Maximum length for strings returned by [describe].
const int _descriptionLengthThreshold = 80;
@ -56,22 +58,38 @@ class Event {
Event({required this.message});
}
/// Specialization of [State] used when type inferring an expression.
class ExpressionState extends State {
/// Whether [SharedInferenceLogWriterImpl.recordStaticType] or
/// [SharedInferenceLogWriterImpl.recordExpressionWithNoType] has been called
/// for the expression represented by this [State] object.
///
/// The inference log infrastructure uses this boolean to verify that each
/// expression that undergoes type inference either receives a static type, or
/// is determined by analysis to not need a static type.
bool typeRecorded = false;
ExpressionState(
{required super.writer, required super.message, required super.nodeSet})
: super(kind: StateKind.expression);
}
/// Public API to the interface log writer.
///
/// This class defines methods that the analyzer or CFE can use to instrument
/// their type inference logic. The implementations are found in
/// [SharedInferenceLogWriterImpl].
abstract interface class SharedInferenceLogWriter {
abstract interface class SharedInferenceLogWriter<Type extends SharedType> {
/// Verifies that every call to an `enter...` method has been matched by a
/// corresponding call to an `exit...` method.
void assertIdle();
/// Called when type inference begins inferring an expression.
void enterExpression(Object node);
void enterExpression(Object node, Type contextType);
/// Called when type inference begins inferring an AST node associated with
/// extension override syntax.
void enterExtensionOverride(Object node);
void enterExtensionOverride(Object node, Type contextType);
/// Called when type inference has discovered that a construct that uses
/// method invocation syntax (e.g. `x.f()`) is actually an invocation of a
@ -114,6 +132,14 @@ abstract interface class SharedInferenceLogWriter {
/// double check that it's only recorded once in the log.
void recordExpressionRewrite(
{Object? oldExpression, required Object newExpression});
/// Called when type inference is inferring an expression, and discovers that
/// the expression should not have any type.
void recordExpressionWithNoType(Object expression);
/// Called when type inference is inferring an expression, and assigns the
/// expression a static type.
void recordStaticType(Object expression, Type type);
}
/// Implementation of the interface log writer.
@ -125,8 +151,8 @@ abstract interface class SharedInferenceLogWriter {
/// from classes derived from [SharedInferenceLogWriterImpl], but these methods
/// are not exposed in [SharedInferenceLogWriter] so that they won't be called
/// accidentally on their own.
abstract class SharedInferenceLogWriterImpl
implements SharedInferenceLogWriter {
abstract class SharedInferenceLogWriterImpl<Type extends SharedType>
implements SharedInferenceLogWriter<Type> {
/// A stack of [State] objects representing the calls that have been made to
/// `enter...` methods without any matched `exit...` method.
///
@ -237,27 +263,26 @@ abstract class SharedInferenceLogWriterImpl
}
@override
void enterExpression(Object node) {
pushState(new State(
kind: StateKind.expression,
void enterExpression(Object node, Type contextType) {
pushState(new ExpressionState(
writer: this,
message: 'INFER EXPRESSION ${describe(node)}',
message: 'INFER EXPRESSION ${describe(node)} IN CONTEXT $contextType',
nodeSet: [node]));
}
@override
void enterExtensionOverride(Object node) {
void enterExtensionOverride(Object node, Type contextType) {
pushState(new State(
kind: StateKind.extensionOverride,
writer: this,
message: 'INFER EXTENSION OVERRIDE ${describe(node)}',
message: 'INFER EXTENSION OVERRIDE ${describe(node)} IN CONTEXT '
'$contextType',
nodeSet: [node]));
}
@override
void enterFunctionExpressionInvocationTarget(Object node) {
pushState(new State(
kind: StateKind.expression,
pushState(new ExpressionState(
writer: this,
message: 'REINTERPRET METHOD NAME ${describe(node)} AS AN EXPRESSION',
nodeSet: [node]));
@ -280,8 +305,14 @@ abstract class SharedInferenceLogWriterImpl
namedArguments: {if (reanalyze) 'reanalyze': reanalyze},
expectedNode: node,
expectedKind: StateKind.expression);
bool typeRecorded = (state as ExpressionState).typeRecorded;
if (reanalyze) {
if (typeRecorded) {
fail('Tried to reanalyze after already recording a static type');
}
addEvent(new Event(message: 'WILL REANALYZE AS OTHER EXPRESSION'));
} else if (!typeRecorded) {
fail('Failed to record a type for $state');
}
popState();
}
@ -349,7 +380,7 @@ abstract class SharedInferenceLogWriterImpl
addEvent(new Event(
message: 'REWRITE ${describe(oldExpression)} TO '
'${describe(newExpression)}'));
state.nodeSet.add(newExpression);
(state as ExpressionState).nodeSet.add(newExpression);
if (oldExpression != null) {
if (_rewrittenExpressions[oldExpression] ?? false) {
fail('Expression already rewritten: ${describe(oldExpression)}');
@ -357,6 +388,30 @@ abstract class SharedInferenceLogWriterImpl
_rewrittenExpressions[oldExpression] = true;
}
}
@override
void recordExpressionWithNoType(Object expression) {
checkCall(
method: 'recordExpressionWithNoType',
arguments: [expression],
expectedNode: expression,
expectedKind: StateKind.expression);
addEvent(
new Event(message: 'EXPRESSION ${describe(expression)} HAS NO TYPE'));
(state as ExpressionState).typeRecorded = true;
}
@override
void recordStaticType(Object expression, Type type) {
checkCall(
method: 'recordStaticType',
arguments: [expression, type],
expectedNode: expression,
expectedKind: StateKind.expression);
addEvent(
new Event(message: 'STATIC TYPE OF ${describe(expression)} IS $type'));
(state as ExpressionState).typeRecorded = true;
}
}
/// Specialization of [Event] representing an event that might be associated

View file

@ -88,7 +88,7 @@ final class AdjacentStringsImpl extends StringLiteralImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitAdjacentStrings(this);
resolver.visitAdjacentStrings(this, contextType: contextType);
}
@override
@ -1715,7 +1715,7 @@ final class AugmentedExpressionImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitAugmentedExpression(this);
resolver.visitAugmentedExpression(this, contextType: contextType);
}
@override
@ -2135,7 +2135,7 @@ final class BooleanLiteralImpl extends LiteralImpl implements BooleanLiteral {
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitBooleanLiteral(this);
resolver.visitBooleanLiteral(this, contextType: contextType);
}
@override
@ -5346,7 +5346,7 @@ final class DoubleLiteralImpl extends LiteralImpl implements DoubleLiteral {
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitDoubleLiteral(this);
resolver.visitDoubleLiteral(this, contextType: contextType);
}
@override
@ -5992,8 +5992,7 @@ final class ExpressionFunctionBodyImpl extends FunctionBodyImpl
sealed class ExpressionImpl extends AstNodeImpl
implements CollectionElementImpl, Expression {
@override
DartType? staticType;
DartType? _staticType;
@override
bool get inConstantContext {
@ -6076,9 +6075,24 @@ sealed class ExpressionImpl extends AstNodeImpl
return null;
}
@override
DartType? get staticType => _staticType;
@override
ExpressionImpl get unParenthesized => this;
/// Record that the static type of the given node is the given type.
///
/// @param expression the node whose type is to be recorded
/// @param type the static type of the node
void recordStaticType(DartType type, {required ResolverVisitor resolver}) {
_staticType = type;
if (type.isBottom) {
resolver.flowAnalysis.flow?.handleExit();
}
inferenceLogWriter?.recordStaticType(this, type);
}
@override
void resolveElement(
ResolverVisitor resolver, CollectionLiteralContext? context) {
@ -6093,6 +6107,17 @@ sealed class ExpressionImpl extends AstNodeImpl
/// call [ResolverVisitor.dispatchExpression], which has some special logic
/// for handling dynamic contexts.
void resolveExpression(ResolverVisitor resolver, DartType contextType);
/// Records that the static type of `this` is [type], without triggering any
/// [ResolverVisitor] behaviors.
///
/// This is used when the expression AST node occurs in a place where it is
/// not technically a true expression, but the analyzer chooses to assign it a
/// static type anyway (e.g. the [SimpleIdentifier] representing the method
/// name in a method invocation).
void setPseudoExpressionStaticType(DartType? type) {
_staticType = type;
}
}
/// An expression used as a statement.
@ -6527,7 +6552,7 @@ final class ExtensionOverrideImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitExtensionOverride(this);
resolver.visitExtensionOverride(this, contextType: contextType);
}
@override
@ -8443,7 +8468,7 @@ final class FunctionReferenceImpl extends CommentReferableExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitFunctionReference(this);
resolver.visitFunctionReference(this, contextType: contextType);
}
@override
@ -10527,7 +10552,7 @@ final class IsExpressionImpl extends ExpressionImpl implements IsExpression {
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitIsExpression(this);
resolver.visitIsExpression(this, contextType: contextType);
}
@override
@ -12876,7 +12901,7 @@ final class NullLiteralImpl extends LiteralImpl implements NullLiteral {
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitNullLiteral(this);
resolver.visitNullLiteral(this, contextType: contextType);
}
@override
@ -13415,7 +13440,7 @@ final class PatternAssignmentImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitPatternAssignment(this);
resolver.visitPatternAssignment(this, contextType: contextType);
}
@override
@ -14960,7 +14985,7 @@ final class RethrowExpressionImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitRethrowExpression(this);
resolver.visitRethrowExpression(this, contextType: contextType);
}
@override
@ -15707,7 +15732,7 @@ final class SimpleStringLiteralImpl extends SingleStringLiteralImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitSimpleStringLiteral(this);
resolver.visitSimpleStringLiteral(this, contextType: contextType);
}
@override
@ -15951,7 +15976,7 @@ final class StringInterpolationImpl extends SingleStringLiteralImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitStringInterpolation(this);
resolver.visitStringInterpolation(this, contextType: contextType);
}
@override
@ -16215,7 +16240,7 @@ final class SuperExpressionImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitSuperExpression(this);
resolver.visitSuperExpression(this, contextType: contextType);
}
@override
@ -16650,11 +16675,12 @@ final class SwitchExpressionImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
inferenceLogWriter?.enterExpression(this);
inferenceLogWriter?.enterExpression(this, contextType);
var previousExhaustiveness = resolver.legacySwitchExhaustiveness;
staticType = resolver
var staticType = resolver
.analyzeSwitchExpression(this, expression, cases.length, contextType)
.type;
recordStaticType(staticType, resolver: resolver);
resolver.popRewrite();
resolver.legacySwitchExhaustiveness = previousExhaustiveness;
inferenceLogWriter?.exitExpression(this);
@ -16971,7 +16997,7 @@ final class SymbolLiteralImpl extends LiteralImpl implements SymbolLiteral {
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitSymbolLiteral(this);
resolver.visitSymbolLiteral(this, contextType: contextType);
}
@override
@ -17097,7 +17123,7 @@ final class ThrowExpressionImpl extends ExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitThrowExpression(this);
resolver.visitThrowExpression(this, contextType: contextType);
}
@override
@ -17552,7 +17578,7 @@ final class TypeLiteralImpl extends CommentReferableExpressionImpl
@override
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
resolver.visitTypeLiteral(this);
resolver.visitTypeLiteral(this, contextType: contextType);
}
@override

View file

@ -2542,7 +2542,7 @@ class _InstanceCreationEvaluator {
StringToken(TokenType.STRING, parameter.name, -1),
)
..staticElement = parameter
..staticType = parameter.type;
..setPseudoExpressionStaticType(parameter.type);
if (parameter.isPositional) {
superArguments.insert(positionalIndex++, value);
} else {
@ -2555,7 +2555,7 @@ class _InstanceCreationEvaluator {
colon: StringToken(TokenType.COLON, ':', -1),
),
expression: value,
)..staticType = value.typeOrThrow,
)..setPseudoExpressionStaticType(value.typeOrThrow),
);
}
}

View file

@ -651,7 +651,7 @@ class ClassElementImpl extends ClassOrMixinElementImpl
StringToken(TokenType.STRING, implicitParameter.name, -1),
)
..staticElement = implicitParameter
..staticType = implicitParameter.type,
..setPseudoExpressionStaticType(implicitParameter.type),
);
}
implicitConstructor.parameters = implicitParameters.toFixedList();

View file

@ -14,7 +14,6 @@ import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
@ -23,14 +22,12 @@ import 'package:analyzer/src/generated/resolver.dart';
class AssignmentExpressionResolver {
final ResolverVisitor _resolver;
final TypePropertyResolver _typePropertyResolver;
final InvocationInferenceHelper _inferenceHelper;
final AssignmentExpressionShared _assignmentShared;
AssignmentExpressionResolver({
required ResolverVisitor resolver,
}) : _resolver = resolver,
_typePropertyResolver = resolver.typePropertyResolver,
_inferenceHelper = resolver.inferenceHelper,
_assignmentShared = AssignmentExpressionShared(
resolver: resolver,
);
@ -325,7 +322,7 @@ class AssignmentExpressionResolver {
} else {
nodeType = assignedType;
}
_inferenceHelper.recordStaticType(node, nodeType);
node.recordStaticType(nodeType, resolver: _resolver);
// TODO(scheglov): Remove from ErrorVerifier?
_checkForInvalidAssignment(

View file

@ -15,7 +15,6 @@ import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/resolution_result.dart';
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
@ -26,13 +25,11 @@ import 'package:analyzer/src/generated/super_context.dart';
class BinaryExpressionResolver {
final ResolverVisitor _resolver;
final TypePropertyResolver _typePropertyResolver;
final InvocationInferenceHelper _inferenceHelper;
BinaryExpressionResolver({
required ResolverVisitor resolver,
}) : _resolver = resolver,
_typePropertyResolver = resolver.typePropertyResolver,
_inferenceHelper = resolver.inferenceHelper;
_typePropertyResolver = resolver.typePropertyResolver;
ErrorReporter get _errorReporter => _resolver.errorReporter;
@ -209,7 +206,7 @@ class BinaryExpressionResolver {
staticType = t;
}
_inferenceHelper.recordStaticType(node, staticType);
node.recordStaticType(staticType, resolver: _resolver);
_resolver.checkForArgumentTypeNotAssignableForArgument(right);
}
@ -238,7 +235,7 @@ class BinaryExpressionResolver {
_checkNonBoolOperand(left, '&&', whyNotPromoted: leftWhyNotPromoted);
_checkNonBoolOperand(right, '&&', whyNotPromoted: rightWhyNotPromoted);
_inferenceHelper.recordStaticType(node, _typeProvider.boolType);
node.recordStaticType(_typeProvider.boolType, resolver: _resolver);
}
void _resolveLogicalOr(BinaryExpressionImpl node) {
@ -265,7 +262,7 @@ class BinaryExpressionResolver {
_checkNonBoolOperand(left, '||', whyNotPromoted: leftWhyNotPromoted);
_checkNonBoolOperand(right, '||', whyNotPromoted: rightWhyNotPromoted);
_inferenceHelper.recordStaticType(node, _typeProvider.boolType);
node.recordStaticType(_typeProvider.boolType, resolver: _resolver);
}
void _resolveRightOperand(
@ -298,7 +295,7 @@ class BinaryExpressionResolver {
void _resolveUnsupportedOperator(BinaryExpressionImpl node) {
node.leftOperand.accept(_resolver);
node.rightOperand.accept(_resolver);
_inferenceHelper.recordStaticType(node, InvalidTypeImpl.instance);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
}
void _resolveUserDefinable(BinaryExpressionImpl node,
@ -324,7 +321,7 @@ class BinaryExpressionResolver {
InvalidTypeImpl.instance,
);
_resolver.popRewrite();
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
}
@ -346,13 +343,13 @@ class BinaryExpressionResolver {
var augmentationTarget = augmentation.augmentationTarget;
// Unresolved by default.
left.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
left.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
switch (augmentationTarget) {
case MethodElement operatorElement:
left.element = operatorElement;
left.staticType = _resolver.thisType ?? InvalidTypeImpl.instance;
left.setPseudoExpressionStaticType(
_resolver.thisType ?? InvalidTypeImpl.instance);
if (operatorElement.name == methodName) {
node.staticElement = operatorElement;
node.staticInvokeType = operatorElement.type;
@ -368,7 +365,7 @@ class BinaryExpressionResolver {
case PropertyAccessorElement accessor:
left.element = accessor;
if (accessor.isGetter) {
left.staticType = accessor.returnType;
left.setPseudoExpressionStaticType(accessor.returnType);
_resolveUserDefinableElement(node, methodName);
} else {
_errorReporter.atToken(
@ -378,7 +375,7 @@ class BinaryExpressionResolver {
}
case PropertyInducingElement property:
left.element = property;
left.staticType = property.type;
left.setPseudoExpressionStaticType(property.type);
_resolveUserDefinableElement(node, methodName);
}
@ -465,7 +462,7 @@ class BinaryExpressionResolver {
}
if (identical(leftType, NeverTypeImpl.instance)) {
_inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
node.recordStaticType(NeverTypeImpl.instance, resolver: _resolver);
return;
}
@ -486,6 +483,6 @@ class BinaryExpressionResolver {
node.staticElement,
);
}
_inferenceHelper.recordStaticType(node, staticType);
node.recordStaticType(staticType, resolver: _resolver);
}
}

View file

@ -129,17 +129,17 @@ class ConstructorReferenceResolver {
constructorName.staticElement = constructorElement.declaration;
constructorName.name?.staticElement = constructorElement.declaration;
node.staticType = inferred;
node.recordStaticType(inferred, resolver: _resolver);
// The NamedType child of `constructorName` doesn't have a static type.
constructorName.type.type = null;
}
} else {
var constructorElement = constructorName.staticElement;
if (constructorElement == null) {
node.staticType = InvalidTypeImpl.instance;
} else {
node.staticType = constructorElement.type;
}
node.recordStaticType(
constructorElement == null
? InvalidTypeImpl.instance
: constructorElement.type,
resolver: _resolver);
// The NamedType child of `constructorName` doesn't have a static type.
constructorName.type.type = null;
}

View file

@ -175,7 +175,7 @@ class ExtensionMemberResolver {
CompileTimeErrorCode.EXTENSION_OVERRIDE_WITHOUT_ACCESS,
);
}
nodeImpl.staticType = _dynamicType;
nodeImpl.setPseudoExpressionStaticType(_dynamicType);
}
var arguments = node.argumentList.arguments;

View file

@ -9,7 +9,6 @@ import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/invocation_inferrer.dart';
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
@ -20,13 +19,11 @@ import 'package:analyzer/src/generated/resolver.dart';
class FunctionExpressionInvocationResolver {
final ResolverVisitor _resolver;
final TypePropertyResolver _typePropertyResolver;
final InvocationInferenceHelper _inferenceHelper;
FunctionExpressionInvocationResolver({
required ResolverVisitor resolver,
}) : _resolver = resolver,
_typePropertyResolver = resolver.typePropertyResolver,
_inferenceHelper = resolver.inferenceHelper;
_typePropertyResolver = resolver.typePropertyResolver;
ErrorReporter get _errorReporter => _resolver.errorReporter;
@ -150,7 +147,7 @@ class FunctionExpressionInvocationResolver {
contextType: contextType,
).resolveInvocation(rawType: rawType);
_inferenceHelper.recordStaticType(node, returnType);
node.recordStaticType(returnType, resolver: _resolver);
}
void _resolveReceiverExtensionOverride(FunctionExpressionInvocationImpl node,
@ -196,7 +193,7 @@ class FunctionExpressionInvocationResolver {
whyNotPromotedList: whyNotPromotedList)
.resolveInvocation(rawType: null);
node.staticInvokeType = type;
node.staticType = type;
node.recordStaticType(type, resolver: _resolver);
}
/// Inference cannot be done, we still want to fill type argument types.

View file

@ -10,16 +10,13 @@ import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/generated/resolver.dart';
class FunctionExpressionResolver {
final ResolverVisitor _resolver;
final InvocationInferenceHelper _inferenceHelper;
FunctionExpressionResolver({required ResolverVisitor resolver})
: _resolver = resolver,
_inferenceHelper = resolver.inferenceHelper;
: _resolver = resolver;
TypeSystemImpl get _typeSystem => _resolver.typeSystem;
@ -160,7 +157,7 @@ class FunctionExpressionResolver {
functionElement.returnType = imposedType ?? DynamicTypeImpl.instance;
}
_inferenceHelper.recordStaticType(node, functionElement.type);
node.recordStaticType(functionElement.type, resolver: _resolver);
}
static bool _shouldUpdateReturnType(FunctionExpression node) {

View file

@ -105,7 +105,7 @@ class FunctionReferenceResolver {
function,
CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
);
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return true;
}
return false;
@ -227,11 +227,11 @@ class FunctionReferenceResolver {
String? name,
}) {
if (rawType == null) {
node.staticType = DynamicTypeImpl.instance;
node.recordStaticType(DynamicTypeImpl.instance, resolver: _resolver);
}
if (rawType is InvalidType) {
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
@ -248,11 +248,11 @@ class FunctionReferenceResolver {
// [CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR] is
// reported elsewhere; don't check type arguments here.
if (node.function is ConstructorReference) {
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
} else {
var typeArguments = node.typeArguments;
if (typeArguments == null) {
node.staticType = rawType;
node.recordStaticType(rawType, resolver: _resolver);
} else {
var typeArgumentTypes = _checkTypeArguments(
typeArguments,
@ -263,7 +263,7 @@ class FunctionReferenceResolver {
var invokeType = rawType.instantiate(typeArgumentTypes);
node.typeArgumentTypes = typeArgumentTypes;
node.staticType = invokeType;
node.recordStaticType(invokeType, resolver: _resolver);
}
}
} else {
@ -274,11 +274,11 @@ class FunctionReferenceResolver {
node.function,
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
);
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
} else if (rawType is DynamicType) {
node.staticType = DynamicTypeImpl.instance;
node.recordStaticType(DynamicTypeImpl.instance, resolver: _resolver);
} else {
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
}
}
}
@ -301,13 +301,13 @@ class FunctionReferenceResolver {
);
_resolver.replaceExpression(node, callReference);
var instantiatedType = callMethodType.instantiate(typeArgumentTypes);
callReference.staticType = instantiatedType;
callReference.recordStaticType(instantiatedType, resolver: _resolver);
}
void _resolveConstructorReference(FunctionReferenceImpl node) {
// TODO(srawlins): Rewrite and resolve [node] as a constructor reference.
node.function.accept(_resolver);
node.staticType = DynamicTypeImpl.instance;
node.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
}
/// Resolves [node] as a [TypeLiteral] referencing an interface type directly
@ -354,7 +354,7 @@ class FunctionReferenceResolver {
var member = result.getter;
if (member == null) {
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
@ -419,16 +419,17 @@ class FunctionReferenceResolver {
CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
arguments: [function.name],
);
function.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
function.prefix.staticElement = prefixElement;
function.prefix.staticType = prefixElement is PromotableElement
? _resolver.localVariableTypeProvider
.getType(function.prefix, isRead: true)
: prefixElement.referenceType;
function.prefix.setPseudoExpressionStaticType(
prefixElement is PromotableElement
? _resolver.localVariableTypeProvider
.getType(function.prefix, isRead: true)
: prefixElement.referenceType);
var functionName = function.identifier.name;
if (prefixElement is PrefixElement) {
@ -439,8 +440,8 @@ class FunctionReferenceResolver {
CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME,
arguments: [functionName, function.prefix.name],
);
function.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
} else {
_resolveReceiverPrefix(node, prefixElement, function, functionElement);
@ -475,7 +476,7 @@ class FunctionReferenceResolver {
}
if (propertyType is FunctionType) {
function.staticType = propertyType;
function.setPseudoExpressionStaticType(propertyType);
_resolve(
node: node,
rawType: propertyType,
@ -493,7 +494,7 @@ class FunctionReferenceResolver {
);
}
function.accept(_resolver);
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
}
void _resolvePropertyAccessFunction(
@ -518,13 +519,13 @@ class FunctionReferenceResolver {
} else if (targetElement is PropertyAccessorElement) {
var variable = targetElement.variable2;
if (variable == null) {
node.staticType = InvalidTypeImpl.instance;
node.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
return;
}
targetType = variable.type;
} else {
// TODO(srawlins): Can we get here?
node.staticType = DynamicTypeImpl.instance;
node.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
return;
}
} else if (target is ExtensionOverrideImpl) {
@ -537,10 +538,10 @@ class FunctionReferenceResolver {
node,
CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
);
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
} else if (targetType is InvalidType) {
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
var functionType = _resolveTypeProperty(
@ -550,7 +551,7 @@ class FunctionReferenceResolver {
);
if (functionType is FunctionType) {
function.staticType = functionType;
function.setPseudoExpressionStaticType(functionType);
_resolve(
node: node,
rawType: functionType,
@ -566,7 +567,7 @@ class FunctionReferenceResolver {
);
}
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
@ -639,8 +640,8 @@ class FunctionReferenceResolver {
return;
} else if (element is ExtensionElement) {
prefix.identifier.staticElement = element;
prefix.identifier.staticType = InvalidTypeImpl.instance;
prefix.staticType = InvalidTypeImpl.instance;
prefix.identifier.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
prefix.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
_resolveDisallowedExpression(node, InvalidTypeImpl.instance);
return;
}
@ -650,7 +651,7 @@ class FunctionReferenceResolver {
'Member of prefixed element, $prefixElement, is not a class, mixin, '
'type alias, or executable element: $element (${element.runtimeType})',
);
node.staticType = InvalidTypeImpl.instance;
node.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
}
void _resolveSimpleIdentifierFunction(
@ -672,8 +673,8 @@ class FunctionReferenceResolver {
CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
arguments: [function.name],
);
function.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
}
@ -696,19 +697,19 @@ class FunctionReferenceResolver {
if (method is PropertyAccessorElement) {
function.staticElement = method;
function.staticType = method.returnType;
function.setPseudoExpressionStaticType(method.returnType);
var variable = method.variable2;
if (variable != null) {
_resolve(node: node, rawType: variable.type);
} else {
function.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
node.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
}
return;
}
function.staticElement = method;
function.staticType = method.type;
function.setPseudoExpressionStaticType(method.type);
_resolve(node: node, rawType: method.type, name: function.name);
return;
} else {
@ -717,8 +718,8 @@ class FunctionReferenceResolver {
CompileTimeErrorCode.UNDEFINED_METHOD,
arguments: [function.name, receiverType],
);
function.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
return;
}
}
@ -750,22 +751,22 @@ class FunctionReferenceResolver {
}
} else if (element is MethodElement) {
function.staticElement = element;
function.staticType = element.type;
function.setPseudoExpressionStaticType(element.type);
_resolve(node: node, rawType: element.type, name: element.name);
return;
} else if (element is FunctionElement) {
function.staticElement = element;
function.staticType = element.type;
function.setPseudoExpressionStaticType(element.type);
_resolve(node: node, rawType: element.type, name: element.name);
return;
} else if (element is PropertyAccessorElement) {
function.staticElement = element;
var variable = element.variable2;
if (variable == null) {
function.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
return;
}
function.staticType = variable.type;
function.setPseudoExpressionStaticType(variable.type);
var callMethod = _getCallMethod(node, variable.type);
if (callMethod is MethodElement) {
_resolveAsImplicitCallReference(node, callMethod);
@ -775,12 +776,12 @@ class FunctionReferenceResolver {
return;
} else if (element is ExecutableElement) {
function.staticElement = element;
function.staticType = element.type;
function.setPseudoExpressionStaticType(element.type);
_resolve(node: node, rawType: element.type);
return;
} else if (element is VariableElement) {
function.staticElement = element;
function.staticType = element.type;
function.setPseudoExpressionStaticType(element.type);
var callMethod = _getCallMethod(node, element.type);
if (callMethod is MethodElement) {
_resolveAsImplicitCallReference(node, callMethod);
@ -790,7 +791,7 @@ class FunctionReferenceResolver {
return;
} else if (element is ExtensionElement) {
function.staticElement = element;
function.staticType = InvalidTypeImpl.instance;
function.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
_resolveDisallowedExpression(node, InvalidTypeImpl.instance);
return;
} else {
@ -850,8 +851,8 @@ class FunctionReferenceResolver {
var typeLiteral = TypeLiteralImpl(
typeName: typeName,
);
typeLiteral.staticType = _typeType;
_resolver.replaceExpression(node, typeLiteral);
typeLiteral.recordStaticType(_typeType, resolver: _resolver);
}
/// Resolves [name] as a property on [receiver].

View file

@ -68,8 +68,7 @@ class InstanceCreationExpressionResolver {
contextType: contextType,
whyNotPromotedList: whyNotPromotedList)
.resolveInvocation(rawType: elementToInfer?.asType);
_resolver.inferenceHelper
.recordStaticType(node, node.constructorName.type.type!);
node.recordStaticType(node.constructorName.type.type!, resolver: _resolver);
_resolver.checkForArgumentTypesNotAssignableInList(
node.argumentList, whyNotPromotedList);
}

View file

@ -144,17 +144,6 @@ class InvocationInferenceHelper {
return tearOffType;
}
/// Record that the static type of the given node is the given type.
///
/// @param expression the node whose type is to be recorded
/// @param type the static type of the node
void recordStaticType(ExpressionImpl expression, DartType type) {
expression.staticType = type;
if (type.isBottom) {
_resolver.flowAnalysis.flow?.handleExit();
}
}
/// Finish resolution of the [MethodInvocation].
///
/// We have already found the invoked [ExecutableElement], and the [rawType]
@ -174,6 +163,6 @@ class InvocationInferenceHelper {
whyNotPromotedList: whyNotPromotedList,
).resolveInvocation(rawType: rawType);
recordStaticType(node, returnType);
node.recordStaticType(returnType, resolver: _resolver);
}
}

View file

@ -316,7 +316,7 @@ class MethodInvocationResolver with ScopeHelpers {
contextType: contextType,
whyNotPromotedList: whyNotPromotedList)
.resolveInvocation(rawType: rawType is FunctionType ? rawType : null);
_inferenceHelper.recordStaticType(node, staticStaticType);
node.recordStaticType(staticStaticType, resolver: _resolver);
}
/// Given that we are accessing a property of the given [classElement] with the
@ -440,7 +440,7 @@ class MethodInvocationResolver with ScopeHelpers {
if (hasMatchingObjectMethod) {
nameNode.staticElement = target;
rawType = target.type;
node.staticType = target.returnType;
node.recordStaticType(target.returnType, resolver: _resolver);
}
}
@ -454,13 +454,16 @@ class MethodInvocationResolver with ScopeHelpers {
.resolveInvocation(rawType: rawType);
if (receiverType is InvalidType) {
nameNode.staticType = InvalidTypeImpl.instance;
nameNode.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
node.staticInvokeType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
} else if (rawType == null) {
nameNode.staticType = DynamicTypeImpl.instance;
nameNode.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
node.staticInvokeType = DynamicTypeImpl.instance;
node.staticType = DynamicTypeImpl.instance;
node.recordStaticType(DynamicTypeImpl.instance, resolver: _resolver);
} else {
// rawType is not `null`, therefore a static type was already recorded
// above.
}
}
@ -507,9 +510,9 @@ class MethodInvocationResolver with ScopeHelpers {
WarningCode.RECEIVER_OF_TYPE_NEVER,
);
node.methodName.staticType = _dynamicType;
node.methodName.setPseudoExpressionStaticType(_dynamicType);
node.staticInvokeType = _dynamicType;
node.staticType = NeverTypeImpl.instance;
node.recordStaticType(NeverTypeImpl.instance, resolver: _resolver);
return;
}
}
@ -729,7 +732,7 @@ class MethodInvocationResolver with ScopeHelpers {
// TODO(scheglov): Replace this with using FunctionType directly.
// Here was erase resolution that _setResolution() sets.
nameNode.staticElement = null;
nameNode.staticType = _dynamicType;
nameNode.setPseudoExpressionStaticType(_dynamicType);
return null;
}
@ -738,9 +741,9 @@ class MethodInvocationResolver with ScopeHelpers {
_setResolution(node, DynamicTypeImpl.instance, whyNotPromotedList,
contextType: contextType);
nameNode.staticElement = null;
nameNode.staticType = DynamicTypeImpl.instance;
nameNode.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
node.staticInvokeType = DynamicTypeImpl.instance;
node.staticType = DynamicTypeImpl.instance;
node.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
return null;
}
@ -905,11 +908,11 @@ class MethodInvocationResolver with ScopeHelpers {
getterReturnType) ??
targetType;
}
functionExpression.staticType = targetType;
functionExpression.setPseudoExpressionStaticType(targetType);
}
inferenceLogWriter
?.enterFunctionExpressionInvocationTarget(node.methodName);
_inferenceHelper.recordStaticType(node.methodName, targetType);
node.methodName.recordStaticType(targetType, resolver: _resolver);
inferenceLogWriter?.exitExpression(node.methodName);
var invocation = FunctionExpressionInvocationImpl(
@ -927,10 +930,10 @@ class MethodInvocationResolver with ScopeHelpers {
required List<WhyNotPromotedGetter> whyNotPromotedList,
required DartType contextType}) {
if (setNameTypeToDynamic) {
node.methodName.staticType = _dynamicType;
node.methodName.setPseudoExpressionStaticType(_dynamicType);
}
node.staticInvokeType = _dynamicType;
node.staticType = _dynamicType;
node.setPseudoExpressionStaticType(_dynamicType);
_setExplicitTypeArgumentTypes();
_resolveArguments_finishInference(node, whyNotPromotedList,
contextType: contextType);
@ -957,13 +960,13 @@ class MethodInvocationResolver with ScopeHelpers {
required List<WhyNotPromotedGetter> whyNotPromotedList,
required DartType contextType}) {
if (setNameTypeToDynamic) {
node.methodName.staticType = InvalidTypeImpl.instance;
node.methodName.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
}
_setExplicitTypeArgumentTypes();
_resolveArguments_finishInference(node, whyNotPromotedList,
contextType: contextType);
node.staticInvokeType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
node.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
}
void _setResolution(MethodInvocationImpl node, DartType type,
@ -971,7 +974,7 @@ class MethodInvocationResolver with ScopeHelpers {
{required DartType contextType}) {
// TODO(scheglov): We need this for StaticTypeAnalyzer to run inference.
// But it seems weird. Do we need to know the raw type of a function?!
node.methodName.staticType = type;
node.methodName.setPseudoExpressionStaticType(type);
if (type == _dynamicType || _isCoreFunction(type)) {
_setDynamicTypeResolution(node,

View file

@ -12,7 +12,6 @@ import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/dart/resolver/assignment_expression_resolver.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/invocation_inferrer.dart';
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
@ -22,14 +21,12 @@ import 'package:analyzer/src/generated/resolver.dart';
class PostfixExpressionResolver {
final ResolverVisitor _resolver;
final TypePropertyResolver _typePropertyResolver;
final InvocationInferenceHelper _inferenceHelper;
final AssignmentExpressionShared _assignmentShared;
PostfixExpressionResolver({
required ResolverVisitor resolver,
}) : _resolver = resolver,
_typePropertyResolver = resolver.typePropertyResolver,
_inferenceHelper = resolver.inferenceHelper,
_assignmentShared = AssignmentExpressionShared(
resolver: resolver,
);
@ -164,7 +161,7 @@ class PostfixExpressionResolver {
Expression operand = node.operand;
if (identical(receiverType, NeverTypeImpl.instance)) {
_inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
node.recordStaticType(NeverTypeImpl.instance, resolver: _resolver);
} else {
DartType operatorReturnType;
if (receiverType.isDartCoreInt) {
@ -184,7 +181,7 @@ class PostfixExpressionResolver {
}
}
_inferenceHelper.recordStaticType(node, receiverType);
node.recordStaticType(receiverType, resolver: _resolver);
_resolver.nullShortingTermination(node);
}
@ -197,8 +194,8 @@ class PostfixExpressionResolver {
node,
ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
);
_inferenceHelper.recordStaticType(operand, DynamicTypeImpl.instance);
_inferenceHelper.recordStaticType(node, DynamicTypeImpl.instance);
operand.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
node.recordStaticType(DynamicTypeImpl.instance, resolver: _resolver);
return;
}
@ -208,7 +205,7 @@ class PostfixExpressionResolver {
var operandType = operand.typeOrThrow;
var type = _typeSystem.promoteToNonNull(operandType);
_inferenceHelper.recordStaticType(node, type);
node.recordStaticType(type, resolver: _resolver);
_resolver.nullShortingTermination(node);
_resolver.flowAnalysis.flow?.nonNullAssert_end(operand);

View file

@ -13,7 +13,6 @@ import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/resolver/assignment_expression_resolver.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/invocation_inferrer.dart';
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
@ -23,14 +22,12 @@ import 'package:analyzer/src/generated/resolver.dart';
class PrefixExpressionResolver {
final ResolverVisitor _resolver;
final TypePropertyResolver _typePropertyResolver;
final InvocationInferenceHelper _inferenceHelper;
final AssignmentExpressionShared _assignmentShared;
PrefixExpressionResolver({
required ResolverVisitor resolver,
}) : _resolver = resolver,
_typePropertyResolver = resolver.typePropertyResolver,
_inferenceHelper = resolver.inferenceHelper,
_assignmentShared = AssignmentExpressionShared(
resolver: resolver,
);
@ -213,7 +210,7 @@ class PrefixExpressionResolver {
TokenType operator = node.operator.type;
var readType = node.readType ?? node.operand.staticType;
if (identical(readType, NeverTypeImpl.instance)) {
_inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
node.recordStaticType(NeverTypeImpl.instance, resolver: _resolver);
} else {
// The other cases are equivalent to invoking a method.
DartType staticType;
@ -241,7 +238,7 @@ class PrefixExpressionResolver {
}
}
}
_inferenceHelper.recordStaticType(node, staticType);
node.recordStaticType(staticType, resolver: _resolver);
}
_resolver.nullShortingTermination(node);
}
@ -255,16 +252,17 @@ class PrefixExpressionResolver {
var augmentationTarget = augmentation.augmentationTarget;
// Unresolved by default.
operand.staticType = InvalidTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
operand.setPseudoExpressionStaticType(InvalidTypeImpl.instance);
switch (augmentationTarget) {
case MethodElement operatorElement:
operand.element = operatorElement;
operand.staticType = _resolver.thisType ?? InvalidTypeImpl.instance;
operand.setPseudoExpressionStaticType(
_resolver.thisType ?? InvalidTypeImpl.instance);
if (operatorElement.name == methodName) {
node.staticElement = operatorElement;
node.staticType = operatorElement.returnType;
node.recordStaticType(operatorElement.returnType,
resolver: _resolver);
} else {
_errorReporter.atToken(
operand.augmentedKeyword,
@ -273,11 +271,12 @@ class PrefixExpressionResolver {
methodName,
],
);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
}
case PropertyAccessorElement accessor:
operand.element = accessor;
if (accessor.isGetter) {
operand.staticType = accessor.returnType;
operand.setPseudoExpressionStaticType(accessor.returnType);
_resolve1(node);
_resolve2(node);
} else {
@ -285,10 +284,11 @@ class PrefixExpressionResolver {
operand.augmentedKeyword,
CompileTimeErrorCode.AUGMENTED_EXPRESSION_IS_SETTER,
);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
}
case PropertyInducingElement property:
operand.element = property;
operand.staticType = property.type;
operand.setPseudoExpressionStaticType(property.type);
_resolve1(node);
_resolve2(node);
}
@ -304,7 +304,7 @@ class PrefixExpressionResolver {
_resolver.boolExpressionVerifier.checkForNonBoolNegationExpression(operand,
whyNotPromoted: whyNotPromoted);
_inferenceHelper.recordStaticType(node, _typeProvider.boolType);
node.recordStaticType(_typeProvider.boolType, resolver: _resolver);
_resolver.flowAnalysis.flow?.logicalNot_end(node, operand);
}

View file

@ -11,6 +11,7 @@ import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/inference_log.dart';
import 'package:analyzer/src/generated/resolver.dart';
class PrefixedIdentifierResolver {
@ -65,8 +66,8 @@ class PrefixedIdentifierResolver {
}
if (identical(node.prefix.staticType, NeverTypeImpl.instance)) {
_inferenceHelper.recordStaticType(identifier, NeverTypeImpl.instance);
_inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
identifier.setPseudoExpressionStaticType(NeverTypeImpl.instance);
node.recordStaticType(NeverTypeImpl.instance, resolver: _resolver);
return null;
}
@ -78,22 +79,24 @@ class PrefixedIdentifierResolver {
} else if (element is InterfaceElement) {
if (_isExpressionIdentifier(node)) {
var type = _typeProvider.typeType;
node.staticType = type;
identifier.staticType = type;
node.recordStaticType(type, resolver: _resolver);
identifier.setPseudoExpressionStaticType(type);
} else {
inferenceLogWriter?.recordExpressionWithNoType(node);
}
return null;
} else if (element is DynamicElementImpl) {
var type = _typeProvider.typeType;
node.staticType = type;
identifier.staticType = type;
node.recordStaticType(type, resolver: _resolver);
identifier.setPseudoExpressionStaticType(type);
return null;
} else if (element is TypeAliasElement) {
if (node.parent is NamedType) {
// no type
} else {
var type = _typeProvider.typeType;
node.staticType = type;
identifier.staticType = type;
node.recordStaticType(type, resolver: _resolver);
identifier.setPseudoExpressionStaticType(type);
}
return null;
} else if (element is MethodElement) {
@ -120,8 +123,8 @@ class PrefixedIdentifierResolver {
type = _inferenceHelper.inferTearOff(node, identifier, type,
contextType: contextType);
}
_inferenceHelper.recordStaticType(identifier, type);
_inferenceHelper.recordStaticType(node, type);
identifier.setPseudoExpressionStaticType(type);
node.recordStaticType(type, resolver: _resolver);
return null;
}
@ -165,6 +168,7 @@ class PrefixedIdentifierResolver {
parent is MethodInvocation && parent.target == node ||
parent is PrefixedIdentifierImpl && parent.prefix == node ||
parent is PropertyAccess && parent.target == node) {
inferenceLogWriter?.recordExpressionWithNoType(node);
return;
}
@ -175,10 +179,10 @@ class PrefixedIdentifierResolver {
);
if (node is PrefixedIdentifierImpl) {
node.identifier.staticType = DynamicTypeImpl.instance;
node.staticType = DynamicTypeImpl.instance;
node.identifier.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
node.recordStaticType(DynamicTypeImpl.instance, resolver: _resolver);
} else if (node is SimpleIdentifier) {
node.staticType = DynamicTypeImpl.instance;
node.recordStaticType(DynamicTypeImpl.instance, resolver: _resolver);
}
}
}

View file

@ -176,13 +176,13 @@ class RecordLiteralResolver {
}
}
_resolver.inferenceHelper.recordStaticType(
node,
node.recordStaticType(
RecordTypeImpl(
positionalFields: positionalFields,
namedFields: namedFields,
nullabilitySuffix: NullabilitySuffix.none,
),
resolver: _resolver,
);
}

View file

@ -10,21 +10,18 @@ import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/inference_log.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/scope_helpers.dart';
class SimpleIdentifierResolver with ScopeHelpers {
final ResolverVisitor _resolver;
final InvocationInferenceHelper _inferenceHelper;
var _currentAlreadyResolved = false;
SimpleIdentifierResolver(this._resolver)
: _inferenceHelper = _resolver.inferenceHelper;
SimpleIdentifierResolver(this._resolver);
@override
ErrorReporter get errorReporter => _resolver.errorReporter;
@ -33,6 +30,7 @@ class SimpleIdentifierResolver with ScopeHelpers {
void resolve(SimpleIdentifierImpl node, {required DartType contextType}) {
if (node.inDeclarationContext()) {
inferenceLogWriter?.recordExpressionWithNoType(node);
return;
}
@ -175,14 +173,14 @@ class SimpleIdentifierResolver with ScopeHelpers {
if (callFunctionType != null) {
var staticType = _resolver.inferenceHelper
.inferTearOff(node, node, callFunctionType, contextType: contextType);
_inferenceHelper.recordStaticType(node, staticType);
node.recordStaticType(staticType, resolver: _resolver);
_currentAlreadyResolved = true;
return null;
}
var recordField = result.recordField;
if (recordField != null) {
_inferenceHelper.recordStaticType(node, recordField.type);
node.recordStaticType(recordField.type, resolver: _resolver);
_currentAlreadyResolved = true;
return null;
}
@ -237,19 +235,24 @@ class SimpleIdentifierResolver with ScopeHelpers {
if (element is ExtensionElement) {
_setExtensionIdentifierType(node);
inferenceLogWriter?.recordExpressionWithNoType(node);
return;
}
DartType staticType = InvalidTypeImpl.instance;
if (element is InterfaceElement) {
if (_isExpressionIdentifier(node)) {
node.staticType = _typeProvider.typeType;
node.recordStaticType(_typeProvider.typeType, resolver: _resolver);
} else {
inferenceLogWriter?.recordExpressionWithNoType(node);
}
return;
} else if (element is TypeAliasElement) {
if (_isExpressionIdentifier(node) ||
element.aliasedType is! InterfaceType) {
node.staticType = _typeProvider.typeType;
node.recordStaticType(_typeProvider.typeType, resolver: _resolver);
} else {
inferenceLogWriter?.recordExpressionWithNoType(node);
}
return;
} else if (element is MethodElement) {
@ -267,6 +270,7 @@ class SimpleIdentifierResolver with ScopeHelpers {
var parent = node.parent;
if (parent is PrefixedIdentifier && parent.prefix == node ||
parent is MethodInvocation && parent.target == node) {
inferenceLogWriter?.recordExpressionWithNoType(node);
return;
}
staticType = InvalidTypeImpl.instance;
@ -288,7 +292,7 @@ class SimpleIdentifierResolver with ScopeHelpers {
staticType = _resolver.inferenceHelper
.inferTearOff(node, node, staticType, contextType: contextType);
}
_inferenceHelper.recordStaticType(node, staticType);
node.recordStaticType(staticType, resolver: _resolver);
}
// TODO(scheglov): this is duplicate
@ -318,10 +322,10 @@ class SimpleIdentifierResolver with ScopeHelpers {
);
if (node is PrefixedIdentifierImpl) {
node.identifier.staticType = DynamicTypeImpl.instance;
node.staticType = DynamicTypeImpl.instance;
node.identifier.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
node.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
} else if (node is SimpleIdentifier) {
node.staticType = DynamicTypeImpl.instance;
node.setPseudoExpressionStaticType(DynamicTypeImpl.instance);
}
}

View file

@ -103,7 +103,9 @@ class TypedLiteralResolver {
node.typeArguments?.accept(_resolver);
_resolveElements(node.elements, context);
_resolveListLiteral2(inferrer, node, contextType: contextType);
var staticType =
_resolveListLiteral2(inferrer, node, contextType: contextType);
node.recordStaticType(staticType, resolver: _resolver);
}
void resolveSetOrMapLiteral(SetOrMapLiteral node,
@ -591,7 +593,7 @@ class TypedLiteralResolver {
}
}
void _resolveListLiteral2(GenericInferrer? inferrer, ListLiteralImpl node,
DartType _resolveListLiteral2(GenericInferrer? inferrer, ListLiteralImpl node,
{required DartType contextType}) {
var typeArguments = node.typeArguments?.arguments;
@ -601,11 +603,10 @@ class TypedLiteralResolver {
if (typeArguments.length == 1) {
elementType = typeArguments[0].typeOrThrow;
}
node.staticType = _typeProvider.listElement.instantiate(
return _typeProvider.listElement.instantiate(
typeArguments: fixedTypeList(elementType),
nullabilitySuffix: NullabilitySuffix.none,
);
return;
}
DartType listDynamicType = _typeProvider.listType(_dynamicType);
@ -617,12 +618,11 @@ class TypedLiteralResolver {
if (inferred != listDynamicType) {
// TODO(brianwilkerson): Determine whether we need to make the inferred
// type non-nullable here or whether it will already be non-nullable.
node.staticType = inferred!;
return;
return inferred!;
}
// If we have no type arguments and couldn't infer any, use dynamic.
node.staticType = listDynamicType;
return listDynamicType;
}
void _resolveSetOrMapLiteral2(GenericInferrer? inferrer,
@ -637,19 +637,23 @@ class TypedLiteralResolver {
if (typeArguments.length == 1) {
node.becomeSet();
var elementType = typeArguments[0].typeOrThrow;
node.staticType = _typeProvider.setElement.instantiate(
typeArguments: fixedTypeList(elementType),
nullabilitySuffix: NullabilitySuffix.none,
);
node.recordStaticType(
_typeProvider.setElement.instantiate(
typeArguments: fixedTypeList(elementType),
nullabilitySuffix: NullabilitySuffix.none,
),
resolver: _resolver);
return;
} else if (typeArguments.length == 2) {
node.becomeMap();
var keyType = typeArguments[0].typeOrThrow;
var valueType = typeArguments[1].typeOrThrow;
node.staticType = _typeProvider.mapElement.instantiate(
typeArguments: fixedTypeList(keyType, valueType),
nullabilitySuffix: NullabilitySuffix.none,
);
node.recordStaticType(
_typeProvider.mapElement.instantiate(
typeArguments: fixedTypeList(keyType, valueType),
nullabilitySuffix: NullabilitySuffix.none,
),
resolver: _resolver);
return;
}
// If we get here, then a nonsense number of type arguments were provided,
@ -683,7 +687,7 @@ class TypedLiteralResolver {
// TODO(brianwilkerson): Decide whether the literalType needs to be made
// non-nullable here or whether that will have happened in
// _inferSetOrMapLiteralType.
node.staticType = literalType;
node.recordStaticType(literalType, resolver: _resolver);
}
DartType _toMapType(

View file

@ -4,6 +4,7 @@
import 'package:_fe_analyzer_shared/src/type_inference/shared_inference_log.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
final bool _assertionsEnabled = () {
@ -53,7 +54,7 @@ void stopInferenceLogging() {
/// The [SharedInferenceLogWriter] interface, augmented with analyzer-specific
/// functionality.
abstract interface class InferenceLogWriter
implements SharedInferenceLogWriter {
implements SharedInferenceLogWriter<DartType> {
/// Checks that [enterExpression] was properly called for [expression].
///
/// This is called from [ResolverVisitor.dispatchExpression], to verify that
@ -63,7 +64,8 @@ abstract interface class InferenceLogWriter
/// The [SharedInferenceLogWriterImpl] implementation, augmented with
/// analyzer-specific functionality.
final class _InferenceLogWriterImpl extends SharedInferenceLogWriterImpl
final class _InferenceLogWriterImpl
extends SharedInferenceLogWriterImpl<DartType>
implements InferenceLogWriter {
@override
void assertExpressionWasRecorded(Object expression) {
@ -72,22 +74,23 @@ final class _InferenceLogWriterImpl extends SharedInferenceLogWriterImpl
}
@override
void enterExpression(covariant Expression node) {
void enterExpression(covariant Expression node, DartType contextType) {
checkCall(
method: 'enterExpression',
arguments: [node],
arguments: [node, contextType],
expectedNode: traceableAncestor(node));
super.enterExpression(node);
super.enterExpression(node, contextType);
_recordedExpressions[node] = true;
}
@override
void enterExtensionOverride(covariant ExtensionOverride node) {
void enterExtensionOverride(
covariant ExtensionOverride node, DartType contextType) {
checkCall(
method: 'enterExtensionOverride',
arguments: [node],
arguments: [node, contextType],
expectedNode: traceableAncestor(node));
super.enterExtensionOverride(node);
super.enterExtensionOverride(node, contextType);
_recordedExpressions[node] = true;
}

View file

@ -1194,7 +1194,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
replaceExpression(expression, genericFunctionInstantiation, parent: parent);
genericFunctionInstantiation.typeArgumentTypes = typeArgumentTypes;
genericFunctionInstantiation.staticType = staticType;
genericFunctionInstantiation.setPseudoExpressionStaticType(staticType);
return genericFunctionInstantiation;
}
@ -1221,7 +1221,8 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
flowAnalysis.flow!.nullAwareAccess_end();
} while (identical(_unfinishedNullShorts.last, node));
if (node is! CascadeExpression && !discardType) {
node.staticType = typeSystem.makeNullable(node.staticType as TypeImpl);
node.setPseudoExpressionStaticType(
typeSystem.makeNullable(node.staticType as TypeImpl));
}
}
}
@ -1773,8 +1774,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitAdjacentStrings(AdjacentStrings node) {
inferenceLogWriter?.enterExpression(node);
void visitAdjacentStrings(AdjacentStrings node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitAdjacentStrings(node as AdjacentStringsImpl);
@ -1806,7 +1808,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
covariant AsExpressionImpl node, {
DartType contextType = UnknownInferredType.instance,
}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
analyzeExpression(node.expression, UnknownInferredType.instance);
@ -1874,7 +1876,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitAssignmentExpression(AssignmentExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_assignmentExpressionResolver.resolve(node as AssignmentExpressionImpl,
contextType: contextType);
@ -1893,8 +1895,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitAugmentedExpression(covariant AugmentedExpressionImpl node) {
inferenceLogWriter?.enterExpression(node);
void visitAugmentedExpression(covariant AugmentedExpressionImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
if (enclosingAugmentation case var augmentation?) {
var augmentedElement = augmentation.augmentationTarget;
if (augmentation is PropertyAccessorElementImpl &&
@ -1902,7 +1905,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
augmentedElement is PropertyAccessorElementImpl &&
augmentedElement.isGetter) {
node.element = augmentedElement;
node.staticType = augmentedElement.returnType;
node.recordStaticType(augmentedElement.returnType, resolver: this);
inferenceLogWriter?.exitExpression(node);
return;
}
@ -1913,7 +1916,8 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
libraryResolutionContext._variableNodes[augmentedElement];
if (augmentedNode != null) {
if (augmentedNode.initializer case var augmentedInitializer?) {
node.staticType = augmentedInitializer.staticType;
node.recordStaticType(augmentedInitializer.staticType!,
resolver: this);
inferenceLogWriter?.exitExpression(node);
return;
}
@ -1921,7 +1925,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
}
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: this);
inferenceLogWriter?.exitExpression(node);
}
@ -1930,7 +1934,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
covariant AugmentedInvocationImpl node, {
DartType contextType = UnknownInferredType.instance,
}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
@ -1951,7 +1955,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
CompileTimeErrorCode.AUGMENTED_EXPRESSION_IS_SETTER,
);
node.element = augmentationTarget;
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: this);
resolveArgumentsOfInvalid();
inferenceLogWriter?.exitExpression(node);
return;
@ -1973,7 +1977,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
);
node.element = augmentationTarget;
node.staticType = InvalidTypeImpl.instance;
node.recordStaticType(InvalidTypeImpl.instance, resolver: this);
resolveArgumentsOfInvalid();
inferenceLogWriter?.exitExpression(node);
return;
@ -1983,7 +1987,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
augmentedKeyword: node.augmentedKeyword,
);
augmentedExpression.element = augmentationTarget;
augmentedExpression.staticType = functionType;
augmentedExpression.setPseudoExpressionStaticType(functionType);
var rewrite = FunctionExpressionInvocationImpl(
function: augmentedExpression,
typeArguments: node.typeArguments,
@ -2012,18 +2016,18 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
whyNotPromotedList: whyNotPromotedList,
).resolveInvocation(rawType: rawType);
if (augmentationTarget is ExecutableElementImpl) {
node.staticType = returnType;
} else {
node.staticType = InvalidTypeImpl.instance;
}
node.recordStaticType(
augmentationTarget is ExecutableElementImpl
? returnType
: InvalidTypeImpl.instance,
resolver: this);
inferenceLogWriter?.exitExpression(node);
}
@override
void visitAwaitExpression(AwaitExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
analyzeExpression(node.expression, _createFutureOr(contextType));
popRewrite();
@ -2037,7 +2041,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitBinaryExpression(BinaryExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_binaryExpressionResolver.resolve(node as BinaryExpressionImpl,
contextType: contextType);
@ -2069,8 +2073,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitBooleanLiteral(BooleanLiteral node) {
inferenceLogWriter?.enterExpression(node);
void visitBooleanLiteral(BooleanLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
flowAnalysis.flow?.booleanLiteral(node, node.value);
checkUnreachableNode(node);
node.visitChildren(this);
@ -2091,7 +2096,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitCascadeExpression(covariant CascadeExpressionImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
analyzeExpression(node.target, contextType);
var targetType = node.target.staticType ?? typeProvider.dynamicType;
@ -2193,7 +2198,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitConditionalExpression(ConditionalExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
Expression condition = node.condition;
var flow = flowAnalysis.flow;
@ -2320,7 +2325,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitConstructorReference(covariant ConstructorReferenceImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
_constructorReferenceResolver.resolve(node, contextType: contextType);
_insertImplicitCallReference(node, contextType: contextType);
inferenceLogWriter?.exitExpression(node);
@ -2388,8 +2393,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitDoubleLiteral(DoubleLiteral node) {
inferenceLogWriter?.enterExpression(node);
void visitDoubleLiteral(DoubleLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitDoubleLiteral(node as DoubleLiteralImpl);
@ -2589,8 +2595,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitExtensionOverride(covariant ExtensionOverrideImpl node) {
inferenceLogWriter?.enterExtensionOverride(node);
void visitExtensionOverride(covariant ExtensionOverrideImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExtensionOverride(node, contextType);
var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
node.typeArguments?.accept(this);
@ -2751,7 +2758,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitFunctionExpression(covariant FunctionExpressionImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
var outerFunction = _enclosingFunction;
_enclosingFunction = node.declaredElement;
@ -2767,7 +2774,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
covariant FunctionExpressionInvocationImpl node, {
DartType contextType = UnknownInferredType.instance,
}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
analyzeExpression(node.function, UnknownInferredType.instance);
node.function = popRewrite()!;
@ -2784,8 +2791,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitFunctionReference(FunctionReference node) {
inferenceLogWriter?.enterExpression(node);
void visitFunctionReference(FunctionReference node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
_functionReferenceResolver.resolve(node as FunctionReferenceImpl);
inferenceLogWriter?.exitExpression(node);
}
@ -2905,7 +2913,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitIndexExpression(covariant IndexExpressionImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
var target = node.target;
@ -2946,7 +2954,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
} else {
type = InvalidTypeImpl.instance;
}
inferenceHelper.recordStaticType(node, type);
node.recordStaticType(type, resolver: this);
var replacement =
insertGenericFunctionInstantiation(node, contextType: contextType);
@ -2960,7 +2968,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
void visitInstanceCreationExpression(
covariant InstanceCreationExpressionImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_instanceCreationExpressionResolver.resolve(node, contextType: contextType);
_insertImplicitCallReference(node, contextType: contextType);
@ -2970,7 +2978,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitIntegerLiteral(IntegerLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitIntegerLiteral(node as IntegerLiteralImpl,
@ -2991,8 +2999,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitIsExpression(covariant IsExpressionImpl node) {
inferenceLogWriter?.enterExpression(node);
void visitIsExpression(covariant IsExpressionImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
analyzeExpression(node.expression, UnknownInferredType.instance);
@ -3036,7 +3045,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitListLiteral(covariant ListLiteralImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_typedLiteralResolver.resolveListLiteral(node, contextType: contextType);
inferenceLogWriter?.exitExpression(node);
@ -3101,7 +3110,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitMethodInvocation(covariant MethodInvocationImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
var target = node.target;
@ -3171,7 +3180,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitNamedExpression(NamedExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.name.accept(this);
analyzeExpression(node.expression, contextType);
@ -3208,8 +3217,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitNullLiteral(NullLiteral node) {
inferenceLogWriter?.enterExpression(node);
void visitNullLiteral(NullLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
node.visitChildren(this);
typeAnalyzer.visitNullLiteral(node as NullLiteralImpl);
flowAnalysis.flow?.nullLiteral(node, node.typeOrThrow);
@ -3220,7 +3230,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitParenthesizedExpression(ParenthesizedExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
analyzeExpression(node.expression, contextType);
popRewrite();
@ -3245,13 +3255,14 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitPatternAssignment(covariant PatternAssignmentImpl node) {
inferenceLogWriter?.enterExpression(node);
void visitPatternAssignment(covariant PatternAssignmentImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
var analysisResult =
analyzePatternAssignment(node, node.pattern, node.expression);
node.patternTypeSchema = analysisResult.patternSchema;
node.staticType = analysisResult.resolveShorting();
node.recordStaticType(analysisResult.resolveShorting(), resolver: this);
popRewrite(); // expression
inferenceLogWriter?.exitExpression(node);
}
@ -3278,7 +3289,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitPostfixExpression(PostfixExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_postfixExpressionResolver.resolve(node as PostfixExpressionImpl,
contextType: contextType);
@ -3291,7 +3302,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitPrefixedIdentifier(covariant PrefixedIdentifierImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
var rewrittenPropertyAccess =
_prefixedIdentifierResolver.resolve(node, contextType: contextType);
@ -3319,7 +3330,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitPrefixExpression(PrefixExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_prefixExpressionResolver.resolve(node as PrefixExpressionImpl,
contextType: contextType);
@ -3332,7 +3343,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitPropertyAccess(covariant PropertyAccessImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
var target = node.target;
@ -3380,8 +3391,8 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
contextType: contextType);
}
inferenceHelper.recordStaticType(propertyName, type);
inferenceHelper.recordStaticType(node, type);
propertyName.setPseudoExpressionStaticType(type);
node.recordStaticType(type, resolver: this);
var replacement =
insertGenericFunctionInstantiation(node, contextType: contextType);
@ -3396,7 +3407,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
covariant RecordLiteralImpl node, {
DartType contextType = UnknownInferredType.instance,
}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_recordLiteralResolver.resolve(node, contextType: contextType);
inferenceLogWriter?.exitExpression(node);
@ -3467,8 +3478,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitRethrowExpression(RethrowExpression node) {
inferenceLogWriter?.enterExpression(node);
void visitRethrowExpression(RethrowExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitRethrowExpression(node as RethrowExpressionImpl);
@ -3496,7 +3508,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitSetOrMapLiteral(SetOrMapLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
_typedLiteralResolver.resolveSetOrMapLiteral(node,
contextType: contextType);
@ -3516,7 +3528,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitSimpleIdentifier(covariant SimpleIdentifierImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
_simpleIdentifierResolver.resolve(node, contextType: contextType);
_insertImplicitCallReference(
insertGenericFunctionInstantiation(node, contextType: contextType),
@ -3525,8 +3537,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitSimpleStringLiteral(SimpleStringLiteral node) {
inferenceLogWriter?.enterExpression(node);
void visitSimpleStringLiteral(SimpleStringLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitSimpleStringLiteral(node as SimpleStringLiteralImpl);
@ -3554,8 +3567,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitStringInterpolation(StringInterpolation node) {
inferenceLogWriter?.enterExpression(node);
void visitStringInterpolation(StringInterpolation node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitStringInterpolation(node as StringInterpolationImpl);
@ -3584,8 +3598,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitSuperExpression(SuperExpression node) {
inferenceLogWriter?.enterExpression(node);
void visitSuperExpression(SuperExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
elementResolver.visitSuperExpression(node);
@ -3622,8 +3637,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitSymbolLiteral(SymbolLiteral node) {
inferenceLogWriter?.enterExpression(node);
void visitSymbolLiteral(SymbolLiteral node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitSymbolLiteral(node as SymbolLiteralImpl);
@ -3633,7 +3649,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
void visitThisExpression(ThisExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node);
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitThisExpression(node as ThisExpressionImpl);
@ -3642,8 +3658,9 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitThrowExpression(ThrowExpression node) {
inferenceLogWriter?.enterExpression(node);
void visitThrowExpression(ThrowExpression node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
typeAnalyzer.visitThrowExpression(node as ThrowExpressionImpl);
@ -3712,11 +3729,12 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
}
@override
void visitTypeLiteral(covariant TypeLiteralImpl node) {
inferenceLogWriter?.enterExpression(node);
void visitTypeLiteral(covariant TypeLiteralImpl node,
{DartType contextType = UnknownInferredType.instance}) {
inferenceLogWriter?.enterExpression(node, contextType);
checkUnreachableNode(node);
node.visitChildren(this);
inferenceHelper.recordStaticType(node, typeProvider.typeType);
node.recordStaticType(typeProvider.typeType, resolver: this);
inferenceLogWriter?.exitExpression(node);
}
@ -3981,7 +3999,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
);
replaceExpression(expression, callReference, parent: parent);
callReference.staticType = callMethodType;
callReference.setPseudoExpressionStaticType(callMethodType);
}
/// Continues resolution of a [FunctionExpressionInvocation] that was created

View file

@ -9,7 +9,6 @@ import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
import 'package:analyzer/src/generated/resolver.dart';
/// Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@ -23,8 +22,6 @@ class StaticTypeAnalyzer {
/// The resolver driving the resolution and type analysis.
final ResolverVisitor _resolver;
final InvocationInferenceHelper _inferenceHelper;
/// The object providing access to the types defined by the language.
late TypeProviderImpl _typeProvider;
@ -38,8 +35,7 @@ class StaticTypeAnalyzer {
/// [_resolver] based on the
///
/// @param resolver the resolver driving this participant
StaticTypeAnalyzer(this._resolver)
: _inferenceHelper = _resolver.inferenceHelper {
StaticTypeAnalyzer(this._resolver) {
_typeProvider = _resolver.typeProvider;
_typeSystem = _resolver.typeSystem;
_dynamicType = _typeProvider.dynamicType;
@ -48,7 +44,7 @@ class StaticTypeAnalyzer {
/// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
/// `String`.</blockquote>
void visitAdjacentStrings(covariant AdjacentStringsImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.stringType);
node.recordStaticType(_typeProvider.stringType, resolver: _resolver);
}
/// The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
@ -58,7 +54,7 @@ class StaticTypeAnalyzer {
///
/// The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
void visitAsExpression(covariant AsExpressionImpl node) {
_inferenceHelper.recordStaticType(node, _getType(node.type));
node.recordStaticType(_getType(node.type), resolver: _resolver);
}
/// The Dart Language Specification, 16.29 (Await Expressions):
@ -68,20 +64,20 @@ class StaticTypeAnalyzer {
void visitAwaitExpression(covariant AwaitExpressionImpl node) {
var resultType = node.expression.typeOrThrow;
resultType = _typeSystem.flatten(resultType);
_inferenceHelper.recordStaticType(node, resultType);
node.recordStaticType(resultType, resolver: _resolver);
}
/// The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is
/// bool.</blockquote>
void visitBooleanLiteral(covariant BooleanLiteralImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.boolType);
node.recordStaticType(_typeProvider.boolType, resolver: _resolver);
}
/// The Dart Language Specification, 12.15.2: <blockquote>A cascaded method invocation expression
/// of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suffix; return
/// t;}(e)</i>.</blockquote>
void visitCascadeExpression(covariant CascadeExpressionImpl node) {
_inferenceHelper.recordStaticType(node, node.target.typeOrThrow);
node.recordStaticType(node.target.typeOrThrow, resolver: _resolver);
}
void visitConditionalExpression(covariant ConditionalExpressionImpl node,
@ -116,13 +112,13 @@ class StaticTypeAnalyzer {
staticType = t;
}
_inferenceHelper.recordStaticType(node, staticType);
node.recordStaticType(staticType, resolver: _resolver);
}
/// The Dart Language Specification, 12.3: <blockquote>The static type of a literal double is
/// double.</blockquote>
void visitDoubleLiteral(covariant DoubleLiteralImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.doubleType);
node.recordStaticType(_typeProvider.doubleType, resolver: _resolver);
}
void visitExtensionOverride(ExtensionOverride node) {
@ -162,7 +158,7 @@ class StaticTypeAnalyzer {
void visitFunctionReference(covariant FunctionReferenceImpl node) {
// TODO(paulberry): implement
node.staticType = _dynamicType;
node.setPseudoExpressionStaticType(_dynamicType);
}
/// <blockquote>
@ -187,9 +183,9 @@ class StaticTypeAnalyzer {
strictCasts: strictCasts) ||
!_typeSystem.isAssignableTo(_typeProvider.doubleType, contextType,
strictCasts: strictCasts)) {
_inferenceHelper.recordStaticType(node, _typeProvider.intType);
node.recordStaticType(_typeProvider.intType, resolver: _resolver);
} else {
_inferenceHelper.recordStaticType(node, _typeProvider.doubleType);
node.recordStaticType(_typeProvider.doubleType, resolver: _resolver);
}
}
@ -198,7 +194,7 @@ class StaticTypeAnalyzer {
///
/// The static type of an is-expression is `bool`.</blockquote>
void visitIsExpression(covariant IsExpressionImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.boolType);
node.recordStaticType(_typeProvider.boolType, resolver: _resolver);
}
void visitMethodInvocation(MethodInvocation node) {
@ -207,37 +203,37 @@ class StaticTypeAnalyzer {
void visitNamedExpression(covariant NamedExpressionImpl node) {
Expression expression = node.expression;
_inferenceHelper.recordStaticType(node, expression.typeOrThrow);
node.recordStaticType(expression.typeOrThrow, resolver: _resolver);
}
/// The Dart Language Specification, 12.2: <blockquote>The static type of `null` is bottom.
/// </blockquote>
void visitNullLiteral(covariant NullLiteralImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.nullType);
node.recordStaticType(_typeProvider.nullType, resolver: _resolver);
}
void visitParenthesizedExpression(
covariant ParenthesizedExpressionImpl node) {
Expression expression = node.expression;
_inferenceHelper.recordStaticType(node, expression.typeOrThrow);
node.recordStaticType(expression.typeOrThrow, resolver: _resolver);
}
/// The Dart Language Specification, 12.9: <blockquote>The static type of a rethrow expression is
/// bottom.</blockquote>
void visitRethrowExpression(covariant RethrowExpressionImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.bottomType);
node.recordStaticType(_typeProvider.bottomType, resolver: _resolver);
}
/// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
/// `String`.</blockquote>
void visitSimpleStringLiteral(covariant SimpleStringLiteralImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.stringType);
node.recordStaticType(_typeProvider.stringType, resolver: _resolver);
}
/// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
/// `String`.</blockquote>
void visitStringInterpolation(covariant StringInterpolationImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.stringType);
node.recordStaticType(_typeProvider.stringType, resolver: _resolver);
}
void visitSuperExpression(covariant SuperExpressionImpl node) {
@ -248,14 +244,14 @@ class StaticTypeAnalyzer {
node.thisOrAncestorOfType<ExtensionDeclaration>() != null) {
// TODO(brianwilkerson): Report this error if it hasn't already been
// reported.
_inferenceHelper.recordStaticType(node, InvalidTypeImpl.instance);
node.recordStaticType(InvalidTypeImpl.instance, resolver: _resolver);
} else {
_inferenceHelper.recordStaticType(node, thisType);
node.recordStaticType(thisType, resolver: _resolver);
}
}
void visitSymbolLiteral(covariant SymbolLiteralImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.symbolType);
node.recordStaticType(_typeProvider.symbolType, resolver: _resolver);
}
/// The Dart Language Specification, 12.10: <blockquote>The static type of `this` is the
@ -267,16 +263,16 @@ class StaticTypeAnalyzer {
if (thisType == null) {
// TODO(brianwilkerson): Report this error if it hasn't already been
// reported.
_inferenceHelper.recordStaticType(node, _dynamicType);
node.recordStaticType(_dynamicType, resolver: _resolver);
} else {
_inferenceHelper.recordStaticType(node, thisType);
node.recordStaticType(thisType, resolver: _resolver);
}
}
/// The Dart Language Specification, 12.8: <blockquote>The static type of a throw expression is
/// bottom.</blockquote>
void visitThrowExpression(covariant ThrowExpressionImpl node) {
_inferenceHelper.recordStaticType(node, _typeProvider.bottomType);
node.recordStaticType(_typeProvider.bottomType, resolver: _resolver);
}
/// Return the type represented by the given type [annotation].

View file

@ -344,7 +344,7 @@ class AstBinaryReader {
target: target,
cascadeSections: sections,
);
node.staticType = target.staticType;
node.setPseudoExpressionStaticType(target.staticType);
return node;
}
@ -482,7 +482,7 @@ class AstBinaryReader {
}
void _readExpressionResolution(ExpressionImpl node) {
node.staticType = _reader.readType();
node.setPseudoExpressionStaticType(_reader.readType());
}
ExtensionOverride _readExtensionOverride() {
@ -925,7 +925,7 @@ class AstBinaryReader {
name: nameNode,
expression: expression,
);
node.staticType = expression.staticType;
node.setPseudoExpressionStaticType(expression.staticType);
return node;
}

View file

@ -520,7 +520,8 @@ class InstanceMemberInferrer {
constructor.parameters,
initializer.argumentList.arguments,
(parameter, argument) {
(argument as SimpleIdentifierImpl).staticType = parameter.type;
(argument as SimpleIdentifierImpl)
.setPseudoExpressionStaticType(parameter.type);
},
);
}

View file

@ -1413,6 +1413,7 @@ recall
recalls
received
receivers
receives
recheck
reclaimed
recognizing