mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:37:53 +00:00
Remove unused support for requesting token details
Change-Id: I9cc160d84e06b4b7be67e53962fe38c1430e74b2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180762 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
089ca8c1eb
commit
a00530b46f
|
@ -109,7 +109,7 @@ a:focus, a:hover {
|
|||
<body>
|
||||
<h1>Analysis Server API Specification</h1>
|
||||
<h1 style="color:#999999">Version
|
||||
1.32.2
|
||||
1.32.3
|
||||
</h1>
|
||||
<p>
|
||||
This document contains a specification of the API provided by the
|
||||
|
@ -236,13 +236,20 @@ a:focus, a:hover {
|
|||
ignoring the item or treating it with some default/fallback handling.
|
||||
</p>
|
||||
<h3>Changelog</h3>
|
||||
<h4>1.32.3</h4>
|
||||
<ul>
|
||||
<li>Removed the experimental <tt>completion.listTokenDetails</tt> request and
|
||||
the associated data types.</li>
|
||||
</ul>
|
||||
<h4>1.32.2</h4>
|
||||
<ul>
|
||||
<li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of comments.</li>
|
||||
<li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of
|
||||
comments.</li>
|
||||
</ul>
|
||||
<h4>1.32.1</h4>
|
||||
<ul>
|
||||
<li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt>.</li>
|
||||
<li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name
|
||||
completions in <tt>pubspec.yaml</tt>.</li>
|
||||
</ul>
|
||||
<h3>Domains</h3>
|
||||
<p>
|
||||
|
@ -1497,7 +1504,6 @@ a:focus, a:hover {
|
|||
|
||||
|
||||
|
||||
|
||||
<h3>Requests</h3><dl><dt class="request"><a name="request_completion.getSuggestions">completion.getSuggestions</a></dt><dd><div class="box"><pre>request: {
|
||||
"id": String
|
||||
"method": "completion.getSuggestions"
|
||||
|
@ -3054,7 +3060,6 @@ a:focus, a:hover {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
const String PROTOCOL_VERSION = '1.32.2';
|
||||
const String PROTOCOL_VERSION = '1.32.3';
|
||||
|
||||
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
|
||||
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
|
||||
|
@ -145,9 +145,6 @@ const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_FILE = 'file';
|
|||
const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_ID = 'id';
|
||||
const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_LABEL = 'label';
|
||||
const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_OFFSET = 'offset';
|
||||
const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS =
|
||||
'completion.listTokenDetails';
|
||||
const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS_FILE = 'file';
|
||||
const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS =
|
||||
'completion.registerLibraryPaths';
|
||||
const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS_PATHS = 'paths';
|
||||
|
@ -159,7 +156,6 @@ const String COMPLETION_RESPONSE_GET_SUGGESTIONS_ID = 'id';
|
|||
const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_CHANGE = 'change';
|
||||
const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_COMPLETION =
|
||||
'completion';
|
||||
const String COMPLETION_RESPONSE_LIST_TOKEN_DETAILS_TOKENS = 'tokens';
|
||||
const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
|
||||
const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
|
||||
const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
|
||||
|
|
|
@ -5886,168 +5886,6 @@ class CompletionGetSuggestionsResult implements ResponseResult {
|
|||
}
|
||||
}
|
||||
|
||||
/// completion.listTokenDetails params
|
||||
///
|
||||
/// {
|
||||
/// "file": FilePath
|
||||
/// }
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
class CompletionListTokenDetailsParams implements RequestParams {
|
||||
String _file;
|
||||
|
||||
/// The path to the file from which tokens should be returned.
|
||||
String get file => _file;
|
||||
|
||||
/// The path to the file from which tokens should be returned.
|
||||
set file(String value) {
|
||||
assert(value != null);
|
||||
_file = value;
|
||||
}
|
||||
|
||||
CompletionListTokenDetailsParams(String file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsParams.fromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json) {
|
||||
json ??= {};
|
||||
if (json is Map) {
|
||||
String file;
|
||||
if (json.containsKey('file')) {
|
||||
file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'file');
|
||||
}
|
||||
return CompletionListTokenDetailsParams(file);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(
|
||||
jsonPath, 'completion.listTokenDetails params', json);
|
||||
}
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsParams.fromRequest(Request request) {
|
||||
return CompletionListTokenDetailsParams.fromJson(
|
||||
RequestDecoder(request), 'params', request.params);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var result = <String, dynamic>{};
|
||||
result['file'] = file;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Request toRequest(String id) {
|
||||
return Request(id, 'completion.listTokenDetails', toJson());
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => json.encode(toJson());
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (other is CompletionListTokenDetailsParams) {
|
||||
return file == other.file;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, file.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/// completion.listTokenDetails result
|
||||
///
|
||||
/// {
|
||||
/// "tokens": List<TokenDetails>
|
||||
/// }
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
class CompletionListTokenDetailsResult implements ResponseResult {
|
||||
List<TokenDetails> _tokens;
|
||||
|
||||
/// A list of the file's scanned tokens including analysis information about
|
||||
/// them.
|
||||
List<TokenDetails> get tokens => _tokens;
|
||||
|
||||
/// A list of the file's scanned tokens including analysis information about
|
||||
/// them.
|
||||
set tokens(List<TokenDetails> value) {
|
||||
assert(value != null);
|
||||
_tokens = value;
|
||||
}
|
||||
|
||||
CompletionListTokenDetailsResult(List<TokenDetails> tokens) {
|
||||
this.tokens = tokens;
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsResult.fromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json) {
|
||||
json ??= {};
|
||||
if (json is Map) {
|
||||
List<TokenDetails> tokens;
|
||||
if (json.containsKey('tokens')) {
|
||||
tokens = jsonDecoder.decodeList(
|
||||
jsonPath + '.tokens',
|
||||
json['tokens'],
|
||||
(String jsonPath, Object json) =>
|
||||
TokenDetails.fromJson(jsonDecoder, jsonPath, json));
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'tokens');
|
||||
}
|
||||
return CompletionListTokenDetailsResult(tokens);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(
|
||||
jsonPath, 'completion.listTokenDetails result', json);
|
||||
}
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsResult.fromResponse(Response response) {
|
||||
return CompletionListTokenDetailsResult.fromJson(
|
||||
ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
|
||||
'result',
|
||||
response.result);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var result = <String, dynamic>{};
|
||||
result['tokens'] =
|
||||
tokens.map((TokenDetails value) => value.toJson()).toList();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Response toResponse(String id) {
|
||||
return Response(id, result: toJson());
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => json.encode(toJson());
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (other is CompletionListTokenDetailsResult) {
|
||||
return listEqual(
|
||||
tokens, other.tokens, (TokenDetails a, TokenDetails b) => a == b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, tokens.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/// completion.registerLibraryPaths params
|
||||
///
|
||||
/// {
|
||||
|
@ -21345,151 +21183,6 @@ class ServerStatusParams implements HasToJson {
|
|||
}
|
||||
}
|
||||
|
||||
/// TokenDetails
|
||||
///
|
||||
/// {
|
||||
/// "lexeme": String
|
||||
/// "type": optional String
|
||||
/// "validElementKinds": optional List<String>
|
||||
/// "offset": int
|
||||
/// }
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
class TokenDetails implements HasToJson {
|
||||
String _lexeme;
|
||||
|
||||
String _type;
|
||||
|
||||
List<String> _validElementKinds;
|
||||
|
||||
int _offset;
|
||||
|
||||
/// The token's lexeme.
|
||||
String get lexeme => _lexeme;
|
||||
|
||||
/// The token's lexeme.
|
||||
set lexeme(String value) {
|
||||
assert(value != null);
|
||||
_lexeme = value;
|
||||
}
|
||||
|
||||
/// A unique id for the type of the identifier. Omitted if the token is not
|
||||
/// an identifier in a reference position.
|
||||
String get type => _type;
|
||||
|
||||
/// A unique id for the type of the identifier. Omitted if the token is not
|
||||
/// an identifier in a reference position.
|
||||
set type(String value) {
|
||||
_type = value;
|
||||
}
|
||||
|
||||
/// An indication of whether this token is in a declaration or reference
|
||||
/// position. (If no other purpose is found for this field then it should be
|
||||
/// renamed and converted to a boolean value.) Omitted if the token is not an
|
||||
/// identifier.
|
||||
List<String> get validElementKinds => _validElementKinds;
|
||||
|
||||
/// An indication of whether this token is in a declaration or reference
|
||||
/// position. (If no other purpose is found for this field then it should be
|
||||
/// renamed and converted to a boolean value.) Omitted if the token is not an
|
||||
/// identifier.
|
||||
set validElementKinds(List<String> value) {
|
||||
_validElementKinds = value;
|
||||
}
|
||||
|
||||
/// The offset of the first character of the token in the file which it
|
||||
/// originated from.
|
||||
int get offset => _offset;
|
||||
|
||||
/// The offset of the first character of the token in the file which it
|
||||
/// originated from.
|
||||
set offset(int value) {
|
||||
assert(value != null);
|
||||
_offset = value;
|
||||
}
|
||||
|
||||
TokenDetails(String lexeme, int offset,
|
||||
{String type, List<String> validElementKinds}) {
|
||||
this.lexeme = lexeme;
|
||||
this.type = type;
|
||||
this.validElementKinds = validElementKinds;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
factory TokenDetails.fromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json) {
|
||||
json ??= {};
|
||||
if (json is Map) {
|
||||
String lexeme;
|
||||
if (json.containsKey('lexeme')) {
|
||||
lexeme = jsonDecoder.decodeString(jsonPath + '.lexeme', json['lexeme']);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'lexeme');
|
||||
}
|
||||
String type;
|
||||
if (json.containsKey('type')) {
|
||||
type = jsonDecoder.decodeString(jsonPath + '.type', json['type']);
|
||||
}
|
||||
List<String> validElementKinds;
|
||||
if (json.containsKey('validElementKinds')) {
|
||||
validElementKinds = jsonDecoder.decodeList(
|
||||
jsonPath + '.validElementKinds',
|
||||
json['validElementKinds'],
|
||||
jsonDecoder.decodeString);
|
||||
}
|
||||
int offset;
|
||||
if (json.containsKey('offset')) {
|
||||
offset = jsonDecoder.decodeInt(jsonPath + '.offset', json['offset']);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'offset');
|
||||
}
|
||||
return TokenDetails(lexeme, offset,
|
||||
type: type, validElementKinds: validElementKinds);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'TokenDetails', json);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var result = <String, dynamic>{};
|
||||
result['lexeme'] = lexeme;
|
||||
if (type != null) {
|
||||
result['type'] = type;
|
||||
}
|
||||
if (validElementKinds != null) {
|
||||
result['validElementKinds'] = validElementKinds;
|
||||
}
|
||||
result['offset'] = offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => json.encode(toJson());
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (other is TokenDetails) {
|
||||
return lexeme == other.lexeme &&
|
||||
type == other.type &&
|
||||
listEqual(validElementKinds, other.validElementKinds,
|
||||
(String a, String b) => a == b) &&
|
||||
offset == other.offset;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, lexeme.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, type.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, validElementKinds.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, offset.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/// TypeHierarchyItem
|
||||
///
|
||||
/// {
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:analysis_server/src/provisional/completion/completion_core.dart'
|
|||
import 'package:analysis_server/src/services/completion/completion_core.dart';
|
||||
import 'package:analysis_server/src/services/completion/completion_performance.dart';
|
||||
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
|
||||
import 'package:analysis_server/src/services/completion/token_details/token_detail_builder.dart';
|
||||
import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
|
||||
import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
|
||||
import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
|
||||
|
@ -251,9 +250,6 @@ class CompletionDomainHandler extends AbstractRequestHandler {
|
|||
} else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
|
||||
processRequest(request);
|
||||
return Response.DELAYED_RESPONSE;
|
||||
} else if (requestName == COMPLETION_REQUEST_LIST_TOKEN_DETAILS) {
|
||||
listTokenDetails(request);
|
||||
return Response.DELAYED_RESPONSE;
|
||||
} else if (requestName == COMPLETION_REQUEST_SET_SUBSCRIPTIONS) {
|
||||
return setSubscriptions(request);
|
||||
}
|
||||
|
@ -273,40 +269,6 @@ class CompletionDomainHandler extends AbstractRequestHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/// Process a `completion.listTokenDetails` request.
|
||||
Future<void> listTokenDetails(Request request) async {
|
||||
var params = CompletionListTokenDetailsParams.fromRequest(request);
|
||||
|
||||
var file = params.file;
|
||||
if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var analysisDriver = server.getAnalysisDriver(file);
|
||||
if (analysisDriver == null) {
|
||||
server.sendResponse(Response.invalidParameter(
|
||||
request,
|
||||
'file',
|
||||
'File is not being analyzed: $file',
|
||||
));
|
||||
}
|
||||
var session = analysisDriver.currentSession;
|
||||
var result = await session.getResolvedUnit(file);
|
||||
if (result.state != ResultState.VALID) {
|
||||
server.sendResponse(Response.invalidParameter(
|
||||
request,
|
||||
'file',
|
||||
'File does not exist or cannot be read: $file',
|
||||
));
|
||||
}
|
||||
|
||||
var builder = TokenDetailBuilder();
|
||||
builder.visitNode(result.unit);
|
||||
server.sendResponse(
|
||||
CompletionListTokenDetailsResult(builder.details).toResponse(request.id),
|
||||
);
|
||||
}
|
||||
|
||||
/// Process a `completion.getSuggestions` request.
|
||||
Future<void> processRequest(Request request) async {
|
||||
performance = CompletionPerformance();
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
// Copyright (c) 2019, 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';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
|
||||
/// An object used to build the details for each token in the code being
|
||||
/// analyzed.
|
||||
class TokenDetailBuilder {
|
||||
/// The list of details that were built.
|
||||
List<TokenDetails> details = [];
|
||||
|
||||
/// Initialize a newly created builder.
|
||||
TokenDetailBuilder();
|
||||
|
||||
/// Visit a [node] in the AST structure to build details for all of the tokens
|
||||
/// contained by that node.
|
||||
void visitNode(AstNode node) {
|
||||
for (var entity in node.childEntities) {
|
||||
if (entity is Token) {
|
||||
_createDetails(entity, null, null);
|
||||
} else if (entity is SimpleIdentifier) {
|
||||
String type;
|
||||
var typeNameNode = _getTypeName(entity);
|
||||
if (typeNameNode != null) {
|
||||
var typeStr = _typeStr(typeNameNode.type);
|
||||
type = 'dart:core;Type<$typeStr>';
|
||||
} else if (entity.staticElement is ClassElement) {
|
||||
type = 'Type';
|
||||
} else if (entity.inDeclarationContext()) {
|
||||
var element = entity.staticElement;
|
||||
if (element is FunctionElement) {
|
||||
type = _typeStr(element.type);
|
||||
} else if (element is MethodElement) {
|
||||
type = _typeStr(element.type);
|
||||
} else if (element is VariableElement) {
|
||||
type = _typeStr(element.type);
|
||||
}
|
||||
} else {
|
||||
type = _typeStr(entity.staticType);
|
||||
}
|
||||
var kinds = <String>[];
|
||||
if (entity.inDeclarationContext()) {
|
||||
kinds.add('declaration');
|
||||
} else {
|
||||
kinds.add('reference');
|
||||
}
|
||||
_createDetails(entity.token, type, kinds);
|
||||
} else if (entity is BooleanLiteral) {
|
||||
_createDetails(entity.literal, _typeStr(entity.staticType), null);
|
||||
} else if (entity is DoubleLiteral) {
|
||||
_createDetails(entity.literal, _typeStr(entity.staticType), null);
|
||||
} else if (entity is IntegerLiteral) {
|
||||
_createDetails(entity.literal, _typeStr(entity.staticType), null);
|
||||
} else if (entity is SimpleStringLiteral) {
|
||||
_createDetails(entity.literal, _typeStr(entity.staticType), null);
|
||||
} else if (entity is Comment) {
|
||||
// Ignore comments and the references within them.
|
||||
} else if (entity is AstNode) {
|
||||
visitNode(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the details for a single [token], using the given list of [kinds].
|
||||
void _createDetails(Token token, String type, List<String> kinds) {
|
||||
details.add(TokenDetails(token.lexeme, token.offset,
|
||||
type: type, validElementKinds: kinds));
|
||||
}
|
||||
|
||||
/// Return the [TypeName] with the [identifier].
|
||||
TypeName _getTypeName(SimpleIdentifier identifier) {
|
||||
var parent = identifier.parent;
|
||||
if (parent is TypeName && identifier == parent.name) {
|
||||
return parent;
|
||||
} else if (parent is PrefixedIdentifier &&
|
||||
parent.identifier == identifier) {
|
||||
var parent2 = parent.parent;
|
||||
if (parent2 is TypeName && parent == parent2.name) {
|
||||
return parent2;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Return a unique identifier for the [type].
|
||||
String _typeStr(DartType type) {
|
||||
var buffer = StringBuffer();
|
||||
_writeType(buffer, type);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/// Return a unique identifier for the type of the given [expression].
|
||||
void _writeType(StringBuffer buffer, DartType type) {
|
||||
if (type == null) {
|
||||
// This should never happen if the AST has been resolved.
|
||||
buffer.write('dynamic');
|
||||
} else if (type is FunctionType) {
|
||||
_writeType(buffer, type.returnType);
|
||||
buffer.write(' Function(');
|
||||
var first = true;
|
||||
for (var parameter in type.parameters) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
buffer.write(', ');
|
||||
}
|
||||
_writeType(buffer, parameter.type);
|
||||
}
|
||||
buffer.write(')');
|
||||
} else if (type is InterfaceType) {
|
||||
Element element = type.element;
|
||||
if (element == null || element.isSynthetic) {
|
||||
assert(false, 'untested branch may print nullable types wrong');
|
||||
// TODO: test this, use the the library's nullability (not tracked yet).
|
||||
buffer.write(type.getDisplayString(withNullability: false));
|
||||
} else {
|
||||
// String uri = element.library.source.uri.toString();
|
||||
var name = element.name;
|
||||
if (element is ClassMemberElement) {
|
||||
var className = element.enclosingElement.name;
|
||||
// TODO(brianwilkerson) Figure out why the uri is a file: URI when it
|
||||
// ought to be a package: URI and restore the code below to include
|
||||
// the URI in the string.
|
||||
// buffer.write('$uri;$className;$name');
|
||||
buffer.write('$className;$name');
|
||||
} else {
|
||||
// buffer.write('$uri;$name');
|
||||
buffer.write('$name');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handle `void` and `dynamic`. Nullability doesn't affect this.
|
||||
assert(type.getDisplayString(withNullability: false) ==
|
||||
type.getDisplayString(withNullability: true));
|
||||
buffer.write(type.getDisplayString(withNullability: false));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,10 +7,10 @@ import 'dart:collection';
|
|||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'domain_completion_test.dart';
|
||||
import 'domain_completion_util.dart';
|
||||
|
||||
/// A base class for classes containing completion tests.
|
||||
class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
|
||||
class CompletionTestCase extends AbstractCompletionDomainTest {
|
||||
static const String CURSOR_MARKER = '!';
|
||||
|
||||
List get suggestedCompletions => suggestions
|
||||
|
|
|
@ -19,7 +19,6 @@ import 'mocks.dart';
|
|||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest);
|
||||
defineReflectiveTests(CompletionDomainHandlerListTokenDetailsTest);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -778,419 +777,6 @@ class B extends A {m() {^}}
|
|||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class CompletionDomainHandlerListTokenDetailsTest
|
||||
extends AbstractCompletionDomainTest {
|
||||
String testFileUri;
|
||||
|
||||
Future<void> expectTokens(String content, List<TokenDetails> expected) async {
|
||||
newFile(testFile, content: content);
|
||||
var request = CompletionListTokenDetailsParams(testFile).toRequest('0');
|
||||
var response = await waitResponse(request);
|
||||
List<Map<String, dynamic>> tokens = response.result['tokens'];
|
||||
_compareTokens(tokens, expected);
|
||||
}
|
||||
|
||||
@override
|
||||
void setUp() {
|
||||
super.setUp();
|
||||
testFileUri = toUriStr(testFile);
|
||||
}
|
||||
|
||||
Future<void> test_classDeclaration() async {
|
||||
await expectTokens('''
|
||||
class A {}
|
||||
class B extends A {}
|
||||
class C implements B {}
|
||||
class D with C {}
|
||||
''', [
|
||||
token('class', 0, null, null),
|
||||
token('A', 6, 'Type',
|
||||
['declaration']), //token('A', 6, 'dart:core;Type', ['declaration']),
|
||||
token('{', 8, null, null),
|
||||
token('}', 9, null, null),
|
||||
token('class', 11, null, null),
|
||||
token('B', 17, 'Type',
|
||||
['declaration']), //token('B', 17, 'dart:core;Type', ['declaration']),
|
||||
token('extends', 19, null, null),
|
||||
token('A', 27, 'dart:core;Type<A>', [
|
||||
'reference'
|
||||
]), //token('A', 27, 'dart:core;Type<$testFileUri;A>', ['reference']),
|
||||
token('{', 29, null, null),
|
||||
token('}', 30, null, null),
|
||||
token('class', 32, null, null),
|
||||
token('C', 38, 'Type',
|
||||
['declaration']), //token('C', 38, 'dart:core;Type', ['declaration']),
|
||||
token('implements', 40, null, null),
|
||||
token('B', 51, 'dart:core;Type<B>', [
|
||||
'reference'
|
||||
]), //token('B', 51, 'dart:core;Type<$testFileUri;B>', ['reference']),
|
||||
token('{', 53, null, null),
|
||||
token('}', 54, null, null),
|
||||
token('class', 56, null, null),
|
||||
token('D', 62, 'Type',
|
||||
['declaration']), //token('D', 62, 'dart:core;Type', ['declaration']),
|
||||
token('with', 64, null, null),
|
||||
token('C', 69, 'dart:core;Type<C>', [
|
||||
'reference'
|
||||
]), //token('C', 69, 'dart:core;Type<$testFileUri;C>', ['reference']),
|
||||
token('{', 71, null, null),
|
||||
token('}', 72, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_genericType() async {
|
||||
await expectTokens('''
|
||||
List<int> x = null;
|
||||
''', [
|
||||
token('List', 0, 'dart:core;Type<List>', [
|
||||
'reference'
|
||||
]), //token('List', 0, 'dart:core;Type<dart:core;List>', ['reference']),
|
||||
token('<', 4, null, null),
|
||||
token('int', 5, 'dart:core;Type<int>', [
|
||||
'reference'
|
||||
]), //token('int', 5, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('>', 8, null, null),
|
||||
token('x', 10, 'List',
|
||||
['declaration']), //token('x', 10, 'dart:core;List', ['declaration']),
|
||||
token('=', 12, null, null),
|
||||
token('null', 14, null, null),
|
||||
token(';', 18, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_getterInvocation() async {
|
||||
await expectTokens('''
|
||||
var x = 'a'.length;
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'int',
|
||||
['declaration']), //token('x', 4, 'dart:core;int', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token("'a'", 8, 'String',
|
||||
null), //token("'a'", 8, 'dart:core;String', null),
|
||||
token('.', 11, null, null),
|
||||
token('length', 12, 'int',
|
||||
['reference']), //token('length', 12, 'dart:core;int', ['reference']),
|
||||
token(';', 18, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_bool() async {
|
||||
await expectTokens('''
|
||||
var x = true;
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'bool',
|
||||
['declaration']), //token('x', 4, 'dart:core;bool', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token(
|
||||
'true', 8, 'bool', null), //token('true', 8, 'dart:core;bool', null),
|
||||
token(';', 12, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_double() async {
|
||||
await expectTokens('''
|
||||
var x = 3.4;
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'double', [
|
||||
'declaration'
|
||||
]), //token('x', 4, 'dart:core;double', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token('3.4', 8, 'double',
|
||||
null), //token('3.4', 8, 'dart:core;double', null),
|
||||
token(';', 11, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_int() async {
|
||||
await expectTokens('''
|
||||
var x = 7;
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'int',
|
||||
['declaration']), //token('x', 4, 'dart:core;int', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token('7', 8, 'int', null), //token('7', 8, 'dart:core;int', null),
|
||||
token(';', 9, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_list() async {
|
||||
await expectTokens('''
|
||||
var x = <int>[];
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'List',
|
||||
['declaration']), //token('x', 4, 'dart:core;List', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token('<', 8, null, null),
|
||||
token('int', 9, 'dart:core;Type<int>', [
|
||||
'reference'
|
||||
]), //token("int", 9, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('>', 12, null, null),
|
||||
token('[', 13, null, null),
|
||||
token(']', 14, null, null),
|
||||
token(';', 15, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_map() async {
|
||||
await expectTokens('''
|
||||
var x = <int, int>{};
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'Map',
|
||||
['declaration']), //token('x', 4, 'dart:core;Map', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token('<', 8, null, null),
|
||||
token('int', 9, 'dart:core;Type<int>', [
|
||||
'reference'
|
||||
]), //token("int", 9, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
// token(',', null, null),
|
||||
token('int', 14, 'dart:core;Type<int>', [
|
||||
'reference'
|
||||
]), //token("int", 14, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('>', 17, null, null),
|
||||
token('{', 18, null, null),
|
||||
token('}', 19, null, null),
|
||||
token(';', 20, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_null() async {
|
||||
await expectTokens('''
|
||||
var x = null;
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'dynamic', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token('null', 8, null, null),
|
||||
token(';', 12, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_set() async {
|
||||
await expectTokens('''
|
||||
var x = <int>{};
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'Set',
|
||||
['declaration']), //token('x', 4, 'dart:core;Set', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token('<', 8, null, null),
|
||||
token('int', 9, 'dart:core;Type<int>', [
|
||||
'reference'
|
||||
]), //token("int", 9, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('>', 12, null, null),
|
||||
token('{', 13, null, null),
|
||||
token('}', 14, null, null),
|
||||
token(';', 15, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_literal_string() async {
|
||||
await expectTokens('''
|
||||
var x = 'a';
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'String', [
|
||||
'declaration'
|
||||
]), //token('x', 4, 'dart:core;String', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token("'a'", 8, 'String',
|
||||
null), //token("'a'", 8, 'dart:core;String', null),
|
||||
token(';', 11, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_methodDeclaration() async {
|
||||
await expectTokens('''
|
||||
class A {
|
||||
String c(int x, int y) {}
|
||||
}
|
||||
''', [
|
||||
token('class', 0, null, null),
|
||||
token('A', 6, 'Type', ['declaration']),
|
||||
//token('A', 6, 'dart:core;Type', ['declaration']),
|
||||
token('{', 8, null, null),
|
||||
token('String', 12, 'dart:core;Type<String>', ['reference']),
|
||||
//token('String', 12, 'dart:core;Type<dart:core;String>', ['reference']),
|
||||
token('c', 19, 'String Function(int, int)',
|
||||
//'dart:core;String Function(dart:core;int, dart:core;int)',
|
||||
['declaration']),
|
||||
token('(', 20, null, null),
|
||||
token('int', 21, 'dart:core;Type<int>', ['reference']),
|
||||
//token('int', 21, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('x', 25, 'int', ['declaration']),
|
||||
//token('x', 25, 'dart:core;int', ['declaration']),
|
||||
// token(',', null, null),
|
||||
token('int', 28, 'dart:core;Type<int>', ['reference']),
|
||||
//token('int', 28, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('y', 32, 'int', ['declaration']),
|
||||
//token('y', 32, 'dart:core;int', ['declaration']),
|
||||
token(')', 33, null, null),
|
||||
token('{', 35, null, null),
|
||||
token('}', 36, null, null),
|
||||
token('}', 38, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_methodInvocation() async {
|
||||
await expectTokens('''
|
||||
var x = 'radar'.indexOf('r', 1);
|
||||
''', [
|
||||
token('var', 0, null, null),
|
||||
token('x', 4, 'int',
|
||||
['declaration']), //token('x', 4, 'dart:core;int', ['declaration']),
|
||||
token('=', 6, null, null),
|
||||
token("'radar'", 8, 'String',
|
||||
null), //token("'radar'", 8, 'dart:core;String', null),
|
||||
token('.', 15, null, null),
|
||||
token('indexOf', 16, 'int Function(Pattern, int)',
|
||||
//'dart:core;int Function(dart:core;Pattern, dart:core;int)',
|
||||
['reference']),
|
||||
token('(', 23, null, null),
|
||||
token("'r'", 24, 'String',
|
||||
null), //token("'r'", 24, 'dart:core;String', null),
|
||||
// token(',', null, null),
|
||||
token('1', 29, 'int', null), //token('1', 29, 'dart:core;int', null),
|
||||
token(')', 30, null, null),
|
||||
token(';', 31, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_mixinDeclaration() async {
|
||||
await expectTokens('''
|
||||
class A {}
|
||||
class B {}
|
||||
mixin D on A implements B {}
|
||||
''', [
|
||||
token('class', 0, null, null),
|
||||
token('A', 6, 'Type',
|
||||
['declaration']), //token('A', 6, 'dart:core;Type', ['declaration']),
|
||||
token('{', 8, null, null),
|
||||
token('}', 9, null, null),
|
||||
token('class', 11, null, null),
|
||||
token('B', 17, 'Type',
|
||||
['declaration']), //token('B', 17, 'dart:core;Type', ['declaration']),
|
||||
token('{', 19, null, null),
|
||||
token('}', 20, null, null),
|
||||
token('mixin', 22, null, null),
|
||||
token('D', 28, 'Type',
|
||||
['declaration']), //token('D', 28, 'dart:core;Type', ['declaration']),
|
||||
token('on', 30, null, null),
|
||||
token('A', 33, 'dart:core;Type<A>', [
|
||||
'reference'
|
||||
]), //token('A', 33, 'dart:core;Type<$testFileUri;A>', ['reference']),
|
||||
token('implements', 35, null, null),
|
||||
token('B', 46, 'dart:core;Type<B>', [
|
||||
'reference'
|
||||
]), //token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
|
||||
token('{', 48, null, null),
|
||||
token('}', 49, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_parameterReference() async {
|
||||
await expectTokens('''
|
||||
int f(int p) {
|
||||
return p;
|
||||
}
|
||||
''', [
|
||||
token('int', 0, 'dart:core;Type<int>', ['reference']),
|
||||
//token('int', 0, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('f', 4, 'int Function(int)', ['declaration']),
|
||||
//token('f', 4, 'dart:core;int Function(dart:core;int)', ['declaration']),
|
||||
token('(', 5, null, null),
|
||||
token('int', 6, 'dart:core;Type<int>', ['reference']),
|
||||
//token('int', 6, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('p', 10, 'int', ['declaration']),
|
||||
//token('p', 10, 'dart:core;int', ['declaration']),
|
||||
token(')', 11, null, null),
|
||||
token('{', 13, null, null),
|
||||
token('return', 17, null, null),
|
||||
token('p', 24, 'int', ['reference']),
|
||||
//token('p', 24, 'dart:core;int', ['reference']),
|
||||
token(';', 25, null, null),
|
||||
token('}', 27, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_topLevelVariable_withDocComment() async {
|
||||
await expectTokens('''
|
||||
/// Doc comment [x] with reference.
|
||||
int x;
|
||||
''', [
|
||||
token('int', 36, 'dart:core;Type<int>', [
|
||||
'reference'
|
||||
]), //token('int', 36, 'dart:core;Type<dart:core;int>', ['reference']),
|
||||
token('x', 40, 'int',
|
||||
['declaration']), //token('x', 40, 'dart:core;int', ['declaration']),
|
||||
token(';', 41, null, null),
|
||||
]);
|
||||
}
|
||||
|
||||
TokenDetails token(
|
||||
String lexeme, int offset, String type, List<String> kinds) {
|
||||
return TokenDetails(lexeme, offset, type: type, validElementKinds: kinds);
|
||||
}
|
||||
|
||||
void _compareTokens(List<Map<String, dynamic>> actualTokens,
|
||||
List<TokenDetails> expectedTokens) {
|
||||
var length = expectedTokens.length;
|
||||
expect(actualTokens, hasLength(length));
|
||||
var errors = <String>[];
|
||||
for (var i = 0; i < length; i++) {
|
||||
var actual = actualTokens[i];
|
||||
var expected = expectedTokens[i];
|
||||
if (actual['lexeme'] != expected.lexeme) {
|
||||
errors.add('Lexeme at $i: '
|
||||
'expected "${expected.lexeme}", '
|
||||
'actual "${actual['lexeme']}"');
|
||||
}
|
||||
if (actual['offset'] != expected.offset) {
|
||||
errors.add('Offset at $i: ("${expected.lexeme}"): '
|
||||
'expected "${expected.offset}", '
|
||||
'actual "${actual['offset']}"');
|
||||
}
|
||||
if (actual['type'] != expected.type) {
|
||||
errors.add('Type at $i ("${expected.lexeme}"): '
|
||||
'expected "${expected.type}", '
|
||||
'actual "${actual['type']}"');
|
||||
}
|
||||
if (_differentKinds(
|
||||
actual['validElementKinds'], expected.validElementKinds)) {
|
||||
errors.add('Kinds at $i ("${expected.lexeme}"): '
|
||||
'expected "${expected.validElementKinds}", '
|
||||
'actual "${actual['validElementKinds']}"');
|
||||
}
|
||||
}
|
||||
expect(errors, isEmpty);
|
||||
}
|
||||
|
||||
/// Return `true` if the two lists of kinds are different.
|
||||
bool _differentKinds(List<String> actual, List<String> expected) {
|
||||
if (actual == null) {
|
||||
return expected != null;
|
||||
} else if (expected == null) {
|
||||
return true;
|
||||
}
|
||||
var expectedLength = expected.length;
|
||||
if (actual.length != expectedLength) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0; i < expectedLength; i++) {
|
||||
if (actual[i] != expected[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class MockRelevancySorter implements DartContributionSorter {
|
||||
bool enabled = true;
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import 'postfix_completion_test.dart' as postfix_completion;
|
|||
import 'refactoring_test.dart' as refactoring;
|
||||
import 'sort_members_test.dart' as sort_members;
|
||||
import 'statement_completion_test.dart' as statement_completion;
|
||||
import 'token_details_test.dart' as token_details;
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
|
@ -26,6 +25,5 @@ void main() {
|
|||
refactoring.main();
|
||||
sort_members.main();
|
||||
statement_completion.main();
|
||||
token_details.main();
|
||||
}, name: 'edit');
|
||||
}
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) 2019, 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:analysis_server/src/domain_completion.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../analysis_abstract.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(CompletionListTokenDetailsTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class CompletionListTokenDetailsTest extends AbstractAnalysisTest {
|
||||
CompletionDomainHandler completionHandler;
|
||||
|
||||
Future<CompletionListTokenDetailsResult> getTokenDetails() async {
|
||||
var params = CompletionListTokenDetailsParams(testFile);
|
||||
await completionHandler.listTokenDetails(params.toRequest('0'));
|
||||
var response = await serverChannel.responseController.stream.first;
|
||||
return CompletionListTokenDetailsResult.fromResponse(response);
|
||||
}
|
||||
|
||||
@override
|
||||
void setUp() {
|
||||
super.setUp();
|
||||
completionHandler = CompletionDomainHandler(server);
|
||||
}
|
||||
|
||||
Future<void> test_packageUri() async {
|
||||
newFile('/project/.packages', content: '''
|
||||
project:lib/
|
||||
''');
|
||||
newFile('/project/lib/c.dart', content: '''
|
||||
class C {}
|
||||
''');
|
||||
addTestFile('''
|
||||
import 'package:project/c.dart';
|
||||
|
||||
C c;
|
||||
''');
|
||||
createProject();
|
||||
var result = await getTokenDetails();
|
||||
var tokens = result.tokens;
|
||||
expect(tokens, hasLength(6));
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) 2019, 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:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../support/integration_tests.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ListTokenDetailsTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ListTokenDetailsTest extends AbstractAnalysisServerIntegrationTest {
|
||||
String testPackagePath;
|
||||
|
||||
@override
|
||||
Future setUp() async {
|
||||
await super.setUp();
|
||||
testPackagePath = path.join(sourceDirectory.path, 'test_package');
|
||||
}
|
||||
|
||||
@override
|
||||
Future standardAnalysisSetup({bool subscribeStatus = true}) {
|
||||
var futures = <Future>[];
|
||||
if (subscribeStatus) {
|
||||
futures.add(sendServerSetSubscriptions([ServerService.STATUS]));
|
||||
}
|
||||
futures.add(sendAnalysisSetAnalysisRoots([testPackagePath], []));
|
||||
return Future.wait(futures);
|
||||
}
|
||||
|
||||
Future<void> test_getSuggestions() async {
|
||||
var aPath = path.join(sourceDirectory.path, 'a');
|
||||
var aLibPath = path.join(aPath, 'lib');
|
||||
writeFile(path.join(aLibPath, 'a.dart'), '''
|
||||
class A {}
|
||||
''');
|
||||
writeFile(path.join(testPackagePath, '.packages'), '''
|
||||
a:file://${path.toUri(aLibPath)}
|
||||
test_package:lib/
|
||||
''');
|
||||
var testFilePath = path.join(testPackagePath, 'lib', 'test.dart');
|
||||
writeFile(testFilePath, '''
|
||||
import 'package:a/a.dart';
|
||||
class B {}
|
||||
String f(A a, B b) => a.toString() + b.toString();
|
||||
''');
|
||||
await standardAnalysisSetup();
|
||||
await analysisFinished;
|
||||
|
||||
var result = await sendCompletionListTokenDetails(testFilePath);
|
||||
expect(result, isNotNull);
|
||||
}
|
||||
}
|
|
@ -5,11 +5,9 @@
|
|||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'get_suggestions_test.dart' as get_suggestions;
|
||||
import 'list_token_details_test.dart' as list_token_details;
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
get_suggestions.main();
|
||||
list_token_details.main();
|
||||
}, name: 'completion');
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ server calls. This file is validated by `coverage_test.dart`.
|
|||
- [ ] completion.existingImports
|
||||
- [ ] completion.getSuggestionDetails
|
||||
- [x] completion.getSuggestions
|
||||
- [x] completion.listTokenDetails
|
||||
- [ ] completion.registerLibraryPaths
|
||||
- [ ] completion.results
|
||||
- [ ] completion.setSubscriptions
|
||||
|
|
|
@ -1046,30 +1046,6 @@ abstract class IntegrationTestMixin {
|
|||
decoder, 'result', result);
|
||||
}
|
||||
|
||||
/// Inspect analysis server's knowledge about all of a file's tokens
|
||||
/// including their lexeme, type, and what element kinds would have been
|
||||
/// appropriate for the token's program location.
|
||||
///
|
||||
/// Parameters
|
||||
///
|
||||
/// file: FilePath
|
||||
///
|
||||
/// The path to the file from which tokens should be returned.
|
||||
///
|
||||
/// Returns
|
||||
///
|
||||
/// tokens: List<TokenDetails>
|
||||
///
|
||||
/// A list of the file's scanned tokens including analysis information
|
||||
/// about them.
|
||||
Future<CompletionListTokenDetailsResult> sendCompletionListTokenDetails(
|
||||
String file) async {
|
||||
var params = CompletionListTokenDetailsParams(file).toJson();
|
||||
var result = await server.send('completion.listTokenDetails', params);
|
||||
var decoder = ResponseDecoder(null);
|
||||
return CompletionListTokenDetailsResult.fromJson(decoder, 'result', result);
|
||||
}
|
||||
|
||||
/// Reports the completion suggestions that should be presented to the user.
|
||||
/// The set of suggestions included in the notification is always a complete
|
||||
/// list that supersedes any previously reported suggestions.
|
||||
|
|
|
@ -1625,23 +1625,6 @@ final Matcher isSourceFileEdit = LazyMatcher(() => MatchesJsonObject(
|
|||
'SourceFileEdit',
|
||||
{'file': isFilePath, 'fileStamp': isInt, 'edits': isListOf(isSourceEdit)}));
|
||||
|
||||
/// TokenDetails
|
||||
///
|
||||
/// {
|
||||
/// "lexeme": String
|
||||
/// "type": optional String
|
||||
/// "validElementKinds": optional List<String>
|
||||
/// "offset": int
|
||||
/// }
|
||||
final Matcher isTokenDetails = LazyMatcher(() => MatchesJsonObject(
|
||||
'TokenDetails', {
|
||||
'lexeme': isString,
|
||||
'offset': isInt
|
||||
}, optionalFields: {
|
||||
'type': isString,
|
||||
'validElementKinds': isListOf(isString)
|
||||
}));
|
||||
|
||||
/// TypeHierarchyItem
|
||||
///
|
||||
/// {
|
||||
|
@ -2134,24 +2117,6 @@ final Matcher isCompletionGetSuggestionsResult = LazyMatcher(() =>
|
|||
MatchesJsonObject(
|
||||
'completion.getSuggestions result', {'id': isCompletionId}));
|
||||
|
||||
/// completion.listTokenDetails params
|
||||
///
|
||||
/// {
|
||||
/// "file": FilePath
|
||||
/// }
|
||||
final Matcher isCompletionListTokenDetailsParams = LazyMatcher(() =>
|
||||
MatchesJsonObject(
|
||||
'completion.listTokenDetails params', {'file': isFilePath}));
|
||||
|
||||
/// completion.listTokenDetails result
|
||||
///
|
||||
/// {
|
||||
/// "tokens": List<TokenDetails>
|
||||
/// }
|
||||
final Matcher isCompletionListTokenDetailsResult = LazyMatcher(() =>
|
||||
MatchesJsonObject('completion.listTokenDetails result',
|
||||
{'tokens': isListOf(isTokenDetails)}));
|
||||
|
||||
/// completion.registerLibraryPaths params
|
||||
///
|
||||
/// {
|
||||
|
|
|
@ -411,16 +411,6 @@ public interface AnalysisServer {
|
|||
*/
|
||||
public void completion_getSuggestions(String file, int offset, GetSuggestionsConsumer consumer);
|
||||
|
||||
/**
|
||||
* {@code completion.listTokenDetails}
|
||||
*
|
||||
* Inspect analysis server's knowledge about all of a file's tokens including their lexeme, type,
|
||||
* and what element kinds would have been appropriate for the token's program location.
|
||||
*
|
||||
* @param file The path to the file from which tokens should be returned.
|
||||
*/
|
||||
public void completion_listTokenDetails(String file, ListTokenDetailsConsumer consumer);
|
||||
|
||||
/**
|
||||
* {@code completion.registerLibraryPaths}
|
||||
*
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*
|
||||
* This file has been automatically generated. Please do not edit it manually.
|
||||
* To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
|
||||
*/
|
||||
package org.dartlang.analysis.server.protocol;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.server.utilities.general.JsonUtilities;
|
||||
import com.google.dart.server.utilities.general.ObjectUtilities;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* A scanned token along with its inferred type information.
|
||||
*
|
||||
* @coverage dart.server.generated.types
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class TokenDetails {
|
||||
|
||||
public static final TokenDetails[] EMPTY_ARRAY = new TokenDetails[0];
|
||||
|
||||
public static final List<TokenDetails> EMPTY_LIST = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* The token's lexeme.
|
||||
*/
|
||||
private final String lexeme;
|
||||
|
||||
/**
|
||||
* A unique id for the type of the identifier. Omitted if the token is not an identifier in a
|
||||
* reference position.
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
/**
|
||||
* An indication of whether this token is in a declaration or reference position. (If no other
|
||||
* purpose is found for this field then it should be renamed and converted to a boolean value.)
|
||||
* Omitted if the token is not an identifier.
|
||||
*/
|
||||
private final List<String> validElementKinds;
|
||||
|
||||
/**
|
||||
* The offset of the first character of the token in the file which it originated from.
|
||||
*/
|
||||
private final int offset;
|
||||
|
||||
/**
|
||||
* Constructor for {@link TokenDetails}.
|
||||
*/
|
||||
public TokenDetails(String lexeme, String type, List<String> validElementKinds, int offset) {
|
||||
this.lexeme = lexeme;
|
||||
this.type = type;
|
||||
this.validElementKinds = validElementKinds;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof TokenDetails) {
|
||||
TokenDetails other = (TokenDetails) obj;
|
||||
return
|
||||
ObjectUtilities.equals(other.lexeme, lexeme) &&
|
||||
ObjectUtilities.equals(other.type, type) &&
|
||||
ObjectUtilities.equals(other.validElementKinds, validElementKinds) &&
|
||||
other.offset == offset;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static TokenDetails fromJson(JsonObject jsonObject) {
|
||||
String lexeme = jsonObject.get("lexeme").getAsString();
|
||||
String type = jsonObject.get("type") == null ? null : jsonObject.get("type").getAsString();
|
||||
List<String> validElementKinds = jsonObject.get("validElementKinds") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("validElementKinds").getAsJsonArray());
|
||||
int offset = jsonObject.get("offset").getAsInt();
|
||||
return new TokenDetails(lexeme, type, validElementKinds, offset);
|
||||
}
|
||||
|
||||
public static List<TokenDetails> fromJsonArray(JsonArray jsonArray) {
|
||||
if (jsonArray == null) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
ArrayList<TokenDetails> list = new ArrayList<TokenDetails>(jsonArray.size());
|
||||
Iterator<JsonElement> iterator = jsonArray.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
list.add(fromJson(iterator.next().getAsJsonObject()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* The token's lexeme.
|
||||
*/
|
||||
public String getLexeme() {
|
||||
return lexeme;
|
||||
}
|
||||
|
||||
/**
|
||||
* The offset of the first character of the token in the file which it originated from.
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique id for the type of the identifier. Omitted if the token is not an identifier in a
|
||||
* reference position.
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* An indication of whether this token is in a declaration or reference position. (If no other
|
||||
* purpose is found for this field then it should be renamed and converted to a boolean value.)
|
||||
* Omitted if the token is not an identifier.
|
||||
*/
|
||||
public List<String> getValidElementKinds() {
|
||||
return validElementKinds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder builder = new HashCodeBuilder();
|
||||
builder.append(lexeme);
|
||||
builder.append(type);
|
||||
builder.append(validElementKinds);
|
||||
builder.append(offset);
|
||||
return builder.toHashCode();
|
||||
}
|
||||
|
||||
public JsonObject toJson() {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("lexeme", lexeme);
|
||||
if (type != null) {
|
||||
jsonObject.addProperty("type", type);
|
||||
}
|
||||
if (validElementKinds != null) {
|
||||
JsonArray jsonArrayValidElementKinds = new JsonArray();
|
||||
for (String elt : validElementKinds) {
|
||||
jsonArrayValidElementKinds.add(new JsonPrimitive(elt));
|
||||
}
|
||||
jsonObject.add("validElementKinds", jsonArrayValidElementKinds);
|
||||
}
|
||||
jsonObject.addProperty("offset", offset);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("[");
|
||||
builder.append("lexeme=");
|
||||
builder.append(lexeme + ", ");
|
||||
builder.append("type=");
|
||||
builder.append(type + ", ");
|
||||
builder.append("validElementKinds=");
|
||||
builder.append(StringUtils.join(validElementKinds, ", ") + ", ");
|
||||
builder.append("offset=");
|
||||
builder.append(offset);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
<body>
|
||||
<h1>Analysis Server API Specification</h1>
|
||||
<h1 style="color:#999999">Version
|
||||
<version>1.32.2</version>
|
||||
<version>1.32.3</version>
|
||||
</h1>
|
||||
<p>
|
||||
This document contains a specification of the API provided by the
|
||||
|
@ -134,13 +134,20 @@
|
|||
ignoring the item or treating it with some default/fallback handling.
|
||||
</p>
|
||||
<h3>Changelog</h3>
|
||||
<h4>1.32.3</h4>
|
||||
<ul>
|
||||
<li>Removed the experimental <tt>completion.listTokenDetails</tt> request and
|
||||
the associated data types.</li>
|
||||
</ul>
|
||||
<h4>1.32.2</h4>
|
||||
<ul>
|
||||
<li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of comments.</li>
|
||||
<li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of
|
||||
comments.</li>
|
||||
</ul>
|
||||
<h4>1.32.1</h4>
|
||||
<ul>
|
||||
<li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt>.</li>
|
||||
<li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name
|
||||
completions in <tt>pubspec.yaml</tt>.</li>
|
||||
</ul>
|
||||
<h3>Domains</h3>
|
||||
<p>
|
||||
|
@ -1520,32 +1527,6 @@
|
|||
</field>
|
||||
</result>
|
||||
</request>
|
||||
<request method="listTokenDetails" experimental="true">
|
||||
<p>
|
||||
Inspect analysis server's knowledge about all of a file's tokens including
|
||||
their lexeme, type, and what element kinds would have been appropriate for
|
||||
the token's program location.
|
||||
</p>
|
||||
<params>
|
||||
<field name="file">
|
||||
<ref>FilePath</ref>
|
||||
<p>
|
||||
The path to the file from which tokens should be returned.
|
||||
</p>
|
||||
</field>
|
||||
</params>
|
||||
<result>
|
||||
<field name="tokens">
|
||||
<list>
|
||||
<ref>TokenDetails</ref>
|
||||
</list>
|
||||
<p>
|
||||
A list of the file's scanned tokens including analysis information
|
||||
about them.
|
||||
</p>
|
||||
</field>
|
||||
</result>
|
||||
</request>
|
||||
<notification event="results">
|
||||
<p>
|
||||
Reports the completion suggestions that should be presented
|
||||
|
@ -4222,44 +4203,6 @@
|
|||
<value><code>INTERFACE</code></value>
|
||||
</enum>
|
||||
</type>
|
||||
<type name="TokenDetails" experimental="true">
|
||||
<p>
|
||||
A scanned token along with its inferred type information.
|
||||
</p>
|
||||
<object>
|
||||
<field name="lexeme">
|
||||
<ref>String</ref>
|
||||
<p>
|
||||
The token's lexeme.
|
||||
</p>
|
||||
</field>
|
||||
<field name="type" optional="true">
|
||||
<ref>String</ref>
|
||||
<p>
|
||||
A unique id for the type of the identifier.
|
||||
Omitted if the token is not an identifier in a reference position.
|
||||
</p>
|
||||
</field>
|
||||
<field name="validElementKinds" optional="true">
|
||||
<list>
|
||||
<ref>String</ref>
|
||||
</list>
|
||||
<p>
|
||||
An indication of whether this token is in a declaration or reference
|
||||
position. (If no other purpose is found for this field then it should
|
||||
be renamed and converted to a boolean value.)
|
||||
Omitted if the token is not an identifier.
|
||||
</p>
|
||||
</field>
|
||||
<field name="offset">
|
||||
<ref>int</ref>
|
||||
<p>
|
||||
The offset of the first character of the token in the file which it
|
||||
originated from.
|
||||
</p>
|
||||
</field>
|
||||
</object>
|
||||
</type>
|
||||
<type name="ExecutionService">
|
||||
<p>
|
||||
An enumeration of the services provided by the execution
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
const String PROTOCOL_VERSION = '1.32.2';
|
||||
const String PROTOCOL_VERSION = '1.32.3';
|
||||
|
||||
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
|
||||
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
|
||||
|
@ -145,9 +145,6 @@ const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_FILE = 'file';
|
|||
const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_ID = 'id';
|
||||
const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_LABEL = 'label';
|
||||
const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_OFFSET = 'offset';
|
||||
const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS =
|
||||
'completion.listTokenDetails';
|
||||
const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS_FILE = 'file';
|
||||
const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS =
|
||||
'completion.registerLibraryPaths';
|
||||
const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS_PATHS = 'paths';
|
||||
|
@ -159,7 +156,6 @@ const String COMPLETION_RESPONSE_GET_SUGGESTIONS_ID = 'id';
|
|||
const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_CHANGE = 'change';
|
||||
const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_COMPLETION =
|
||||
'completion';
|
||||
const String COMPLETION_RESPONSE_LIST_TOKEN_DETAILS_TOKENS = 'tokens';
|
||||
const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
|
||||
const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
|
||||
const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
|
||||
|
|
|
@ -5886,168 +5886,6 @@ class CompletionGetSuggestionsResult implements ResponseResult {
|
|||
}
|
||||
}
|
||||
|
||||
/// completion.listTokenDetails params
|
||||
///
|
||||
/// {
|
||||
/// "file": FilePath
|
||||
/// }
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
class CompletionListTokenDetailsParams implements RequestParams {
|
||||
String _file;
|
||||
|
||||
/// The path to the file from which tokens should be returned.
|
||||
String get file => _file;
|
||||
|
||||
/// The path to the file from which tokens should be returned.
|
||||
set file(String value) {
|
||||
assert(value != null);
|
||||
_file = value;
|
||||
}
|
||||
|
||||
CompletionListTokenDetailsParams(String file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsParams.fromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json) {
|
||||
json ??= {};
|
||||
if (json is Map) {
|
||||
String file;
|
||||
if (json.containsKey('file')) {
|
||||
file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'file');
|
||||
}
|
||||
return CompletionListTokenDetailsParams(file);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(
|
||||
jsonPath, 'completion.listTokenDetails params', json);
|
||||
}
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsParams.fromRequest(Request request) {
|
||||
return CompletionListTokenDetailsParams.fromJson(
|
||||
RequestDecoder(request), 'params', request.params);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var result = <String, dynamic>{};
|
||||
result['file'] = file;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Request toRequest(String id) {
|
||||
return Request(id, 'completion.listTokenDetails', toJson());
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => json.encode(toJson());
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (other is CompletionListTokenDetailsParams) {
|
||||
return file == other.file;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, file.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/// completion.listTokenDetails result
|
||||
///
|
||||
/// {
|
||||
/// "tokens": List<TokenDetails>
|
||||
/// }
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
class CompletionListTokenDetailsResult implements ResponseResult {
|
||||
List<TokenDetails> _tokens;
|
||||
|
||||
/// A list of the file's scanned tokens including analysis information about
|
||||
/// them.
|
||||
List<TokenDetails> get tokens => _tokens;
|
||||
|
||||
/// A list of the file's scanned tokens including analysis information about
|
||||
/// them.
|
||||
set tokens(List<TokenDetails> value) {
|
||||
assert(value != null);
|
||||
_tokens = value;
|
||||
}
|
||||
|
||||
CompletionListTokenDetailsResult(List<TokenDetails> tokens) {
|
||||
this.tokens = tokens;
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsResult.fromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json) {
|
||||
json ??= {};
|
||||
if (json is Map) {
|
||||
List<TokenDetails> tokens;
|
||||
if (json.containsKey('tokens')) {
|
||||
tokens = jsonDecoder.decodeList(
|
||||
jsonPath + '.tokens',
|
||||
json['tokens'],
|
||||
(String jsonPath, Object json) =>
|
||||
TokenDetails.fromJson(jsonDecoder, jsonPath, json));
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'tokens');
|
||||
}
|
||||
return CompletionListTokenDetailsResult(tokens);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(
|
||||
jsonPath, 'completion.listTokenDetails result', json);
|
||||
}
|
||||
}
|
||||
|
||||
factory CompletionListTokenDetailsResult.fromResponse(Response response) {
|
||||
return CompletionListTokenDetailsResult.fromJson(
|
||||
ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
|
||||
'result',
|
||||
response.result);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var result = <String, dynamic>{};
|
||||
result['tokens'] =
|
||||
tokens.map((TokenDetails value) => value.toJson()).toList();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Response toResponse(String id) {
|
||||
return Response(id, result: toJson());
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => json.encode(toJson());
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (other is CompletionListTokenDetailsResult) {
|
||||
return listEqual(
|
||||
tokens, other.tokens, (TokenDetails a, TokenDetails b) => a == b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, tokens.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/// completion.registerLibraryPaths params
|
||||
///
|
||||
/// {
|
||||
|
@ -21345,151 +21183,6 @@ class ServerStatusParams implements HasToJson {
|
|||
}
|
||||
}
|
||||
|
||||
/// TokenDetails
|
||||
///
|
||||
/// {
|
||||
/// "lexeme": String
|
||||
/// "type": optional String
|
||||
/// "validElementKinds": optional List<String>
|
||||
/// "offset": int
|
||||
/// }
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
class TokenDetails implements HasToJson {
|
||||
String _lexeme;
|
||||
|
||||
String _type;
|
||||
|
||||
List<String> _validElementKinds;
|
||||
|
||||
int _offset;
|
||||
|
||||
/// The token's lexeme.
|
||||
String get lexeme => _lexeme;
|
||||
|
||||
/// The token's lexeme.
|
||||
set lexeme(String value) {
|
||||
assert(value != null);
|
||||
_lexeme = value;
|
||||
}
|
||||
|
||||
/// A unique id for the type of the identifier. Omitted if the token is not
|
||||
/// an identifier in a reference position.
|
||||
String get type => _type;
|
||||
|
||||
/// A unique id for the type of the identifier. Omitted if the token is not
|
||||
/// an identifier in a reference position.
|
||||
set type(String value) {
|
||||
_type = value;
|
||||
}
|
||||
|
||||
/// An indication of whether this token is in a declaration or reference
|
||||
/// position. (If no other purpose is found for this field then it should be
|
||||
/// renamed and converted to a boolean value.) Omitted if the token is not an
|
||||
/// identifier.
|
||||
List<String> get validElementKinds => _validElementKinds;
|
||||
|
||||
/// An indication of whether this token is in a declaration or reference
|
||||
/// position. (If no other purpose is found for this field then it should be
|
||||
/// renamed and converted to a boolean value.) Omitted if the token is not an
|
||||
/// identifier.
|
||||
set validElementKinds(List<String> value) {
|
||||
_validElementKinds = value;
|
||||
}
|
||||
|
||||
/// The offset of the first character of the token in the file which it
|
||||
/// originated from.
|
||||
int get offset => _offset;
|
||||
|
||||
/// The offset of the first character of the token in the file which it
|
||||
/// originated from.
|
||||
set offset(int value) {
|
||||
assert(value != null);
|
||||
_offset = value;
|
||||
}
|
||||
|
||||
TokenDetails(String lexeme, int offset,
|
||||
{String type, List<String> validElementKinds}) {
|
||||
this.lexeme = lexeme;
|
||||
this.type = type;
|
||||
this.validElementKinds = validElementKinds;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
factory TokenDetails.fromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json) {
|
||||
json ??= {};
|
||||
if (json is Map) {
|
||||
String lexeme;
|
||||
if (json.containsKey('lexeme')) {
|
||||
lexeme = jsonDecoder.decodeString(jsonPath + '.lexeme', json['lexeme']);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'lexeme');
|
||||
}
|
||||
String type;
|
||||
if (json.containsKey('type')) {
|
||||
type = jsonDecoder.decodeString(jsonPath + '.type', json['type']);
|
||||
}
|
||||
List<String> validElementKinds;
|
||||
if (json.containsKey('validElementKinds')) {
|
||||
validElementKinds = jsonDecoder.decodeList(
|
||||
jsonPath + '.validElementKinds',
|
||||
json['validElementKinds'],
|
||||
jsonDecoder.decodeString);
|
||||
}
|
||||
int offset;
|
||||
if (json.containsKey('offset')) {
|
||||
offset = jsonDecoder.decodeInt(jsonPath + '.offset', json['offset']);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'offset');
|
||||
}
|
||||
return TokenDetails(lexeme, offset,
|
||||
type: type, validElementKinds: validElementKinds);
|
||||
} else {
|
||||
throw jsonDecoder.mismatch(jsonPath, 'TokenDetails', json);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var result = <String, dynamic>{};
|
||||
result['lexeme'] = lexeme;
|
||||
if (type != null) {
|
||||
result['type'] = type;
|
||||
}
|
||||
if (validElementKinds != null) {
|
||||
result['validElementKinds'] = validElementKinds;
|
||||
}
|
||||
result['offset'] = offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => json.encode(toJson());
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (other is TokenDetails) {
|
||||
return lexeme == other.lexeme &&
|
||||
type == other.type &&
|
||||
listEqual(validElementKinds, other.validElementKinds,
|
||||
(String a, String b) => a == b) &&
|
||||
offset == other.offset;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = 0;
|
||||
hash = JenkinsSmiHash.combine(hash, lexeme.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, type.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, validElementKinds.hashCode);
|
||||
hash = JenkinsSmiHash.combine(hash, offset.hashCode);
|
||||
return JenkinsSmiHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/// TypeHierarchyItem
|
||||
///
|
||||
/// {
|
||||
|
|
Loading…
Reference in a new issue