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

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

Issue 1723243002: Validation of `@protected` method invocations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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
Index: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 59359c19e033baa505730e881a6fa2a963e29a0b..66f6fc4235e2cb8221d8b650429184a141b0ce89 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -206,6 +206,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
@override
Object visitMethodInvocation(MethodInvocation node) {
_checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
+ _checkForInvalidProtectedMethodCalls(node);
return super.visitMethodInvocation(node);
}
@@ -608,6 +609,38 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * Produces a hint if the given invocation is of a protected method outside
+ * a subclass instance method.
+ */
+ void _checkForInvalidProtectedMethodCalls(MethodInvocation node) {
+ Element element = node.methodName.staticElement;
Brian Wilkerson 2016/02/23 17:45:56 Given that this is a hint, I suspect that we want
pquitslund 2016/02/23 22:59:07 Done.
+ if (element == null || !element.isProtected) {
+ return;
+ }
+
+ ClassElement definingClass = element.enclosingElement;
+
+ MethodDeclaration decl =
+ node.getAncestor((AstNode node) => node is MethodDeclaration);
+ if (decl == null) {
+ _errorReporter.reportErrorForNode(
+ HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
+ node,
+ [node.methodName.toString(), definingClass.name]);
+ return;
+ }
+
+ ClassElement invokingClass = decl.element?.enclosingElement;
+ if (invokingClass != null &&
+ !invokingClass.type.isSubtypeOf(definingClass.type)) {
Brian Wilkerson 2016/02/23 17:45:56 The comment for the annotation says "extend or mix
pquitslund 2016/02/23 22:59:07 Fixed.
+ _errorReporter.reportErrorForNode(
+ HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
+ node,
+ [node.methodName.toString(), definingClass.name]);
+ }
+ }
+
+ /**
* Check that the imported library does not define a loadLibrary function. The import has already
* been determined to be deferred when this is called.
*
@@ -8387,26 +8420,6 @@ class ResolverVisitor extends ScopedVisitor {
return null;
}
- void _inferArgumentTypesFromContext(InvocationExpression node) {
- DartType contextType = node.staticInvokeType;
- if (contextType is FunctionType) {
- DartType originalType = node.function.staticType;
- DartType returnContextType = InferenceContext.getType(node);
- TypeSystem ts = typeSystem;
- if (returnContextType != null &&
- node.typeArguments == null &&
- originalType is FunctionType &&
- originalType.typeFormals.isNotEmpty &&
- ts is StrongTypeSystemImpl) {
-
- contextType = ts.inferGenericFunctionCall(typeProvider, originalType,
- DartType.EMPTY_LIST, DartType.EMPTY_LIST, returnContextType);
- }
-
- InferenceContext.setType(node.argumentList, contextType);
- }
- }
-
@override
Object visitNamedExpression(NamedExpression node) {
InferenceContext.setType(node.expression, InferenceContext.getType(node));
@@ -8734,6 +8747,25 @@ class ResolverVisitor extends ScopedVisitor {
return null;
}
+ void _inferArgumentTypesFromContext(InvocationExpression node) {
+ DartType contextType = node.staticInvokeType;
+ if (contextType is FunctionType) {
+ DartType originalType = node.function.staticType;
+ DartType returnContextType = InferenceContext.getType(node);
+ TypeSystem ts = typeSystem;
+ if (returnContextType != null &&
+ node.typeArguments == null &&
+ originalType is FunctionType &&
+ originalType.typeFormals.isNotEmpty &&
+ ts is StrongTypeSystemImpl) {
+ contextType = ts.inferGenericFunctionCall(typeProvider, originalType,
+ DartType.EMPTY_LIST, DartType.EMPTY_LIST, returnContextType);
+ }
+
+ InferenceContext.setType(node.argumentList, contextType);
+ }
+ }
+
void _inferFormalParameterList(FormalParameterList node, DartType type) {
if (typeAnalyzer.inferFormalParameterList(node, type)) {
// TODO(leafp): This gets dropped on the floor if we're in the field

Powered by Google App Engine
This is Rietveld 408576698