| OLD | NEW | 
|---|
|  | (Empty) | 
| 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 |  | 
| 3 // BSD-style license that can be found in the LICENSE file. |  | 
| 4 |  | 
| 5 library analysis_server.analysis.index.index_core; |  | 
| 6 |  | 
| 7 import 'dart:async'; |  | 
| 8 import 'dart:collection'; |  | 
| 9 |  | 
| 10 import 'package:analysis_server/src/services/index/index.dart'; |  | 
| 11 import 'package:analyzer/src/generated/engine.dart'; |  | 
| 12 import 'package:analyzer/src/generated/source.dart'; |  | 
| 13 |  | 
| 14 /** |  | 
| 15  * An object that can have a [Relationship] with various [Location]s in a code |  | 
| 16  * base. The object is abstractly represented by a [kind] and an [offset] within |  | 
| 17  * a [source]. |  | 
| 18  * |  | 
| 19  * Clients must ensure that two distinct objects in the same source cannot have |  | 
| 20  * the same kind and offset. Failure to do so will make it impossible for |  | 
| 21  * clients to identify the model element corresponding to the indexable object. |  | 
| 22  * |  | 
| 23  * Clients are expected to subtype this class when implementing plugins. |  | 
| 24  */ |  | 
| 25 abstract class IndexableObject { |  | 
| 26   /** |  | 
| 27    * Return the kind of this object. |  | 
| 28    */ |  | 
| 29   IndexableObjectKind get kind; |  | 
| 30 |  | 
| 31   /** |  | 
| 32    * Return the length of the indexable object within its source. |  | 
| 33    */ |  | 
| 34   int get length; |  | 
| 35 |  | 
| 36   /** |  | 
| 37    * Return the name of this element. |  | 
| 38    */ |  | 
| 39   // TODO(brianwilkerson) Remove the need for this getter. |  | 
| 40   String get name; |  | 
| 41 |  | 
| 42   /** |  | 
| 43    * Return the offset of the indexable object within its source. |  | 
| 44    */ |  | 
| 45   int get offset; |  | 
| 46 |  | 
| 47   /** |  | 
| 48    * Return the source containing the indexable object. |  | 
| 49    */ |  | 
| 50   Source get source; |  | 
| 51 } |  | 
| 52 |  | 
| 53 /** |  | 
| 54  * The kind associated with an [IndexableObject]. |  | 
| 55  * |  | 
| 56  * Clients are expected to implement this class when implementing plugins. |  | 
| 57  */ |  | 
| 58 abstract class IndexableObjectKind { |  | 
| 59   /** |  | 
| 60    * The next available index for a newly created kind of indexable object. |  | 
| 61    */ |  | 
| 62   static int _nextIndex = 0; |  | 
| 63 |  | 
| 64   /** |  | 
| 65    * A table mapping indexes to object kinds. |  | 
| 66    */ |  | 
| 67   static Map<int, IndexableObjectKind> _registry = |  | 
| 68       new HashMap<int, IndexableObjectKind>(); |  | 
| 69 |  | 
| 70   /** |  | 
| 71    * Return the next available index for a newly created kind of indexable |  | 
| 72    * object. |  | 
| 73    */ |  | 
| 74   static int get nextIndex => _nextIndex++; |  | 
| 75 |  | 
| 76   /** |  | 
| 77    * Return the unique index for this kind of indexable object. Implementations |  | 
| 78    * should invoke [nextIndex] to allocate an index that cannot be used by any |  | 
| 79    * other object kind. |  | 
| 80    */ |  | 
| 81   int get index; |  | 
| 82 |  | 
| 83   /** |  | 
| 84    * Return the indexable object of this kind that exists in the given |  | 
| 85    * [context], in the source with the given [filePath], and at the given |  | 
| 86    * [offset]. |  | 
| 87    */ |  | 
| 88   IndexableObject decode(AnalysisContext context, String filePath, int offset); |  | 
| 89 |  | 
| 90   /** |  | 
| 91    * Return the object kind with the given [index]. |  | 
| 92    */ |  | 
| 93   static IndexableObjectKind getKind(int index) { |  | 
| 94     return _registry[index]; |  | 
| 95   } |  | 
| 96 |  | 
| 97   /** |  | 
| 98    * Register the given object [kind] so that it can be found by it's unique |  | 
| 99    * index. The index of the [kind] must not be changed after it is passed to |  | 
| 100    * this method. |  | 
| 101    */ |  | 
| 102   static void register(IndexableObjectKind kind) { |  | 
| 103     int index = kind.index; |  | 
| 104     if (_registry.containsKey(index)) { |  | 
| 105       throw new ArgumentError('duplicate index for kind: $index'); |  | 
| 106     } |  | 
| 107     _registry[index] = kind; |  | 
| 108   } |  | 
| 109 } |  | 
| 110 |  | 
| 111 /** |  | 
| 112  * An object used to add relationships to the index. |  | 
| 113  * |  | 
| 114  * Clients are expected to subtype this class when implementing plugins. |  | 
| 115  */ |  | 
| 116 abstract class IndexContributor { |  | 
| 117   /** |  | 
| 118    * Contribute relationships to the given index [store] as a result of |  | 
| 119    * analyzing the given [source] in the given [context]. |  | 
| 120    */ |  | 
| 121   void contributeTo(IndexStore store, AnalysisContext context, Source source); |  | 
| 122 } |  | 
| 123 |  | 
| 124 // A sketch of what the driver routine might look like: |  | 
| 125 // |  | 
| 126 //void buildIndexForSource(AnalysisContext context, Source source) { |  | 
| 127 //  IndexStoreImpl store; |  | 
| 128 //  store.aboutToIndex(context, source); |  | 
| 129 //  try { |  | 
| 130 //    for (IndexContributor contributor in contributors) { |  | 
| 131 //      contributor.contributeTo(store, context, source); |  | 
| 132 //    } |  | 
| 133 //  } finally { |  | 
| 134 //    store.doneIndexing(); |  | 
| 135 //  } |  | 
| 136 //} |  | 
| 137 |  | 
| 138 /** |  | 
| 139  * An object that stores information about the relationships between locations |  | 
| 140  * in a code base. |  | 
| 141  * |  | 
| 142  * Clients are not expected to subtype this class. |  | 
| 143  */ |  | 
| 144 abstract class IndexStore { |  | 
| 145   /** |  | 
| 146    * Remove all of the information from the index. |  | 
| 147    */ |  | 
| 148   void clear(); |  | 
| 149 |  | 
| 150   /** |  | 
| 151    * Return a future that completes with the locations that have the given |  | 
| 152    * [relationship] with the given [indexable] object. |  | 
| 153    * |  | 
| 154    * For example, if the [indexable] object represents a function and the |  | 
| 155    * relationship is the `is-invoked-by` relationship, then the returned |  | 
| 156    * locations will be all of the places where the function is invoked. |  | 
| 157    */ |  | 
| 158   Future<List<Location>> getRelationships( |  | 
| 159       IndexableObject indexable, Relationship relationship); |  | 
| 160 |  | 
| 161   /** |  | 
| 162    * Record that the given [indexable] object and [location] have the given |  | 
| 163    * [relationship]. |  | 
| 164    * |  | 
| 165    * For example, if the [relationship] is the `is-invoked-by` relationship, |  | 
| 166    * then the [indexable] object would be the function being invoked and |  | 
| 167    * [location] would be the point at which it is invoked. Each indexable object |  | 
| 168    * can have the same relationship with multiple locations. In other words, if |  | 
| 169    * the following code were executed |  | 
| 170    * |  | 
| 171    *     recordRelationship(indexable, isReferencedBy, location1); |  | 
| 172    *     recordRelationship(indexable, isReferencedBy, location2); |  | 
| 173    * |  | 
| 174    * (where `location1 != location2`) then both relationships would be |  | 
| 175    * maintained in the index and the result of executing |  | 
| 176    * |  | 
| 177    *     getRelationship(indexable, isReferencedBy); |  | 
| 178    * |  | 
| 179    * would be a list containing both `location1` and `location2`. |  | 
| 180    */ |  | 
| 181   void recordRelationship( |  | 
| 182       IndexableObject indexable, Relationship relationship, Location location); |  | 
| 183 |  | 
| 184   /** |  | 
| 185    * Remove from the index all of the information associated with the given |  | 
| 186    * [context]. |  | 
| 187    * |  | 
| 188    * This method should be invoked when the [context] is disposed. |  | 
| 189    */ |  | 
| 190   void removeContext(AnalysisContext context); |  | 
| 191 |  | 
| 192   /** |  | 
| 193    * Remove from the index all of the information associated with indexable |  | 
| 194    * objects or locations in the given [source]. This includes relationships |  | 
| 195    * between an indexable object in [source] and any other locations, as well as |  | 
| 196    * relationships between any other indexable objects and locations within |  | 
| 197    * the [source]. |  | 
| 198    * |  | 
| 199    * This method should be invoked when [source] is no longer part of the given |  | 
| 200    * [context]. |  | 
| 201    */ |  | 
| 202   void removeSource(AnalysisContext context, Source source); |  | 
| 203 |  | 
| 204   /** |  | 
| 205    * Remove from the index all of the information associated with indexable |  | 
| 206    * objects or locations in the given sources. This includes relationships |  | 
| 207    * between an indexable object in the given sources and any other locations, |  | 
| 208    * as well as relationships between any other indexable objects and a location |  | 
| 209    * within the given sources. |  | 
| 210    * |  | 
| 211    * This method should be invoked when the sources described by the given |  | 
| 212    * [container] are no longer part of the given [context]. |  | 
| 213    */ |  | 
| 214   void removeSources(AnalysisContext context, SourceContainer container); |  | 
| 215 } |  | 
| 216 |  | 
| 217 /** |  | 
| 218  * Instances of the class [Location] represent a location related to an |  | 
| 219  * indexable object. |  | 
| 220  * |  | 
| 221  * The location is expressed as an offset and length, but the offset is relative |  | 
| 222  * to the source containing the indexable object rather than the start of the |  | 
| 223  * indexable object within that source. |  | 
| 224  * |  | 
| 225  * Clients are not expected to subtype this class. |  | 
| 226  */ |  | 
| 227 abstract class Location { |  | 
| 228   /** |  | 
| 229    * An empty list of locations. |  | 
| 230    */ |  | 
| 231   static const List<Location> EMPTY_LIST = const <Location>[]; |  | 
| 232 |  | 
| 233   /** |  | 
| 234    * Return the indexable object containing this location. |  | 
| 235    */ |  | 
| 236   IndexableObject get indexable; |  | 
| 237 |  | 
| 238   /** |  | 
| 239    * Return `true` if this location is a qualified reference. |  | 
| 240    */ |  | 
| 241   bool get isQualified; |  | 
| 242 |  | 
| 243   /** |  | 
| 244    * Return `true` if this location is a resolved reference. |  | 
| 245    */ |  | 
| 246   bool get isResolved; |  | 
| 247 |  | 
| 248   /** |  | 
| 249    * Return the length of this location. |  | 
| 250    */ |  | 
| 251   int get length; |  | 
| 252 |  | 
| 253   /** |  | 
| 254    * Return the offset of this location within the source containing the |  | 
| 255    * indexable object. |  | 
| 256    */ |  | 
| 257   int get offset; |  | 
| 258 } |  | 
| 259 |  | 
| 260 /** |  | 
| 261  * A relationship between an indexable object and a location. Relationships are |  | 
| 262  * identified by a globally unique identifier. |  | 
| 263  * |  | 
| 264  * Clients are not expected to subtype this class. |  | 
| 265  */ |  | 
| 266 abstract class Relationship { |  | 
| 267   /** |  | 
| 268    * Return a relationship that has the given [identifier]. If the relationship |  | 
| 269    * has already been created, then it will be returned, otherwise a new |  | 
| 270    * relationship will be created |  | 
| 271    */ |  | 
| 272   factory Relationship(String identifier) => |  | 
| 273       RelationshipImpl.getRelationship(identifier); |  | 
| 274 } |  | 
| OLD | NEW | 
|---|