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

Side by Side Diff: pkg/analyzer/lib/src/generated/error_verifier.dart

Issue 1871103002: Support for @JS() validation (#26225). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: test fixes Created 4 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.generated.error_verifier; 5 library analyzer.src.generated.error_verifier;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
11 import 'package:analyzer/dart/ast/token.dart'; 11 import 'package:analyzer/dart/ast/token.dart';
12 import 'package:analyzer/dart/ast/visitor.dart'; 12 import 'package:analyzer/dart/ast/visitor.dart';
13 import 'package:analyzer/dart/element/element.dart'; 13 import 'package:analyzer/dart/element/element.dart';
14 import 'package:analyzer/dart/element/type.dart'; 14 import 'package:analyzer/dart/element/type.dart';
15 import 'package:analyzer/dart/element/visitor.dart'; 15 import 'package:analyzer/dart/element/visitor.dart';
16 import 'package:analyzer/src/dart/ast/token.dart'; 16 import 'package:analyzer/src/dart/ast/token.dart';
17 import 'package:analyzer/src/dart/ast/utilities.dart';
17 import 'package:analyzer/src/dart/element/element.dart'; 18 import 'package:analyzer/src/dart/element/element.dart';
18 import 'package:analyzer/src/dart/element/member.dart'; 19 import 'package:analyzer/src/dart/element/member.dart';
19 import 'package:analyzer/src/dart/element/type.dart'; 20 import 'package:analyzer/src/dart/element/type.dart';
20 import 'package:analyzer/src/generated/constant.dart'; 21 import 'package:analyzer/src/generated/constant.dart';
21 import 'package:analyzer/src/generated/element_resolver.dart'; 22 import 'package:analyzer/src/generated/element_resolver.dart';
22 import 'package:analyzer/src/generated/error.dart'; 23 import 'package:analyzer/src/generated/error.dart';
23 import 'package:analyzer/src/generated/java_engine.dart'; 24 import 'package:analyzer/src/generated/java_engine.dart';
24 import 'package:analyzer/src/generated/parser.dart' 25 import 'package:analyzer/src/generated/parser.dart'
25 show Parser, ParserErrorCode; 26 show Parser, ParserErrorCode;
26 import 'package:analyzer/src/generated/resolver.dart'; 27 import 'package:analyzer/src/generated/resolver.dart';
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 _isInStaticMethod = false; 299 _isInStaticMethod = false;
299 _boolType = _typeProvider.boolType; 300 _boolType = _typeProvider.boolType;
300 _intType = _typeProvider.intType; 301 _intType = _typeProvider.intType;
301 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes; 302 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes;
302 _typeSystem = _currentLibrary.context.typeSystem; 303 _typeSystem = _currentLibrary.context.typeSystem;
303 } 304 }
304 305
305 @override 306 @override
306 Object visitAnnotation(Annotation node) { 307 Object visitAnnotation(Annotation node) {
307 _checkForInvalidAnnotationFromDeferredLibrary(node); 308 _checkForInvalidAnnotationFromDeferredLibrary(node);
309 _checkForMissingJSLibAnnotation(node);
308 return super.visitAnnotation(node); 310 return super.visitAnnotation(node);
309 } 311 }
310 312
311 @override 313 @override
312 Object visitArgumentList(ArgumentList node) { 314 Object visitArgumentList(ArgumentList node) {
313 _checkForArgumentTypesNotAssignableInList(node); 315 _checkForArgumentTypesNotAssignableInList(node);
314 return super.visitArgumentList(node); 316 return super.visitArgumentList(node);
315 } 317 }
316 318
317 @override 319 @override
(...skipping 3404 matching lines...) Expand 10 before | Expand all | Expand 10 after
3722 if (!executableElement.isStatic) { 3724 if (!executableElement.isStatic) {
3723 return; 3725 return;
3724 } 3726 }
3725 3727
3726 _errorReporter.reportErrorForNode( 3728 _errorReporter.reportErrorForNode(
3727 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 3729 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
3728 name, 3730 name,
3729 [name.name]); 3731 [name.name]);
3730 } 3732 }
3731 3733
3732 void _checkForMissingRequiredParam(
3733 DartType type, ArgumentList argumentList, AstNode node) {
3734 if (type is FunctionType) {
3735 List<ParameterElement> parameters = type.parameters;
3736 for (ParameterElement param in parameters) {
3737 if (param.parameterKind == ParameterKind.NAMED) {
3738 ElementAnnotationImpl annotation = _getRequiredAnnotation(param);
3739 if (annotation != null) {
3740 String paramName = param.name;
3741 if (!_containsNamedExpression(argumentList, paramName)) {
3742 DartObject constantValue = annotation.constantValue;
3743 String reason =
3744 constantValue.getField('reason')?.toStringValue() ?? '';
3745 _errorReporter.reportErrorForNode(
3746 HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]);
3747 }
3748 }
3749 }
3750 }
3751 }
3752 }
3753
3754 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
3755 .metadata
3756 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
3757
3758 bool _containsNamedExpression(ArgumentList args, String name) {
3759 for (Expression expression in args.arguments) {
3760 if (expression is NamedExpression) {
3761 if (expression.name.label.name == name) {
3762 return true;
3763 }
3764 }
3765 }
3766 return false;
3767 }
3768
3769 /** 3734 /**
3770 * Check whether the given [executableElement] collides with the name of a 3735 * Check whether the given [executableElement] collides with the name of a
3771 * static method in one of its superclasses, and reports the appropriate 3736 * static method in one of its superclasses, and reports the appropriate
3772 * warning if it does. The [errorNameTarget] is the node to report problems 3737 * warning if it does. The [errorNameTarget] is the node to report problems
3773 * on. 3738 * on.
3774 * 3739 *
3775 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC]. 3740 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC].
3776 */ 3741 */
3777 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( 3742 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(
3778 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { 3743 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) {
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
4235 int offset = statement.offset; 4200 int offset = statement.offset;
4236 int end = statement.rightParenthesis.end; 4201 int end = statement.rightParenthesis.end;
4237 _errorReporter.reportErrorForOffset( 4202 _errorReporter.reportErrorForOffset(
4238 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, 4203 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
4239 offset, 4204 offset,
4240 end - offset, 4205 end - offset,
4241 [constantNames[i]]); 4206 [constantNames[i]]);
4242 } 4207 }
4243 } 4208 }
4244 4209
4210 void _checkForMissingJSLibAnnotation(Annotation node) {
4211 if (node.elementAnnotation.isJS) {
4212 Element element = ElementLocator.locate(node.parent);
4213 if (element?.library?.isJS != true) {
4214 _errorReporter.reportErrorForNode(
4215 HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]);
4216 }
4217 }
4218 }
4219
4220 void _checkForMissingRequiredParam(
4221 DartType type, ArgumentList argumentList, AstNode node) {
4222 if (type is FunctionType) {
4223 List<ParameterElement> parameters = type.parameters;
4224 for (ParameterElement param in parameters) {
4225 if (param.parameterKind == ParameterKind.NAMED) {
4226 ElementAnnotationImpl annotation = _getRequiredAnnotation(param);
4227 if (annotation != null) {
4228 String paramName = param.name;
4229 if (!_containsNamedExpression(argumentList, paramName)) {
4230 DartObject constantValue = annotation.constantValue;
4231 String reason =
4232 constantValue.getField('reason')?.toStringValue() ?? '';
4233 _errorReporter.reportErrorForNode(
4234 HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]);
4235 }
4236 }
4237 }
4238 }
4239 }
4240 }
4241
4245 /** 4242 /**
4246 * Verify that the given function [body] does not contain return statements 4243 * Verify that the given function [body] does not contain return statements
4247 * that both have and do not have return values. 4244 * that both have and do not have return values.
4248 * 4245 *
4249 * See [StaticWarningCode.MIXED_RETURN_TYPES]. 4246 * See [StaticWarningCode.MIXED_RETURN_TYPES].
4250 */ 4247 */
4251 void _checkForMixedReturns(BlockFunctionBody body) { 4248 void _checkForMixedReturns(BlockFunctionBody body) {
4252 if (_hasReturnWithoutValue) { 4249 if (_hasReturnWithoutValue) {
4253 return; 4250 return;
4254 } 4251 }
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after
5648 } 5645 }
5649 } 5646 }
5650 DartType staticReturnType = getStaticType(returnExpression); 5647 DartType staticReturnType = getStaticType(returnExpression);
5651 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { 5648 if (staticReturnType != null && _enclosingFunction.isAsynchronous) {
5652 return _typeProvider.futureType.instantiate( 5649 return _typeProvider.futureType.instantiate(
5653 <DartType>[staticReturnType.flattenFutures(_typeSystem)]); 5650 <DartType>[staticReturnType.flattenFutures(_typeSystem)]);
5654 } 5651 }
5655 return staticReturnType; 5652 return staticReturnType;
5656 } 5653 }
5657 5654
5655 bool _containsNamedExpression(ArgumentList args, String name) {
5656 for (Expression expression in args.arguments) {
5657 if (expression is NamedExpression) {
5658 if (expression.name.label.name == name) {
5659 return true;
5660 }
5661 }
5662 }
5663 return false;
5664 }
5665
5658 MethodElement _findOverriddenMemberThatMustCallSuper(MethodDeclaration node) { 5666 MethodElement _findOverriddenMemberThatMustCallSuper(MethodDeclaration node) {
5659 ExecutableElement overriddenMember = _getOverriddenMember(node.element); 5667 ExecutableElement overriddenMember = _getOverriddenMember(node.element);
5660 List<ExecutableElement> seen = <ExecutableElement>[]; 5668 List<ExecutableElement> seen = <ExecutableElement>[];
5661 while ( 5669 while (
5662 overriddenMember is MethodElement && !seen.contains(overriddenMember)) { 5670 overriddenMember is MethodElement && !seen.contains(overriddenMember)) {
5663 for (ElementAnnotation annotation in overriddenMember.metadata) { 5671 for (ElementAnnotation annotation in overriddenMember.metadata) {
5664 if (annotation.isMustCallSuper) { 5672 if (annotation.isMustCallSuper) {
5665 return overriddenMember; 5673 return overriddenMember;
5666 } 5674 }
5667 } 5675 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
5728 } 5736 }
5729 5737
5730 ClassElement classElement = 5738 ClassElement classElement =
5731 member.getAncestor((element) => element is ClassElement); 5739 member.getAncestor((element) => element is ClassElement);
5732 if (classElement == null) { 5740 if (classElement == null) {
5733 return null; 5741 return null;
5734 } 5742 }
5735 return _inheritanceManager.lookupInheritance(classElement, member.name); 5743 return _inheritanceManager.lookupInheritance(classElement, member.name);
5736 } 5744 }
5737 5745
5746 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
5747 .metadata
5748 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
5749
5738 /** 5750 /**
5739 * Return the type of the first and only parameter of the given [setter]. 5751 * Return the type of the first and only parameter of the given [setter].
5740 */ 5752 */
5741 DartType _getSetterType(PropertyAccessorElement setter) { 5753 DartType _getSetterType(PropertyAccessorElement setter) {
5742 // Get the parameters for MethodDeclaration or FunctionDeclaration 5754 // Get the parameters for MethodDeclaration or FunctionDeclaration
5743 List<ParameterElement> setterParameters = setter.parameters; 5755 List<ParameterElement> setterParameters = setter.parameters;
5744 // If there are no setter parameters, return no type. 5756 // If there are no setter parameters, return no type.
5745 if (setterParameters.length == 0) { 5757 if (setterParameters.length == 0) {
5746 return null; 5758 return null;
5747 } 5759 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
6103 class _InvocationCollector extends RecursiveAstVisitor { 6115 class _InvocationCollector extends RecursiveAstVisitor {
6104 final List<String> superCalls = <String>[]; 6116 final List<String> superCalls = <String>[];
6105 6117
6106 @override 6118 @override
6107 visitMethodInvocation(MethodInvocation node) { 6119 visitMethodInvocation(MethodInvocation node) {
6108 if (node.target is SuperExpression) { 6120 if (node.target is SuperExpression) {
6109 superCalls.add(node.methodName.name); 6121 superCalls.add(node.methodName.name);
6110 } 6122 }
6111 } 6123 }
6112 } 6124 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/hint_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698