OLD | NEW |
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 computer.overrides; | 5 library computer.overrides; |
6 | 6 |
7 import 'package:analysis_server/src/collections.dart'; | 7 import 'package:analysis_server/src/collections.dart'; |
8 import 'package:analysis_server/src/protocol_server.dart'; | 8 import 'package:analysis_server/src/protocol_server.dart'; |
9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
10 import 'package:analyzer/src/generated/element.dart' as engine; | 10 import 'package:analyzer/src/generated/element.dart' as engine; |
11 | 11 |
12 /** | 12 /** |
13 * A computer for class member overrides in a Dart [CompilationUnit]. | 13 * A computer for class member overrides in a Dart [CompilationUnit]. |
14 */ | 14 */ |
15 class DartUnitOverridesComputer { | 15 class DartUnitOverridesComputer { |
| 16 static const List<ElementKind> FIELD_KINDS = const <ElementKind>[ |
| 17 ElementKind.FIELD, |
| 18 ElementKind.GETTER, |
| 19 ElementKind.SETTER |
| 20 ]; |
| 21 |
| 22 static const List<ElementKind> GETTER_KINDS = const <ElementKind>[ |
| 23 ElementKind.FIELD, |
| 24 ElementKind.GETTER |
| 25 ]; |
| 26 |
| 27 static const List<ElementKind> METHOD_KINDS = const <ElementKind>[ |
| 28 ElementKind.METHOD |
| 29 ]; |
| 30 |
| 31 static const List<ElementKind> SETTER_KINDS = const <ElementKind>[ |
| 32 ElementKind.FIELD, |
| 33 ElementKind.SETTER |
| 34 ]; |
| 35 |
16 final CompilationUnit _unit; | 36 final CompilationUnit _unit; |
17 | 37 |
18 final List<Override> _overrides = <Override>[]; | 38 final List<Override> _overrides = <Override>[]; |
19 engine.ClassElement _currentClass; | 39 engine.ClassElement _currentClass; |
20 | 40 |
21 DartUnitOverridesComputer(this._unit); | 41 DartUnitOverridesComputer(this._unit); |
22 | 42 |
23 /** | 43 /** |
24 * Returns the computed occurrences, not `null`. | 44 * Returns the computed occurrences, not `null`. |
25 */ | 45 */ |
26 List<Override> compute() { | 46 List<Override> compute() { |
27 for (CompilationUnitMember unitMember in _unit.declarations) { | 47 for (CompilationUnitMember unitMember in _unit.declarations) { |
28 if (unitMember is ClassDeclaration) { | 48 if (unitMember is ClassDeclaration) { |
29 _currentClass = unitMember.element; | 49 _currentClass = unitMember.element; |
30 for (ClassMember classMember in unitMember.members) { | 50 for (ClassMember classMember in unitMember.members) { |
31 if (classMember is MethodDeclaration) { | 51 if (classMember is MethodDeclaration) { |
32 if (classMember.isStatic) { | 52 if (classMember.isStatic) { |
33 continue; | 53 continue; |
34 } | 54 } |
35 SimpleIdentifier nameNode = classMember.name; | 55 SimpleIdentifier nameNode = classMember.name; |
36 _addOverride(nameNode.offset, nameNode.length, nameNode.name); | 56 List<ElementKind> kinds; |
| 57 if (classMember.isGetter) { |
| 58 kinds = GETTER_KINDS; |
| 59 } else if (classMember.isSetter) { |
| 60 kinds = SETTER_KINDS; |
| 61 } else { |
| 62 kinds = METHOD_KINDS; |
| 63 } |
| 64 _addOverride( |
| 65 nameNode.offset, nameNode.length, nameNode.name, kinds); |
37 } | 66 } |
38 if (classMember is FieldDeclaration) { | 67 if (classMember is FieldDeclaration) { |
39 if (classMember.isStatic) { | 68 if (classMember.isStatic) { |
40 continue; | 69 continue; |
41 } | 70 } |
42 List<VariableDeclaration> fields = classMember.fields.variables; | 71 List<VariableDeclaration> fields = classMember.fields.variables; |
43 for (VariableDeclaration field in fields) { | 72 for (VariableDeclaration field in fields) { |
44 SimpleIdentifier nameNode = field.name; | 73 SimpleIdentifier nameNode = field.name; |
45 _addOverride(nameNode.offset, nameNode.length, nameNode.name); | 74 _addOverride( |
| 75 nameNode.offset, nameNode.length, nameNode.name, FIELD_KINDS); |
46 } | 76 } |
47 } | 77 } |
48 } | 78 } |
49 } | 79 } |
50 } | 80 } |
51 return _overrides; | 81 return _overrides; |
52 } | 82 } |
53 | 83 |
54 void _addInterfaceOverrides( | 84 void _addInterfaceOverrides( |
55 Set<engine.Element> elements, | 85 Set<engine.Element> elements, |
56 String name, | 86 String name, |
| 87 List<ElementKind> kinds, |
57 engine.InterfaceType type, | 88 engine.InterfaceType type, |
58 bool checkType, | 89 bool checkType, |
59 Set<engine.InterfaceType> visited) { | 90 Set<engine.InterfaceType> visited) { |
60 if (type == null) { | 91 if (type == null) { |
61 return; | 92 return; |
62 } | 93 } |
63 if (!visited.add(type)) { | 94 if (!visited.add(type)) { |
64 return; | 95 return; |
65 } | 96 } |
66 // check type | 97 // check type |
67 if (checkType) { | 98 if (checkType) { |
68 engine.Element element = _lookupMember(type.element, name); | 99 engine.Element element = _lookupMember(type.element, name, kinds); |
69 if (element != null) { | 100 if (element != null) { |
70 elements.add(element); | 101 elements.add(element); |
71 return; | 102 return; |
72 } | 103 } |
73 } | 104 } |
74 // check interfaces | 105 // check interfaces |
75 for (engine.InterfaceType interfaceType in type.interfaces) { | 106 for (engine.InterfaceType interfaceType in type.interfaces) { |
76 _addInterfaceOverrides(elements, name, interfaceType, true, visited); | 107 _addInterfaceOverrides( |
| 108 elements, name, kinds, interfaceType, true, visited); |
77 } | 109 } |
78 // check super | 110 // check super |
79 _addInterfaceOverrides(elements, name, type.superclass, checkType, visited); | 111 _addInterfaceOverrides( |
| 112 elements, name, kinds, type.superclass, checkType, visited); |
80 } | 113 } |
81 | 114 |
82 void _addOverride(int offset, int length, String name) { | 115 void _addOverride( |
| 116 int offset, int length, String name, List<ElementKind> kinds) { |
83 // super | 117 // super |
84 engine.Element superEngineElement; | 118 engine.Element superEngineElement; |
85 { | 119 { |
86 engine.InterfaceType superType = _currentClass.supertype; | 120 engine.InterfaceType superType = _currentClass.supertype; |
87 if (superType != null) { | 121 if (superType != null) { |
88 superEngineElement = _lookupMember(superType.element, name); | 122 superEngineElement = _lookupMember(superType.element, name, kinds); |
89 } | 123 } |
90 } | 124 } |
91 // interfaces | 125 // interfaces |
92 Set<engine.Element> interfaceEngineElements = new Set<engine.Element>(); | 126 Set<engine.Element> interfaceEngineElements = new Set<engine.Element>(); |
93 _addInterfaceOverrides(interfaceEngineElements, name, _currentClass.type, | 127 _addInterfaceOverrides(interfaceEngineElements, name, kinds, |
94 false, new Set<engine.InterfaceType>()); | 128 _currentClass.type, false, new Set<engine.InterfaceType>()); |
95 interfaceEngineElements.remove(superEngineElement); | 129 interfaceEngineElements.remove(superEngineElement); |
96 // is there any override? | 130 // is there any override? |
97 if (superEngineElement != null || interfaceEngineElements.isNotEmpty) { | 131 if (superEngineElement != null || interfaceEngineElements.isNotEmpty) { |
98 OverriddenMember superMember = superEngineElement != null | 132 OverriddenMember superMember = superEngineElement != null |
99 ? newOverriddenMember_fromEngine(superEngineElement) | 133 ? newOverriddenMember_fromEngine(superEngineElement) |
100 : null; | 134 : null; |
101 List<OverriddenMember> interfaceMembers = interfaceEngineElements | 135 List<OverriddenMember> interfaceMembers = interfaceEngineElements |
102 .map((member) => newOverriddenMember_fromEngine(member)) | 136 .map((member) => newOverriddenMember_fromEngine(member)) |
103 .toList(); | 137 .toList(); |
104 _overrides.add(new Override(offset, length, | 138 _overrides.add(new Override(offset, length, |
105 superclassMember: superMember, | 139 superclassMember: superMember, |
106 interfaceMembers: nullIfEmpty(interfaceMembers))); | 140 interfaceMembers: nullIfEmpty(interfaceMembers))); |
107 } | 141 } |
108 } | 142 } |
109 | 143 |
110 static engine.Element _lookupMember( | 144 static engine.Element _lookupMember( |
111 engine.ClassElement classElement, String name) { | 145 engine.ClassElement classElement, String name, List<ElementKind> kinds) { |
112 if (classElement == null) { | 146 if (classElement == null) { |
113 return null; | 147 return null; |
114 } | 148 } |
115 engine.LibraryElement library = classElement.library; | 149 engine.LibraryElement library = classElement.library; |
| 150 engine.Element member; |
116 // method | 151 // method |
117 engine.Element member = classElement.lookUpMethod(name, library); | 152 if (kinds.contains(ElementKind.METHOD)) { |
118 if (member != null) { | 153 member = classElement.lookUpMethod(name, library); |
119 return member; | 154 if (member != null) { |
| 155 return member; |
| 156 } |
120 } | 157 } |
121 // getter | 158 // getter |
122 member = classElement.lookUpGetter(name, library); | 159 if (kinds.contains(ElementKind.GETTER)) { |
123 if (member != null) { | 160 member = classElement.lookUpGetter(name, library); |
124 return member; | 161 if (member != null) { |
| 162 return member; |
| 163 } |
125 } | 164 } |
126 // setter | 165 // setter |
127 member = classElement.lookUpSetter(name + '=', library); | 166 if (kinds.contains(ElementKind.SETTER)) { |
128 if (member != null) { | 167 member = classElement.lookUpSetter(name + '=', library); |
129 return member; | 168 if (member != null) { |
| 169 return member; |
| 170 } |
130 } | 171 } |
131 // not found | 172 // not found |
132 return null; | 173 return null; |
133 } | 174 } |
134 } | 175 } |
OLD | NEW |