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

Side by Side Diff: pkg/analyzer/lib/src/task/strong/checker.dart

Issue 2352433002: support `@virtual` fields, fix #27384 (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « pkg/analyzer/lib/src/summary/link.dart ('k') | pkg/analyzer/lib/src/task/strong_mode.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
6 // refactored to fit into analyzer. 6 // refactored to fit into analyzer.
7 library analyzer.src.task.strong.checker; 7 library analyzer.src.task.strong.checker;
8 8
9 import 'package:analyzer/analyzer.dart'; 9 import 'package:analyzer/analyzer.dart';
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
11 import 'package:analyzer/dart/ast/token.dart' show TokenType; 11 import 'package:analyzer/dart/ast/token.dart' show TokenType;
12 import 'package:analyzer/dart/ast/token.dart'; 12 import 'package:analyzer/dart/ast/token.dart';
13 import 'package:analyzer/dart/ast/visitor.dart'; 13 import 'package:analyzer/dart/ast/visitor.dart';
14 import 'package:analyzer/dart/element/element.dart'; 14 import 'package:analyzer/dart/element/element.dart';
15 import 'package:analyzer/dart/element/type.dart'; 15 import 'package:analyzer/dart/element/type.dart';
16 import 'package:analyzer/src/dart/element/element.dart';
16 import 'package:analyzer/src/dart/element/type.dart'; 17 import 'package:analyzer/src/dart/element/type.dart';
17 import 'package:analyzer/src/error/codes.dart' show StrongModeCode; 18 import 'package:analyzer/src/error/codes.dart' show StrongModeCode;
18 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl; 19 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
19 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; 20 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
20 import 'package:analyzer/src/generated/type_system.dart'; 21 import 'package:analyzer/src/generated/type_system.dart';
21 22
22 import 'ast_properties.dart'; 23 import 'ast_properties.dart';
23 24
24 /// Given an [expression] and a corresponding [typeSystem] and [typeProvider], 25 /// Given an [expression] and a corresponding [typeSystem] and [typeProvider],
25 /// gets the known static type of the expression. 26 /// gets the known static type of the expression.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 } else if (expression is PropertyAccess) { 68 } else if (expression is PropertyAccess) {
68 return expression.propertyName.staticElement; 69 return expression.propertyName.staticElement;
69 } else if (expression is Identifier) { 70 } else if (expression is Identifier) {
70 return expression.staticElement; 71 return expression.staticElement;
71 } 72 }
72 return null; 73 return null;
73 } 74 }
74 75
75 /// Return the field on type corresponding to member, or null if none 76 /// Return the field on type corresponding to member, or null if none
76 /// exists or the "field" is actually a getter/setter. 77 /// exists or the "field" is actually a getter/setter.
77 PropertyInducingElement _getMemberField( 78 FieldElement _getMemberField(
78 InterfaceType type, PropertyAccessorElement member) { 79 InterfaceType type, PropertyAccessorElement member) {
79 String memberName = member.name; 80 String memberName = member.name;
80 PropertyInducingElement field; 81 FieldElement field;
81 if (member.isGetter) { 82 if (member.isGetter) {
82 // The subclass member is an explicit getter or a field 83 // The subclass member is an explicit getter or a field
83 // - lookup the getter on the superclass. 84 // - lookup the getter on the superclass.
84 var getter = type.getGetter(memberName); 85 var getter = type.getGetter(memberName);
85 if (getter == null || getter.isStatic) return null; 86 if (getter == null || getter.isStatic) return null;
86 field = getter.variable; 87 field = getter.variable;
87 } else if (!member.isSynthetic) { 88 } else if (!member.isSynthetic) {
88 // The subclass member is an explicit setter 89 // The subclass member is an explicit setter
89 // - lookup the setter on the superclass. 90 // - lookup the setter on the superclass.
90 // Note: an implicit (synthetic) setter would have already been flagged on 91 // Note: an implicit (synthetic) setter would have already been flagged on
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 AstNode node, AstNode errorLocation, bool isSubclass) { 1382 AstNode node, AstNode errorLocation, bool isSubclass) {
1382 assert(!element.isStatic); 1383 assert(!element.isStatic);
1383 1384
1384 FunctionType subType = _elementType(element); 1385 FunctionType subType = _elementType(element);
1385 // TODO(vsm): Test for generic 1386 // TODO(vsm): Test for generic
1386 FunctionType baseType = _getMemberType(type, element); 1387 FunctionType baseType = _getMemberType(type, element);
1387 if (baseType == null) return false; 1388 if (baseType == null) return false;
1388 1389
1389 if (isSubclass && element is PropertyAccessorElement) { 1390 if (isSubclass && element is PropertyAccessorElement) {
1390 // Disallow any overriding if the base class defines this member 1391 // Disallow any overriding if the base class defines this member
1391 // as a field. We effectively treat fields as final / non-virtual. 1392 // as a field. We effectively treat fields as final / non-virtual,
1392 PropertyInducingElement field = _getMemberField(type, element); 1393 // unless they are explicitly marked as @virtual
1393 if (field != null) { 1394 var field = _getMemberField(type, element);
1395 if (field != null && !field.isVirtual) {
1394 _checker._recordMessage( 1396 _checker._recordMessage(
1395 errorLocation, StrongModeCode.INVALID_FIELD_OVERRIDE, [ 1397 errorLocation, StrongModeCode.INVALID_FIELD_OVERRIDE, [
1396 element.enclosingElement.name, 1398 element.enclosingElement.name,
1397 element.name, 1399 element.name,
1398 subType, 1400 subType,
1399 type, 1401 type,
1400 baseType 1402 baseType
1401 ]); 1403 ]);
1402 } 1404 }
1403 } 1405 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 var visited = new Set<InterfaceType>(); 1465 var visited = new Set<InterfaceType>();
1464 do { 1466 do {
1465 visited.add(current); 1467 visited.add(current);
1466 current.mixins.reversed.forEach( 1468 current.mixins.reversed.forEach(
1467 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); 1469 (m) => _checkIndividualOverridesFromClass(node, m, seen, true));
1468 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); 1470 _checkIndividualOverridesFromClass(node, current.superclass, seen, true);
1469 current = current.superclass; 1471 current = current.superclass;
1470 } while (!current.isObject && !visited.contains(current)); 1472 } while (!current.isObject && !visited.contains(current));
1471 } 1473 }
1472 } 1474 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/summary/link.dart ('k') | pkg/analyzer/lib/src/task/strong_mode.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698