diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 02de8b57230..d7651acbf06 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -238,6 +238,7 @@ const String SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS =
const String SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS_PATTERN = 'pattern';
const String SEARCH_REQUEST_GET_ELEMENT_DECLARATIONS =
'search.getElementDeclarations';
+const String SEARCH_REQUEST_GET_ELEMENT_DECLARATIONS_FILE = 'file';
const String SEARCH_REQUEST_GET_ELEMENT_DECLARATIONS_MAX_RESULTS = 'maxResults';
const String SEARCH_REQUEST_GET_ELEMENT_DECLARATIONS_PATTERN = 'pattern';
const String SEARCH_REQUEST_GET_TYPE_HIERARCHY = 'search.getTypeHierarchy';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 07bc62954dc..54ffbeec7b9 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -15557,6 +15557,7 @@ class SearchFindTopLevelDeclarationsResult implements ResponseResult {
* search.getElementDeclarations params
*
* {
+ * "file": optional FilePath
* "pattern": optional String
* "maxResults": optional int
* }
@@ -15564,10 +15565,26 @@ class SearchFindTopLevelDeclarationsResult implements ResponseResult {
* Clients may not extend, implement or mix-in this class.
*/
class SearchGetElementDeclarationsParams implements RequestParams {
+ String _file;
+
String _pattern;
int _maxResults;
+ /**
+ * If this field is provided, return only declarations in this file. If this
+ * field is missing, return declarations in all files.
+ */
+ String get file => _file;
+
+ /**
+ * If this field is provided, return only declarations in this file. If this
+ * field is missing, return declarations in all files.
+ */
+ void set file(String value) {
+ this._file = value;
+ }
+
/**
* The regular expression used to match the names of declarations. If this
* field is missing, return all declarations.
@@ -15596,7 +15613,9 @@ class SearchGetElementDeclarationsParams implements RequestParams {
this._maxResults = value;
}
- SearchGetElementDeclarationsParams({String pattern, int maxResults}) {
+ SearchGetElementDeclarationsParams(
+ {String file, String pattern, int maxResults}) {
+ this.file = file;
this.pattern = pattern;
this.maxResults = maxResults;
}
@@ -15607,6 +15626,10 @@ class SearchGetElementDeclarationsParams implements RequestParams {
json = {};
}
if (json is Map) {
+ String file;
+ if (json.containsKey("file")) {
+ file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]);
+ }
String pattern;
if (json.containsKey("pattern")) {
pattern =
@@ -15618,7 +15641,7 @@ class SearchGetElementDeclarationsParams implements RequestParams {
jsonDecoder.decodeInt(jsonPath + ".maxResults", json["maxResults"]);
}
return new SearchGetElementDeclarationsParams(
- pattern: pattern, maxResults: maxResults);
+ file: file, pattern: pattern, maxResults: maxResults);
} else {
throw jsonDecoder.mismatch(
jsonPath, "search.getElementDeclarations params", json);
@@ -15633,6 +15656,9 @@ class SearchGetElementDeclarationsParams implements RequestParams {
@override
Map toJson() {
Map result = {};
+ if (file != null) {
+ result["file"] = file;
+ }
if (pattern != null) {
result["pattern"] = pattern;
}
@@ -15653,7 +15679,9 @@ class SearchGetElementDeclarationsParams implements RequestParams {
@override
bool operator ==(other) {
if (other is SearchGetElementDeclarationsParams) {
- return pattern == other.pattern && maxResults == other.maxResults;
+ return file == other.file &&
+ pattern == other.pattern &&
+ maxResults == other.maxResults;
}
return false;
}
@@ -15661,6 +15689,7 @@ class SearchGetElementDeclarationsParams implements RequestParams {
@override
int get hashCode {
int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, file.hashCode);
hash = JenkinsSmiHash.combine(hash, pattern.hashCode);
hash = JenkinsSmiHash.combine(hash, maxResults.hashCode);
return JenkinsSmiHash.finish(hash);
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index ecdce2a0a99..d3ffa605a9a 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -180,8 +180,9 @@ class SearchDomainHandler implements protocol.RequestHandler {
int remainingMaxResults = params.maxResults;
for (var driver in server.driverMap.values.toList()) {
- var driverDeclarations =
- await driver.search.declarations(regExp, remainingMaxResults, files);
+ var driverDeclarations = await driver.search.declarations(
+ regExp, remainingMaxResults, files,
+ onlyForFile: params.file);
declarations.addAll(driverDeclarations);
if (remainingMaxResults != null) {
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index f1c05fc93d4..cf284ec6f05 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1201,6 +1201,11 @@ abstract class IntegrationTestMixin {
*
* Parameters
*
+ * file: FilePath (optional)
+ *
+ * If this field is provided, return only declarations in this file. If
+ * this field is missing, return declarations in all files.
+ *
* pattern: String (optional)
*
* The regular expression used to match the names of declarations. If this
@@ -1222,9 +1227,9 @@ abstract class IntegrationTestMixin {
* The list of the paths of files with declarations.
*/
Future sendSearchGetElementDeclarations(
- {String pattern, int maxResults}) async {
+ {String file, String pattern, int maxResults}) async {
var params = new SearchGetElementDeclarationsParams(
- pattern: pattern, maxResults: maxResults)
+ file: file, pattern: pattern, maxResults: maxResults)
.toJson();
var result = await server.send("search.getElementDeclarations", params);
ResponseDecoder decoder = new ResponseDecoder(null);
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 6a6dc6a3ed5..966801efacb 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -2683,13 +2683,18 @@ final Matcher isSearchFindTopLevelDeclarationsResult = new LazyMatcher(() =>
* search.getElementDeclarations params
*
* {
+ * "file": optional FilePath
* "pattern": optional String
* "maxResults": optional int
* }
*/
final Matcher isSearchGetElementDeclarationsParams = new LazyMatcher(() =>
new MatchesJsonObject("search.getElementDeclarations params", null,
- optionalFields: {"pattern": isString, "maxResults": isInt}));
+ optionalFields: {
+ "file": isFilePath,
+ "pattern": isString,
+ "maxResults": isInt
+ }));
/**
* search.getElementDeclarations result
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index 4feda64fbf8..71bf567f971 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_test.dart
@@ -126,6 +126,21 @@ class D {}
}
}
+ test_onlyForFile() async {
+ var a = newFile(join(testFolder, 'a.dart'), content: 'class A {}').path;
+ newFile(join(testFolder, 'b.dart'), content: 'class B {}').path;
+
+ await _getDeclarations(file: a);
+
+ expect(declarationsResult.files, [a]);
+ expect(declarationsResult.declarations, hasLength(1));
+
+ var declaration = declarationsResult.declarations[0];
+ expect(declaration.name, 'A');
+ expect(declaration.kind, ElementKind.CLASS);
+ expect(declarationsResult.files[declaration.fileIndex], a);
+ }
+
test_parameters() async {
addTestFile(r'''
void f(bool a, String b) {}
@@ -170,9 +185,10 @@ typedef tf2 = int Function(T tp, S sp);
assertHas('tf2', ElementKind.FUNCTION_TYPE_ALIAS);
}
- Future _getDeclarations({String pattern, int maxResults}) async {
+ Future _getDeclarations(
+ {String file, String pattern, int maxResults}) async {
Request request = new SearchGetElementDeclarationsParams(
- pattern: pattern, maxResults: maxResults)
+ file: file, pattern: pattern, maxResults: maxResults)
.toRequest('0');
Response response = await waitResponse(request);
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index f1f240163d0..e551044bc63 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -734,12 +734,14 @@ public interface AnalysisServer {
*
* Return top-level and class member declarations.
*
+ * @param file If this field is provided, return only declarations in this file. If this field is
+ * missing, return declarations in all files.
* @param pattern The regular expression used to match the names of declarations. If this field is
* missing, return all declarations.
* @param maxResults The maximum number of declarations to return. If this field is missing, return
* all matching declarations.
*/
- public void search_getElementDeclarations(String pattern, int maxResults, GetElementDeclarationsConsumer consumer);
+ public void search_getElementDeclarations(String file, String pattern, int maxResults, GetElementDeclarationsConsumer consumer);
/**
* {@code search.getTypeHierarchy}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 5be66aea9e6..92aeb4f7a49 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1579,6 +1579,13 @@
Return top-level and class member declarations.
+
+ [FilePath]
+
+ If this field is provided, return only declarations in this file.
+ If this field is missing, return declarations in all files.
+
+
[String]
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 6b8d5e36082..00b550c58dc 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -118,7 +118,8 @@ class Search {
* we just want reduce amount of data, not to make it absolute minimum.
*/
Future> declarations(
- RegExp regExp, int maxResults, List files) async {
+ RegExp regExp, int maxResults, List files,
+ {String onlyForFile}) async {
List declarations = [];
UnlinkedUnit unlinkedUnit;
@@ -179,6 +180,10 @@ class Search {
try {
for (String path in _driver.addedFiles) {
+ if (onlyForFile != null && path != onlyForFile) {
+ continue;
+ }
+
FileState file = _driver.fsState.getFileForPath(path);
int fileIndex;
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index d2a4e23f537..933ade73115 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -157,20 +157,23 @@ class C {}
expect(declarations, hasLength(2));
}
- test_declarations_regExp() async {
- await _resolveTestUnit('''
-class A {}
-class B {}
-class C {}
-class D {}
-''');
+ test_declarations_onlyForFile() async {
+ var a = _p('/test/lib/a.dart');
+ var b = _p('/test/lib/b.dart');
+ provider.newFile(a, 'class A {}');
+ provider.newFile(b, 'class B {}');
+
+ driver.addFile(a);
+ driver.addFile(b);
+
var files = [];
List declarations =
- await driver.search.declarations(new RegExp(r'[A-C]'), null, files);
- _assertHasDeclaration(declarations, 'A', DeclarationKind.CLASS);
+ await driver.search.declarations(null, null, files, onlyForFile: b);
+
+ expect(files, [b]);
+
+ _assertNoDeclaration(declarations, 'A');
_assertHasDeclaration(declarations, 'B', DeclarationKind.CLASS);
- _assertHasDeclaration(declarations, 'C', DeclarationKind.CLASS);
- _assertNoDeclaration(declarations, 'D');
}
test_declarations_parameters() async {
@@ -211,6 +214,22 @@ typedef F(int a);
expect(declaration.parameters, '(int a)');
}
+ test_declarations_regExp() async {
+ await _resolveTestUnit('''
+class A {}
+class B {}
+class C {}
+class D {}
+''');
+ var files = [];
+ List declarations =
+ await driver.search.declarations(new RegExp(r'[A-C]'), null, files);
+ _assertHasDeclaration(declarations, 'A', DeclarationKind.CLASS);
+ _assertHasDeclaration(declarations, 'B', DeclarationKind.CLASS);
+ _assertHasDeclaration(declarations, 'C', DeclarationKind.CLASS);
+ _assertNoDeclaration(declarations, 'D');
+ }
+
test_declarations_top() async {
await _resolveTestUnit('''
int get g => 0;