Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(592)

Unified Diff: pkg/analyzer/lib/src/generated/error_verifier.dart

Issue 2093523002: fix #25573, add option to disable implicit dynamic (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge remote-tracking branch 'origin/master' into no_implicit_dynamic Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/error_verifier.dart
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index eca427d5390ccb170d4b1cab66e96d115e3eae17..6d4177b0f0e79829e10c2498d14eeead68461ac9 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -79,7 +79,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
/**
* The options for verification.
*/
- AnalysisOptions _options;
+ AnalysisOptionsImpl _options;
/**
* The object providing access to the types defined by the language.
@@ -676,6 +676,12 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
@override
+ Object visitExtendsClause(ExtendsClause node) {
+ _checkForImplicitDynamicType(node.superclass);
+ return super.visitExtendsClause(node);
+ }
+
+ @override
Object visitFieldDeclaration(FieldDeclaration node) {
_isInStaticVariableDeclaration = node.isStatic;
_isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
@@ -747,6 +753,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
_checkForTypeAnnotationDeferredClass(returnType);
_checkForIllegalReturnType(returnType);
+ _checkForImplicitDynamicReturn(node, node.element);
return super.visitFunctionDeclaration(node);
} finally {
_enclosingFunction = outerFunction;
@@ -781,6 +788,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
} else if (expressionType is FunctionType) {
_checkTypeArguments(expressionType.element, node.typeArguments);
}
+ _checkForImplicitDynamicInvoke(node);
return super.visitFunctionExpressionInvocation(node);
}
@@ -799,6 +807,18 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
_isInFunctionTypedFormalParameter = true;
try {
_checkForTypeAnnotationDeferredClass(node.returnType);
+
+ // TODO(jmesserly): ideally we'd use _checkForImplicitDynamicReturn, and
+ // we can get the function element via `node?.element?.type?.element` but
+ // it doesn't have hasImplicitReturnType set correctly.
+ if (!_options.implicitDynamic && node.returnType == null) {
+ DartType parameterType = node.element.type;
+ if (parameterType is FunctionType &&
+ parameterType.returnType.isDynamic) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_RETURN, node, [node.identifier]);
+ }
+ }
return super.visitFunctionTypedFormalParameter(node);
} finally {
_isInFunctionTypedFormalParameter = old;
@@ -812,6 +832,12 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
@override
+ Object visitImplementsClause(ImplementsClause node) {
+ node.interfaces.forEach(_checkForImplicitDynamicType);
+ return super.visitImplementsClause(node);
+ }
+
+ @override
Object visitImportDirective(ImportDirective node) {
ImportElement importElement = node.element;
if (importElement != null) {
@@ -848,6 +874,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
_checkForNewWithUndefinedConstructor(node, constructorName, typeName);
}
}
+ _checkForImplicitDynamicType(typeName);
return super.visitInstanceCreationExpression(node);
} finally {
_isInConstInstanceCreation = wasInConstInstanceCreation;
@@ -873,7 +900,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
_checkForExpectedOneListTypeArgument(node, typeArguments);
}
-
+ _checkForImplicitDynamicTypedLiteral(node);
_checkForListElementTypeNotAssignable(node);
return super.visitListLiteral(node);
}
@@ -891,7 +918,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
_checkExpectedTwoMapTypeArguments(typeArguments);
}
-
+ _checkForImplicitDynamicTypedLiteral(node);
_checkForMapTypeNotAssignable(node);
_checkForNonConstMapAsExpressionStatement(node);
return super.visitMapLiteral(node);
@@ -930,6 +957,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
_checkForAllInvalidOverrideErrorCodesForMethod(node);
_checkForTypeAnnotationDeferredClass(returnTypeName);
_checkForIllegalReturnType(returnTypeName);
+ _checkForImplicitDynamicReturn(node, node.element);
_checkForMustCallSuper(node);
return super.visitMethodDeclaration(node);
} finally {
@@ -951,6 +979,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
_checkTypeArguments(
node.methodName.staticElement, node.typeArguments, target?.staticType);
+ _checkForImplicitDynamicInvoke(node);
return super.visitMethodInvocation(node);
}
@@ -1046,6 +1075,15 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
_checkForConstFormalParameter(node);
_checkForPrivateOptionalParameter(node);
_checkForTypeAnnotationDeferredClass(node.type);
+
+ // Checks for an implicit dynamic parameter type.
+ //
+ // We can skip other parameter kinds besides simple formal, because:
+ // - DefaultFormalParameter contains a simple one, so it gets here,
+ // - FieldFormalParameter error should be reported on the field,
+ // - FunctionTypedFormalParameter is a function type, not dynamic.
+ _checkForImplicitDynamicIdentifier(node, node.identifier);
+
return super.visitSimpleFormalParameter(node);
}
@@ -1116,6 +1154,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
_checkForTypeParameterSupertypeOfItsBound(node);
_checkForTypeAnnotationDeferredClass(node.bound);
+ _checkForImplicitDynamicType(node.bound);
return super.visitTypeParameter(node);
}
@@ -1125,6 +1164,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
Expression initializerNode = node.initializer;
// do checks
_checkForInvalidAssignment(nameNode, initializerNode);
+ _checkForImplicitDynamicIdentifier(node, nameNode);
// visit name
nameNode.accept(this);
// visit initializer
@@ -1163,6 +1203,12 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
@override
+ Object visitWithClause(WithClause node) {
+ node.mixinTypes.forEach(_checkForImplicitDynamicType);
+ return super.visitWithClause(node);
+ }
+
+ @override
Object visitYieldStatement(YieldStatement node) {
if (_inGenerator) {
_checkForYieldOfInvalidType(node.expression, node.star != null);
@@ -3538,6 +3584,113 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
return foundError;
}
+ void _checkForImplicitDynamicIdentifier(AstNode node, Identifier id) {
+ if (_options.implicitDynamic) {
+ return;
+ }
+ VariableElement variable = getVariableElement(id);
+ if (variable != null &&
+ variable.hasImplicitType &&
+ variable.type.isDynamic) {
+ ErrorCode errorCode;
+ if (variable is FieldElement) {
+ errorCode = StrongModeCode.IMPLICIT_DYNAMIC_FIELD;
+ } else if (variable is ParameterElement) {
+ errorCode = StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER;
+ } else {
+ errorCode = StrongModeCode.IMPLICIT_DYNAMIC_VARIABLE;
+ }
+ _errorReporter.reportErrorForNode(errorCode, node, [id]);
+ }
+ }
+
+ void _checkForImplicitDynamicInvoke(InvocationExpression node) {
+ if (_options.implicitDynamic ||
+ node == null ||
+ node.typeArguments != null) {
+ return;
+ }
+ DartType invokeType = node.staticInvokeType;
+ DartType declaredType = node.function.staticType;
+ if (invokeType is FunctionType && declaredType is FunctionType) {
+ Iterable<DartType> typeArgs =
+ FunctionTypeImpl.recoverTypeArguments(declaredType, invokeType);
+ if (typeArgs.any((t) => t.isDynamic)) {
+ // Issue an error depending on what we're trying to call.
+ Expression function = node.function;
+ if (function is Identifier) {
+ Element element = function.staticElement;
+ if (element is MethodElement) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
+ node.function,
+ [element.displayName, element.typeParameters.join(', ')]);
+ return;
+ }
+
+ if (element is FunctionElement) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
+ node.function,
+ [element.displayName, element.typeParameters.join(', ')]);
+ return;
+ }
+ }
+
+ // The catch all case if neither of those matched.
+ // For example, invoking a function expression.
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
+ node.function,
+ [declaredType]);
+ }
+ }
+ }
+
+ void _checkForImplicitDynamicReturn(AstNode node, ExecutableElement element) {
+ if (_options.implicitDynamic) {
+ return;
+ }
+ if (element is PropertyAccessorElement && element.isSetter) {
+ return;
+ }
+ if (element != null &&
+ element.hasImplicitReturnType &&
+ element.returnType.isDynamic) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_RETURN, node, [element.displayName]);
+ }
+ }
+
+ void _checkForImplicitDynamicType(TypeName node) {
+ if (_options.implicitDynamic ||
+ node == null ||
+ node.typeArguments != null) {
+ return;
+ }
+ DartType type = node.type;
+ if (type is ParameterizedType &&
+ type.typeArguments.isNotEmpty &&
+ type.typeArguments.any((t) => t.isDynamic)) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_TYPE, node, [type]);
+ }
+ }
+
+ void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
+ if (_options.implicitDynamic || node.typeArguments != null) {
+ return;
+ }
+ DartType type = node.staticType;
+ // It's an error if either the key or value was inferred as dynamic.
+ if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
+ ErrorCode errorCode = node is ListLiteral
+ ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
+ : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
+ _errorReporter.reportErrorForNode(errorCode, node);
+ }
+ }
+
/**
* Verify that if the given [identifier] is part of a constructor initializer,
* then it does not implicitly reference 'this' expression.
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698