| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analyzer_plugin/protocol/protocol_generated.dart'; |
| |
| /// An object that manages the subscriptions for analysis results. |
| /// |
| /// Clients may not extend, implement or mix-in this class. |
| class SubscriptionManager { |
| /// The current set of subscriptions. |
| Map<AnalysisService, List<String>>? _subscriptions; |
| |
| /// Initialize a newly created subscription manager to have no subscriptions. |
| SubscriptionManager(); |
| |
| /// Return `true` if the file with the given [filePath] has a subscription for |
| /// the given [service]. |
| bool hasSubscriptionForFile(String filePath, AnalysisService service) { |
| var subscriptions = _subscriptions; |
| if (subscriptions == null) { |
| return false; |
| } |
| var files = subscriptions[service]; |
| return files != null && files.contains(filePath); |
| } |
| |
| /// Return a list of the services for which the file with the given [filePath] |
| /// has been subscribed. |
| List<AnalysisService> servicesForFile(String filePath) { |
| var services = <AnalysisService>[]; |
| var subscriptions = _subscriptions; |
| if (subscriptions != null) { |
| subscriptions.forEach((AnalysisService service, List<String> files) { |
| if (files.contains(filePath)) { |
| services.add(service); |
| } |
| }); |
| } |
| return services; |
| } |
| |
| /// Set the current set of subscriptions to those described by the given map |
| /// of [subscriptions]. Return a map representing the subset of the |
| /// subscriptions that are new. These are the subscriptions for which a |
| /// notification should be sent. The returned map is keyed by the path of each |
| /// file for which notifications should be send and has values representing |
| /// the list of services that were added for that file. |
| Map<String, List<AnalysisService>> setSubscriptions( |
| Map<AnalysisService, List<String>> subscriptions) { |
| var newSubscriptions = <String, List<AnalysisService>>{}; |
| var currentSubscriptions = _subscriptions; |
| if (currentSubscriptions == null) { |
| // This is the first time subscriptions have been set, so all of the |
| // subscriptions are new. |
| subscriptions.forEach((AnalysisService service, List<String> paths) { |
| for (var path in paths) { |
| newSubscriptions |
| .putIfAbsent(path, () => <AnalysisService>[]) |
| .add(service); |
| } |
| }); |
| } else { |
| // The subscriptions have been changed, to we need to compute the |
| // difference. |
| subscriptions.forEach((AnalysisService service, List<String> paths) { |
| var oldPaths = currentSubscriptions[service]; |
| for (var path in paths) { |
| if (oldPaths == null || !oldPaths.contains(path)) { |
| newSubscriptions |
| .putIfAbsent(path, () => <AnalysisService>[]) |
| .add(service); |
| } |
| } |
| }); |
| } |
| _subscriptions = subscriptions; |
| return newSubscriptions; |
| } |
| } |