| 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/dart/element/element.dart' as engine; | 9 import 'package:analyzer/dart/element/element.dart' as engine; |
| 10 import 'package:analyzer/dart/element/type.dart' as engine; | 10 import 'package:analyzer/dart/element/type.dart' as engine; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 */ | 46 */ |
| 47 List<Override> compute() { | 47 List<Override> compute() { |
| 48 for (CompilationUnitMember unitMember in _unit.declarations) { | 48 for (CompilationUnitMember unitMember in _unit.declarations) { |
| 49 if (unitMember is ClassDeclaration) { | 49 if (unitMember is ClassDeclaration) { |
| 50 _currentClass = unitMember.element; | 50 _currentClass = unitMember.element; |
| 51 for (ClassMember classMember in unitMember.members) { | 51 for (ClassMember classMember in unitMember.members) { |
| 52 if (classMember is MethodDeclaration) { | 52 if (classMember is MethodDeclaration) { |
| 53 if (classMember.isStatic) { | 53 if (classMember.isStatic) { |
| 54 continue; | 54 continue; |
| 55 } | 55 } |
| 56 SimpleIdentifier nameNode = classMember.name; | 56 SimpleIdentifier name = classMember.name; |
| 57 List<ElementKind> kinds; | 57 List<ElementKind> kinds; |
| 58 if (classMember.isGetter) { | 58 if (classMember.isGetter) { |
| 59 kinds = GETTER_KINDS; | 59 kinds = GETTER_KINDS; |
| 60 } else if (classMember.isSetter) { | 60 } else if (classMember.isSetter) { |
| 61 kinds = SETTER_KINDS; | 61 kinds = SETTER_KINDS; |
| 62 } else { | 62 } else { |
| 63 kinds = METHOD_KINDS; | 63 kinds = METHOD_KINDS; |
| 64 } | 64 } |
| 65 _addOverride( | 65 new _SingleOverrideComputer(_currentClass, name, kinds) |
| 66 nameNode.offset, nameNode.length, nameNode.name, kinds); | 66 .addOverrideTo(_overrides); |
| 67 } | 67 } |
| 68 if (classMember is FieldDeclaration) { | 68 if (classMember is FieldDeclaration) { |
| 69 if (classMember.isStatic) { | 69 if (classMember.isStatic) { |
| 70 continue; | 70 continue; |
| 71 } | 71 } |
| 72 List<VariableDeclaration> fields = classMember.fields.variables; | 72 List<VariableDeclaration> fields = classMember.fields.variables; |
| 73 for (VariableDeclaration field in fields) { | 73 for (VariableDeclaration field in fields) { |
| 74 SimpleIdentifier nameNode = field.name; | 74 SimpleIdentifier name = field.name; |
| 75 _addOverride( | 75 new _SingleOverrideComputer(_currentClass, name, FIELD_KINDS) |
| 76 nameNode.offset, nameNode.length, nameNode.name, FIELD_KINDS); | 76 .addOverrideTo(_overrides); |
| 77 } | 77 } |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 return _overrides; | 82 return _overrides; |
| 83 } | 83 } |
| 84 } |
| 85 |
| 86 /** |
| 87 * Computer for [Override] for a single declaration. |
| 88 */ |
| 89 class _SingleOverrideComputer { |
| 90 final engine.LibraryElement currentLibrary; |
| 91 final engine.ClassElement currentClass; |
| 92 final SimpleIdentifier node; |
| 93 final String name; |
| 94 final List<ElementKind> kinds; |
| 95 |
| 96 _SingleOverrideComputer( |
| 97 engine.ClassElement currentClass, SimpleIdentifier node, this.kinds) |
| 98 : currentClass = currentClass, |
| 99 currentLibrary = currentClass.library, |
| 100 node = node, |
| 101 name = node.name; |
| 102 |
| 103 /** |
| 104 * Add a new [Override] for this declaration to the given [overrides]. |
| 105 */ |
| 106 void addOverrideTo(List<Override> overrides) { |
| 107 // super |
| 108 engine.Element superEngineElement; |
| 109 { |
| 110 engine.InterfaceType superType = currentClass.supertype; |
| 111 if (superType != null) { |
| 112 superEngineElement = _lookupMember(superType.element); |
| 113 } |
| 114 } |
| 115 // interfaces |
| 116 Set<engine.Element> interfaceEngineElements = new Set<engine.Element>(); |
| 117 _addInterfaceOverrides(interfaceEngineElements, currentClass.type, false, |
| 118 new Set<engine.InterfaceType>()); |
| 119 interfaceEngineElements.remove(superEngineElement); |
| 120 // is there any override? |
| 121 if (superEngineElement != null || interfaceEngineElements.isNotEmpty) { |
| 122 OverriddenMember superMember = superEngineElement != null |
| 123 ? newOverriddenMember_fromEngine(superEngineElement) |
| 124 : null; |
| 125 List<OverriddenMember> interfaceMembers = interfaceEngineElements |
| 126 .map((member) => newOverriddenMember_fromEngine(member)) |
| 127 .toList(); |
| 128 overrides.add(new Override(node.offset, node.length, |
| 129 superclassMember: superMember, |
| 130 interfaceMembers: nullIfEmpty(interfaceMembers))); |
| 131 } |
| 132 } |
| 84 | 133 |
| 85 void _addInterfaceOverrides( | 134 void _addInterfaceOverrides( |
| 86 Set<engine.Element> elements, | 135 Set<engine.Element> elements, |
| 87 String name, | |
| 88 List<ElementKind> kinds, | |
| 89 engine.InterfaceType type, | 136 engine.InterfaceType type, |
| 90 bool checkType, | 137 bool checkType, |
| 91 Set<engine.InterfaceType> visited) { | 138 Set<engine.InterfaceType> visited) { |
| 92 if (type == null) { | 139 if (type == null) { |
| 93 return; | 140 return; |
| 94 } | 141 } |
| 95 if (!visited.add(type)) { | 142 if (!visited.add(type)) { |
| 96 return; | 143 return; |
| 97 } | 144 } |
| 98 // check type | 145 // check type |
| 99 if (checkType) { | 146 if (checkType) { |
| 100 engine.Element element = _lookupMember(type.element, name, kinds); | 147 engine.Element element = _lookupMember(type.element); |
| 101 if (element != null) { | 148 if (element != null) { |
| 102 elements.add(element); | 149 elements.add(element); |
| 103 return; | 150 return; |
| 104 } | 151 } |
| 105 } | 152 } |
| 106 // check interfaces | 153 // check interfaces |
| 107 for (engine.InterfaceType interfaceType in type.interfaces) { | 154 for (engine.InterfaceType interfaceType in type.interfaces) { |
| 108 _addInterfaceOverrides( | 155 _addInterfaceOverrides(elements, interfaceType, true, visited); |
| 109 elements, name, kinds, interfaceType, true, visited); | |
| 110 } | 156 } |
| 111 // check super | 157 // check super |
| 112 _addInterfaceOverrides( | 158 _addInterfaceOverrides(elements, type.superclass, checkType, visited); |
| 113 elements, name, kinds, type.superclass, checkType, visited); | |
| 114 } | 159 } |
| 115 | 160 |
| 116 void _addOverride( | 161 engine.Element _lookupMember(engine.ClassElement classElement) { |
| 117 int offset, int length, String name, List<ElementKind> kinds) { | |
| 118 // super | |
| 119 engine.Element superEngineElement; | |
| 120 { | |
| 121 engine.InterfaceType superType = _currentClass.supertype; | |
| 122 if (superType != null) { | |
| 123 superEngineElement = _lookupMember(superType.element, name, kinds); | |
| 124 } | |
| 125 } | |
| 126 // interfaces | |
| 127 Set<engine.Element> interfaceEngineElements = new Set<engine.Element>(); | |
| 128 _addInterfaceOverrides(interfaceEngineElements, name, kinds, | |
| 129 _currentClass.type, false, new Set<engine.InterfaceType>()); | |
| 130 interfaceEngineElements.remove(superEngineElement); | |
| 131 // is there any override? | |
| 132 if (superEngineElement != null || interfaceEngineElements.isNotEmpty) { | |
| 133 OverriddenMember superMember = superEngineElement != null | |
| 134 ? newOverriddenMember_fromEngine(superEngineElement) | |
| 135 : null; | |
| 136 List<OverriddenMember> interfaceMembers = interfaceEngineElements | |
| 137 .map((member) => newOverriddenMember_fromEngine(member)) | |
| 138 .toList(); | |
| 139 _overrides.add(new Override(offset, length, | |
| 140 superclassMember: superMember, | |
| 141 interfaceMembers: nullIfEmpty(interfaceMembers))); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 static engine.Element _lookupMember( | |
| 146 engine.ClassElement classElement, String name, List<ElementKind> kinds) { | |
| 147 if (classElement == null) { | 162 if (classElement == null) { |
| 148 return null; | 163 return null; |
| 149 } | 164 } |
| 150 engine.LibraryElement library = classElement.library; | |
| 151 engine.Element member; | 165 engine.Element member; |
| 152 // method | 166 // method |
| 153 if (kinds.contains(ElementKind.METHOD)) { | 167 if (kinds.contains(ElementKind.METHOD)) { |
| 154 member = classElement.lookUpMethod(name, library); | 168 member = classElement.lookUpMethod(name, currentLibrary); |
| 155 if (member != null) { | 169 if (member != null) { |
| 156 return member; | 170 return member; |
| 157 } | 171 } |
| 158 } | 172 } |
| 159 // getter | 173 // getter |
| 160 if (kinds.contains(ElementKind.GETTER)) { | 174 if (kinds.contains(ElementKind.GETTER)) { |
| 161 member = classElement.lookUpGetter(name, library); | 175 member = classElement.lookUpGetter(name, currentLibrary); |
| 162 if (member != null) { | 176 if (member != null) { |
| 163 return member; | 177 return member; |
| 164 } | 178 } |
| 165 } | 179 } |
| 166 // setter | 180 // setter |
| 167 if (kinds.contains(ElementKind.SETTER)) { | 181 if (kinds.contains(ElementKind.SETTER)) { |
| 168 member = classElement.lookUpSetter(name + '=', library); | 182 member = classElement.lookUpSetter(name + '=', currentLibrary); |
| 169 if (member != null) { | 183 if (member != null) { |
| 170 return member; | 184 return member; |
| 171 } | 185 } |
| 172 } | 186 } |
| 173 // not found | 187 // not found |
| 174 return null; | 188 return null; |
| 175 } | 189 } |
| 176 } | 190 } |
| OLD | NEW |