blob: d8b10ec446fa115413cd95f588b9c03b759943ee [file] [log] [blame]
// 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.
library operation.analysis;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/computer/computer_highlights.dart';
import 'package:analysis_server/src/computer/computer_navigation.dart';
import 'package:analysis_server/src/computer/computer_occurrences.dart';
import 'package:analysis_server/src/computer/computer_outline.dart';
import 'package:analysis_server/src/computer/computer_overrides.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/operation/operation.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_services/constants.dart';
import 'package:analysis_services/index/index.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/html.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analysis_server/src/computer/error.dart' as server_prefix;
void sendAnalysisNotificationErrors(AnalysisServer server, String file,
LineInfo lineInfo, List<AnalysisError> errors) {
Notification notification = new Notification(ANALYSIS_ERRORS);
notification.setParameter(FILE, file);
notification.setParameter(
ERRORS,
server_prefix.engineErrorsToJson(lineInfo, errors));
server.sendNotification(notification);
}
void sendAnalysisNotificationHighlights(AnalysisServer server, String file,
CompilationUnit dartUnit) {
Notification notification = new Notification(ANALYSIS_HIGHLIGHTS);
notification.setParameter(FILE, file);
notification.setParameter(
REGIONS,
new DartUnitHighlightsComputer(dartUnit).compute());
server.sendNotification(notification);
}
void sendAnalysisNotificationNavigation(AnalysisServer server, String file,
CompilationUnit dartUnit) {
Notification notification = new Notification(ANALYSIS_NAVIGATION);
notification.setParameter(FILE, file);
notification.setParameter(
REGIONS,
new DartUnitNavigationComputer(dartUnit).compute());
server.sendNotification(notification);
}
void sendAnalysisNotificationOccurrences(AnalysisServer server, String file,
CompilationUnit dartUnit) {
Notification notification = new Notification(ANALYSIS_OCCURRENCES);
notification.setParameter(FILE, file);
notification.setParameter(
OCCURRENCES,
new DartUnitOccurrencesComputer(dartUnit).compute());
server.sendNotification(notification);
}
void sendAnalysisNotificationOutline(AnalysisServer server,
AnalysisContext context, Source source, CompilationUnit dartUnit) {
Notification notification = new Notification(ANALYSIS_OUTLINE);
notification.setParameter(FILE, source.fullName);
notification.setParameter(
OUTLINE,
new DartUnitOutlineComputer(context, source, dartUnit).compute());
server.sendNotification(notification);
}
void sendAnalysisNotificationOverrides(AnalysisServer server, String file,
CompilationUnit dartUnit) {
Notification notification = new Notification(ANALYSIS_OVERRIDES);
notification.setParameter(FILE, file);
notification.setParameter(
OVERRIDES,
new DartUnitOverridesComputer(dartUnit).compute());
server.sendNotification(notification);
}
/**
* Instances of [PerformAnalysisOperation] perform a single analysis task.
*/
class PerformAnalysisOperation extends ServerOperation {
final AnalysisContext context;
final bool isContinue;
PerformAnalysisOperation(this.context, this.isContinue);
@override
ServerOperationPriority get priority {
if (isContinue) {
return ServerOperationPriority.ANALYSIS_CONTINUE;
} else {
return ServerOperationPriority.ANALYSIS;
}
}
@override
void perform(AnalysisServer server) {
//
// TODO(brianwilkerson) Add an optional function-valued parameter to
// performAnalysisTask that will be called when the task has been computed
// but before it is performed and send notification in the function:
//
// AnalysisResult result = context.performAnalysisTask((taskDescription) {
// sendStatusNotification(context.toString(), taskDescription);
// });
// prepare results
AnalysisResult result = context.performAnalysisTask();
List<ChangeNotice> notices = result.changeNotices;
if (notices == null) {
server.sendContextAnalysisDoneNotifications(context);
return;
}
// process results
sendNotices(server, notices);
updateIndex(server.index, notices);
// continue analysis
server.addOperation(new PerformAnalysisOperation(context, true));
}
/**
* Send the information in the given list of notices back to the client.
*/
void sendNotices(AnalysisServer server, List<ChangeNotice> notices) {
for (int i = 0; i < notices.length; i++) {
ChangeNotice notice = notices[i];
Source source = notice.source;
String file = source.fullName;
// Dart
CompilationUnit dartUnit = notice.compilationUnit;
if (dartUnit != null) {
if (server.hasAnalysisSubscription(AnalysisService.HIGHLIGHTS, file)) {
sendAnalysisNotificationHighlights(server, file, dartUnit);
}
if (server.hasAnalysisSubscription(AnalysisService.NAVIGATION, file)) {
sendAnalysisNotificationNavigation(server, file, dartUnit);
}
if (server.hasAnalysisSubscription(AnalysisService.OCCURRENCES, file)) {
sendAnalysisNotificationOccurrences(server, file, dartUnit);
}
if (server.hasAnalysisSubscription(AnalysisService.OUTLINE, file)) {
sendAnalysisNotificationOutline(server, context, source, dartUnit);
}
if (server.hasAnalysisSubscription(AnalysisService.OVERRIDES, file)) {
sendAnalysisNotificationOverrides(server, file, dartUnit);
}
}
if (server.shouldSendErrorsNotificationFor(file)) {
sendAnalysisNotificationErrors(
server,
file,
notice.lineInfo,
notice.errors);
}
}
}
void updateIndex(Index index, List<ChangeNotice> notices) {
if (index == null) {
return;
}
for (ChangeNotice notice in notices) {
// Dart
{
CompilationUnit dartUnit = notice.compilationUnit;
if (dartUnit != null) {
index.indexUnit(context, dartUnit);
}
}
// HTML
{
HtmlUnit htmlUnit = notice.htmlUnit;
if (htmlUnit != null) {
index.indexHtmlUnit(context, htmlUnit);
}
}
}
}
}