mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:45:06 +00:00
Initial implementation of copy/paste support
R=devoncarew@google.com Review-Url: https://codereview.chromium.org/2972833002 .
This commit is contained in:
parent
56f07cf770
commit
d9754a58e9
|
@ -3945,6 +3945,12 @@ a:focus, a:hover {
|
|||
which does not match a file currently subject to
|
||||
analysis.
|
||||
</p>
|
||||
</dd><dt class="value">IMPORT_ELEMENTS_INVALID_FILE</dt><dd>
|
||||
|
||||
<p>
|
||||
An "edit.importElements" request specified a FilePath that does not
|
||||
match a file currently subject to analysis.
|
||||
</p>
|
||||
</dd><dt class="value">INVALID_ANALYSIS_ROOT</dt><dd>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -468,6 +468,16 @@ class Response {
|
|||
error: new RequestError(RequestErrorCode.GET_ERRORS_INVALID_FILE,
|
||||
'Error during `analysis.getErrors`: invalid file.'));
|
||||
|
||||
/**
|
||||
* Initialize a newly created instance to represent the
|
||||
* GET_IMPORTED_ELEMENTS_INVALID_FILE error condition.
|
||||
*/
|
||||
Response.getImportedElementsInvalidFile(Request request)
|
||||
: this(request.id,
|
||||
error: new RequestError(
|
||||
RequestErrorCode.GET_IMPORTED_ELEMENTS_INVALID_FILE,
|
||||
'Error during `analysis.getImportedElements`: invalid file.'));
|
||||
|
||||
/**
|
||||
* Initialize a newly created instance to represent the
|
||||
* GET_NAVIGATION_INVALID_FILE error condition.
|
||||
|
@ -488,6 +498,16 @@ class Response {
|
|||
RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE,
|
||||
'Error during `analysis.getReachableSources`: invalid file.'));
|
||||
|
||||
/**
|
||||
* Initialize a newly created instance to represent the
|
||||
* IMPORT_ELEMENTS_INVALID_FILE error condition.
|
||||
*/
|
||||
Response.importElementsInvalidFile(Request request)
|
||||
: this(request.id,
|
||||
error: new RequestError(
|
||||
RequestErrorCode.IMPORT_ELEMENTS_INVALID_FILE,
|
||||
'Error during `edit.importElements`: invalid file.'));
|
||||
|
||||
/**
|
||||
* Initialize a newly created instance to represent an error condition caused
|
||||
* by an analysis.reanalyze [request] that specifies an analysis root that is
|
||||
|
|
|
@ -83,7 +83,6 @@ const String ANALYSIS_REQUEST_UPDATE_OPTIONS = 'analysis.updateOptions';
|
|||
const String ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS = 'options';
|
||||
const String ANALYSIS_RESPONSE_GET_ERRORS_ERRORS = 'errors';
|
||||
const String ANALYSIS_RESPONSE_GET_HOVER_HOVERS = 'hovers';
|
||||
const String ANALYSIS_RESPONSE_GET_IMPORTED_ELEMENTS_COMPLETE = 'complete';
|
||||
const String ANALYSIS_RESPONSE_GET_IMPORTED_ELEMENTS_ELEMENTS = 'elements';
|
||||
const String ANALYSIS_RESPONSE_GET_LIBRARY_DEPENDENCIES_LIBRARIES = 'libraries';
|
||||
const String ANALYSIS_RESPONSE_GET_LIBRARY_DEPENDENCIES_PACKAGE_MAP =
|
||||
|
@ -179,7 +178,6 @@ const String EDIT_RESPONSE_GET_REFACTORING_POTENTIAL_EDITS = 'potentialEdits';
|
|||
const String EDIT_RESPONSE_GET_STATEMENT_COMPLETION_CHANGE = 'change';
|
||||
const String EDIT_RESPONSE_GET_STATEMENT_COMPLETION_WHITESPACE_ONLY =
|
||||
'whitespaceOnly';
|
||||
const String EDIT_RESPONSE_IMPORT_ELEMENTS_COMPLETE = 'complete';
|
||||
const String EDIT_RESPONSE_IMPORT_ELEMENTS_EDITS = 'edits';
|
||||
const String EDIT_RESPONSE_IS_POSTFIX_COMPLETION_APPLICABLE_VALUE = 'value';
|
||||
const String EDIT_RESPONSE_LIST_POSTFIX_COMPLETION_TEMPLATES_TEMPLATES =
|
||||
|
|
|
@ -1044,7 +1044,6 @@ class AnalysisGetImportedElementsParams implements RequestParams {
|
|||
*
|
||||
* {
|
||||
* "elements": List<ImportedElements>
|
||||
* "complete": bool
|
||||
* }
|
||||
*
|
||||
* Clients may not extend, implement or mix-in this class.
|
||||
|
@ -1052,8 +1051,6 @@ class AnalysisGetImportedElementsParams implements RequestParams {
|
|||
class AnalysisGetImportedElementsResult implements ResponseResult {
|
||||
List<ImportedElements> _elements;
|
||||
|
||||
bool _complete;
|
||||
|
||||
/**
|
||||
* The information about the elements that are referenced in the specified
|
||||
* region of the specified file that come from imported libraries.
|
||||
|
@ -1069,29 +1066,8 @@ class AnalysisGetImportedElementsResult implements ResponseResult {
|
|||
this._elements = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if all of the elements that are referenced in the specified region
|
||||
* are included in the list of elements. The list of elements will be
|
||||
* incomplete if there is an error in the specified region that prevents an
|
||||
* identifier from being resolved to a single element.
|
||||
*/
|
||||
bool get complete => _complete;
|
||||
|
||||
/**
|
||||
* True if all of the elements that are referenced in the specified region
|
||||
* are included in the list of elements. The list of elements will be
|
||||
* incomplete if there is an error in the specified region that prevents an
|
||||
* identifier from being resolved to a single element.
|
||||
*/
|
||||
void set complete(bool value) {
|
||||
assert(value != null);
|
||||
this._complete = value;
|
||||
}
|
||||
|
||||
AnalysisGetImportedElementsResult(
|
||||
List<ImportedElements> elements, bool complete) {
|
||||
AnalysisGetImportedElementsResult(List<ImportedElements> elements) {
|
||||
this.elements = elements;
|
||||
this.complete = complete;
|
||||
}
|
||||
|
||||
factory AnalysisGetImportedElementsResult.fromJson(
|
||||
|
@ -1110,14 +1086,7 @@ class AnalysisGetImportedElementsResult implements ResponseResult {
|
|||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, "elements");
|
||||
}
|
||||
bool complete;
|
||||
if (json.containsKey("complete")) {
|
||||
complete =
|
||||
jsonDecoder.decodeBool(jsonPath + ".complete", json["complete"]);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, "complete");
|
||||
}
|
||||
return new AnalysisGetImportedElementsResult(elements, complete);
|
||||
return new AnalysisGetImportedElementsResult(elements);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(
|
||||
jsonPath, "analysis.getImportedElements result", json);
|
||||
|
@ -1136,7 +1105,6 @@ class AnalysisGetImportedElementsResult implements ResponseResult {
|
|||
Map<String, dynamic> result = {};
|
||||
result["elements"] =
|
||||
elements.map((ImportedElements value) => value.toJson()).toList();
|
||||
result["complete"] = complete;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1152,8 +1120,7 @@ class AnalysisGetImportedElementsResult implements ResponseResult {
|
|||
bool operator ==(other) {
|
||||
if (other is AnalysisGetImportedElementsResult) {
|
||||
return listEqual(elements, other.elements,
|
||||
(ImportedElements a, ImportedElements b) => a == b) &&
|
||||
complete == other.complete;
|
||||
(ImportedElements a, ImportedElements b) => a == b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1162,7 +1129,6 @@ class AnalysisGetImportedElementsResult implements ResponseResult {
|
|||
int get hashCode {
|
||||
int hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, elements.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, complete.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
@ -7717,7 +7683,6 @@ class EditImportElementsParams implements RequestParams {
|
|||
*
|
||||
* {
|
||||
* "edits": List<SourceEdit>
|
||||
* "complete": bool
|
||||
* }
|
||||
*
|
||||
* Clients may not extend, implement or mix-in this class.
|
||||
|
@ -7725,8 +7690,6 @@ class EditImportElementsParams implements RequestParams {
|
|||
class EditImportElementsResult implements ResponseResult {
|
||||
List<SourceEdit> _edits;
|
||||
|
||||
bool _complete;
|
||||
|
||||
/**
|
||||
* The edit(s) to be applied in order to make the specified elements
|
||||
* accessible.
|
||||
|
@ -7742,30 +7705,8 @@ class EditImportElementsResult implements ResponseResult {
|
|||
this._edits = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if all of the elements that are to be made accessible would be
|
||||
* accessible if the edits were applied. The edits will not be complete, for
|
||||
* example, if one of the libraries cannot be referenced in the target
|
||||
* library or if one of the element names is already imported from a
|
||||
* different library.
|
||||
*/
|
||||
bool get complete => _complete;
|
||||
|
||||
/**
|
||||
* True if all of the elements that are to be made accessible would be
|
||||
* accessible if the edits were applied. The edits will not be complete, for
|
||||
* example, if one of the libraries cannot be referenced in the target
|
||||
* library or if one of the element names is already imported from a
|
||||
* different library.
|
||||
*/
|
||||
void set complete(bool value) {
|
||||
assert(value != null);
|
||||
this._complete = value;
|
||||
}
|
||||
|
||||
EditImportElementsResult(List<SourceEdit> edits, bool complete) {
|
||||
EditImportElementsResult(List<SourceEdit> edits) {
|
||||
this.edits = edits;
|
||||
this.complete = complete;
|
||||
}
|
||||
|
||||
factory EditImportElementsResult.fromJson(
|
||||
|
@ -7784,14 +7725,7 @@ class EditImportElementsResult implements ResponseResult {
|
|||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, "edits");
|
||||
}
|
||||
bool complete;
|
||||
if (json.containsKey("complete")) {
|
||||
complete =
|
||||
jsonDecoder.decodeBool(jsonPath + ".complete", json["complete"]);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, "complete");
|
||||
}
|
||||
return new EditImportElementsResult(edits, complete);
|
||||
return new EditImportElementsResult(edits);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, "edit.importElements result", json);
|
||||
}
|
||||
|
@ -7808,7 +7742,6 @@ class EditImportElementsResult implements ResponseResult {
|
|||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> result = {};
|
||||
result["edits"] = edits.map((SourceEdit value) => value.toJson()).toList();
|
||||
result["complete"] = complete;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -7824,8 +7757,7 @@ class EditImportElementsResult implements ResponseResult {
|
|||
bool operator ==(other) {
|
||||
if (other is EditImportElementsResult) {
|
||||
return listEqual(
|
||||
edits, other.edits, (SourceEdit a, SourceEdit b) => a == b) &&
|
||||
complete == other.complete;
|
||||
edits, other.edits, (SourceEdit a, SourceEdit b) => a == b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -7834,7 +7766,6 @@ class EditImportElementsResult implements ResponseResult {
|
|||
int get hashCode {
|
||||
int hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, edits.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, complete.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
@ -12638,6 +12569,7 @@ class RequestError implements HasToJson {
|
|||
* GET_IMPORTED_ELEMENTS_INVALID_FILE
|
||||
* GET_NAVIGATION_INVALID_FILE
|
||||
* GET_REACHABLE_SOURCES_INVALID_FILE
|
||||
* IMPORT_ELEMENTS_INVALID_FILE
|
||||
* INVALID_ANALYSIS_ROOT
|
||||
* INVALID_EXECUTION_CONTEXT
|
||||
* INVALID_FILE_PATH_FORMAT
|
||||
|
@ -12721,6 +12653,13 @@ class RequestErrorCode implements Enum {
|
|||
static const RequestErrorCode GET_REACHABLE_SOURCES_INVALID_FILE =
|
||||
const RequestErrorCode._("GET_REACHABLE_SOURCES_INVALID_FILE");
|
||||
|
||||
/**
|
||||
* An "edit.importElements" request specified a FilePath that does not match
|
||||
* a file currently subject to analysis.
|
||||
*/
|
||||
static const RequestErrorCode IMPORT_ELEMENTS_INVALID_FILE =
|
||||
const RequestErrorCode._("IMPORT_ELEMENTS_INVALID_FILE");
|
||||
|
||||
/**
|
||||
* A path passed as an argument to a request (such as analysis.reanalyze) is
|
||||
* required to be an analysis root, but isn't.
|
||||
|
@ -12853,6 +12792,7 @@ class RequestErrorCode implements Enum {
|
|||
GET_IMPORTED_ELEMENTS_INVALID_FILE,
|
||||
GET_NAVIGATION_INVALID_FILE,
|
||||
GET_REACHABLE_SOURCES_INVALID_FILE,
|
||||
IMPORT_ELEMENTS_INVALID_FILE,
|
||||
INVALID_ANALYSIS_ROOT,
|
||||
INVALID_EXECUTION_CONTEXT,
|
||||
INVALID_FILE_PATH_FORMAT,
|
||||
|
@ -12896,6 +12836,8 @@ class RequestErrorCode implements Enum {
|
|||
return GET_NAVIGATION_INVALID_FILE;
|
||||
case "GET_REACHABLE_SOURCES_INVALID_FILE":
|
||||
return GET_REACHABLE_SOURCES_INVALID_FILE;
|
||||
case "IMPORT_ELEMENTS_INVALID_FILE":
|
||||
return IMPORT_ELEMENTS_INVALID_FILE;
|
||||
case "INVALID_ANALYSIS_ROOT":
|
||||
return INVALID_ANALYSIS_ROOT;
|
||||
case "INVALID_EXECUTION_CONTEXT":
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
// 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:analysis_server/protocol/protocol_generated.dart';
|
||||
import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/dart/analysis/session.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
|
||||
|
||||
/**
|
||||
* An object used to compute the edits required to ensure that a list of
|
||||
* elements is imported into a given library.
|
||||
*/
|
||||
class ImportElementsComputer {
|
||||
/**
|
||||
* The analysis session used to compute the unit.
|
||||
*/
|
||||
final AnalysisSession session;
|
||||
|
||||
/**
|
||||
* The library element representing the library to which the imports are to be
|
||||
* added.
|
||||
*/
|
||||
final LibraryElement libraryElement;
|
||||
|
||||
/**
|
||||
* The path of the defining compilation unit of the library.
|
||||
*/
|
||||
final String path;
|
||||
|
||||
/**
|
||||
* The elements that are to be imported into the library.
|
||||
*/
|
||||
final List<ImportedElements> elements;
|
||||
|
||||
/**
|
||||
* Initialize a newly created computer to compute the edits required to ensure
|
||||
* that the given list of [elements] is imported into a given [library].
|
||||
*/
|
||||
ImportElementsComputer(ResolveResult result, this.path, this.elements)
|
||||
: session = result.session,
|
||||
libraryElement = result.libraryElement;
|
||||
|
||||
/**
|
||||
* Compute and return the list of edits.
|
||||
*/
|
||||
List<SourceEdit> compute() {
|
||||
DartChangeBuilder builder = new DartChangeBuilder(session);
|
||||
builder.addFileEdit(path, (DartFileEditBuilder builder) {
|
||||
// TODO(brianwilkerson) Implement this.
|
||||
});
|
||||
return <SourceEdit>[]; // builder.sourceChange
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// 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:analysis_server/protocol/protocol_generated.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
|
||||
/**
|
||||
* An object used to compute the list of elements referenced within a given
|
||||
* region of a compilation unit that are imported into the compilation unit's
|
||||
* library.
|
||||
*/
|
||||
class ImportedElementsComputer {
|
||||
/**
|
||||
* The compilation unit in which the elements are referenced.
|
||||
*/
|
||||
final CompilationUnit unit;
|
||||
|
||||
/**
|
||||
* The offset of the region containing the references to be returned.
|
||||
*/
|
||||
final int offset;
|
||||
|
||||
/**
|
||||
* The length of the region containing the references to be returned.
|
||||
*/
|
||||
final int length;
|
||||
|
||||
/**
|
||||
* Initialize a newly created computer to compute the list of imported
|
||||
* elements referenced in the given [unit] within the region with the given
|
||||
* [offset] and [length].
|
||||
*/
|
||||
ImportedElementsComputer(this.unit, this.offset, this.length);
|
||||
|
||||
/**
|
||||
* Compute and return the list of imported elements.
|
||||
*/
|
||||
List<ImportedElements> compute() {
|
||||
// TODO(brianwilkerson) Implement this.
|
||||
return <ImportedElements>[];
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import 'package:analysis_server/plugin/analysis/analysis_domain.dart';
|
|||
import 'package:analysis_server/protocol/protocol_constants.dart';
|
||||
import 'package:analysis_server/src/analysis_server.dart';
|
||||
import 'package:analysis_server/src/computer/computer_hover.dart';
|
||||
import 'package:analysis_server/src/computer/imported_elements_computer.dart';
|
||||
import 'package:analysis_server/src/domain_abstract.dart';
|
||||
import 'package:analysis_server/src/domains/analysis/navigation.dart';
|
||||
import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
|
||||
|
@ -99,6 +100,32 @@ class AnalysisDomainHandler extends AbstractRequestHandler {
|
|||
new AnalysisGetHoverResult(hovers).toResponse(request.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the `analysis.getImportedElements` request.
|
||||
*/
|
||||
Future<Null> getImportedElements(Request request) async {
|
||||
AnalysisGetImportedElementsParams params =
|
||||
new AnalysisGetImportedElementsParams.fromRequest(request);
|
||||
//
|
||||
// Prepare the resolved unit.
|
||||
//
|
||||
AnalysisResult result = await server.getAnalysisResult(params.file);
|
||||
if (result == null) {
|
||||
server.sendResponse(new Response.getImportedElementsInvalidFile(request));
|
||||
}
|
||||
//
|
||||
// Compute the list of imported elements.
|
||||
//
|
||||
List<ImportedElements> elements =
|
||||
new ImportedElementsComputer(result.unit, params.offset, params.length)
|
||||
.compute();
|
||||
//
|
||||
// Send the response.
|
||||
//
|
||||
server.sendResponse(
|
||||
new AnalysisGetImportedElementsResult(elements).toResponse(request.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the `analysis.getLibraryDependencies` request.
|
||||
*/
|
||||
|
@ -216,6 +243,9 @@ class AnalysisDomainHandler extends AbstractRequestHandler {
|
|||
} else if (requestName == ANALYSIS_REQUEST_GET_HOVER) {
|
||||
getHover(request);
|
||||
return Response.DELAYED_RESPONSE;
|
||||
} else if (requestName == ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS) {
|
||||
getImportedElements(request);
|
||||
return Response.DELAYED_RESPONSE;
|
||||
} else if (requestName == ANALYSIS_REQUEST_GET_LIBRARY_DEPENDENCIES) {
|
||||
return getLibraryDependencies(request);
|
||||
} else if (requestName == ANALYSIS_REQUEST_GET_NAVIGATION) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
|
|||
import 'package:analysis_server/protocol/protocol_constants.dart';
|
||||
import 'package:analysis_server/src/analysis_server.dart';
|
||||
import 'package:analysis_server/src/collections.dart';
|
||||
import 'package:analysis_server/src/computer/import_elements_computer.dart';
|
||||
import 'package:analysis_server/src/domain_abstract.dart';
|
||||
import 'package:analysis_server/src/plugin/plugin_manager.dart';
|
||||
import 'package:analysis_server/src/plugin/result_converter.dart';
|
||||
|
@ -350,6 +351,9 @@ class EditDomainHandler extends AbstractRequestHandler {
|
|||
return Response.DELAYED_RESPONSE;
|
||||
} else if (requestName == EDIT_REQUEST_GET_REFACTORING) {
|
||||
return _getRefactoring(request);
|
||||
} else if (requestName == EDIT_REQUEST_IMPORT_ELEMENTS) {
|
||||
importElements(request);
|
||||
return Response.DELAYED_RESPONSE;
|
||||
} else if (requestName == EDIT_REQUEST_ORGANIZE_DIRECTIVES) {
|
||||
organizeDirectives(request);
|
||||
return Response.DELAYED_RESPONSE;
|
||||
|
@ -376,6 +380,32 @@ class EditDomainHandler extends AbstractRequestHandler {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the `edit.importElements` request.
|
||||
*/
|
||||
Future<Null> importElements(Request request) async {
|
||||
EditImportElementsParams params =
|
||||
new EditImportElementsParams.fromRequest(request);
|
||||
//
|
||||
// Prepare the resolved unit.
|
||||
//
|
||||
AnalysisResult result = await server.getAnalysisResult(params.file);
|
||||
if (result == null) {
|
||||
server.sendResponse(new Response.importElementsInvalidFile(request));
|
||||
}
|
||||
//
|
||||
// Compute the edits required to import the required elements.
|
||||
//
|
||||
List<SourceEdit> edits =
|
||||
new ImportElementsComputer(result, params.file, params.elements)
|
||||
.compute();
|
||||
//
|
||||
// Send the response.
|
||||
//
|
||||
server.sendResponse(
|
||||
new EditImportElementsResult(edits).toResponse(request.id));
|
||||
}
|
||||
|
||||
Future isPostfixCompletionApplicable(Request request) async {
|
||||
var params = new EditGetPostfixCompletionParams.fromRequest(request);
|
||||
bool value = false;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
// 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 'dart:async';
|
||||
|
||||
import 'package:analysis_server/protocol/protocol_generated.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../support/integration_tests.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(AnalysisGetImportedElementsIntegrationTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class AnalysisGetImportedElementsIntegrationTest
|
||||
extends AbstractAnalysisServerIntegrationTest {
|
||||
/**
|
||||
* Pathname of the file containing Dart code.
|
||||
*/
|
||||
String pathname;
|
||||
|
||||
/**
|
||||
* Dart code under test.
|
||||
*/
|
||||
final String text = r'''
|
||||
main() {}
|
||||
''';
|
||||
|
||||
/**
|
||||
* Check that an analysis.getImportedElements request on the region starting
|
||||
* with the first character that matches [target] and having the given
|
||||
* [length] matches the given list of [expected] imported elements.
|
||||
*/
|
||||
checkElements(
|
||||
String target, int length, List<ImportedElements> expected) async {
|
||||
int offset = text.indexOf(target);
|
||||
AnalysisGetImportedElementsResult result =
|
||||
await sendAnalysisGetImportedElements(pathname, offset, length);
|
||||
|
||||
expect(result.elements, hasLength(expected.length));
|
||||
// TODO(brianwilkerson) Finish implementing this.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that an analysis.getImportedElements request on the region matching
|
||||
* [target] produces an empty list of elements.
|
||||
*/
|
||||
Future<Null> checkNoElements(String target) async {
|
||||
int offset = text.indexOf(target);
|
||||
AnalysisGetImportedElementsResult result =
|
||||
await sendAnalysisGetImportedElements(pathname, offset, target.length);
|
||||
|
||||
expect(result.elements, hasLength(0));
|
||||
}
|
||||
|
||||
setUp() {
|
||||
return super.setUp().then((_) {
|
||||
pathname = sourcePath('test.dart');
|
||||
});
|
||||
}
|
||||
|
||||
test_getImportedElements() async {
|
||||
writeFile(pathname, text);
|
||||
standardAnalysisSetup();
|
||||
await analysisFinished;
|
||||
|
||||
List<Future> tests = [];
|
||||
tests.add(checkNoElements('main() {}'));
|
||||
return Future.wait(tests);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import 'error_test.dart' as error_test;
|
|||
import 'get_errors_nonStandard_sdk.dart' as get_errors_nonStandard_sdk;
|
||||
import 'get_errors_test.dart' as get_errors_test;
|
||||
import 'get_hover_test.dart' as get_hover_test;
|
||||
import 'get_imported_elements_test.dart' as get_imported_elements_test;
|
||||
import 'get_library_dependencies_test.dart' as get_library_dependencies_test;
|
||||
import 'get_navigation_test.dart' as get_navigation_test;
|
||||
import 'get_reachable_sources_test.dart' as get_reachable_sources_test;
|
||||
|
@ -41,6 +42,7 @@ main() {
|
|||
get_errors_nonStandard_sdk.main();
|
||||
get_library_dependencies_test.main();
|
||||
get_hover_test.main();
|
||||
get_imported_elements_test.main();
|
||||
get_navigation_test.main();
|
||||
get_reachable_sources_test.main();
|
||||
highlights_test.main();
|
||||
|
|
|
@ -4,7 +4,7 @@ server calls. This file is validated by `coverage_test.dart`.
|
|||
## analysis domain
|
||||
- [x] analysis.getErrors
|
||||
- [x] analysis.getHover
|
||||
- [ ] analysis.getImportedElements
|
||||
- [x] analysis.getImportedElements
|
||||
- [x] analysis.getLibraryDependencies (failing - see #29310)
|
||||
- [x] analysis.getNavigation (failing - see #28799)
|
||||
- [x] analysis.getReachableSources (failing - see #29311)
|
||||
|
@ -31,7 +31,7 @@ server calls. This file is validated by `coverage_test.dart`.
|
|||
- [x] edit.getPostfixCompletion
|
||||
- [x] edit.getRefactoring
|
||||
- [x] edit.getStatementCompletion
|
||||
- [ ] edit.importElements
|
||||
- [x] edit.importElements
|
||||
- [x] edit.isPostfixCompletionApplicable
|
||||
- [x] edit.listPostfixCompletionTemplates
|
||||
- [x] edit.sortMembers
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
// 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 'dart:async';
|
||||
|
||||
import 'package:analysis_server/protocol/protocol_generated.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../support/integration_tests.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(AnalysisGetImportElementsIntegrationTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class AnalysisGetImportElementsIntegrationTest
|
||||
extends AbstractAnalysisServerIntegrationTest {
|
||||
/**
|
||||
* Pathname of the file containing Dart code.
|
||||
*/
|
||||
String pathname;
|
||||
|
||||
/**
|
||||
* Dart code under test.
|
||||
*/
|
||||
final String text = r'''
|
||||
''';
|
||||
|
||||
/**
|
||||
* Check that an edit.importElements request with the given list of [elements]
|
||||
* produces the [expected] list of edits.
|
||||
*/
|
||||
checkEdits(List<ImportedElements> elements, List<SourceEdit> expected) async {
|
||||
EditImportElementsResult result =
|
||||
await sendEditImportElements(pathname, elements);
|
||||
|
||||
expect(result.edits, hasLength(expected.length));
|
||||
// TODO(brianwilkerson) Finish implementing this.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that an edit.importElements request with the given list of [elements]
|
||||
* produces no edits.
|
||||
*/
|
||||
Future<Null> checkNoEdits(List<ImportedElements> elements) async {
|
||||
EditImportElementsResult result =
|
||||
await sendEditImportElements(pathname, <ImportedElements>[]);
|
||||
|
||||
expect(result.edits, hasLength(0));
|
||||
}
|
||||
|
||||
setUp() {
|
||||
return super.setUp().then((_) {
|
||||
pathname = sourcePath('test.dart');
|
||||
});
|
||||
}
|
||||
|
||||
test_getImportedElements() async {
|
||||
writeFile(pathname, text);
|
||||
standardAnalysisSetup();
|
||||
await analysisFinished;
|
||||
|
||||
List<Future> tests = [];
|
||||
// Test that an empty list of elements produces no edits.
|
||||
tests.add(checkNoEdits(<ImportedElements>[]));
|
||||
return Future.wait(tests);
|
||||
}
|
||||
}
|
|
@ -9,9 +9,10 @@ import 'get_assists_test.dart' as get_assists_test;
|
|||
import 'get_available_refactorings_test.dart'
|
||||
as get_available_refactorings_test;
|
||||
import 'get_fixes_test.dart' as get_fixes_test;
|
||||
import 'get_refactoring_test.dart' as get_refactoring_test;
|
||||
import 'get_postfix_completion_test.dart' as get_postfix_completion_test;
|
||||
import 'get_refactoring_test.dart' as get_refactoring_test;
|
||||
import 'get_statement_completion_test.dart' as get_statement_completion_test;
|
||||
import 'import_elements_test.dart' as import_elements_test;
|
||||
import 'is_postfix_completion_applicable_test.dart'
|
||||
as is_postfix_completion_applicable_test;
|
||||
import 'list_postfix_completion_templates_test.dart'
|
||||
|
@ -28,6 +29,7 @@ main() {
|
|||
get_refactoring_test.main();
|
||||
get_postfix_completion_test.main();
|
||||
get_statement_completion_test.main();
|
||||
import_elements_test.main();
|
||||
is_postfix_completion_applicable_test.main();
|
||||
list_postfix_completion_templates_test.main();
|
||||
organize_directives_test.main();
|
||||
|
|
|
@ -265,13 +265,6 @@ abstract class IntegrationTestMixin {
|
|||
*
|
||||
* The information about the elements that are referenced in the specified
|
||||
* region of the specified file that come from imported libraries.
|
||||
*
|
||||
* complete: bool
|
||||
*
|
||||
* True if all of the elements that are referenced in the specified region
|
||||
* are included in the list of elements. The list of elements will be
|
||||
* incomplete if there is an error in the specified region that prevents an
|
||||
* identifier from being resolved to a single element.
|
||||
*/
|
||||
Future<AnalysisGetImportedElementsResult> sendAnalysisGetImportedElements(
|
||||
String file, int offset, int length) async {
|
||||
|
@ -1625,6 +1618,11 @@ abstract class IntegrationTestMixin {
|
|||
* that all of the elements in the specified list of imported elements are
|
||||
* accessible within the library.
|
||||
*
|
||||
* If a request is made for a file that does not exist, or that is not
|
||||
* currently subject to analysis (e.g. because it is not associated with any
|
||||
* analysis root specified via analysis.setAnalysisRoots), an error of type
|
||||
* IMPORT_ELEMENTS_INVALID_FILE will be generated.
|
||||
*
|
||||
* Parameters
|
||||
*
|
||||
* file: FilePath
|
||||
|
@ -1641,14 +1639,6 @@ abstract class IntegrationTestMixin {
|
|||
*
|
||||
* The edit(s) to be applied in order to make the specified elements
|
||||
* accessible.
|
||||
*
|
||||
* complete: bool
|
||||
*
|
||||
* True if all of the elements that are to be made accessible would be
|
||||
* accessible if the edits were applied. The edits will not be complete,
|
||||
* for example, if one of the libraries cannot be referenced in the target
|
||||
* library or if one of the element names is already imported from a
|
||||
* different library.
|
||||
*/
|
||||
Future<EditImportElementsResult> sendEditImportElements(
|
||||
String file, List<ImportedElements> elements) async {
|
||||
|
|
|
@ -1030,6 +1030,7 @@ final Matcher isRequestError = new LazyMatcher(() => new MatchesJsonObject(
|
|||
* GET_IMPORTED_ELEMENTS_INVALID_FILE
|
||||
* GET_NAVIGATION_INVALID_FILE
|
||||
* GET_REACHABLE_SOURCES_INVALID_FILE
|
||||
* IMPORT_ELEMENTS_INVALID_FILE
|
||||
* INVALID_ANALYSIS_ROOT
|
||||
* INVALID_EXECUTION_CONTEXT
|
||||
* INVALID_FILE_PATH_FORMAT
|
||||
|
@ -1058,6 +1059,7 @@ final Matcher isRequestErrorCode = new MatchesEnum("RequestErrorCode", [
|
|||
"GET_IMPORTED_ELEMENTS_INVALID_FILE",
|
||||
"GET_NAVIGATION_INVALID_FILE",
|
||||
"GET_REACHABLE_SOURCES_INVALID_FILE",
|
||||
"IMPORT_ELEMENTS_INVALID_FILE",
|
||||
"INVALID_ANALYSIS_ROOT",
|
||||
"INVALID_EXECUTION_CONTEXT",
|
||||
"INVALID_FILE_PATH_FORMAT",
|
||||
|
@ -1312,12 +1314,11 @@ final Matcher isAnalysisGetImportedElementsParams = new LazyMatcher(() =>
|
|||
*
|
||||
* {
|
||||
* "elements": List<ImportedElements>
|
||||
* "complete": bool
|
||||
* }
|
||||
*/
|
||||
final Matcher isAnalysisGetImportedElementsResult = new LazyMatcher(() =>
|
||||
new MatchesJsonObject("analysis.getImportedElements result",
|
||||
{"elements": isListOf(isImportedElements), "complete": isBool}));
|
||||
{"elements": isListOf(isImportedElements)}));
|
||||
|
||||
/**
|
||||
* analysis.getLibraryDependencies params
|
||||
|
@ -1988,12 +1989,11 @@ final Matcher isEditImportElementsParams = new LazyMatcher(() =>
|
|||
*
|
||||
* {
|
||||
* "edits": List<SourceEdit>
|
||||
* "complete": bool
|
||||
* }
|
||||
*/
|
||||
final Matcher isEditImportElementsResult = new LazyMatcher(() =>
|
||||
new MatchesJsonObject("edit.importElements result",
|
||||
{"edits": isListOf(isSourceEdit), "complete": isBool}));
|
||||
new MatchesJsonObject(
|
||||
"edit.importElements result", {"edits": isListOf(isSourceEdit)}));
|
||||
|
||||
/**
|
||||
* edit.isPostfixCompletionApplicable params
|
||||
|
|
|
@ -502,6 +502,10 @@ public interface AnalysisServer {
|
|||
* Return a list of edits that would need to be applied in order to ensure that all of the elements
|
||||
* in the specified list of imported elements are accessible within the library.
|
||||
*
|
||||
* If a request is made for a file that does not exist, or that is not currently subject to
|
||||
* analysis (e.g. because it is not associated with any analysis root specified via
|
||||
* analysis.setAnalysisRoots), an error of type IMPORT_ELEMENTS_INVALID_FILE will be generated.
|
||||
*
|
||||
* @param file The file in which the specified elements are to be made accessible.
|
||||
* @param elements The elements to be made accessible in the specified file.
|
||||
*/
|
||||
|
|
|
@ -75,6 +75,12 @@ public class RequestErrorCode {
|
|||
*/
|
||||
public static final String GET_REACHABLE_SOURCES_INVALID_FILE = "GET_REACHABLE_SOURCES_INVALID_FILE";
|
||||
|
||||
/**
|
||||
* An "edit.importElements" request specified a FilePath that does not match a file currently
|
||||
* subject to analysis.
|
||||
*/
|
||||
public static final String IMPORT_ELEMENTS_INVALID_FILE = "IMPORT_ELEMENTS_INVALID_FILE";
|
||||
|
||||
/**
|
||||
* A path passed as an argument to a request (such as analysis.reanalyze) is required to be an
|
||||
* analysis root, but isn't.
|
||||
|
|
|
@ -475,15 +475,6 @@
|
|||
libraries.
|
||||
</p>
|
||||
</field>
|
||||
<field name="complete">
|
||||
<ref>bool</ref>
|
||||
<p>
|
||||
True if all of the elements that are referenced in the specified
|
||||
region are included in the list of elements. The list of elements will
|
||||
be incomplete if there is an error in the specified region that
|
||||
prevents an identifier from being resolved to a single element.
|
||||
</p>
|
||||
</field>
|
||||
</result>
|
||||
</request>
|
||||
<request method="getLibraryDependencies">
|
||||
|
@ -2083,6 +2074,12 @@
|
|||
that all of the elements in the specified list of imported elements are
|
||||
accessible within the library.
|
||||
</p>
|
||||
<p>
|
||||
If a request is made for a file that does not exist, or that is not
|
||||
currently subject to analysis (e.g. because it is not associated with any
|
||||
analysis root specified via analysis.setAnalysisRoots), an error of type
|
||||
<tt>IMPORT_ELEMENTS_INVALID_FILE</tt> will be generated.
|
||||
</p>
|
||||
<params>
|
||||
<field name="file">
|
||||
<ref>FilePath</ref>
|
||||
|
@ -2109,16 +2106,6 @@
|
|||
accessible.
|
||||
</p>
|
||||
</field>
|
||||
<field name="complete">
|
||||
<ref>bool</ref>
|
||||
<p>
|
||||
True if all of the elements that are to be made accessible would be
|
||||
accessible if the edits were applied. The edits will not be complete,
|
||||
for example, if one of the libraries cannot be referenced in the
|
||||
target library or if one of the element names is already imported from
|
||||
a different library.
|
||||
</p>
|
||||
</field>
|
||||
</result>
|
||||
</request>
|
||||
<request method="sortMembers">
|
||||
|
@ -3148,6 +3135,13 @@
|
|||
analysis.
|
||||
</p>
|
||||
</value>
|
||||
<value>
|
||||
<code>IMPORT_ELEMENTS_INVALID_FILE</code>
|
||||
<p>
|
||||
An "edit.importElements" request specified a FilePath that does not
|
||||
match a file currently subject to analysis.
|
||||
</p>
|
||||
</value>
|
||||
<value>
|
||||
<code>INVALID_ANALYSIS_ROOT</code>
|
||||
<p>
|
||||
|
|
Loading…
Reference in a new issue