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

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

Issue 2738113002: Add strong mode error for mixins defining conflicting private names (issue 28809) (Closed)
Patch Set: Created 3 years, 9 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';
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 _checkForExtendsDeferredClass(extendsClause); 479 _checkForExtendsDeferredClass(extendsClause);
480 _checkForImplementsDeferredClass(implementsClause); 480 _checkForImplementsDeferredClass(implementsClause);
481 _checkForNonAbstractClassInheritsAbstractMember(node.name); 481 _checkForNonAbstractClassInheritsAbstractMember(node.name);
482 _checkForInconsistentMethodInheritance(); 482 _checkForInconsistentMethodInheritance();
483 _checkForRecursiveInterfaceInheritance(_enclosingClass); 483 _checkForRecursiveInterfaceInheritance(_enclosingClass);
484 _checkForConflictingGetterAndMethod(); 484 _checkForConflictingGetterAndMethod();
485 _checkForConflictingInstanceGetterAndSuperclassMember(); 485 _checkForConflictingInstanceGetterAndSuperclassMember();
486 _checkImplementsSuperClass(node); 486 _checkImplementsSuperClass(node);
487 _checkImplementsFunctionWithoutCall(node); 487 _checkImplementsFunctionWithoutCall(node);
488 _checkForMixinHasNoConstructors(node); 488 _checkForMixinHasNoConstructors(node);
489 if (_options.strongMode) {
490 _checkForMixinWithConflictingPrivateMember(node);
491 }
489 } 492 }
490 } 493 }
491 visitClassDeclarationIncrementally(node); 494 visitClassDeclarationIncrementally(node);
492 _checkForFinalNotInitializedInClass(node); 495 _checkForFinalNotInitializedInClass(node);
493 _checkForDuplicateDefinitionInheritance(); 496 _checkForDuplicateDefinitionInheritance();
494 _checkForConflictingInstanceMethodSetter(node); 497 _checkForConflictingInstanceMethodSetter(node);
495 _checkForBadFunctionUse(node); 498 _checkForBadFunctionUse(node);
496 return super.visitClassDeclaration(node); 499 return super.visitClassDeclaration(node);
497 } finally { 500 } finally {
498 _isInNativeClass = false; 501 _isInNativeClass = false;
(...skipping 4393 matching lines...) Expand 10 before | Expand all | Expand 10 after
4892 if (!enableSuperMixins && mixinElement.hasReferenceToSuper) { 4895 if (!enableSuperMixins && mixinElement.hasReferenceToSuper) {
4893 _errorReporter.reportErrorForNode( 4896 _errorReporter.reportErrorForNode(
4894 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, 4897 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
4895 mixinName, 4898 mixinName,
4896 [mixinElement.name]); 4899 [mixinElement.name]);
4897 } 4900 }
4898 return false; 4901 return false;
4899 } 4902 }
4900 4903
4901 /** 4904 /**
4905 * Check for the declaration of a mixin from a library other than the current
4906 * library that defines a private member that conflicts with a private name
4907 * from the same library but from a superclass or a different mixin.
4908 */
4909 void _checkForMixinWithConflictingPrivateMember(ClassDeclaration node) {
4910 WithClause withClause = node.withClause;
4911 if (withClause == null) {
4912 return;
4913 }
4914 DartType declaredSupertype = node.extendsClause?.superclass?.type;
4915 if (declaredSupertype is! InterfaceType) {
4916 return;
4917 }
4918 InterfaceType superclass = declaredSupertype;
4919 Map<LibraryElement, Map<String, String>> mixedInNames =
4920 <LibraryElement, Map<String, String>>{};
4921
4922 /**
4923 * Report an error and return `true` if the given [name] is a private name
4924 * (which is defined in the given [library]) and it conflicts with another
4925 * definition of that name inherited from the superclass.
4926 */
4927 bool isConflictingName(
4928 String name, LibraryElement library, TypeName typeName) {
4929 if (Identifier.isPrivateName(name)) {
4930 Map<String, String> names =
4931 mixedInNames.putIfAbsent(library, () => <String, String>{});
4932 if (names.containsKey(name)) {
4933 _errorReporter.reportErrorForNode(
4934 CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION,
4935 typeName,
4936 [name, typeName.name.name, names[name]]);
4937 return true;
4938 }
4939 names[name] = typeName.name.name;
4940 ExecutableElement inheritedMember =
4941 superclass.lookUpMethod(name, library) ??
4942 superclass.lookUpGetter(name, library) ??
4943 superclass.lookUpSetter(name, library);
4944 if (inheritedMember != null) {
4945 _errorReporter.reportErrorForNode(
4946 CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION,
4947 typeName, [
4948 name,
4949 typeName.name.name,
4950 inheritedMember.enclosingElement.name
4951 ]);
4952 return true;
4953 }
4954 }
4955 return false;
4956 }
4957
4958 for (TypeName mixinType in withClause.mixinTypes) {
4959 DartType type = mixinType.type;
4960 if (type is InterfaceType) {
4961 LibraryElement library = type.element.library;
4962 if (library != _currentLibrary) {
4963 for (PropertyAccessorElement accessor in type.accessors) {
4964 if (isConflictingName(accessor.name, library, mixinType)) {
4965 return;
4966 }
4967 }
4968 for (MethodElement method in type.methods) {
4969 if (isConflictingName(method.name, library, mixinType)) {
4970 return;
4971 }
4972 }
4973 }
4974 }
4975 }
4976 }
4977
4978 /**
4902 * Verify that the given [constructor] has at most one 'super' initializer. 4979 * Verify that the given [constructor] has at most one 'super' initializer.
4903 * 4980 *
4904 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. 4981 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS].
4905 */ 4982 */
4906 void _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) { 4983 void _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) {
4907 bool hasSuperInitializer = false; 4984 bool hasSuperInitializer = false;
4908 for (ConstructorInitializer initializer in constructor.initializers) { 4985 for (ConstructorInitializer initializer in constructor.initializers) {
4909 if (initializer is SuperConstructorInvocation) { 4986 if (initializer is SuperConstructorInvocation) {
4910 if (hasSuperInitializer) { 4987 if (hasSuperInitializer) {
4911 _errorReporter.reportErrorForNode( 4988 _errorReporter.reportErrorForNode(
(...skipping 2178 matching lines...) Expand 10 before | Expand all | Expand 10 after
7090 class _InvocationCollector extends RecursiveAstVisitor { 7167 class _InvocationCollector extends RecursiveAstVisitor {
7091 final List<String> superCalls = <String>[]; 7168 final List<String> superCalls = <String>[];
7092 7169
7093 @override 7170 @override
7094 visitMethodInvocation(MethodInvocation node) { 7171 visitMethodInvocation(MethodInvocation node) {
7095 if (node.target is SuperExpression) { 7172 if (node.target is SuperExpression) {
7096 superCalls.add(node.methodName.name); 7173 superCalls.add(node.methodName.name);
7097 } 7174 }
7098 } 7175 }
7099 } 7176 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/error/codes.dart ('k') | pkg/analyzer/test/generated/compile_time_error_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698