Skip to content

Commit

Permalink
Use InvalidType instead of DynamicType when unresolved.
Browse files Browse the repository at this point in the history
Bug: #36697
Change-Id: If982ca46030959160f21950c5b5e3127895d937b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/300181
Reviewed-by: Samuel Rawlins <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
scheglov authored and Commit Queue committed May 10, 2023
1 parent 4992725 commit a3956e4
Show file tree
Hide file tree
Showing 96 changed files with 2,137 additions and 981 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ class DartUnitHighlightsComputer {

static bool _isDynamicExpression(Expression e) {
var type = e.staticType;
return type != null && type is DynamicType;
return type != null && type is DynamicType || type is InvalidType;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class AddDiagnosticPropertyReference extends CorrectionProducer {
constructorId = 'TransformProperty';
} else {
constructorId = 'DiagnosticsProperty';
if (type is! DynamicType) {
if (!(type is DynamicType || type is InvalidType)) {
typeArgs = [type];
}
}
Expand All @@ -94,7 +94,7 @@ class AddDiagnosticPropertyReference extends CorrectionProducer {
builder.write('<');
builder.writeTypes(typeArgs);
builder.write('>');
} else if (type is DynamicType) {
} else if (type is DynamicType || type is InvalidType) {
TypeAnnotation? declType;
final decl = node.thisOrAncestorOfType<VariableDeclarationList>();
if (decl != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2891,7 +2891,7 @@ void f() {

Future<void> test_ForEachStatement_body_untyped() async {
// Block ForEachStatement
addTestSource('void f(args) {for (var foo in bar) {^}}');
addTestSource('void f(args) {for (var foo in args) {^}}');
await computeSuggestions();

expect(replacementOffset, completionOffset);
Expand Down Expand Up @@ -5769,7 +5769,7 @@ class B extends A1 with A2 {
assertSuggestClass('B');
assertSuggestField('a', 'int');
assertSuggestMethod('b', 'B', 'int');
assertSuggestField('foo', 'dynamic');
assertSuggestField('foo', 'InvalidType');
assertSuggestClass('A1');
assertSuggestConstructor('A1');
assertNotSuggested('x');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3077,7 +3077,7 @@ void f() {new C().^}''');
expect(replacementLength, 0);
assertSuggestGetter('f', 'X');
assertSuggestGetter('_g', null);
assertSuggestField(r'$p', 'dynamic');
assertSuggestField(r'$p', 'InvalidType');
assertSuggestMethod(r'$q', 'I', 'void');
assertNotSuggested('b');
assertNotSuggested('_c');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

Expand Down Expand Up @@ -119,16 +118,4 @@ f() {
}
''');
}

Future<void> test_synthetic_implicitCast() async {
createAnalysisOptionsFile(implicitCasts: false);
await resolveTestCode('''
int foo =
''');
await assertNoFix(
errorFilter: (e) {
return e.errorCode == CompileTimeErrorCode.INVALID_ASSIGNMENT;
},
);
}
}
2 changes: 1 addition & 1 deletion pkg/analyzer/lib/src/dart/analysis/driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ import 'package:analyzer/src/utilities/uri_cache.dart';
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 271;
static const int DATA_VERSION = 272;

/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer/lib/src/dart/element/normalize.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class NormalizeHelper {

// NORM(T) = T if T is primitive
if (identical(T, DynamicTypeImpl.instance) ||
identical(T, InvalidTypeImpl.instance) ||
identical(T, NeverTypeImpl.instance) ||
identical(T, VoidTypeImpl.instance) ||
T_nullability == NullabilitySuffix.none &&
Expand Down
3 changes: 3 additions & 0 deletions pkg/analyzer/lib/src/dart/element/subtype.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class SubtypeHelper {
// Right Top: if `T1` is a top type (i.e. `dynamic`, or `void`, or
// `Object?`) then `T0 <: T1`.
if (identical(T1, DynamicTypeImpl.instance) ||
identical(T1, InvalidTypeImpl.instance) ||
identical(T1, VoidTypeImpl.instance) ||
T1_nullability == NullabilitySuffix.question && T1.isDartCoreObject) {
return true;
Expand All @@ -62,6 +63,7 @@ class SubtypeHelper {
// Left Top: if `T0` is `dynamic` or `void`,
// then `T0 <: T1` if `Object? <: T1`.
if (identical(T0, DynamicTypeImpl.instance) ||
identical(T0, InvalidTypeImpl.instance) ||
identical(T0, VoidTypeImpl.instance)) {
if (isSubtypeOf(_objectQuestion, T1)) {
return true;
Expand Down Expand Up @@ -107,6 +109,7 @@ class SubtypeHelper {
// then the subtyping does not hold, the result is false.
if (T0_nullability == NullabilitySuffix.none && T0.isDartCoreNull ||
identical(T0, DynamicTypeImpl.instance) ||
identical(T0, InvalidTypeImpl.instance) ||
identical(T0, VoidTypeImpl.instance) ||
T0_nullability == NullabilitySuffix.question) {
return false;
Expand Down
20 changes: 16 additions & 4 deletions pkg/analyzer/lib/src/dart/element/type_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,11 @@ class TypeSystemImpl implements TypeSystem {
return true;
}

// Accept the invalid type, we have already reported an error for it.
if (fromType is InvalidType) {
return true;
}

// A 'call' method tearoff.
if (fromType is InterfaceType &&
!isNullable(fromType) &&
Expand Down Expand Up @@ -1005,7 +1010,8 @@ class TypeSystemImpl implements TypeSystem {
/// whose bound is dynamic bounded, or an intersection (promoted type
/// parameter type) whose second operand is dynamic bounded.
bool isDynamicBounded(DartType type) {
if (identical(type, DynamicTypeImpl.instance)) {
if (identical(type, DynamicTypeImpl.instance) ||
identical(type, InvalidTypeImpl.instance)) {
return true;
}

Expand Down Expand Up @@ -1193,12 +1199,14 @@ class TypeSystemImpl implements TypeSystem {
}

// MORETOP(dynamic, S) = true
if (identical(T, DynamicTypeImpl.instance)) {
if (identical(T, DynamicTypeImpl.instance) ||
identical(T, InvalidTypeImpl.instance)) {
return true;
}

// MORETOP(T, dynamic) = false
if (identical(S, DynamicTypeImpl.instance)) {
if (identical(S, DynamicTypeImpl.instance) ||
identical(S, InvalidTypeImpl.instance)) {
return false;
}

Expand Down Expand Up @@ -1266,6 +1274,7 @@ class TypeSystemImpl implements TypeSystem {
@override
bool isNonNullable(DartType type) {
if (type is DynamicType ||
type is InvalidType ||
type is UnknownInferredType ||
type is VoidType ||
type.isDartCoreNull) {
Expand Down Expand Up @@ -1310,6 +1319,7 @@ class TypeSystemImpl implements TypeSystem {
@override
bool isNullable(DartType type) {
if (type is DynamicType ||
type is InvalidType ||
type is UnknownInferredType ||
type is VoidType ||
type.isDartCoreNull) {
Expand Down Expand Up @@ -1355,6 +1365,7 @@ class TypeSystemImpl implements TypeSystem {
@override
bool isStrictlyNonNullable(DartType type) {
if (type is DynamicType ||
type is InvalidType ||
type is UnknownInferredType ||
type is VoidType ||
type.isDartCoreNull) {
Expand Down Expand Up @@ -1387,7 +1398,8 @@ class TypeSystemImpl implements TypeSystem {
}

// TOP(dynamic) is true
if (identical(type, DynamicTypeImpl.instance)) {
if (identical(type, DynamicTypeImpl.instance) ||
identical(type, InvalidTypeImpl.instance)) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ class AssignmentExpressionResolver {
var writeElement = leftResolution.writeElement;

if (hasRead) {
_resolver.setReadElement(left, readElement);
_resolver.setReadElement(
left,
readElement,
atDynamicTarget: leftResolution.atDynamicTarget,
);
{
final recordField = leftResolution.recordField;
if (recordField != null) {
Expand All @@ -71,7 +75,11 @@ class AssignmentExpressionResolver {
}
_resolveOperator(node);
}
_resolver.setWriteElement(left, writeElement);
_resolver.setWriteElement(
left,
writeElement,
atDynamicTarget: leftResolution.atDynamicTarget,
);
_resolver.migrationResolutionHooks
?.setCompoundAssignmentExpressionTypes(node);

Expand Down Expand Up @@ -261,9 +269,11 @@ class AssignmentExpressionResolver {
operator == TokenType.BAR_BAR_EQ) {
assignedType = _typeProvider.boolType;
} else {
var leftType = node.readType!;
var operatorElement = node.staticElement;
if (operatorElement != null) {
var leftType = node.readType!;
if (leftType is DynamicType) {
assignedType = DynamicTypeImpl.instance;
} else if (operatorElement != null) {
var rightType = rightHandSide.typeOrThrow;
assignedType = _typeSystem.refineBinaryExpressionType(
leftType,
Expand All @@ -273,7 +283,7 @@ class AssignmentExpressionResolver {
operatorElement,
);
} else {
assignedType = DynamicTypeImpl.instance;
assignedType = InvalidTypeImpl.instance;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class BinaryExpressionResolver {
var rightContextType = contextType;
if (rightContextType == null ||
rightContextType is DynamicType ||
rightContextType is InvalidType ||
rightContextType is UnknownInferredType) {
rightContextType = leftType;
}
Expand Down Expand Up @@ -262,7 +263,7 @@ class BinaryExpressionResolver {
{required DartType? contextType}) {
node.leftOperand.accept(_resolver);
node.rightOperand.accept(_resolver);
_inferenceHelper.recordStaticType(node, DynamicTypeImpl.instance,
_inferenceHelper.recordStaticType(node, InvalidTypeImpl.instance,
contextType: contextType);
}

Expand Down Expand Up @@ -377,8 +378,12 @@ class BinaryExpressionResolver {
return;
}

DartType staticType =
node.staticInvokeType?.returnType ?? DynamicTypeImpl.instance;
var staticType = node.staticInvokeType?.returnType;
if (leftType is DynamicType) {
staticType ??= DynamicTypeImpl.instance;
} else {
staticType ??= InvalidTypeImpl.instance;
}
if (leftOperand is! ExtensionOverride) {
staticType = _typeSystem.refineBinaryExpressionType(
leftType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class ConstructorReferenceResolver {
} else {
var constructorElement = constructorName.staticElement;
if (constructorElement == null) {
node.staticType = DynamicTypeImpl.instance;
node.staticType = InvalidTypeImpl.instance;
} else {
node.staticType = constructorElement.type;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ class TypeSystemOperations
bool isDynamic(DartType type) => type is DynamicType;

@override
bool isError(DartType type) => false;
bool isError(DartType type) => type is InvalidType;

@override
bool isNever(DartType type) {
Expand Down
30 changes: 16 additions & 14 deletions pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,28 @@ class ForResolver {
/// a type for the elements being iterated over. Inference is based
/// on the type of the iterator or stream over which the foreach loop
/// is defined.
DartType? _computeForEachElementType(Expression iterable, bool isAsync) {
DartType _computeForEachElementType(Expression iterable, bool isAsync) {
var iterableType = iterable.staticType;
if (iterableType == null) return null;
if (iterableType == null) {
return InvalidTypeImpl.instance;
}

iterableType = _typeSystem.resolveToBound(iterableType);
if (iterableType is DynamicType) {
return DynamicTypeImpl.instance;
}

ClassElement iteratedElement = isAsync
? _resolver.typeProvider.streamElement
: _resolver.typeProvider.iterableElement;

var iteratedType = iterableType.asInstanceOf(iteratedElement);

if (iteratedType != null) {
var elementType = iteratedType.typeArguments.single;
elementType = _resolver.toLegacyTypeIfOptOut(elementType);
return elementType;
} else {
return null;
if (iteratedType == null) {
return InvalidTypeImpl.instance;
}

var elementType = iteratedType.typeArguments.single;
return _resolver.toLegacyTypeIfOptOut(elementType);
}

void _forEachParts(AstNode node, bool isAsync, ForEachParts forEachParts,
Expand Down Expand Up @@ -162,9 +166,7 @@ class ForResolver {

loopVariable?.accept(_resolver);
var elementType = _computeForEachElementType(iterable, isAsync);
if (loopVariable != null &&
elementType != null &&
loopVariable.type == null) {
if (loopVariable != null && loopVariable.type == null) {
var loopVariableElement =
loopVariable.declaredElement as LocalVariableElementImpl;
loopVariableElement.type = elementType;
Expand All @@ -179,8 +181,8 @@ class ForResolver {
_resolver.flowAnalysis.flow?.forEach_bodyBegin(node);
if (identifierElement is PromotableElement &&
forEachParts is ForEachPartsWithIdentifier) {
_resolver.flowAnalysis.flow?.write(forEachParts, identifierElement,
elementType ?? DynamicTypeImpl.instance, null);
_resolver.flowAnalysis.flow
?.write(forEachParts, identifierElement, elementType, null);
}

visitBody();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ class FunctionExpressionInvocationResolver {
function,
);
}
_unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList,
contextType: contextType);
final type = result.isGetterInvalid
? InvalidTypeImpl.instance
: DynamicTypeImpl.instance;
_unresolved(node, type, whyNotPromotedList, contextType: contextType);
return;
}

Expand All @@ -98,7 +100,7 @@ class FunctionExpressionInvocationResolver {
CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
function,
);
_unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList,
_unresolved(node, InvalidTypeImpl.instance, whyNotPromotedList,
contextType: contextType);
return;
}
Expand Down Expand Up @@ -189,7 +191,7 @@ class FunctionExpressionInvocationResolver {
contextType: contextType,
whyNotPromotedList: whyNotPromotedList)
.resolveInvocation(rawType: null);
node.staticInvokeType = DynamicTypeImpl.instance;
node.staticInvokeType = type;
node.staticType = type;
}

Expand Down
Loading

0 comments on commit a3956e4

Please sign in to comment.