| // Copyright (c) 2014, 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 'dart:async'; | |
| import 'package:analysis_server/src/analysis_server.dart'; | |
| import 'package:analysis_server/src/computer/computer_closingLabels.dart'; | |
| import 'package:analysis_server/src/computer/computer_folding.dart'; | |
| import 'package:analysis_server/src/computer/computer_highlights.dart'; | |
| import 'package:analysis_server/src/computer/computer_highlights2.dart'; | |
| import 'package:analysis_server/src/computer/computer_outline.dart'; | |
| import 'package:analysis_server/src/computer/computer_overrides.dart'; | |
| import 'package:analysis_server/src/domains/analysis/implemented_dart.dart'; | |
| import 'package:analysis_server/src/protocol_server.dart' as protocol; | |
| import 'package:analysis_server/src/services/search/search_engine.dart'; | |
| import 'package:analyzer/dart/ast/ast.dart'; | |
| import 'package:analyzer/dart/element/element.dart'; | |
| import 'package:analyzer/src/generated/source.dart'; | |
| Future<Null> scheduleImplementedNotification( | |
| AnalysisServer server, Iterable<String> files) async { | |
| SearchEngine searchEngine = server.searchEngine; | |
| if (searchEngine == null) { | |
| return; | |
| } | |
| for (String file in files) { | |
| CompilationUnit unit = server.getCachedAnalysisResult(file)?.unit; | |
| CompilationUnitElement unitElement = unit?.element; | |
| if (unitElement != null) { | |
| try { | |
| ImplementedComputer computer = | |
| new ImplementedComputer(searchEngine, unitElement); | |
| await computer.compute(); | |
| var params = new protocol.AnalysisImplementedParams( | |
| file, computer.classes, computer.members); | |
| server.sendNotification(params.toNotification()); | |
| } catch (exception, stackTrace) { | |
| server.sendServerErrorNotification( | |
| 'Failed to send analysis.implemented notification.', | |
| exception, | |
| stackTrace); | |
| } | |
| } | |
| } | |
| } | |
| void sendAnalysisNotificationAnalyzedFiles(AnalysisServer server) { | |
| _sendNotification(server, () { | |
| Set<String> analyzedFiles = server.driverMap.values | |
| .map((driver) => driver.knownFiles) | |
| .expand((files) => files) | |
| .toSet(); | |
| // Exclude *.yaml files because IDEA Dart plugin attempts to index | |
| // all the files in folders which contain analyzed files. | |
| analyzedFiles.removeWhere((file) => file.endsWith('.yaml')); | |
| Set<String> prevAnalyzedFiles = server.prevAnalyzedFiles; | |
| if (prevAnalyzedFiles != null && | |
| prevAnalyzedFiles.length == analyzedFiles.length && | |
| prevAnalyzedFiles.difference(analyzedFiles).isEmpty) { | |
| // No change to the set of analyzed files. No need to send another | |
| // notification. | |
| return; | |
| } | |
| server.prevAnalyzedFiles = analyzedFiles; | |
| protocol.AnalysisAnalyzedFilesParams params = | |
| new protocol.AnalysisAnalyzedFilesParams(analyzedFiles.toList()); | |
| server.sendNotification(params.toNotification()); | |
| }); | |
| } | |
| void sendAnalysisNotificationClosingLabels(AnalysisServer server, String file, | |
| LineInfo lineInfo, CompilationUnit dartUnit) { | |
| _sendNotification(server, () { | |
| var labels = | |
| new DartUnitClosingLabelsComputer(lineInfo, dartUnit).compute(); | |
| var params = new protocol.AnalysisClosingLabelsParams(file, labels); | |
| server.sendNotification(params.toNotification()); | |
| }); | |
| } | |
| void sendAnalysisNotificationFolding(AnalysisServer server, String file, | |
| LineInfo lineInfo, CompilationUnit dartUnit) { | |
| _sendNotification(server, () { | |
| var regions = new DartUnitFoldingComputer(lineInfo, dartUnit).compute(); | |
| var params = new protocol.AnalysisFoldingParams(file, regions); | |
| server.sendNotification(params.toNotification()); | |
| }); | |
| } | |
| void sendAnalysisNotificationFlushResults( | |
| AnalysisServer server, List<String> files) { | |
| _sendNotification(server, () { | |
| if (files != null && files.isNotEmpty) { | |
| var params = new protocol.AnalysisFlushResultsParams(files); | |
| server.sendNotification(params.toNotification()); | |
| } | |
| }); | |
| } | |
| void sendAnalysisNotificationHighlights( | |
| AnalysisServer server, String file, CompilationUnit dartUnit) { | |
| _sendNotification(server, () { | |
| List<protocol.HighlightRegion> regions; | |
| if (server.options.useAnalysisHighlight2) { | |
| regions = new DartUnitHighlightsComputer2(dartUnit).compute(); | |
| } else { | |
| regions = new DartUnitHighlightsComputer(dartUnit).compute(); | |
| } | |
| var params = new protocol.AnalysisHighlightsParams(file, regions); | |
| server.sendNotification(params.toNotification()); | |
| }); | |
| } | |
| void sendAnalysisNotificationOutline(AnalysisServer server, String file, | |
| LineInfo lineInfo, SourceKind sourceKind, CompilationUnit dartUnit) { | |
| _sendNotification(server, () { | |
| // compute FileKind | |
| protocol.FileKind fileKind = protocol.FileKind.LIBRARY; | |
| if (sourceKind == SourceKind.LIBRARY) { | |
| fileKind = protocol.FileKind.LIBRARY; | |
| } else if (sourceKind == SourceKind.PART) { | |
| fileKind = protocol.FileKind.PART; | |
| } | |
| // compute library name | |
| String libraryName = _computeLibraryName(dartUnit); | |
| // compute Outline | |
| var computer = new DartUnitOutlineComputer(file, lineInfo, dartUnit, | |
| withBasicFlutter: true); | |
| protocol.Outline outline = computer.compute(); | |
| // send notification | |
| var params = new protocol.AnalysisOutlineParams(file, fileKind, outline, | |
| libraryName: libraryName); | |
| server.sendNotification(params.toNotification()); | |
| }); | |
| } | |
| void sendAnalysisNotificationOverrides( | |
| AnalysisServer server, String file, CompilationUnit dartUnit) { | |
| _sendNotification(server, () { | |
| var overrides = new DartUnitOverridesComputer(dartUnit).compute(); | |
| var params = new protocol.AnalysisOverridesParams(file, overrides); | |
| server.sendNotification(params.toNotification()); | |
| }); | |
| } | |
| String _computeLibraryName(CompilationUnit unit) { | |
| for (Directive directive in unit.directives) { | |
| if (directive is LibraryDirective && directive.name != null) { | |
| return directive.name.name; | |
| } | |
| } | |
| for (Directive directive in unit.directives) { | |
| if (directive is PartOfDirective && directive.libraryName != null) { | |
| return directive.libraryName.name; | |
| } | |
| } | |
| return null; | |
| } | |
| /** | |
| * Runs the given notification producing function [f], catching exceptions. | |
| */ | |
| void _sendNotification(AnalysisServer server, f()) { | |
| ServerPerformanceStatistics.notices.makeCurrentWhile(() { | |
| try { | |
| f(); | |
| } catch (exception, stackTrace) { | |
| server.sendServerErrorNotification( | |
| 'Failed to send notification', exception, stackTrace); | |
| } | |
| }); | |
| } |