Implement SearchEngine for the new driver.

Only search for references, and only to local variables is implemented so far.

R=brianwilkerson@google.com
BUG=

Review URL: https://codereview.chromium.org/2521363003 .
This commit is contained in:
Konstantin Shcheglov 2016-11-22 12:01:52 -08:00
parent ed47486f60
commit 26307d77b6
4 changed files with 173 additions and 16 deletions

View file

@ -24,6 +24,7 @@ import 'package:analysis_server/src/services/correction/namespace.dart';
import 'package:analysis_server/src/services/index/index.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analysis_server/src/services/search/search_engine_internal2.dart';
import 'package:analysis_server/src/single_context_manager.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@ -119,7 +120,7 @@ class AnalysisServer {
/**
* The [SearchEngine] for this server, may be `null` if indexing is disabled.
*/
final SearchEngine searchEngine;
SearchEngine searchEngine;
/**
* The plugin associated with this analysis server.
@ -346,7 +347,7 @@ class AnalysisServer {
this.channel,
this.resourceProvider,
PubPackageMapProvider packageMapProvider,
Index _index,
this.index,
this.serverPlugin,
this.options,
this.sdkManager,
@ -354,9 +355,7 @@ class AnalysisServer {
{ResolverProvider fileResolverProvider: null,
ResolverProvider packageResolverProvider: null,
bool useSingleContextManager: false,
this.rethrowExceptions: true})
: index = _index,
searchEngine = _index != null ? new SearchEngineImpl(_index) : null {
this.rethrowExceptions: true}) {
_performance = performanceDuringStartup;
defaultContextOptions.incremental = true;
defaultContextOptions.incrementalApi =
@ -414,6 +413,11 @@ class AnalysisServer {
});
});
_setupIndexInvalidation();
if (options.enableNewAnalysisDriver) {
searchEngine = new SearchEngineImpl2(driverMap.values);
} else if (index != null) {
searchEngine = new SearchEngineImpl(index);
}
pubSummaryManager =
new PubSummaryManager(resourceProvider, '${io.pid}.temp');
Notification notification = new ServerConnectedParams(VERSION, io.pid,
@ -602,11 +606,13 @@ class AnalysisServer {
* otherwise in the first driver, otherwise `null` is returned.
*/
Future<nd.AnalysisResult> getAnalysisResult(String path) async {
print('[getAnalysisResult] path: $path');
nd.AnalysisResult result = priorityFileResults[path];
if (result != null) {
return result;
}
nd.AnalysisDriver driver = getAnalysisDriver(path);
print('[getAnalysisResult] driver: ${driver.name}');
return driver?.getResult(path);
}
@ -771,7 +777,13 @@ class AnalysisServer {
* the [offset].
*/
Future<AstNode> getNodeAtOffset(String file, int offset) async {
CompilationUnit unit = await getResolvedCompilationUnit(file);
CompilationUnit unit;
if (options.enableNewAnalysisDriver) {
nd.AnalysisResult result = await getAnalysisResult(file);
unit = result?.unit;
} else {
unit = await getResolvedCompilationUnit(file);
}
if (unit != null) {
return new NodeLocator(offset).searchWithin(unit);
}

View file

@ -49,20 +49,13 @@ class SearchDomainHandler implements protocol.RequestHandler {
searchEngine = server.searchEngine;
Future findElementReferences(protocol.Request request) async {
if (server.options.enableNewAnalysisDriver) {
// TODO(scheglov) implement for the new analysis driver
String searchId = (_nextSearchId++).toString();
var result = new protocol.SearchFindElementReferencesResult();
result.id = searchId;
_sendSearchResult(request, result);
_sendSearchNotification(searchId, true, <protocol.SearchResult>[]);
return;
}
var params =
new protocol.SearchFindElementReferencesParams.fromRequest(request);
String file = params.file;
await server.onAnalysisComplete;
// prepare element
if (!server.options.enableNewAnalysisDriver) {
await server.onAnalysisComplete;
}
Element element = await server.getElementAtOffset(file, params.offset);
if (element is ImportElement) {
element = (element as ImportElement).prefix;

View file

@ -0,0 +1,149 @@
// Copyright (c) 2016, 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/services/search/search_engine.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/search.dart';
import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
/**
* A [SearchEngine] implementation.
*/
class SearchEngineImpl2 implements SearchEngine {
final Iterable<AnalysisDriver> _drivers;
SearchEngineImpl2(this._drivers);
@override
Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) async {
// TODO(scheglov) implement
return [];
}
@override
Future<List<SearchMatch>> searchMemberDeclarations(String name) async {
// TODO(scheglov) implement
return [];
}
@override
Future<List<SearchMatch>> searchMemberReferences(String name) async {
// TODO(scheglov) implement
return [];
}
@override
Future<List<SearchMatch>> searchReferences(Element element) async {
List<SearchResult> allResults = [];
for (AnalysisDriver driver in _drivers) {
List<SearchResult> results = await driver.search.references(element);
allResults.addAll(results);
}
return allResults.map(_SearchMatch.forSearchResult).toList();
}
@override
Future<List<SearchMatch>> searchSubtypes(ClassElement type) async {
// TODO(scheglov) implement
return [];
}
@override
Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) async {
// TODO(scheglov) implement
return [];
}
}
class _SearchMatch implements SearchMatch {
@override
final String file;
@override
final Source librarySource;
@override
final Source unitSource;
@override
final LibraryElement libraryElement;
@override
final Element element;
@override
final bool isResolved;
@override
final bool isQualified;
@override
final MatchKind kind;
@override
final SourceRange sourceRange;
_SearchMatch(
this.file,
this.librarySource,
this.unitSource,
this.libraryElement,
this.element,
this.isResolved,
this.isQualified,
this.kind,
this.sourceRange);
@override
String toString() {
StringBuffer buffer = new StringBuffer();
buffer.write("SearchMatch(kind=");
buffer.write(kind);
buffer.write(", libraryUri=");
buffer.write(librarySource.uri);
buffer.write(", unitUri=");
buffer.write(unitSource.uri);
buffer.write(", range=");
buffer.write(sourceRange);
buffer.write(", isResolved=");
buffer.write(isResolved);
buffer.write(", isQualified=");
buffer.write(isQualified);
buffer.write(")");
return buffer.toString();
}
static _SearchMatch forSearchResult(SearchResult result) {
Element enclosingElement = result.enclosingElement;
return new _SearchMatch(
enclosingElement.source.fullName,
enclosingElement.librarySource,
enclosingElement.source,
enclosingElement.library,
enclosingElement,
result.isResolved,
result.isQualified,
toMatchKind(result.kind),
new SourceRange(result.offset, result.length));
}
static MatchKind toMatchKind(SearchResultKind kind) {
if (kind == SearchResultKind.READ) {
return MatchKind.READ;
}
if (kind == SearchResultKind.READ_WRITE) {
return MatchKind.READ_WRITE;
}
if (kind == SearchResultKind.WRITE) {
return MatchKind.WRITE;
}
if (kind == SearchResultKind.INVOCATION) {
return MatchKind.INVOCATION;
}
return MatchKind.REFERENCE;
}
}

View file

@ -39,6 +39,9 @@ class Search {
Future<List<SearchResult>> _searchReferences_Local(
Element element, bool isRootNode(AstNode n)) async {
String path = element.source.fullName;
if (!_driver.addedFiles.contains(path)) {
return const <SearchResult>[];
}
// Prepare the unit.
AnalysisResult analysisResult = await _driver.getResult(path);