| 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 |