OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library analyzer.dart.element.visitor; |
| 6 |
| 7 import 'package:analyzer/dart/element/element.dart'; |
| 8 |
| 9 /** |
| 10 * An element visitor that will recursively visit all of the elements in an |
| 11 * element model (like instances of the class [RecursiveElementVisitor]). In |
| 12 * addition, when an element of a specific type is visited not only will the |
| 13 * visit method for that specific type of element be invoked, but additional |
| 14 * methods for the supertypes of that element will also be invoked. For example, |
| 15 * using an instance of this class to visit a [MethodElement] will cause the |
| 16 * method [visitMethodElement] to be invoked but will also cause the methods |
| 17 * [visitExecutableElement] and [visitElement] to be subsequently invoked. This |
| 18 * allows visitors to be written that visit all executable elements without |
| 19 * needing to override the visit method for each of the specific subclasses of |
| 20 * [ExecutableElement]. |
| 21 * |
| 22 * Note, however, that unlike many visitors, element visitors visit objects |
| 23 * based on the interfaces implemented by those elements. Because interfaces |
| 24 * form a graph structure rather than a tree structure the way classes do, and |
| 25 * because it is generally undesirable for an object to be visited more than |
| 26 * once, this class flattens the interface graph into a pseudo-tree. In |
| 27 * particular, this class treats elements as if the element types were |
| 28 * structured in the following way: |
| 29 * |
| 30 * <pre> |
| 31 * Element |
| 32 * ClassElement |
| 33 * CompilationUnitElement |
| 34 * ExecutableElement |
| 35 * ConstructorElement |
| 36 * LocalElement |
| 37 * FunctionElement |
| 38 * MethodElement |
| 39 * PropertyAccessorElement |
| 40 * ExportElement |
| 41 * HtmlElement |
| 42 * ImportElement |
| 43 * LabelElement |
| 44 * LibraryElement |
| 45 * MultiplyDefinedElement |
| 46 * PrefixElement |
| 47 * TypeAliasElement |
| 48 * TypeParameterElement |
| 49 * UndefinedElement |
| 50 * VariableElement |
| 51 * PropertyInducingElement |
| 52 * FieldElement |
| 53 * TopLevelVariableElement |
| 54 * LocalElement |
| 55 * LocalVariableElement |
| 56 * ParameterElement |
| 57 * FieldFormalParameterElement |
| 58 * </pre> |
| 59 * |
| 60 * Subclasses that override a visit method must either invoke the overridden |
| 61 * visit method or explicitly invoke the more general visit method. Failure to |
| 62 * do so will cause the visit methods for superclasses of the element to not be |
| 63 * invoked and will cause the children of the visited node to not be visited. |
| 64 * |
| 65 * Clients may extend or implement this class. |
| 66 */ |
| 67 class GeneralizingElementVisitor<R> implements ElementVisitor<R> { |
| 68 @override |
| 69 R visitClassElement(ClassElement element) => visitElement(element); |
| 70 |
| 71 @override |
| 72 R visitCompilationUnitElement(CompilationUnitElement element) => |
| 73 visitElement(element); |
| 74 |
| 75 @override |
| 76 R visitConstructorElement(ConstructorElement element) => |
| 77 visitExecutableElement(element); |
| 78 |
| 79 R visitElement(Element element) { |
| 80 element.visitChildren(this); |
| 81 return null; |
| 82 } |
| 83 |
| 84 R visitExecutableElement(ExecutableElement element) => visitElement(element); |
| 85 |
| 86 @override |
| 87 R visitExportElement(ExportElement element) => visitElement(element); |
| 88 |
| 89 @override |
| 90 R visitFieldElement(FieldElement element) => |
| 91 visitPropertyInducingElement(element); |
| 92 |
| 93 @override |
| 94 R visitFieldFormalParameterElement(FieldFormalParameterElement element) => |
| 95 visitParameterElement(element); |
| 96 |
| 97 @override |
| 98 R visitFunctionElement(FunctionElement element) => visitLocalElement(element); |
| 99 |
| 100 @override |
| 101 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => |
| 102 visitElement(element); |
| 103 |
| 104 @override |
| 105 R visitImportElement(ImportElement element) => visitElement(element); |
| 106 |
| 107 @override |
| 108 R visitLabelElement(LabelElement element) => visitElement(element); |
| 109 |
| 110 @override |
| 111 R visitLibraryElement(LibraryElement element) => visitElement(element); |
| 112 |
| 113 R visitLocalElement(LocalElement element) { |
| 114 if (element is LocalVariableElement) { |
| 115 return visitVariableElement(element); |
| 116 } else if (element is ParameterElement) { |
| 117 return visitVariableElement(element); |
| 118 } else if (element is FunctionElement) { |
| 119 return visitExecutableElement(element); |
| 120 } |
| 121 return null; |
| 122 } |
| 123 |
| 124 @override |
| 125 R visitLocalVariableElement(LocalVariableElement element) => |
| 126 visitLocalElement(element); |
| 127 |
| 128 @override |
| 129 R visitMethodElement(MethodElement element) => |
| 130 visitExecutableElement(element); |
| 131 |
| 132 @override |
| 133 R visitMultiplyDefinedElement(MultiplyDefinedElement element) => |
| 134 visitElement(element); |
| 135 |
| 136 @override |
| 137 R visitParameterElement(ParameterElement element) => |
| 138 visitLocalElement(element); |
| 139 |
| 140 @override |
| 141 R visitPrefixElement(PrefixElement element) => visitElement(element); |
| 142 |
| 143 @override |
| 144 R visitPropertyAccessorElement(PropertyAccessorElement element) => |
| 145 visitExecutableElement(element); |
| 146 |
| 147 R visitPropertyInducingElement(PropertyInducingElement element) => |
| 148 visitVariableElement(element); |
| 149 |
| 150 @override |
| 151 R visitTopLevelVariableElement(TopLevelVariableElement element) => |
| 152 visitPropertyInducingElement(element); |
| 153 |
| 154 @override |
| 155 R visitTypeParameterElement(TypeParameterElement element) => |
| 156 visitElement(element); |
| 157 |
| 158 R visitVariableElement(VariableElement element) => visitElement(element); |
| 159 } |
| 160 |
| 161 /** |
| 162 * A visitor that will recursively visit all of the element in an element model. |
| 163 * For example, using an instance of this class to visit a |
| 164 * [CompilationUnitElement] will also cause all of the types in the compilation |
| 165 * unit to be visited. |
| 166 * |
| 167 * Subclasses that override a visit method must either invoke the overridden |
| 168 * visit method or must explicitly ask the visited element to visit its |
| 169 * children. Failure to do so will cause the children of the visited element to |
| 170 * not be visited. |
| 171 * |
| 172 * Clients may extend or implement this class. |
| 173 */ |
| 174 class RecursiveElementVisitor<R> implements ElementVisitor<R> { |
| 175 @override |
| 176 R visitClassElement(ClassElement element) { |
| 177 element.visitChildren(this); |
| 178 return null; |
| 179 } |
| 180 |
| 181 @override |
| 182 R visitCompilationUnitElement(CompilationUnitElement element) { |
| 183 element.visitChildren(this); |
| 184 return null; |
| 185 } |
| 186 |
| 187 @override |
| 188 R visitConstructorElement(ConstructorElement element) { |
| 189 element.visitChildren(this); |
| 190 return null; |
| 191 } |
| 192 |
| 193 @override |
| 194 R visitExportElement(ExportElement element) { |
| 195 element.visitChildren(this); |
| 196 return null; |
| 197 } |
| 198 |
| 199 @override |
| 200 R visitFieldElement(FieldElement element) { |
| 201 element.visitChildren(this); |
| 202 return null; |
| 203 } |
| 204 |
| 205 @override |
| 206 R visitFieldFormalParameterElement(FieldFormalParameterElement element) { |
| 207 element.visitChildren(this); |
| 208 return null; |
| 209 } |
| 210 |
| 211 @override |
| 212 R visitFunctionElement(FunctionElement element) { |
| 213 element.visitChildren(this); |
| 214 return null; |
| 215 } |
| 216 |
| 217 @override |
| 218 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { |
| 219 element.visitChildren(this); |
| 220 return null; |
| 221 } |
| 222 |
| 223 @override |
| 224 R visitImportElement(ImportElement element) { |
| 225 element.visitChildren(this); |
| 226 return null; |
| 227 } |
| 228 |
| 229 @override |
| 230 R visitLabelElement(LabelElement element) { |
| 231 element.visitChildren(this); |
| 232 return null; |
| 233 } |
| 234 |
| 235 @override |
| 236 R visitLibraryElement(LibraryElement element) { |
| 237 element.visitChildren(this); |
| 238 return null; |
| 239 } |
| 240 |
| 241 @override |
| 242 R visitLocalVariableElement(LocalVariableElement element) { |
| 243 element.visitChildren(this); |
| 244 return null; |
| 245 } |
| 246 |
| 247 @override |
| 248 R visitMethodElement(MethodElement element) { |
| 249 element.visitChildren(this); |
| 250 return null; |
| 251 } |
| 252 |
| 253 @override |
| 254 R visitMultiplyDefinedElement(MultiplyDefinedElement element) { |
| 255 element.visitChildren(this); |
| 256 return null; |
| 257 } |
| 258 |
| 259 @override |
| 260 R visitParameterElement(ParameterElement element) { |
| 261 element.visitChildren(this); |
| 262 return null; |
| 263 } |
| 264 |
| 265 @override |
| 266 R visitPrefixElement(PrefixElement element) { |
| 267 element.visitChildren(this); |
| 268 return null; |
| 269 } |
| 270 |
| 271 @override |
| 272 R visitPropertyAccessorElement(PropertyAccessorElement element) { |
| 273 element.visitChildren(this); |
| 274 return null; |
| 275 } |
| 276 |
| 277 @override |
| 278 R visitTopLevelVariableElement(TopLevelVariableElement element) { |
| 279 element.visitChildren(this); |
| 280 return null; |
| 281 } |
| 282 |
| 283 @override |
| 284 R visitTypeParameterElement(TypeParameterElement element) { |
| 285 element.visitChildren(this); |
| 286 return null; |
| 287 } |
| 288 } |
| 289 |
| 290 /** |
| 291 * A visitor that will do nothing when visiting an element. It is intended to be |
| 292 * a superclass for classes that use the visitor pattern primarily as a dispatch |
| 293 * mechanism (and hence don't need to recursively visit a whole structure) and |
| 294 * that only need to visit a small number of element types. |
| 295 * |
| 296 * Clients may extend or implement this class. |
| 297 */ |
| 298 class SimpleElementVisitor<R> implements ElementVisitor<R> { |
| 299 @override |
| 300 R visitClassElement(ClassElement element) => null; |
| 301 |
| 302 @override |
| 303 R visitCompilationUnitElement(CompilationUnitElement element) => null; |
| 304 |
| 305 @override |
| 306 R visitConstructorElement(ConstructorElement element) => null; |
| 307 |
| 308 @override |
| 309 R visitExportElement(ExportElement element) => null; |
| 310 |
| 311 @override |
| 312 R visitFieldElement(FieldElement element) => null; |
| 313 |
| 314 @override |
| 315 R visitFieldFormalParameterElement(FieldFormalParameterElement element) => |
| 316 null; |
| 317 |
| 318 @override |
| 319 R visitFunctionElement(FunctionElement element) => null; |
| 320 |
| 321 @override |
| 322 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null; |
| 323 |
| 324 @override |
| 325 R visitImportElement(ImportElement element) => null; |
| 326 |
| 327 @override |
| 328 R visitLabelElement(LabelElement element) => null; |
| 329 |
| 330 @override |
| 331 R visitLibraryElement(LibraryElement element) => null; |
| 332 |
| 333 @override |
| 334 R visitLocalVariableElement(LocalVariableElement element) => null; |
| 335 |
| 336 @override |
| 337 R visitMethodElement(MethodElement element) => null; |
| 338 |
| 339 @override |
| 340 R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null; |
| 341 |
| 342 @override |
| 343 R visitParameterElement(ParameterElement element) => null; |
| 344 |
| 345 @override |
| 346 R visitPrefixElement(PrefixElement element) => null; |
| 347 |
| 348 @override |
| 349 R visitPropertyAccessorElement(PropertyAccessorElement element) => null; |
| 350 |
| 351 @override |
| 352 R visitTopLevelVariableElement(TopLevelVariableElement element) => null; |
| 353 |
| 354 @override |
| 355 R visitTypeParameterElement(TypeParameterElement element) => null; |
| 356 } |
OLD | NEW |